diff options
774 files changed, 11111 insertions, 12641 deletions
diff --git a/Documentation/DocBook/kernel-locking.tmpl b/Documentation/DocBook/kernel-locking.tmpl index 084f6ad7b7a..0b1a3f97f28 100644 --- a/Documentation/DocBook/kernel-locking.tmpl +++ b/Documentation/DocBook/kernel-locking.tmpl | |||
@@ -1922,9 +1922,12 @@ machines due to caching. | |||
1922 | <function>mutex_lock()</function> | 1922 | <function>mutex_lock()</function> |
1923 | </para> | 1923 | </para> |
1924 | <para> | 1924 | <para> |
1925 | There is a <function>mutex_trylock()</function> which can be | 1925 | There is a <function>mutex_trylock()</function> which does not |
1926 | used inside interrupt context, as it will not sleep. | 1926 | sleep. Still, it must not be used inside interrupt context since |
1927 | its implementation is not safe for that. | ||
1927 | <function>mutex_unlock()</function> will also never sleep. | 1928 | <function>mutex_unlock()</function> will also never sleep. |
1929 | It cannot be used in interrupt context either since a mutex | ||
1930 | must be released by the same task that acquired it. | ||
1928 | </para> | 1931 | </para> |
1929 | </listitem> | 1932 | </listitem> |
1930 | </itemizedlist> | 1933 | </itemizedlist> |
diff --git a/Documentation/DocBook/tracepoint.tmpl b/Documentation/DocBook/tracepoint.tmpl index e8473eae2a2..b57a9ede322 100644 --- a/Documentation/DocBook/tracepoint.tmpl +++ b/Documentation/DocBook/tracepoint.tmpl | |||
@@ -104,4 +104,9 @@ | |||
104 | <title>Block IO</title> | 104 | <title>Block IO</title> |
105 | !Iinclude/trace/events/block.h | 105 | !Iinclude/trace/events/block.h |
106 | </chapter> | 106 | </chapter> |
107 | |||
108 | <chapter id="workqueue"> | ||
109 | <title>Workqueue</title> | ||
110 | !Iinclude/trace/events/workqueue.h | ||
111 | </chapter> | ||
107 | </book> | 112 | </book> |
diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg index 1a07fd674cd..a7952c2bd95 100644 --- a/Documentation/hwmon/f71882fg +++ b/Documentation/hwmon/f71882fg | |||
@@ -2,10 +2,6 @@ Kernel driver f71882fg | |||
2 | ====================== | 2 | ====================== |
3 | 3 | ||
4 | Supported chips: | 4 | Supported chips: |
5 | * Fintek F71808E | ||
6 | Prefix: 'f71808fg' | ||
7 | Addresses scanned: none, address read from Super I/O config space | ||
8 | Datasheet: Not public | ||
9 | * Fintek F71858FG | 5 | * Fintek F71858FG |
10 | Prefix: 'f71858fg' | 6 | Prefix: 'f71858fg' |
11 | Addresses scanned: none, address read from Super I/O config space | 7 | Addresses scanned: none, address read from Super I/O config space |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 2c85c0692b0..8dd7248508a 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1974,15 +1974,18 @@ and is between 256 and 4096 characters. It is defined in the file | |||
1974 | force Enable ASPM even on devices that claim not to support it. | 1974 | force Enable ASPM even on devices that claim not to support it. |
1975 | WARNING: Forcing ASPM on may cause system lockups. | 1975 | WARNING: Forcing ASPM on may cause system lockups. |
1976 | 1976 | ||
1977 | pcie_ports= [PCIE] PCIe ports handling: | ||
1978 | auto Ask the BIOS whether or not to use native PCIe services | ||
1979 | associated with PCIe ports (PME, hot-plug, AER). Use | ||
1980 | them only if that is allowed by the BIOS. | ||
1981 | native Use native PCIe services associated with PCIe ports | ||
1982 | unconditionally. | ||
1983 | compat Treat PCIe ports as PCI-to-PCI bridges, disable the PCIe | ||
1984 | ports driver. | ||
1985 | |||
1977 | pcie_pme= [PCIE,PM] Native PCIe PME signaling options: | 1986 | pcie_pme= [PCIE,PM] Native PCIe PME signaling options: |
1978 | Format: {auto|force}[,nomsi] | ||
1979 | auto Use native PCIe PME signaling if the BIOS allows the | ||
1980 | kernel to control PCIe config registers of root ports. | ||
1981 | force Use native PCIe PME signaling even if the BIOS refuses | ||
1982 | to allow the kernel to control the relevant PCIe config | ||
1983 | registers. | ||
1984 | nomsi Do not use MSI for native PCIe PME signaling (this makes | 1987 | nomsi Do not use MSI for native PCIe PME signaling (this makes |
1985 | all PCIe root ports use INTx for everything). | 1988 | all PCIe root ports use INTx for all services). |
1986 | 1989 | ||
1987 | pcmv= [HW,PCMCIA] BadgePAD 4 | 1990 | pcmv= [HW,PCMCIA] BadgePAD 4 |
1988 | 1991 | ||
@@ -2629,8 +2632,10 @@ and is between 256 and 4096 characters. It is defined in the file | |||
2629 | aux-ide-disks -- unplug non-primary-master IDE devices | 2632 | aux-ide-disks -- unplug non-primary-master IDE devices |
2630 | nics -- unplug network devices | 2633 | nics -- unplug network devices |
2631 | all -- unplug all emulated devices (NICs and IDE disks) | 2634 | all -- unplug all emulated devices (NICs and IDE disks) |
2632 | ignore -- continue loading the Xen platform PCI driver even | 2635 | unnecessary -- unplugging emulated devices is |
2633 | if the version check failed | 2636 | unnecessary even if the host did not respond to |
2637 | the unplug protocol | ||
2638 | never -- do not unplug even if version check succeeds | ||
2634 | 2639 | ||
2635 | xirc2ps_cs= [NET,PCMCIA] | 2640 | xirc2ps_cs= [NET,PCMCIA] |
2636 | Format: | 2641 | Format: |
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index f6f80257add..1565eefd6fd 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt | |||
@@ -1024,6 +1024,10 @@ ThinkPad-specific interface. The driver will disable its native | |||
1024 | backlight brightness control interface if it detects that the standard | 1024 | backlight brightness control interface if it detects that the standard |
1025 | ACPI interface is available in the ThinkPad. | 1025 | ACPI interface is available in the ThinkPad. |
1026 | 1026 | ||
1027 | If you want to use the thinkpad-acpi backlight brightness control | ||
1028 | instead of the generic ACPI video backlight brightness control for some | ||
1029 | reason, you should use the acpi_backlight=vendor kernel parameter. | ||
1030 | |||
1027 | The brightness_enable module parameter can be used to control whether | 1031 | The brightness_enable module parameter can be used to control whether |
1028 | the LCD brightness control feature will be enabled when available. | 1032 | the LCD brightness control feature will be enabled when available. |
1029 | brightness_enable=0 forces it to be disabled. brightness_enable=1 | 1033 | brightness_enable=0 forces it to be disabled. brightness_enable=1 |
diff --git a/Documentation/lguest/Makefile b/Documentation/lguest/Makefile index 28c8cdfcafd..bebac6b4f33 100644 --- a/Documentation/lguest/Makefile +++ b/Documentation/lguest/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | # This creates the demonstration utility "lguest" which runs a Linux guest. | 1 | # This creates the demonstration utility "lguest" which runs a Linux guest. |
2 | CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -I../../include -I../../arch/x86/include -U_FORTIFY_SOURCE | 2 | # Missing headers? Add "-I../../include -I../../arch/x86/include" |
3 | CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -U_FORTIFY_SOURCE | ||
3 | 4 | ||
4 | all: lguest | 5 | all: lguest |
5 | 6 | ||
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index e9ce3c55451..8a6a8c6d498 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c | |||
@@ -39,14 +39,14 @@ | |||
39 | #include <limits.h> | 39 | #include <limits.h> |
40 | #include <stddef.h> | 40 | #include <stddef.h> |
41 | #include <signal.h> | 41 | #include <signal.h> |
42 | #include "linux/lguest_launcher.h" | 42 | #include <linux/virtio_config.h> |
43 | #include "linux/virtio_config.h" | 43 | #include <linux/virtio_net.h> |
44 | #include "linux/virtio_net.h" | 44 | #include <linux/virtio_blk.h> |
45 | #include "linux/virtio_blk.h" | 45 | #include <linux/virtio_console.h> |
46 | #include "linux/virtio_console.h" | 46 | #include <linux/virtio_rng.h> |
47 | #include "linux/virtio_rng.h" | 47 | #include <linux/virtio_ring.h> |
48 | #include "linux/virtio_ring.h" | 48 | #include <asm/bootparam.h> |
49 | #include "asm/bootparam.h" | 49 | #include "../../include/linux/lguest_launcher.h" |
50 | /*L:110 | 50 | /*L:110 |
51 | * We can ignore the 42 include files we need for this program, but I do want | 51 | * We can ignore the 42 include files we need for this program, but I do want |
52 | * to draw attention to the use of kernel-style types. | 52 | * to draw attention to the use of kernel-style types. |
@@ -1447,14 +1447,15 @@ static void add_to_bridge(int fd, const char *if_name, const char *br_name) | |||
1447 | static void configure_device(int fd, const char *tapif, u32 ipaddr) | 1447 | static void configure_device(int fd, const char *tapif, u32 ipaddr) |
1448 | { | 1448 | { |
1449 | struct ifreq ifr; | 1449 | struct ifreq ifr; |
1450 | struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr; | 1450 | struct sockaddr_in sin; |
1451 | 1451 | ||
1452 | memset(&ifr, 0, sizeof(ifr)); | 1452 | memset(&ifr, 0, sizeof(ifr)); |
1453 | strcpy(ifr.ifr_name, tapif); | 1453 | strcpy(ifr.ifr_name, tapif); |
1454 | 1454 | ||
1455 | /* Don't read these incantations. Just cut & paste them like I did! */ | 1455 | /* Don't read these incantations. Just cut & paste them like I did! */ |
1456 | sin->sin_family = AF_INET; | 1456 | sin.sin_family = AF_INET; |
1457 | sin->sin_addr.s_addr = htonl(ipaddr); | 1457 | sin.sin_addr.s_addr = htonl(ipaddr); |
1458 | memcpy(&ifr.ifr_addr, &sin, sizeof(sin)); | ||
1458 | if (ioctl(fd, SIOCSIFADDR, &ifr) != 0) | 1459 | if (ioctl(fd, SIOCSIFADDR, &ifr) != 0) |
1459 | err(1, "Setting %s interface address", tapif); | 1460 | err(1, "Setting %s interface address", tapif); |
1460 | ifr.ifr_flags = IFF_UP; | 1461 | ifr.ifr_flags = IFF_UP; |
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt index 568fa08e82e..302db5da49b 100644 --- a/Documentation/powerpc/booting-without-of.txt +++ b/Documentation/powerpc/booting-without-of.txt | |||
@@ -49,40 +49,13 @@ Table of Contents | |||
49 | f) MDIO on GPIOs | 49 | f) MDIO on GPIOs |
50 | g) SPI busses | 50 | g) SPI busses |
51 | 51 | ||
52 | VII - Marvell Discovery mv64[345]6x System Controller chips | 52 | VII - Specifying interrupt information for devices |
53 | 1) The /system-controller node | ||
54 | 2) Child nodes of /system-controller | ||
55 | a) Marvell Discovery MDIO bus | ||
56 | b) Marvell Discovery ethernet controller | ||
57 | c) Marvell Discovery PHY nodes | ||
58 | d) Marvell Discovery SDMA nodes | ||
59 | e) Marvell Discovery BRG nodes | ||
60 | f) Marvell Discovery CUNIT nodes | ||
61 | g) Marvell Discovery MPSCROUTING nodes | ||
62 | h) Marvell Discovery MPSCINTR nodes | ||
63 | i) Marvell Discovery MPSC nodes | ||
64 | j) Marvell Discovery Watch Dog Timer nodes | ||
65 | k) Marvell Discovery I2C nodes | ||
66 | l) Marvell Discovery PIC (Programmable Interrupt Controller) nodes | ||
67 | m) Marvell Discovery MPP (Multipurpose Pins) multiplexing nodes | ||
68 | n) Marvell Discovery GPP (General Purpose Pins) nodes | ||
69 | o) Marvell Discovery PCI host bridge node | ||
70 | p) Marvell Discovery CPU Error nodes | ||
71 | q) Marvell Discovery SRAM Controller nodes | ||
72 | r) Marvell Discovery PCI Error Handler nodes | ||
73 | s) Marvell Discovery Memory Controller nodes | ||
74 | |||
75 | VIII - Specifying interrupt information for devices | ||
76 | 1) interrupts property | 53 | 1) interrupts property |
77 | 2) interrupt-parent property | 54 | 2) interrupt-parent property |
78 | 3) OpenPIC Interrupt Controllers | 55 | 3) OpenPIC Interrupt Controllers |
79 | 4) ISA Interrupt Controllers | 56 | 4) ISA Interrupt Controllers |
80 | 57 | ||
81 | IX - Specifying GPIO information for devices | 58 | VIII - Specifying device power management information (sleep property) |
82 | 1) gpios property | ||
83 | 2) gpio-controller nodes | ||
84 | |||
85 | X - Specifying device power management information (sleep property) | ||
86 | 59 | ||
87 | Appendix A - Sample SOC node for MPC8540 | 60 | Appendix A - Sample SOC node for MPC8540 |
88 | 61 | ||
diff --git a/Documentation/powerpc/hvcs.txt b/Documentation/powerpc/hvcs.txt index f93462c5db2..6d8be3468d7 100644 --- a/Documentation/powerpc/hvcs.txt +++ b/Documentation/powerpc/hvcs.txt | |||
@@ -560,7 +560,7 @@ The proper channel for reporting bugs is either through the Linux OS | |||
560 | distribution company that provided your OS or by posting issues to the | 560 | distribution company that provided your OS or by posting issues to the |
561 | PowerPC development mailing list at: | 561 | PowerPC development mailing list at: |
562 | 562 | ||
563 | linuxppc-dev@ozlabs.org | 563 | linuxppc-dev@lists.ozlabs.org |
564 | 564 | ||
565 | This request is to provide a documented and searchable public exchange | 565 | This request is to provide a documented and searchable public exchange |
566 | of the problems and solutions surrounding this driver for the benefit of | 566 | of the problems and solutions surrounding this driver for the benefit of |
diff --git a/MAINTAINERS b/MAINTAINERS index 24fbd772e3b..102352e6d61 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -454,9 +454,20 @@ L: linux-rdma@vger.kernel.org | |||
454 | S: Maintained | 454 | S: Maintained |
455 | F: drivers/infiniband/hw/amso1100/ | 455 | F: drivers/infiniband/hw/amso1100/ |
456 | 456 | ||
457 | ANALOG DEVICES INC ASOC DRIVERS | ||
458 | L: uclinux-dist-devel@blackfin.uclinux.org | ||
459 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | ||
460 | W: http://blackfin.uclinux.org/ | ||
461 | S: Supported | ||
462 | F: sound/soc/blackfin/* | ||
463 | F: sound/soc/codecs/ad1* | ||
464 | F: sound/soc/codecs/adau* | ||
465 | F: sound/soc/codecs/adav* | ||
466 | F: sound/soc/codecs/ssm* | ||
467 | |||
457 | AOA (Apple Onboard Audio) ALSA DRIVER | 468 | AOA (Apple Onboard Audio) ALSA DRIVER |
458 | M: Johannes Berg <johannes@sipsolutions.net> | 469 | M: Johannes Berg <johannes@sipsolutions.net> |
459 | L: linuxppc-dev@ozlabs.org | 470 | L: linuxppc-dev@lists.ozlabs.org |
460 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 471 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
461 | S: Maintained | 472 | S: Maintained |
462 | F: sound/aoa/ | 473 | F: sound/aoa/ |
@@ -1441,6 +1452,16 @@ S: Maintained | |||
1441 | F: Documentation/video4linux/cafe_ccic | 1452 | F: Documentation/video4linux/cafe_ccic |
1442 | F: drivers/media/video/cafe_ccic* | 1453 | F: drivers/media/video/cafe_ccic* |
1443 | 1454 | ||
1455 | CAIF NETWORK LAYER | ||
1456 | M: Sjur Braendeland <sjur.brandeland@stericsson.com> | ||
1457 | L: netdev@vger.kernel.org | ||
1458 | S: Supported | ||
1459 | F: Documentation/networking/caif/ | ||
1460 | F: drivers/net/caif/ | ||
1461 | F: include/linux/caif/ | ||
1462 | F: include/net/caif/ | ||
1463 | F: net/caif/ | ||
1464 | |||
1444 | CALGARY x86-64 IOMMU | 1465 | CALGARY x86-64 IOMMU |
1445 | M: Muli Ben-Yehuda <muli@il.ibm.com> | 1466 | M: Muli Ben-Yehuda <muli@il.ibm.com> |
1446 | M: "Jon D. Mason" <jdmason@kudzu.us> | 1467 | M: "Jon D. Mason" <jdmason@kudzu.us> |
@@ -1479,8 +1500,8 @@ F: include/linux/can/platform/ | |||
1479 | 1500 | ||
1480 | CELL BROADBAND ENGINE ARCHITECTURE | 1501 | CELL BROADBAND ENGINE ARCHITECTURE |
1481 | M: Arnd Bergmann <arnd@arndb.de> | 1502 | M: Arnd Bergmann <arnd@arndb.de> |
1482 | L: linuxppc-dev@ozlabs.org | 1503 | L: linuxppc-dev@lists.ozlabs.org |
1483 | L: cbe-oss-dev@ozlabs.org | 1504 | L: cbe-oss-dev@lists.ozlabs.org |
1484 | W: http://www.ibm.com/developerworks/power/cell/ | 1505 | W: http://www.ibm.com/developerworks/power/cell/ |
1485 | S: Supported | 1506 | S: Supported |
1486 | F: arch/powerpc/include/asm/cell*.h | 1507 | F: arch/powerpc/include/asm/cell*.h |
@@ -1672,8 +1693,7 @@ F: kernel/cgroup* | |||
1672 | F: mm/*cgroup* | 1693 | F: mm/*cgroup* |
1673 | 1694 | ||
1674 | CORETEMP HARDWARE MONITORING DRIVER | 1695 | CORETEMP HARDWARE MONITORING DRIVER |
1675 | M: Rudolf Marek <r.marek@assembler.cz> | 1696 | M: Fenghua Yu <fenghua.yu@intel.com> |
1676 | M: Huaxu Wan <huaxu.wan@intel.com> | ||
1677 | L: lm-sensors@lm-sensors.org | 1697 | L: lm-sensors@lm-sensors.org |
1678 | S: Maintained | 1698 | S: Maintained |
1679 | F: Documentation/hwmon/coretemp | 1699 | F: Documentation/hwmon/coretemp |
@@ -2198,6 +2218,12 @@ L: linux-rdma@vger.kernel.org | |||
2198 | S: Supported | 2218 | S: Supported |
2199 | F: drivers/infiniband/hw/ehca/ | 2219 | F: drivers/infiniband/hw/ehca/ |
2200 | 2220 | ||
2221 | EHEA (IBM pSeries eHEA 10Gb ethernet adapter) DRIVER | ||
2222 | M: Breno Leitao <leitao@linux.vnet.ibm.com> | ||
2223 | L: netdev@vger.kernel.org | ||
2224 | S: Maintained | ||
2225 | F: drivers/net/ehea/ | ||
2226 | |||
2201 | EMBEDDED LINUX | 2227 | EMBEDDED LINUX |
2202 | M: Paul Gortmaker <paul.gortmaker@windriver.com> | 2228 | M: Paul Gortmaker <paul.gortmaker@windriver.com> |
2203 | M: Matt Mackall <mpm@selenic.com> | 2229 | M: Matt Mackall <mpm@selenic.com> |
@@ -2293,6 +2319,12 @@ S: Maintained | |||
2293 | F: Documentation/hwmon/f71805f | 2319 | F: Documentation/hwmon/f71805f |
2294 | F: drivers/hwmon/f71805f.c | 2320 | F: drivers/hwmon/f71805f.c |
2295 | 2321 | ||
2322 | FANOTIFY | ||
2323 | M: Eric Paris <eparis@redhat.com> | ||
2324 | S: Maintained | ||
2325 | F: fs/notify/fanotify/ | ||
2326 | F: include/linux/fanotify.h | ||
2327 | |||
2296 | FARSYNC SYNCHRONOUS DRIVER | 2328 | FARSYNC SYNCHRONOUS DRIVER |
2297 | M: Kevin Curtis <kevin.curtis@farsite.co.uk> | 2329 | M: Kevin Curtis <kevin.curtis@farsite.co.uk> |
2298 | W: http://www.farsite.co.uk/ | 2330 | W: http://www.farsite.co.uk/ |
@@ -2378,13 +2410,13 @@ F: include/linux/fb.h | |||
2378 | FREESCALE DMA DRIVER | 2410 | FREESCALE DMA DRIVER |
2379 | M: Li Yang <leoli@freescale.com> | 2411 | M: Li Yang <leoli@freescale.com> |
2380 | M: Zhang Wei <zw@zh-kernel.org> | 2412 | M: Zhang Wei <zw@zh-kernel.org> |
2381 | L: linuxppc-dev@ozlabs.org | 2413 | L: linuxppc-dev@lists.ozlabs.org |
2382 | S: Maintained | 2414 | S: Maintained |
2383 | F: drivers/dma/fsldma.* | 2415 | F: drivers/dma/fsldma.* |
2384 | 2416 | ||
2385 | FREESCALE I2C CPM DRIVER | 2417 | FREESCALE I2C CPM DRIVER |
2386 | M: Jochen Friedrich <jochen@scram.de> | 2418 | M: Jochen Friedrich <jochen@scram.de> |
2387 | L: linuxppc-dev@ozlabs.org | 2419 | L: linuxppc-dev@lists.ozlabs.org |
2388 | L: linux-i2c@vger.kernel.org | 2420 | L: linux-i2c@vger.kernel.org |
2389 | S: Maintained | 2421 | S: Maintained |
2390 | F: drivers/i2c/busses/i2c-cpm.c | 2422 | F: drivers/i2c/busses/i2c-cpm.c |
@@ -2400,7 +2432,7 @@ F: drivers/video/imxfb.c | |||
2400 | FREESCALE SOC FS_ENET DRIVER | 2432 | FREESCALE SOC FS_ENET DRIVER |
2401 | M: Pantelis Antoniou <pantelis.antoniou@gmail.com> | 2433 | M: Pantelis Antoniou <pantelis.antoniou@gmail.com> |
2402 | M: Vitaly Bordug <vbordug@ru.mvista.com> | 2434 | M: Vitaly Bordug <vbordug@ru.mvista.com> |
2403 | L: linuxppc-dev@ozlabs.org | 2435 | L: linuxppc-dev@lists.ozlabs.org |
2404 | L: netdev@vger.kernel.org | 2436 | L: netdev@vger.kernel.org |
2405 | S: Maintained | 2437 | S: Maintained |
2406 | F: drivers/net/fs_enet/ | 2438 | F: drivers/net/fs_enet/ |
@@ -2408,7 +2440,7 @@ F: include/linux/fs_enet_pd.h | |||
2408 | 2440 | ||
2409 | FREESCALE QUICC ENGINE LIBRARY | 2441 | FREESCALE QUICC ENGINE LIBRARY |
2410 | M: Timur Tabi <timur@freescale.com> | 2442 | M: Timur Tabi <timur@freescale.com> |
2411 | L: linuxppc-dev@ozlabs.org | 2443 | L: linuxppc-dev@lists.ozlabs.org |
2412 | S: Supported | 2444 | S: Supported |
2413 | F: arch/powerpc/sysdev/qe_lib/ | 2445 | F: arch/powerpc/sysdev/qe_lib/ |
2414 | F: arch/powerpc/include/asm/*qe.h | 2446 | F: arch/powerpc/include/asm/*qe.h |
@@ -2416,27 +2448,27 @@ F: arch/powerpc/include/asm/*qe.h | |||
2416 | FREESCALE USB PERIPHERAL DRIVERS | 2448 | FREESCALE USB PERIPHERAL DRIVERS |
2417 | M: Li Yang <leoli@freescale.com> | 2449 | M: Li Yang <leoli@freescale.com> |
2418 | L: linux-usb@vger.kernel.org | 2450 | L: linux-usb@vger.kernel.org |
2419 | L: linuxppc-dev@ozlabs.org | 2451 | L: linuxppc-dev@lists.ozlabs.org |
2420 | S: Maintained | 2452 | S: Maintained |
2421 | F: drivers/usb/gadget/fsl* | 2453 | F: drivers/usb/gadget/fsl* |
2422 | 2454 | ||
2423 | FREESCALE QUICC ENGINE UCC ETHERNET DRIVER | 2455 | FREESCALE QUICC ENGINE UCC ETHERNET DRIVER |
2424 | M: Li Yang <leoli@freescale.com> | 2456 | M: Li Yang <leoli@freescale.com> |
2425 | L: netdev@vger.kernel.org | 2457 | L: netdev@vger.kernel.org |
2426 | L: linuxppc-dev@ozlabs.org | 2458 | L: linuxppc-dev@lists.ozlabs.org |
2427 | S: Maintained | 2459 | S: Maintained |
2428 | F: drivers/net/ucc_geth* | 2460 | F: drivers/net/ucc_geth* |
2429 | 2461 | ||
2430 | FREESCALE QUICC ENGINE UCC UART DRIVER | 2462 | FREESCALE QUICC ENGINE UCC UART DRIVER |
2431 | M: Timur Tabi <timur@freescale.com> | 2463 | M: Timur Tabi <timur@freescale.com> |
2432 | L: linuxppc-dev@ozlabs.org | 2464 | L: linuxppc-dev@lists.ozlabs.org |
2433 | S: Supported | 2465 | S: Supported |
2434 | F: drivers/serial/ucc_uart.c | 2466 | F: drivers/serial/ucc_uart.c |
2435 | 2467 | ||
2436 | FREESCALE SOC SOUND DRIVERS | 2468 | FREESCALE SOC SOUND DRIVERS |
2437 | M: Timur Tabi <timur@freescale.com> | 2469 | M: Timur Tabi <timur@freescale.com> |
2438 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 2470 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
2439 | L: linuxppc-dev@ozlabs.org | 2471 | L: linuxppc-dev@lists.ozlabs.org |
2440 | S: Supported | 2472 | S: Supported |
2441 | F: sound/soc/fsl/fsl* | 2473 | F: sound/soc/fsl/fsl* |
2442 | F: sound/soc/fsl/mpc8610_hpcd.c | 2474 | F: sound/soc/fsl/mpc8610_hpcd.c |
@@ -2571,7 +2603,7 @@ F: mm/memory-failure.c | |||
2571 | F: mm/hwpoison-inject.c | 2603 | F: mm/hwpoison-inject.c |
2572 | 2604 | ||
2573 | HYPERVISOR VIRTUAL CONSOLE DRIVER | 2605 | HYPERVISOR VIRTUAL CONSOLE DRIVER |
2574 | L: linuxppc-dev@ozlabs.org | 2606 | L: linuxppc-dev@lists.ozlabs.org |
2575 | S: Odd Fixes | 2607 | S: Odd Fixes |
2576 | F: drivers/char/hvc_* | 2608 | F: drivers/char/hvc_* |
2577 | 2609 | ||
@@ -3489,9 +3521,9 @@ F: drivers/usb/misc/legousbtower.c | |||
3489 | 3521 | ||
3490 | LGUEST | 3522 | LGUEST |
3491 | M: Rusty Russell <rusty@rustcorp.com.au> | 3523 | M: Rusty Russell <rusty@rustcorp.com.au> |
3492 | L: lguest@ozlabs.org | 3524 | L: lguest@lists.ozlabs.org |
3493 | W: http://lguest.ozlabs.org/ | 3525 | W: http://lguest.ozlabs.org/ |
3494 | S: Maintained | 3526 | S: Odd Fixes |
3495 | F: Documentation/lguest/ | 3527 | F: Documentation/lguest/ |
3496 | F: arch/x86/lguest/ | 3528 | F: arch/x86/lguest/ |
3497 | F: drivers/lguest/ | 3529 | F: drivers/lguest/ |
@@ -3508,7 +3540,7 @@ LINUX FOR POWERPC (32-BIT AND 64-BIT) | |||
3508 | M: Benjamin Herrenschmidt <benh@kernel.crashing.org> | 3540 | M: Benjamin Herrenschmidt <benh@kernel.crashing.org> |
3509 | M: Paul Mackerras <paulus@samba.org> | 3541 | M: Paul Mackerras <paulus@samba.org> |
3510 | W: http://www.penguinppc.org/ | 3542 | W: http://www.penguinppc.org/ |
3511 | L: linuxppc-dev@ozlabs.org | 3543 | L: linuxppc-dev@lists.ozlabs.org |
3512 | Q: http://patchwork.ozlabs.org/project/linuxppc-dev/list/ | 3544 | Q: http://patchwork.ozlabs.org/project/linuxppc-dev/list/ |
3513 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git | 3545 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git |
3514 | S: Supported | 3546 | S: Supported |
@@ -3518,14 +3550,14 @@ F: arch/powerpc/ | |||
3518 | LINUX FOR POWER MACINTOSH | 3550 | LINUX FOR POWER MACINTOSH |
3519 | M: Benjamin Herrenschmidt <benh@kernel.crashing.org> | 3551 | M: Benjamin Herrenschmidt <benh@kernel.crashing.org> |
3520 | W: http://www.penguinppc.org/ | 3552 | W: http://www.penguinppc.org/ |
3521 | L: linuxppc-dev@ozlabs.org | 3553 | L: linuxppc-dev@lists.ozlabs.org |
3522 | S: Maintained | 3554 | S: Maintained |
3523 | F: arch/powerpc/platforms/powermac/ | 3555 | F: arch/powerpc/platforms/powermac/ |
3524 | F: drivers/macintosh/ | 3556 | F: drivers/macintosh/ |
3525 | 3557 | ||
3526 | LINUX FOR POWERPC EMBEDDED MPC5XXX | 3558 | LINUX FOR POWERPC EMBEDDED MPC5XXX |
3527 | M: Grant Likely <grant.likely@secretlab.ca> | 3559 | M: Grant Likely <grant.likely@secretlab.ca> |
3528 | L: linuxppc-dev@ozlabs.org | 3560 | L: linuxppc-dev@lists.ozlabs.org |
3529 | T: git git://git.secretlab.ca/git/linux-2.6.git | 3561 | T: git git://git.secretlab.ca/git/linux-2.6.git |
3530 | S: Maintained | 3562 | S: Maintained |
3531 | F: arch/powerpc/platforms/512x/ | 3563 | F: arch/powerpc/platforms/512x/ |
@@ -3535,7 +3567,7 @@ LINUX FOR POWERPC EMBEDDED PPC4XX | |||
3535 | M: Josh Boyer <jwboyer@linux.vnet.ibm.com> | 3567 | M: Josh Boyer <jwboyer@linux.vnet.ibm.com> |
3536 | M: Matt Porter <mporter@kernel.crashing.org> | 3568 | M: Matt Porter <mporter@kernel.crashing.org> |
3537 | W: http://www.penguinppc.org/ | 3569 | W: http://www.penguinppc.org/ |
3538 | L: linuxppc-dev@ozlabs.org | 3570 | L: linuxppc-dev@lists.ozlabs.org |
3539 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx.git | 3571 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx.git |
3540 | S: Maintained | 3572 | S: Maintained |
3541 | F: arch/powerpc/platforms/40x/ | 3573 | F: arch/powerpc/platforms/40x/ |
@@ -3544,7 +3576,7 @@ F: arch/powerpc/platforms/44x/ | |||
3544 | LINUX FOR POWERPC EMBEDDED XILINX VIRTEX | 3576 | LINUX FOR POWERPC EMBEDDED XILINX VIRTEX |
3545 | M: Grant Likely <grant.likely@secretlab.ca> | 3577 | M: Grant Likely <grant.likely@secretlab.ca> |
3546 | W: http://wiki.secretlab.ca/index.php/Linux_on_Xilinx_Virtex | 3578 | W: http://wiki.secretlab.ca/index.php/Linux_on_Xilinx_Virtex |
3547 | L: linuxppc-dev@ozlabs.org | 3579 | L: linuxppc-dev@lists.ozlabs.org |
3548 | T: git git://git.secretlab.ca/git/linux-2.6.git | 3580 | T: git git://git.secretlab.ca/git/linux-2.6.git |
3549 | S: Maintained | 3581 | S: Maintained |
3550 | F: arch/powerpc/*/*virtex* | 3582 | F: arch/powerpc/*/*virtex* |
@@ -3554,20 +3586,20 @@ LINUX FOR POWERPC EMBEDDED PPC8XX | |||
3554 | M: Vitaly Bordug <vitb@kernel.crashing.org> | 3586 | M: Vitaly Bordug <vitb@kernel.crashing.org> |
3555 | M: Marcelo Tosatti <marcelo@kvack.org> | 3587 | M: Marcelo Tosatti <marcelo@kvack.org> |
3556 | W: http://www.penguinppc.org/ | 3588 | W: http://www.penguinppc.org/ |
3557 | L: linuxppc-dev@ozlabs.org | 3589 | L: linuxppc-dev@lists.ozlabs.org |
3558 | S: Maintained | 3590 | S: Maintained |
3559 | F: arch/powerpc/platforms/8xx/ | 3591 | F: arch/powerpc/platforms/8xx/ |
3560 | 3592 | ||
3561 | LINUX FOR POWERPC EMBEDDED PPC83XX AND PPC85XX | 3593 | LINUX FOR POWERPC EMBEDDED PPC83XX AND PPC85XX |
3562 | M: Kumar Gala <galak@kernel.crashing.org> | 3594 | M: Kumar Gala <galak@kernel.crashing.org> |
3563 | W: http://www.penguinppc.org/ | 3595 | W: http://www.penguinppc.org/ |
3564 | L: linuxppc-dev@ozlabs.org | 3596 | L: linuxppc-dev@lists.ozlabs.org |
3565 | S: Maintained | 3597 | S: Maintained |
3566 | F: arch/powerpc/platforms/83xx/ | 3598 | F: arch/powerpc/platforms/83xx/ |
3567 | 3599 | ||
3568 | LINUX FOR POWERPC PA SEMI PWRFICIENT | 3600 | LINUX FOR POWERPC PA SEMI PWRFICIENT |
3569 | M: Olof Johansson <olof@lixom.net> | 3601 | M: Olof Johansson <olof@lixom.net> |
3570 | L: linuxppc-dev@ozlabs.org | 3602 | L: linuxppc-dev@lists.ozlabs.org |
3571 | S: Maintained | 3603 | S: Maintained |
3572 | F: arch/powerpc/platforms/pasemi/ | 3604 | F: arch/powerpc/platforms/pasemi/ |
3573 | F: drivers/*/*pasemi* | 3605 | F: drivers/*/*pasemi* |
@@ -3920,8 +3952,7 @@ F: Documentation/sound/oss/MultiSound | |||
3920 | F: sound/oss/msnd* | 3952 | F: sound/oss/msnd* |
3921 | 3953 | ||
3922 | MULTITECH MULTIPORT CARD (ISICOM) | 3954 | MULTITECH MULTIPORT CARD (ISICOM) |
3923 | M: Jiri Slaby <jirislaby@gmail.com> | 3955 | S: Orphan |
3924 | S: Maintained | ||
3925 | F: drivers/char/isicom.c | 3956 | F: drivers/char/isicom.c |
3926 | F: include/linux/isicom.h | 3957 | F: include/linux/isicom.h |
3927 | 3958 | ||
@@ -4600,7 +4631,7 @@ F: include/linux/preempt.h | |||
4600 | PRISM54 WIRELESS DRIVER | 4631 | PRISM54 WIRELESS DRIVER |
4601 | M: "Luis R. Rodriguez" <mcgrof@gmail.com> | 4632 | M: "Luis R. Rodriguez" <mcgrof@gmail.com> |
4602 | L: linux-wireless@vger.kernel.org | 4633 | L: linux-wireless@vger.kernel.org |
4603 | W: http://prism54.org | 4634 | W: http://wireless.kernel.org/en/users/Drivers/p54 |
4604 | S: Obsolete | 4635 | S: Obsolete |
4605 | F: drivers/net/wireless/prism54/ | 4636 | F: drivers/net/wireless/prism54/ |
4606 | 4637 | ||
@@ -4613,14 +4644,14 @@ F: drivers/ata/sata_promise.* | |||
4613 | PS3 NETWORK SUPPORT | 4644 | PS3 NETWORK SUPPORT |
4614 | M: Geoff Levand <geoff@infradead.org> | 4645 | M: Geoff Levand <geoff@infradead.org> |
4615 | L: netdev@vger.kernel.org | 4646 | L: netdev@vger.kernel.org |
4616 | L: cbe-oss-dev@ozlabs.org | 4647 | L: cbe-oss-dev@lists.ozlabs.org |
4617 | S: Maintained | 4648 | S: Maintained |
4618 | F: drivers/net/ps3_gelic_net.* | 4649 | F: drivers/net/ps3_gelic_net.* |
4619 | 4650 | ||
4620 | PS3 PLATFORM SUPPORT | 4651 | PS3 PLATFORM SUPPORT |
4621 | M: Geoff Levand <geoff@infradead.org> | 4652 | M: Geoff Levand <geoff@infradead.org> |
4622 | L: linuxppc-dev@ozlabs.org | 4653 | L: linuxppc-dev@lists.ozlabs.org |
4623 | L: cbe-oss-dev@ozlabs.org | 4654 | L: cbe-oss-dev@lists.ozlabs.org |
4624 | S: Maintained | 4655 | S: Maintained |
4625 | F: arch/powerpc/boot/ps3* | 4656 | F: arch/powerpc/boot/ps3* |
4626 | F: arch/powerpc/include/asm/lv1call.h | 4657 | F: arch/powerpc/include/asm/lv1call.h |
@@ -4634,7 +4665,7 @@ F: sound/ppc/snd_ps3* | |||
4634 | 4665 | ||
4635 | PS3VRAM DRIVER | 4666 | PS3VRAM DRIVER |
4636 | M: Jim Paris <jim@jtan.com> | 4667 | M: Jim Paris <jim@jtan.com> |
4637 | L: cbe-oss-dev@ozlabs.org | 4668 | L: cbe-oss-dev@lists.ozlabs.org |
4638 | S: Maintained | 4669 | S: Maintained |
4639 | F: drivers/block/ps3vram.c | 4670 | F: drivers/block/ps3vram.c |
4640 | 4671 | ||
@@ -5080,7 +5111,7 @@ F: drivers/mmc/host/sdhci.* | |||
5080 | 5111 | ||
5081 | SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF) | 5112 | SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF) |
5082 | M: Anton Vorontsov <avorontsov@ru.mvista.com> | 5113 | M: Anton Vorontsov <avorontsov@ru.mvista.com> |
5083 | L: linuxppc-dev@ozlabs.org | 5114 | L: linuxppc-dev@lists.ozlabs.org |
5084 | L: linux-mmc@vger.kernel.org | 5115 | L: linux-mmc@vger.kernel.org |
5085 | S: Maintained | 5116 | S: Maintained |
5086 | F: drivers/mmc/host/sdhci-of.* | 5117 | F: drivers/mmc/host/sdhci-of.* |
@@ -5497,8 +5528,8 @@ F: drivers/net/spider_net* | |||
5497 | 5528 | ||
5498 | SPU FILE SYSTEM | 5529 | SPU FILE SYSTEM |
5499 | M: Jeremy Kerr <jk@ozlabs.org> | 5530 | M: Jeremy Kerr <jk@ozlabs.org> |
5500 | L: linuxppc-dev@ozlabs.org | 5531 | L: linuxppc-dev@lists.ozlabs.org |
5501 | L: cbe-oss-dev@ozlabs.org | 5532 | L: cbe-oss-dev@lists.ozlabs.org |
5502 | W: http://www.ibm.com/developerworks/power/cell/ | 5533 | W: http://www.ibm.com/developerworks/power/cell/ |
5503 | S: Supported | 5534 | S: Supported |
5504 | F: Documentation/filesystems/spufs.txt | 5535 | F: Documentation/filesystems/spufs.txt |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 2 | 1 | VERSION = 2 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
3 | SUBLEVEL = 36 | 3 | SUBLEVEL = 36 |
4 | EXTRAVERSION = -rc1 | 4 | EXTRAVERSION = -rc3 |
5 | NAME = Sheep on Meth | 5 | NAME = Sheep on Meth |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
@@ -1408,8 +1408,8 @@ checkstack: | |||
1408 | $(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \ | 1408 | $(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \ |
1409 | $(PERL) $(src)/scripts/checkstack.pl $(CHECKSTACK_ARCH) | 1409 | $(PERL) $(src)/scripts/checkstack.pl $(CHECKSTACK_ARCH) |
1410 | 1410 | ||
1411 | kernelrelease: include/config/kernel.release | 1411 | kernelrelease: |
1412 | @echo $(KERNELRELEASE) | 1412 | @echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))" |
1413 | 1413 | ||
1414 | kernelversion: | 1414 | kernelversion: |
1415 | @echo $(KERNELVERSION) | 1415 | @echo $(KERNELVERSION) |
diff --git a/arch/alpha/include/asm/cache.h b/arch/alpha/include/asm/cache.h index f199e69a5d0..ad368a93a46 100644 --- a/arch/alpha/include/asm/cache.h +++ b/arch/alpha/include/asm/cache.h | |||
@@ -17,7 +17,6 @@ | |||
17 | # define L1_CACHE_SHIFT 5 | 17 | # define L1_CACHE_SHIFT 5 |
18 | #endif | 18 | #endif |
19 | 19 | ||
20 | #define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)) | ||
21 | #define SMP_CACHE_BYTES L1_CACHE_BYTES | 20 | #define SMP_CACHE_BYTES L1_CACHE_BYTES |
22 | 21 | ||
23 | #endif | 22 | #endif |
diff --git a/arch/alpha/kernel/err_marvel.c b/arch/alpha/kernel/err_marvel.c index 52a79dfc13c..5c905aaaecc 100644 --- a/arch/alpha/kernel/err_marvel.c +++ b/arch/alpha/kernel/err_marvel.c | |||
@@ -109,7 +109,7 @@ marvel_print_err_cyc(u64 err_cyc) | |||
109 | #define IO7__ERR_CYC__CYCLE__M (0x7) | 109 | #define IO7__ERR_CYC__CYCLE__M (0x7) |
110 | 110 | ||
111 | printk("%s Packet In Error: %s\n" | 111 | printk("%s Packet In Error: %s\n" |
112 | "%s Error in %s, cycle %ld%s%s\n", | 112 | "%s Error in %s, cycle %lld%s%s\n", |
113 | err_print_prefix, | 113 | err_print_prefix, |
114 | packet_desc[EXTRACT(err_cyc, IO7__ERR_CYC__PACKET)], | 114 | packet_desc[EXTRACT(err_cyc, IO7__ERR_CYC__PACKET)], |
115 | err_print_prefix, | 115 | err_print_prefix, |
@@ -313,7 +313,7 @@ marvel_print_po7_ugbge_sym(u64 ugbge_sym) | |||
313 | } | 313 | } |
314 | 314 | ||
315 | printk("%s Up Hose Garbage Symptom:\n" | 315 | printk("%s Up Hose Garbage Symptom:\n" |
316 | "%s Source Port: %ld - Dest PID: %ld - OpCode: %s\n", | 316 | "%s Source Port: %lld - Dest PID: %lld - OpCode: %s\n", |
317 | err_print_prefix, | 317 | err_print_prefix, |
318 | err_print_prefix, | 318 | err_print_prefix, |
319 | EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_SRC_PORT), | 319 | EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_SRC_PORT), |
@@ -552,7 +552,7 @@ marvel_print_pox_spl_cmplt(u64 spl_cmplt) | |||
552 | #define IO7__POX_SPLCMPLT__REM_BYTE_COUNT__M (0xfff) | 552 | #define IO7__POX_SPLCMPLT__REM_BYTE_COUNT__M (0xfff) |
553 | 553 | ||
554 | printk("%s Split Completion Error:\n" | 554 | printk("%s Split Completion Error:\n" |
555 | "%s Source (Bus:Dev:Func): %ld:%ld:%ld\n", | 555 | "%s Source (Bus:Dev:Func): %lld:%lld:%lld\n", |
556 | err_print_prefix, | 556 | err_print_prefix, |
557 | err_print_prefix, | 557 | err_print_prefix, |
558 | EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_BUS), | 558 | EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_BUS), |
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index fb58150a7e8..5d1e6d6ce68 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
@@ -252,7 +252,7 @@ SYSCALL_DEFINE3(osf_statfs, const char __user *, pathname, | |||
252 | 252 | ||
253 | retval = user_path(pathname, &path); | 253 | retval = user_path(pathname, &path); |
254 | if (!retval) { | 254 | if (!retval) { |
255 | retval = do_osf_statfs(&path buffer, bufsiz); | 255 | retval = do_osf_statfs(&path, buffer, bufsiz); |
256 | path_put(&path); | 256 | path_put(&path); |
257 | } | 257 | } |
258 | return retval; | 258 | return retval; |
diff --git a/arch/alpha/kernel/perf_event.c b/arch/alpha/kernel/perf_event.c index 51c39fa4169..85d8e4f58c8 100644 --- a/arch/alpha/kernel/perf_event.c +++ b/arch/alpha/kernel/perf_event.c | |||
@@ -241,20 +241,20 @@ static inline unsigned long alpha_read_pmc(int idx) | |||
241 | static int alpha_perf_event_set_period(struct perf_event *event, | 241 | static int alpha_perf_event_set_period(struct perf_event *event, |
242 | struct hw_perf_event *hwc, int idx) | 242 | struct hw_perf_event *hwc, int idx) |
243 | { | 243 | { |
244 | long left = atomic64_read(&hwc->period_left); | 244 | long left = local64_read(&hwc->period_left); |
245 | long period = hwc->sample_period; | 245 | long period = hwc->sample_period; |
246 | int ret = 0; | 246 | int ret = 0; |
247 | 247 | ||
248 | if (unlikely(left <= -period)) { | 248 | if (unlikely(left <= -period)) { |
249 | left = period; | 249 | left = period; |
250 | atomic64_set(&hwc->period_left, left); | 250 | local64_set(&hwc->period_left, left); |
251 | hwc->last_period = period; | 251 | hwc->last_period = period; |
252 | ret = 1; | 252 | ret = 1; |
253 | } | 253 | } |
254 | 254 | ||
255 | if (unlikely(left <= 0)) { | 255 | if (unlikely(left <= 0)) { |
256 | left += period; | 256 | left += period; |
257 | atomic64_set(&hwc->period_left, left); | 257 | local64_set(&hwc->period_left, left); |
258 | hwc->last_period = period; | 258 | hwc->last_period = period; |
259 | ret = 1; | 259 | ret = 1; |
260 | } | 260 | } |
@@ -269,7 +269,7 @@ static int alpha_perf_event_set_period(struct perf_event *event, | |||
269 | if (left > (long)alpha_pmu->pmc_max_period[idx]) | 269 | if (left > (long)alpha_pmu->pmc_max_period[idx]) |
270 | left = alpha_pmu->pmc_max_period[idx]; | 270 | left = alpha_pmu->pmc_max_period[idx]; |
271 | 271 | ||
272 | atomic64_set(&hwc->prev_count, (unsigned long)(-left)); | 272 | local64_set(&hwc->prev_count, (unsigned long)(-left)); |
273 | 273 | ||
274 | alpha_write_pmc(idx, (unsigned long)(-left)); | 274 | alpha_write_pmc(idx, (unsigned long)(-left)); |
275 | 275 | ||
@@ -300,10 +300,10 @@ static unsigned long alpha_perf_event_update(struct perf_event *event, | |||
300 | long delta; | 300 | long delta; |
301 | 301 | ||
302 | again: | 302 | again: |
303 | prev_raw_count = atomic64_read(&hwc->prev_count); | 303 | prev_raw_count = local64_read(&hwc->prev_count); |
304 | new_raw_count = alpha_read_pmc(idx); | 304 | new_raw_count = alpha_read_pmc(idx); |
305 | 305 | ||
306 | if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count, | 306 | if (local64_cmpxchg(&hwc->prev_count, prev_raw_count, |
307 | new_raw_count) != prev_raw_count) | 307 | new_raw_count) != prev_raw_count) |
308 | goto again; | 308 | goto again; |
309 | 309 | ||
@@ -316,8 +316,8 @@ again: | |||
316 | delta += alpha_pmu->pmc_max_period[idx] + 1; | 316 | delta += alpha_pmu->pmc_max_period[idx] + 1; |
317 | } | 317 | } |
318 | 318 | ||
319 | atomic64_add(delta, &event->count); | 319 | local64_add(delta, &event->count); |
320 | atomic64_sub(delta, &hwc->period_left); | 320 | local64_sub(delta, &hwc->period_left); |
321 | 321 | ||
322 | return new_raw_count; | 322 | return new_raw_count; |
323 | } | 323 | } |
@@ -636,7 +636,7 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
636 | if (!hwc->sample_period) { | 636 | if (!hwc->sample_period) { |
637 | hwc->sample_period = alpha_pmu->pmc_max_period[0]; | 637 | hwc->sample_period = alpha_pmu->pmc_max_period[0]; |
638 | hwc->last_period = hwc->sample_period; | 638 | hwc->last_period = hwc->sample_period; |
639 | atomic64_set(&hwc->period_left, hwc->sample_period); | 639 | local64_set(&hwc->period_left, hwc->sample_period); |
640 | } | 640 | } |
641 | 641 | ||
642 | return 0; | 642 | return 0; |
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 88e608aebc8..842dba308ea 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c | |||
@@ -387,8 +387,9 @@ EXPORT_SYMBOL(dump_elf_task_fp); | |||
387 | * sys_execve() executes a new program. | 387 | * sys_execve() executes a new program. |
388 | */ | 388 | */ |
389 | asmlinkage int | 389 | asmlinkage int |
390 | do_sys_execve(const char __user *ufilename, char __user * __user *argv, | 390 | do_sys_execve(const char __user *ufilename, |
391 | char __user * __user *envp, struct pt_regs *regs) | 391 | const char __user *const __user *argv, |
392 | const char __user *const __user *envp, struct pt_regs *regs) | ||
392 | { | 393 | { |
393 | int error; | 394 | int error; |
394 | char *filename; | 395 | char *filename; |
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h index 3d2627ec986..d3e52d3fd59 100644 --- a/arch/alpha/kernel/proto.h +++ b/arch/alpha/kernel/proto.h | |||
@@ -156,9 +156,6 @@ extern void SMC669_Init(int); | |||
156 | /* es1888.c */ | 156 | /* es1888.c */ |
157 | extern void es1888_init(void); | 157 | extern void es1888_init(void); |
158 | 158 | ||
159 | /* ns87312.c */ | ||
160 | extern void ns87312_enable_ide(long ide_base); | ||
161 | |||
162 | /* ../lib/fpreg.c */ | 159 | /* ../lib/fpreg.c */ |
163 | extern void alpha_write_fp_reg (unsigned long reg, unsigned long val); | 160 | extern void alpha_write_fp_reg (unsigned long reg, unsigned long val); |
164 | extern unsigned long alpha_read_fp_reg (unsigned long reg); | 161 | extern unsigned long alpha_read_fp_reg (unsigned long reg); |
diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c index affd0f3f25d..14c8898d19e 100644 --- a/arch/alpha/kernel/sys_cabriolet.c +++ b/arch/alpha/kernel/sys_cabriolet.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include "irq_impl.h" | 33 | #include "irq_impl.h" |
34 | #include "pci_impl.h" | 34 | #include "pci_impl.h" |
35 | #include "machvec_impl.h" | 35 | #include "machvec_impl.h" |
36 | 36 | #include "pc873xx.h" | |
37 | 37 | ||
38 | /* Note mask bit is true for DISABLED irqs. */ | 38 | /* Note mask bit is true for DISABLED irqs. */ |
39 | static unsigned long cached_irq_mask = ~0UL; | 39 | static unsigned long cached_irq_mask = ~0UL; |
@@ -236,17 +236,30 @@ cabriolet_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | |||
236 | } | 236 | } |
237 | 237 | ||
238 | static inline void __init | 238 | static inline void __init |
239 | cabriolet_enable_ide(void) | ||
240 | { | ||
241 | if (pc873xx_probe() == -1) { | ||
242 | printk(KERN_ERR "Probing for PC873xx Super IO chip failed.\n"); | ||
243 | } else { | ||
244 | printk(KERN_INFO "Found %s Super IO chip at 0x%x\n", | ||
245 | pc873xx_get_model(), pc873xx_get_base()); | ||
246 | |||
247 | pc873xx_enable_ide(); | ||
248 | } | ||
249 | } | ||
250 | |||
251 | static inline void __init | ||
239 | cabriolet_init_pci(void) | 252 | cabriolet_init_pci(void) |
240 | { | 253 | { |
241 | common_init_pci(); | 254 | common_init_pci(); |
242 | ns87312_enable_ide(0x398); | 255 | cabriolet_enable_ide(); |
243 | } | 256 | } |
244 | 257 | ||
245 | static inline void __init | 258 | static inline void __init |
246 | cia_cab_init_pci(void) | 259 | cia_cab_init_pci(void) |
247 | { | 260 | { |
248 | cia_init_pci(); | 261 | cia_init_pci(); |
249 | ns87312_enable_ide(0x398); | 262 | cabriolet_enable_ide(); |
250 | } | 263 | } |
251 | 264 | ||
252 | /* | 265 | /* |
diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c index 230464885b5..4da596b6adb 100644 --- a/arch/alpha/kernel/sys_takara.c +++ b/arch/alpha/kernel/sys_takara.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include "irq_impl.h" | 29 | #include "irq_impl.h" |
30 | #include "pci_impl.h" | 30 | #include "pci_impl.h" |
31 | #include "machvec_impl.h" | 31 | #include "machvec_impl.h" |
32 | 32 | #include "pc873xx.h" | |
33 | 33 | ||
34 | /* Note mask bit is true for DISABLED irqs. */ | 34 | /* Note mask bit is true for DISABLED irqs. */ |
35 | static unsigned long cached_irq_mask[2] = { -1, -1 }; | 35 | static unsigned long cached_irq_mask[2] = { -1, -1 }; |
@@ -264,7 +264,14 @@ takara_init_pci(void) | |||
264 | alpha_mv.pci_map_irq = takara_map_irq_srm; | 264 | alpha_mv.pci_map_irq = takara_map_irq_srm; |
265 | 265 | ||
266 | cia_init_pci(); | 266 | cia_init_pci(); |
267 | ns87312_enable_ide(0x26e); | 267 | |
268 | if (pc873xx_probe() == -1) { | ||
269 | printk(KERN_ERR "Probing for PC873xx Super IO chip failed.\n"); | ||
270 | } else { | ||
271 | printk(KERN_INFO "Found %s Super IO chip at 0x%x\n", | ||
272 | pc873xx_get_model(), pc873xx_get_base()); | ||
273 | pc873xx_enable_ide(); | ||
274 | } | ||
268 | } | 275 | } |
269 | 276 | ||
270 | 277 | ||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 92951103255..16bc8eb4901 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -1601,6 +1601,7 @@ config ZRELADDR | |||
1601 | ARCH_ORION5X ||\ | 1601 | ARCH_ORION5X ||\ |
1602 | ARCH_SPEAR3XX ||\ | 1602 | ARCH_SPEAR3XX ||\ |
1603 | ARCH_SPEAR6XX ||\ | 1603 | ARCH_SPEAR6XX ||\ |
1604 | ARCH_TEGRA ||\ | ||
1604 | ARCH_U8500 ||\ | 1605 | ARCH_U8500 ||\ |
1605 | ARCH_VERSATILE ||\ | 1606 | ARCH_VERSATILE ||\ |
1606 | ARCH_W90X900 | 1607 | ARCH_W90X900 |
@@ -1622,7 +1623,8 @@ config ZRELADDR | |||
1622 | default 0x40008000 if ARCH_STMP378X ||\ | 1623 | default 0x40008000 if ARCH_STMP378X ||\ |
1623 | ARCH_STMP37XX ||\ | 1624 | ARCH_STMP37XX ||\ |
1624 | ARCH_SH7372 ||\ | 1625 | ARCH_SH7372 ||\ |
1625 | ARCH_SH7377 | 1626 | ARCH_SH7377 ||\ |
1627 | ARCH_S5PV310 | ||
1626 | default 0x50008000 if ARCH_S3C64XX ||\ | 1628 | default 0x50008000 if ARCH_S3C64XX ||\ |
1627 | ARCH_SH7367 | 1629 | ARCH_SH7367 |
1628 | default 0x60008000 if ARCH_VEXPRESS | 1630 | default 0x60008000 if ARCH_VEXPRESS |
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 99b8200138d..59c1ce858fc 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
@@ -21,6 +21,9 @@ GZFLAGS :=-9 | |||
21 | # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb: | 21 | # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb: |
22 | KBUILD_CFLAGS +=$(call cc-option,-marm,) | 22 | KBUILD_CFLAGS +=$(call cc-option,-marm,) |
23 | 23 | ||
24 | # Never generate .eh_frame | ||
25 | KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm) | ||
26 | |||
24 | # Do not use arch/arm/defconfig - it's always outdated. | 27 | # Do not use arch/arm/defconfig - it's always outdated. |
25 | # Select a platform tht is kept up-to-date | 28 | # Select a platform tht is kept up-to-date |
26 | KBUILD_DEFCONFIG := versatile_defconfig | 29 | KBUILD_DEFCONFIG := versatile_defconfig |
diff --git a/arch/arm/configs/omap_4430sdp_defconfig b/arch/arm/configs/omap_4430sdp_defconfig index 63e0c2d50f3..14c1e18c648 100644 --- a/arch/arm/configs/omap_4430sdp_defconfig +++ b/arch/arm/configs/omap_4430sdp_defconfig | |||
@@ -13,6 +13,9 @@ CONFIG_MODULE_SRCVERSION_ALL=y | |||
13 | # CONFIG_BLK_DEV_BSG is not set | 13 | # CONFIG_BLK_DEV_BSG is not set |
14 | CONFIG_ARCH_OMAP=y | 14 | CONFIG_ARCH_OMAP=y |
15 | CONFIG_ARCH_OMAP4=y | 15 | CONFIG_ARCH_OMAP4=y |
16 | # CONFIG_ARCH_OMAP2PLUS_TYPICAL is not set | ||
17 | # CONFIG_ARCH_OMAP2 is not set | ||
18 | # CONFIG_ARCH_OMAP3 is not set | ||
16 | # CONFIG_OMAP_MUX is not set | 19 | # CONFIG_OMAP_MUX is not set |
17 | CONFIG_OMAP_32K_TIMER=y | 20 | CONFIG_OMAP_32K_TIMER=y |
18 | CONFIG_OMAP_DM_TIMER=y | 21 | CONFIG_OMAP_DM_TIMER=y |
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index c974be8913a..7ce15eb15f7 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h | |||
@@ -158,15 +158,24 @@ struct pt_regs { | |||
158 | */ | 158 | */ |
159 | static inline int valid_user_regs(struct pt_regs *regs) | 159 | static inline int valid_user_regs(struct pt_regs *regs) |
160 | { | 160 | { |
161 | if (user_mode(regs) && (regs->ARM_cpsr & PSR_I_BIT) == 0) { | 161 | unsigned long mode = regs->ARM_cpsr & MODE_MASK; |
162 | regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT); | 162 | |
163 | return 1; | 163 | /* |
164 | * Always clear the F (FIQ) and A (delayed abort) bits | ||
165 | */ | ||
166 | regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT); | ||
167 | |||
168 | if ((regs->ARM_cpsr & PSR_I_BIT) == 0) { | ||
169 | if (mode == USR_MODE) | ||
170 | return 1; | ||
171 | if (elf_hwcap & HWCAP_26BIT && mode == USR26_MODE) | ||
172 | return 1; | ||
164 | } | 173 | } |
165 | 174 | ||
166 | /* | 175 | /* |
167 | * Force CPSR to something logical... | 176 | * Force CPSR to something logical... |
168 | */ | 177 | */ |
169 | regs->ARM_cpsr &= PSR_f | PSR_s | (PSR_x & ~PSR_A_BIT) | PSR_T_BIT | MODE32_BIT; | 178 | regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | PSR_T_BIT | MODE32_BIT; |
170 | if (!(elf_hwcap & HWCAP_26BIT)) | 179 | if (!(elf_hwcap & HWCAP_26BIT)) |
171 | regs->ARM_cpsr |= USR_MODE; | 180 | regs->ARM_cpsr |= USR_MODE; |
172 | 181 | ||
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index dd2bf53000f..d02cfb68348 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h | |||
@@ -392,6 +392,7 @@ | |||
392 | #define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE+363) | 392 | #define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE+363) |
393 | #define __NR_perf_event_open (__NR_SYSCALL_BASE+364) | 393 | #define __NR_perf_event_open (__NR_SYSCALL_BASE+364) |
394 | #define __NR_recvmmsg (__NR_SYSCALL_BASE+365) | 394 | #define __NR_recvmmsg (__NR_SYSCALL_BASE+365) |
395 | #define __NR_accept4 (__NR_SYSCALL_BASE+366) | ||
395 | 396 | ||
396 | /* | 397 | /* |
397 | * The following SWIs are ARM private. | 398 | * The following SWIs are ARM private. |
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 37ae301cc47..afeb71fa72c 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S | |||
@@ -375,6 +375,7 @@ | |||
375 | CALL(sys_rt_tgsigqueueinfo) | 375 | CALL(sys_rt_tgsigqueueinfo) |
376 | CALL(sys_perf_event_open) | 376 | CALL(sys_perf_event_open) |
377 | /* 365 */ CALL(sys_recvmmsg) | 377 | /* 365 */ CALL(sys_recvmmsg) |
378 | CALL(sys_accept4) | ||
378 | #ifndef syscalls_counted | 379 | #ifndef syscalls_counted |
379 | .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls | 380 | .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls |
380 | #define syscalls_counted | 381 | #define syscalls_counted |
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c index 56418f98cd0..33c7077174d 100644 --- a/arch/arm/kernel/etm.c +++ b/arch/arm/kernel/etm.c | |||
@@ -230,7 +230,7 @@ static void etm_dump(void) | |||
230 | etb_lock(t); | 230 | etb_lock(t); |
231 | } | 231 | } |
232 | 232 | ||
233 | static void sysrq_etm_dump(int key, struct tty_struct *tty) | 233 | static void sysrq_etm_dump(int key) |
234 | { | 234 | { |
235 | dev_dbg(tracer.dev, "Dumping ETB buffer\n"); | 235 | dev_dbg(tracer.dev, "Dumping ETB buffer\n"); |
236 | etm_dump(); | 236 | etm_dump(); |
diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c index 778c2f7024f..d6e8b4d2e60 100644 --- a/arch/arm/kernel/kgdb.c +++ b/arch/arm/kernel/kgdb.c | |||
@@ -79,7 +79,7 @@ sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task) | |||
79 | return; | 79 | return; |
80 | 80 | ||
81 | /* Initialize to zero */ | 81 | /* Initialize to zero */ |
82 | for (regno = 0; regno < GDB_MAX_REGS; regno++) | 82 | for (regno = 0; regno < DBG_MAX_REG_NUM; regno++) |
83 | gdb_regs[regno] = 0; | 83 | gdb_regs[regno] = 0; |
84 | 84 | ||
85 | /* Otherwise, we have only some registers from switch_to() */ | 85 | /* Otherwise, we have only some registers from switch_to() */ |
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index 5b7c541a4c6..62e7c61d034 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c | |||
@@ -62,8 +62,9 @@ asmlinkage int sys_vfork(struct pt_regs *regs) | |||
62 | /* sys_execve() executes a new program. | 62 | /* sys_execve() executes a new program. |
63 | * This is called indirectly via a small wrapper | 63 | * This is called indirectly via a small wrapper |
64 | */ | 64 | */ |
65 | asmlinkage int sys_execve(const char __user *filenamei, char __user * __user *argv, | 65 | asmlinkage int sys_execve(const char __user *filenamei, |
66 | char __user * __user *envp, struct pt_regs *regs) | 66 | const char __user *const __user *argv, |
67 | const char __user *const __user *envp, struct pt_regs *regs) | ||
67 | { | 68 | { |
68 | int error; | 69 | int error; |
69 | char * filename; | 70 | char * filename; |
@@ -78,14 +79,17 @@ out: | |||
78 | return error; | 79 | return error; |
79 | } | 80 | } |
80 | 81 | ||
81 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | 82 | int kernel_execve(const char *filename, |
83 | const char *const argv[], | ||
84 | const char *const envp[]) | ||
82 | { | 85 | { |
83 | struct pt_regs regs; | 86 | struct pt_regs regs; |
84 | int ret; | 87 | int ret; |
85 | 88 | ||
86 | memset(®s, 0, sizeof(struct pt_regs)); | 89 | memset(®s, 0, sizeof(struct pt_regs)); |
87 | ret = do_execve(filename, (char __user * __user *)argv, | 90 | ret = do_execve(filename, |
88 | (char __user * __user *)envp, ®s); | 91 | (const char __user *const __user *)argv, |
92 | (const char __user *const __user *)envp, ®s); | ||
89 | if (ret < 0) | 93 | if (ret < 0) |
90 | goto out; | 94 | goto out; |
91 | 95 | ||
diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c index 575ff1ae85a..339150ab0ea 100644 --- a/arch/arm/mach-imx/mach-cpuimx27.c +++ b/arch/arm/mach-imx/mach-cpuimx27.c | |||
@@ -279,13 +279,13 @@ static void __init eukrea_cpuimx27_init(void) | |||
279 | #if defined(CONFIG_USB_ULPI) | 279 | #if defined(CONFIG_USB_ULPI) |
280 | if (otg_mode_host) { | 280 | if (otg_mode_host) { |
281 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | 281 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, |
282 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | 282 | ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); |
283 | 283 | ||
284 | mxc_register_device(&mxc_otg_host, &otg_pdata); | 284 | mxc_register_device(&mxc_otg_host, &otg_pdata); |
285 | } | 285 | } |
286 | 286 | ||
287 | usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | 287 | usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, |
288 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | 288 | ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); |
289 | 289 | ||
290 | mxc_register_device(&mxc_usbh2, &usbh2_pdata); | 290 | mxc_register_device(&mxc_usbh2, &usbh2_pdata); |
291 | #endif | 291 | #endif |
diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c index a389d1148f1..23c9e1f37b9 100644 --- a/arch/arm/mach-imx/mach-pca100.c +++ b/arch/arm/mach-imx/mach-pca100.c | |||
@@ -419,13 +419,13 @@ static void __init pca100_init(void) | |||
419 | #if defined(CONFIG_USB_ULPI) | 419 | #if defined(CONFIG_USB_ULPI) |
420 | if (otg_mode_host) { | 420 | if (otg_mode_host) { |
421 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | 421 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, |
422 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | 422 | ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); |
423 | 423 | ||
424 | mxc_register_device(&mxc_otg_host, &otg_pdata); | 424 | mxc_register_device(&mxc_otg_host, &otg_pdata); |
425 | } | 425 | } |
426 | 426 | ||
427 | usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | 427 | usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, |
428 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | 428 | ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); |
429 | 429 | ||
430 | mxc_register_device(&mxc_usbh2, &usbh2_pdata); | 430 | mxc_register_device(&mxc_usbh2, &usbh2_pdata); |
431 | #endif | 431 | #endif |
diff --git a/arch/arm/mach-mx25/mach-cpuimx25.c b/arch/arm/mach-mx25/mach-cpuimx25.c index 56b2e26d23b..a5f0174290b 100644 --- a/arch/arm/mach-mx25/mach-cpuimx25.c +++ b/arch/arm/mach-mx25/mach-cpuimx25.c | |||
@@ -138,7 +138,7 @@ static void __init eukrea_cpuimx25_init(void) | |||
138 | #if defined(CONFIG_USB_ULPI) | 138 | #if defined(CONFIG_USB_ULPI) |
139 | if (otg_mode_host) { | 139 | if (otg_mode_host) { |
140 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | 140 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, |
141 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | 141 | ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); |
142 | 142 | ||
143 | mxc_register_device(&mxc_otg, &otg_pdata); | 143 | mxc_register_device(&mxc_otg, &otg_pdata); |
144 | } | 144 | } |
diff --git a/arch/arm/mach-mx3/mach-cpuimx35.c b/arch/arm/mach-mx3/mach-cpuimx35.c index 63f970f340a..9770a6a973b 100644 --- a/arch/arm/mach-mx3/mach-cpuimx35.c +++ b/arch/arm/mach-mx3/mach-cpuimx35.c | |||
@@ -192,7 +192,7 @@ static void __init mxc_board_init(void) | |||
192 | #if defined(CONFIG_USB_ULPI) | 192 | #if defined(CONFIG_USB_ULPI) |
193 | if (otg_mode_host) { | 193 | if (otg_mode_host) { |
194 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | 194 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, |
195 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | 195 | ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); |
196 | 196 | ||
197 | mxc_register_device(&mxc_otg_host, &otg_pdata); | 197 | mxc_register_device(&mxc_otg_host, &otg_pdata); |
198 | } | 198 | } |
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 63b2d8859c3..88d3a1e920f 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile | |||
@@ -25,6 +25,7 @@ obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o | |||
25 | obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o | 25 | obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o |
26 | obj-$(CONFIG_ARCH_OMAP4) += omap44xx-smc.o omap4-common.o | 26 | obj-$(CONFIG_ARCH_OMAP4) += omap44xx-smc.o omap4-common.o |
27 | 27 | ||
28 | AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a | ||
28 | AFLAGS_omap44xx-smc.o :=-Wa,-march=armv7-a | 29 | AFLAGS_omap44xx-smc.o :=-Wa,-march=armv7-a |
29 | 30 | ||
30 | # Functions loaded to SRAM | 31 | # Functions loaded to SRAM |
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 138646deac8..dfdce2d8277 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c | |||
@@ -3417,7 +3417,13 @@ int __init omap3xxx_clk_init(void) | |||
3417 | struct omap_clk *c; | 3417 | struct omap_clk *c; |
3418 | u32 cpu_clkflg = CK_3XXX; | 3418 | u32 cpu_clkflg = CK_3XXX; |
3419 | 3419 | ||
3420 | if (cpu_is_omap34xx()) { | 3420 | if (cpu_is_omap3517()) { |
3421 | cpu_mask = RATE_IN_3XXX | RATE_IN_3430ES2PLUS; | ||
3422 | cpu_clkflg |= CK_3517; | ||
3423 | } else if (cpu_is_omap3505()) { | ||
3424 | cpu_mask = RATE_IN_3XXX | RATE_IN_3430ES2PLUS; | ||
3425 | cpu_clkflg |= CK_3505; | ||
3426 | } else if (cpu_is_omap34xx()) { | ||
3421 | cpu_mask = RATE_IN_3XXX; | 3427 | cpu_mask = RATE_IN_3XXX; |
3422 | cpu_clkflg |= CK_343X; | 3428 | cpu_clkflg |= CK_343X; |
3423 | 3429 | ||
@@ -3432,12 +3438,6 @@ int __init omap3xxx_clk_init(void) | |||
3432 | cpu_mask |= RATE_IN_3430ES2PLUS; | 3438 | cpu_mask |= RATE_IN_3430ES2PLUS; |
3433 | cpu_clkflg |= CK_3430ES2; | 3439 | cpu_clkflg |= CK_3430ES2; |
3434 | } | 3440 | } |
3435 | } else if (cpu_is_omap3517()) { | ||
3436 | cpu_mask = RATE_IN_3XXX | RATE_IN_3430ES2PLUS; | ||
3437 | cpu_clkflg |= CK_3517; | ||
3438 | } else if (cpu_is_omap3505()) { | ||
3439 | cpu_mask = RATE_IN_3XXX | RATE_IN_3430ES2PLUS; | ||
3440 | cpu_clkflg |= CK_3505; | ||
3441 | } | 3441 | } |
3442 | 3442 | ||
3443 | if (omap3_has_192mhz_clk()) | 3443 | if (omap3_has_192mhz_clk()) |
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index e8256a2ed8e..9a879f95950 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c | |||
@@ -284,8 +284,8 @@ static void __init omap3_check_revision(void) | |||
284 | default: | 284 | default: |
285 | omap_revision = OMAP3630_REV_ES1_2; | 285 | omap_revision = OMAP3630_REV_ES1_2; |
286 | omap_chip.oc |= CHIP_IS_OMAP3630ES1_2; | 286 | omap_chip.oc |= CHIP_IS_OMAP3630ES1_2; |
287 | break; | ||
288 | } | 287 | } |
288 | break; | ||
289 | default: | 289 | default: |
290 | /* Unknown default to latest silicon rev as default*/ | 290 | /* Unknown default to latest silicon rev as default*/ |
291 | omap_revision = OMAP3630_REV_ES1_2; | 291 | omap_revision = OMAP3630_REV_ES1_2; |
diff --git a/arch/arm/mach-omap2/include/mach/entry-macro.S b/arch/arm/mach-omap2/include/mach/entry-macro.S index 50fd7491664..06e64e1fc28 100644 --- a/arch/arm/mach-omap2/include/mach/entry-macro.S +++ b/arch/arm/mach-omap2/include/mach/entry-macro.S | |||
@@ -177,7 +177,10 @@ omap_irq_base: .word 0 | |||
177 | cmpne \irqnr, \tmp | 177 | cmpne \irqnr, \tmp |
178 | cmpcs \irqnr, \irqnr | 178 | cmpcs \irqnr, \irqnr |
179 | .endm | 179 | .endm |
180 | #endif | ||
181 | #endif /* MULTI_OMAP2 */ | ||
180 | 182 | ||
183 | #ifdef CONFIG_SMP | ||
181 | /* We assume that irqstat (the raw value of the IRQ acknowledge | 184 | /* We assume that irqstat (the raw value of the IRQ acknowledge |
182 | * register) is preserved from the macro above. | 185 | * register) is preserved from the macro above. |
183 | * If there is an IPI, we immediately signal end of interrupt | 186 | * If there is an IPI, we immediately signal end of interrupt |
@@ -205,8 +208,7 @@ omap_irq_base: .word 0 | |||
205 | streq \irqstat, [\base, #GIC_CPU_EOI] | 208 | streq \irqstat, [\base, #GIC_CPU_EOI] |
206 | cmp \tmp, #0 | 209 | cmp \tmp, #0 |
207 | .endm | 210 | .endm |
208 | #endif | 211 | #endif /* CONFIG_SMP */ |
209 | #endif /* MULTI_OMAP2 */ | ||
210 | 212 | ||
211 | .macro irq_prio_table | 213 | .macro irq_prio_table |
212 | .endm | 214 | .endm |
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index af3c20c8d3f..9e9f70e18e3 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c | |||
@@ -102,8 +102,7 @@ static void __init wakeup_secondary(void) | |||
102 | * Send a 'sev' to wake the secondary core from WFE. | 102 | * Send a 'sev' to wake the secondary core from WFE. |
103 | * Drain the outstanding writes to memory | 103 | * Drain the outstanding writes to memory |
104 | */ | 104 | */ |
105 | dsb(); | 105 | dsb_sev(); |
106 | set_event(); | ||
107 | mb(); | 106 | mb(); |
108 | } | 107 | } |
109 | 108 | ||
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index fb4994ad622..7b03426c72a 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
@@ -480,7 +480,9 @@ void omap_sram_idle(void) | |||
480 | } | 480 | } |
481 | 481 | ||
482 | /* Disable IO-PAD and IO-CHAIN wakeup */ | 482 | /* Disable IO-PAD and IO-CHAIN wakeup */ |
483 | if (omap3_has_io_wakeup() && core_next_state < PWRDM_POWER_ON) { | 483 | if (omap3_has_io_wakeup() && |
484 | (per_next_state < PWRDM_POWER_ON || | ||
485 | core_next_state < PWRDM_POWER_ON)) { | ||
484 | prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); | 486 | prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); |
485 | omap3_disable_io_chain(); | 487 | omap3_disable_io_chain(); |
486 | } | 488 | } |
diff --git a/arch/arm/mach-s3c2410/include/mach/vmalloc.h b/arch/arm/mach-s3c2410/include/mach/vmalloc.h index 315b0078a34..54297eb0bf5 100644 --- a/arch/arm/mach-s3c2410/include/mach/vmalloc.h +++ b/arch/arm/mach-s3c2410/include/mach/vmalloc.h | |||
@@ -15,6 +15,6 @@ | |||
15 | #ifndef __ASM_ARCH_VMALLOC_H | 15 | #ifndef __ASM_ARCH_VMALLOC_H |
16 | #define __ASM_ARCH_VMALLOC_H | 16 | #define __ASM_ARCH_VMALLOC_H |
17 | 17 | ||
18 | #define VMALLOC_END (0xE0000000) | 18 | #define VMALLOC_END 0xE0000000UL |
19 | 19 | ||
20 | #endif /* __ASM_ARCH_VMALLOC_H */ | 20 | #endif /* __ASM_ARCH_VMALLOC_H */ |
diff --git a/arch/arm/mach-s3c64xx/include/mach/vmalloc.h b/arch/arm/mach-s3c64xx/include/mach/vmalloc.h index 7411ef3711a..bc0e9138986 100644 --- a/arch/arm/mach-s3c64xx/include/mach/vmalloc.h +++ b/arch/arm/mach-s3c64xx/include/mach/vmalloc.h | |||
@@ -15,6 +15,6 @@ | |||
15 | #ifndef __ASM_ARCH_VMALLOC_H | 15 | #ifndef __ASM_ARCH_VMALLOC_H |
16 | #define __ASM_ARCH_VMALLOC_H | 16 | #define __ASM_ARCH_VMALLOC_H |
17 | 17 | ||
18 | #define VMALLOC_END (0xE0000000) | 18 | #define VMALLOC_END 0xE0000000UL |
19 | 19 | ||
20 | #endif /* __ASM_ARCH_VMALLOC_H */ | 20 | #endif /* __ASM_ARCH_VMALLOC_H */ |
diff --git a/arch/arm/mach-s5p6440/include/mach/vmalloc.h b/arch/arm/mach-s5p6440/include/mach/vmalloc.h index 16df257b1dc..e3f0eebf520 100644 --- a/arch/arm/mach-s5p6440/include/mach/vmalloc.h +++ b/arch/arm/mach-s5p6440/include/mach/vmalloc.h | |||
@@ -12,6 +12,6 @@ | |||
12 | #ifndef __ASM_ARCH_VMALLOC_H | 12 | #ifndef __ASM_ARCH_VMALLOC_H |
13 | #define __ASM_ARCH_VMALLOC_H | 13 | #define __ASM_ARCH_VMALLOC_H |
14 | 14 | ||
15 | #define VMALLOC_END (0xE0000000) | 15 | #define VMALLOC_END 0xE0000000UL |
16 | 16 | ||
17 | #endif /* __ASM_ARCH_VMALLOC_H */ | 17 | #endif /* __ASM_ARCH_VMALLOC_H */ |
diff --git a/arch/arm/mach-s5p6442/include/mach/vmalloc.h b/arch/arm/mach-s5p6442/include/mach/vmalloc.h index be3333688c2..f5c83f02c18 100644 --- a/arch/arm/mach-s5p6442/include/mach/vmalloc.h +++ b/arch/arm/mach-s5p6442/include/mach/vmalloc.h | |||
@@ -12,6 +12,6 @@ | |||
12 | #ifndef __ASM_ARCH_VMALLOC_H | 12 | #ifndef __ASM_ARCH_VMALLOC_H |
13 | #define __ASM_ARCH_VMALLOC_H | 13 | #define __ASM_ARCH_VMALLOC_H |
14 | 14 | ||
15 | #define VMALLOC_END (0xE0000000) | 15 | #define VMALLOC_END 0xE0000000UL |
16 | 16 | ||
17 | #endif /* __ASM_ARCH_VMALLOC_H */ | 17 | #endif /* __ASM_ARCH_VMALLOC_H */ |
diff --git a/arch/arm/mach-s5pv210/include/mach/vmalloc.h b/arch/arm/mach-s5pv210/include/mach/vmalloc.h index 58f515e0747..df9a2880832 100644 --- a/arch/arm/mach-s5pv210/include/mach/vmalloc.h +++ b/arch/arm/mach-s5pv210/include/mach/vmalloc.h | |||
@@ -17,6 +17,6 @@ | |||
17 | #ifndef __ASM_ARCH_VMALLOC_H | 17 | #ifndef __ASM_ARCH_VMALLOC_H |
18 | #define __ASM_ARCH_VMALLOC_H __FILE__ | 18 | #define __ASM_ARCH_VMALLOC_H __FILE__ |
19 | 19 | ||
20 | #define VMALLOC_END (0xE0000000) | 20 | #define VMALLOC_END (0xE0000000UL) |
21 | 21 | ||
22 | #endif /* __ASM_ARCH_VMALLOC_H */ | 22 | #endif /* __ASM_ARCH_VMALLOC_H */ |
diff --git a/arch/arm/mach-s5pv310/clock.c b/arch/arm/mach-s5pv310/clock.c index 77f2b4d85e6..26a0f03df8e 100644 --- a/arch/arm/mach-s5pv310/clock.c +++ b/arch/arm/mach-s5pv310/clock.c | |||
@@ -30,6 +30,16 @@ static struct clk clk_sclk_hdmi27m = { | |||
30 | .rate = 27000000, | 30 | .rate = 27000000, |
31 | }; | 31 | }; |
32 | 32 | ||
33 | static int s5pv310_clksrc_mask_peril0_ctrl(struct clk *clk, int enable) | ||
34 | { | ||
35 | return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable); | ||
36 | } | ||
37 | |||
38 | static int s5pv310_clk_ip_peril_ctrl(struct clk *clk, int enable) | ||
39 | { | ||
40 | return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable); | ||
41 | } | ||
42 | |||
33 | /* Core list of CMU_CPU side */ | 43 | /* Core list of CMU_CPU side */ |
34 | 44 | ||
35 | static struct clksrc_clk clk_mout_apll = { | 45 | static struct clksrc_clk clk_mout_apll = { |
@@ -39,6 +49,14 @@ static struct clksrc_clk clk_mout_apll = { | |||
39 | }, | 49 | }, |
40 | .sources = &clk_src_apll, | 50 | .sources = &clk_src_apll, |
41 | .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 }, | 51 | .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 }, |
52 | }; | ||
53 | |||
54 | static struct clksrc_clk clk_sclk_apll = { | ||
55 | .clk = { | ||
56 | .name = "sclk_apll", | ||
57 | .id = -1, | ||
58 | .parent = &clk_mout_apll.clk, | ||
59 | }, | ||
42 | .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 }, | 60 | .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 }, |
43 | }; | 61 | }; |
44 | 62 | ||
@@ -61,7 +79,7 @@ static struct clksrc_clk clk_mout_mpll = { | |||
61 | }; | 79 | }; |
62 | 80 | ||
63 | static struct clk *clkset_moutcore_list[] = { | 81 | static struct clk *clkset_moutcore_list[] = { |
64 | [0] = &clk_mout_apll.clk, | 82 | [0] = &clk_sclk_apll.clk, |
65 | [1] = &clk_mout_mpll.clk, | 83 | [1] = &clk_mout_mpll.clk, |
66 | }; | 84 | }; |
67 | 85 | ||
@@ -154,7 +172,7 @@ static struct clksrc_clk clk_pclk_dbg = { | |||
154 | 172 | ||
155 | static struct clk *clkset_corebus_list[] = { | 173 | static struct clk *clkset_corebus_list[] = { |
156 | [0] = &clk_mout_mpll.clk, | 174 | [0] = &clk_mout_mpll.clk, |
157 | [1] = &clk_mout_apll.clk, | 175 | [1] = &clk_sclk_apll.clk, |
158 | }; | 176 | }; |
159 | 177 | ||
160 | static struct clksrc_sources clkset_mout_corebus = { | 178 | static struct clksrc_sources clkset_mout_corebus = { |
@@ -220,7 +238,7 @@ static struct clksrc_clk clk_pclk_acp = { | |||
220 | 238 | ||
221 | static struct clk *clkset_aclk_top_list[] = { | 239 | static struct clk *clkset_aclk_top_list[] = { |
222 | [0] = &clk_mout_mpll.clk, | 240 | [0] = &clk_mout_mpll.clk, |
223 | [1] = &clk_mout_apll.clk, | 241 | [1] = &clk_sclk_apll.clk, |
224 | }; | 242 | }; |
225 | 243 | ||
226 | static struct clksrc_sources clkset_aclk_200 = { | 244 | static struct clksrc_sources clkset_aclk_200 = { |
@@ -321,11 +339,6 @@ static struct clksrc_clk clk_sclk_vpll = { | |||
321 | .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 }, | 339 | .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 }, |
322 | }; | 340 | }; |
323 | 341 | ||
324 | static int s5pv310_clk_ip_peril_ctrl(struct clk *clk, int enable) | ||
325 | { | ||
326 | return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable); | ||
327 | } | ||
328 | |||
329 | static struct clk init_clocks_disable[] = { | 342 | static struct clk init_clocks_disable[] = { |
330 | { | 343 | { |
331 | .name = "timers", | 344 | .name = "timers", |
@@ -337,7 +350,37 @@ static struct clk init_clocks_disable[] = { | |||
337 | }; | 350 | }; |
338 | 351 | ||
339 | static struct clk init_clocks[] = { | 352 | static struct clk init_clocks[] = { |
340 | /* Nothing here yet */ | 353 | { |
354 | .name = "uart", | ||
355 | .id = 0, | ||
356 | .enable = s5pv310_clk_ip_peril_ctrl, | ||
357 | .ctrlbit = (1 << 0), | ||
358 | }, { | ||
359 | .name = "uart", | ||
360 | .id = 1, | ||
361 | .enable = s5pv310_clk_ip_peril_ctrl, | ||
362 | .ctrlbit = (1 << 1), | ||
363 | }, { | ||
364 | .name = "uart", | ||
365 | .id = 2, | ||
366 | .enable = s5pv310_clk_ip_peril_ctrl, | ||
367 | .ctrlbit = (1 << 2), | ||
368 | }, { | ||
369 | .name = "uart", | ||
370 | .id = 3, | ||
371 | .enable = s5pv310_clk_ip_peril_ctrl, | ||
372 | .ctrlbit = (1 << 3), | ||
373 | }, { | ||
374 | .name = "uart", | ||
375 | .id = 4, | ||
376 | .enable = s5pv310_clk_ip_peril_ctrl, | ||
377 | .ctrlbit = (1 << 4), | ||
378 | }, { | ||
379 | .name = "uart", | ||
380 | .id = 5, | ||
381 | .enable = s5pv310_clk_ip_peril_ctrl, | ||
382 | .ctrlbit = (1 << 5), | ||
383 | } | ||
341 | }; | 384 | }; |
342 | 385 | ||
343 | static struct clk *clkset_group_list[] = { | 386 | static struct clk *clkset_group_list[] = { |
@@ -359,8 +402,8 @@ static struct clksrc_clk clksrcs[] = { | |||
359 | .clk = { | 402 | .clk = { |
360 | .name = "uclk1", | 403 | .name = "uclk1", |
361 | .id = 0, | 404 | .id = 0, |
405 | .enable = s5pv310_clksrc_mask_peril0_ctrl, | ||
362 | .ctrlbit = (1 << 0), | 406 | .ctrlbit = (1 << 0), |
363 | .enable = s5pv310_clk_ip_peril_ctrl, | ||
364 | }, | 407 | }, |
365 | .sources = &clkset_group, | 408 | .sources = &clkset_group, |
366 | .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 }, | 409 | .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 }, |
@@ -369,8 +412,8 @@ static struct clksrc_clk clksrcs[] = { | |||
369 | .clk = { | 412 | .clk = { |
370 | .name = "uclk1", | 413 | .name = "uclk1", |
371 | .id = 1, | 414 | .id = 1, |
372 | .enable = s5pv310_clk_ip_peril_ctrl, | 415 | .enable = s5pv310_clksrc_mask_peril0_ctrl, |
373 | .ctrlbit = (1 << 1), | 416 | .ctrlbit = (1 << 4), |
374 | }, | 417 | }, |
375 | .sources = &clkset_group, | 418 | .sources = &clkset_group, |
376 | .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 }, | 419 | .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 }, |
@@ -379,8 +422,8 @@ static struct clksrc_clk clksrcs[] = { | |||
379 | .clk = { | 422 | .clk = { |
380 | .name = "uclk1", | 423 | .name = "uclk1", |
381 | .id = 2, | 424 | .id = 2, |
382 | .enable = s5pv310_clk_ip_peril_ctrl, | 425 | .enable = s5pv310_clksrc_mask_peril0_ctrl, |
383 | .ctrlbit = (1 << 2), | 426 | .ctrlbit = (1 << 8), |
384 | }, | 427 | }, |
385 | .sources = &clkset_group, | 428 | .sources = &clkset_group, |
386 | .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 }, | 429 | .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 }, |
@@ -389,8 +432,8 @@ static struct clksrc_clk clksrcs[] = { | |||
389 | .clk = { | 432 | .clk = { |
390 | .name = "uclk1", | 433 | .name = "uclk1", |
391 | .id = 3, | 434 | .id = 3, |
392 | .enable = s5pv310_clk_ip_peril_ctrl, | 435 | .enable = s5pv310_clksrc_mask_peril0_ctrl, |
393 | .ctrlbit = (1 << 3), | 436 | .ctrlbit = (1 << 12), |
394 | }, | 437 | }, |
395 | .sources = &clkset_group, | 438 | .sources = &clkset_group, |
396 | .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 }, | 439 | .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 }, |
@@ -399,7 +442,7 @@ static struct clksrc_clk clksrcs[] = { | |||
399 | .clk = { | 442 | .clk = { |
400 | .name = "sclk_pwm", | 443 | .name = "sclk_pwm", |
401 | .id = -1, | 444 | .id = -1, |
402 | .enable = s5pv310_clk_ip_peril_ctrl, | 445 | .enable = s5pv310_clksrc_mask_peril0_ctrl, |
403 | .ctrlbit = (1 << 24), | 446 | .ctrlbit = (1 << 24), |
404 | }, | 447 | }, |
405 | .sources = &clkset_group, | 448 | .sources = &clkset_group, |
@@ -411,6 +454,7 @@ static struct clksrc_clk clksrcs[] = { | |||
411 | /* Clock initialization code */ | 454 | /* Clock initialization code */ |
412 | static struct clksrc_clk *sysclks[] = { | 455 | static struct clksrc_clk *sysclks[] = { |
413 | &clk_mout_apll, | 456 | &clk_mout_apll, |
457 | &clk_sclk_apll, | ||
414 | &clk_mout_epll, | 458 | &clk_mout_epll, |
415 | &clk_mout_mpll, | 459 | &clk_mout_mpll, |
416 | &clk_moutcore, | 460 | &clk_moutcore, |
@@ -470,11 +514,11 @@ void __init_or_cpufreq s5pv310_setup_clocks(void) | |||
470 | apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0), pll_4508); | 514 | apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0), pll_4508); |
471 | mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0), pll_4508); | 515 | mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0), pll_4508); |
472 | epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0), | 516 | epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0), |
473 | __raw_readl(S5P_EPLL_CON1), pll_4500); | 517 | __raw_readl(S5P_EPLL_CON1), pll_4600); |
474 | 518 | ||
475 | vpllsrc = clk_get_rate(&clk_vpllsrc.clk); | 519 | vpllsrc = clk_get_rate(&clk_vpllsrc.clk); |
476 | vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0), | 520 | vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0), |
477 | __raw_readl(S5P_VPLL_CON1), pll_4502); | 521 | __raw_readl(S5P_VPLL_CON1), pll_4650); |
478 | 522 | ||
479 | clk_fout_apll.rate = apll; | 523 | clk_fout_apll.rate = apll; |
480 | clk_fout_mpll.rate = mpll; | 524 | clk_fout_mpll.rate = mpll; |
diff --git a/arch/arm/mach-s5pv310/cpu.c b/arch/arm/mach-s5pv310/cpu.c index 196c9f12ed8..e5b261a99ab 100644 --- a/arch/arm/mach-s5pv310/cpu.c +++ b/arch/arm/mach-s5pv310/cpu.c | |||
@@ -45,6 +45,16 @@ static struct map_desc s5pv310_iodesc[] __initdata = { | |||
45 | .pfn = __phys_to_pfn(S5PV310_PA_L2CC), | 45 | .pfn = __phys_to_pfn(S5PV310_PA_L2CC), |
46 | .length = SZ_4K, | 46 | .length = SZ_4K, |
47 | .type = MT_DEVICE, | 47 | .type = MT_DEVICE, |
48 | }, { | ||
49 | .virtual = (unsigned long)S5P_VA_SYSRAM, | ||
50 | .pfn = __phys_to_pfn(S5PV310_PA_SYSRAM), | ||
51 | .length = SZ_4K, | ||
52 | .type = MT_DEVICE, | ||
53 | }, { | ||
54 | .virtual = (unsigned long)S5P_VA_CMU, | ||
55 | .pfn = __phys_to_pfn(S5PV310_PA_CMU), | ||
56 | .length = SZ_128K, | ||
57 | .type = MT_DEVICE, | ||
48 | }, | 58 | }, |
49 | }; | 59 | }; |
50 | 60 | ||
diff --git a/arch/arm/mach-s5pv310/include/mach/irqs.h b/arch/arm/mach-s5pv310/include/mach/irqs.h index 56885ca3773..4cdedda6e65 100644 --- a/arch/arm/mach-s5pv310/include/mach/irqs.h +++ b/arch/arm/mach-s5pv310/include/mach/irqs.h | |||
@@ -15,12 +15,14 @@ | |||
15 | 15 | ||
16 | #include <plat/irqs.h> | 16 | #include <plat/irqs.h> |
17 | 17 | ||
18 | /* Private Peripheral Interrupt */ | 18 | /* PPI: Private Peripheral Interrupt */ |
19 | |||
19 | #define IRQ_PPI(x) S5P_IRQ(x+16) | 20 | #define IRQ_PPI(x) S5P_IRQ(x+16) |
20 | 21 | ||
21 | #define IRQ_LOCALTIMER IRQ_PPI(13) | 22 | #define IRQ_LOCALTIMER IRQ_PPI(13) |
22 | 23 | ||
23 | /* Shared Peripheral Interrupt */ | 24 | /* SPI: Shared Peripheral Interrupt */ |
25 | |||
24 | #define IRQ_SPI(x) S5P_IRQ(x+32) | 26 | #define IRQ_SPI(x) S5P_IRQ(x+32) |
25 | 27 | ||
26 | #define IRQ_EINT0 IRQ_SPI(40) | 28 | #define IRQ_EINT0 IRQ_SPI(40) |
@@ -36,7 +38,7 @@ | |||
36 | #define IRQ_PCIE IRQ_SPI(50) | 38 | #define IRQ_PCIE IRQ_SPI(50) |
37 | #define IRQ_SYSTEM_TIMER IRQ_SPI(51) | 39 | #define IRQ_SYSTEM_TIMER IRQ_SPI(51) |
38 | #define IRQ_MFC IRQ_SPI(52) | 40 | #define IRQ_MFC IRQ_SPI(52) |
39 | #define IRQ_WTD IRQ_SPI(53) | 41 | #define IRQ_WDT IRQ_SPI(53) |
40 | #define IRQ_AUDIO_SS IRQ_SPI(54) | 42 | #define IRQ_AUDIO_SS IRQ_SPI(54) |
41 | #define IRQ_AC97 IRQ_SPI(55) | 43 | #define IRQ_AC97 IRQ_SPI(55) |
42 | #define IRQ_SPDIF IRQ_SPI(56) | 44 | #define IRQ_SPDIF IRQ_SPI(56) |
@@ -67,8 +69,9 @@ | |||
67 | #define IRQ_IIC COMBINER_IRQ(27, 0) | 69 | #define IRQ_IIC COMBINER_IRQ(27, 0) |
68 | 70 | ||
69 | /* Set the default NR_IRQS */ | 71 | /* Set the default NR_IRQS */ |
72 | |||
70 | #define NR_IRQS COMBINER_IRQ(MAX_COMBINER_NR, 0) | 73 | #define NR_IRQS COMBINER_IRQ(MAX_COMBINER_NR, 0) |
71 | 74 | ||
72 | #define MAX_COMBINER_NR 39 | 75 | #define MAX_COMBINER_NR 39 |
73 | 76 | ||
74 | #endif /* ASM_ARCH_IRQS_H */ | 77 | #endif /* __ASM_ARCH_IRQS_H */ |
diff --git a/arch/arm/mach-s5pv310/include/mach/map.h b/arch/arm/mach-s5pv310/include/mach/map.h index 87697c9fca5..213e1101a3b 100644 --- a/arch/arm/mach-s5pv310/include/mach/map.h +++ b/arch/arm/mach-s5pv310/include/mach/map.h | |||
@@ -23,12 +23,16 @@ | |||
23 | 23 | ||
24 | #include <plat/map-s5p.h> | 24 | #include <plat/map-s5p.h> |
25 | 25 | ||
26 | #define S5PV310_PA_SYSRAM (0x02025000) | ||
27 | |||
26 | #define S5PV310_PA_CHIPID (0x10000000) | 28 | #define S5PV310_PA_CHIPID (0x10000000) |
27 | #define S5P_PA_CHIPID S5PV310_PA_CHIPID | 29 | #define S5P_PA_CHIPID S5PV310_PA_CHIPID |
28 | 30 | ||
29 | #define S5PV310_PA_SYSCON (0x10020000) | 31 | #define S5PV310_PA_SYSCON (0x10020000) |
30 | #define S5P_PA_SYSCON S5PV310_PA_SYSCON | 32 | #define S5P_PA_SYSCON S5PV310_PA_SYSCON |
31 | 33 | ||
34 | #define S5PV310_PA_CMU (0x10030000) | ||
35 | |||
32 | #define S5PV310_PA_WATCHDOG (0x10060000) | 36 | #define S5PV310_PA_WATCHDOG (0x10060000) |
33 | 37 | ||
34 | #define S5PV310_PA_COMBINER (0x10448000) | 38 | #define S5PV310_PA_COMBINER (0x10448000) |
@@ -39,8 +43,12 @@ | |||
39 | #define S5PV310_PA_GIC_DIST (0x10501000) | 43 | #define S5PV310_PA_GIC_DIST (0x10501000) |
40 | #define S5PV310_PA_L2CC (0x10502000) | 44 | #define S5PV310_PA_L2CC (0x10502000) |
41 | 45 | ||
42 | #define S5PV310_PA_GPIO (0x11000000) | 46 | #define S5PV310_PA_GPIO1 (0x11400000) |
43 | #define S5P_PA_GPIO S5PV310_PA_GPIO | 47 | #define S5PV310_PA_GPIO2 (0x11000000) |
48 | #define S5PV310_PA_GPIO3 (0x03860000) | ||
49 | #define S5P_PA_GPIO S5PV310_PA_GPIO1 | ||
50 | |||
51 | #define S5PV310_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000)) | ||
44 | 52 | ||
45 | #define S5PV310_PA_UART (0x13800000) | 53 | #define S5PV310_PA_UART (0x13800000) |
46 | 54 | ||
@@ -63,6 +71,10 @@ | |||
63 | 71 | ||
64 | /* compatibiltiy defines. */ | 72 | /* compatibiltiy defines. */ |
65 | #define S3C_PA_UART S5PV310_PA_UART | 73 | #define S3C_PA_UART S5PV310_PA_UART |
74 | #define S3C_PA_HSMMC0 S5PV310_PA_HSMMC(0) | ||
75 | #define S3C_PA_HSMMC1 S5PV310_PA_HSMMC(1) | ||
76 | #define S3C_PA_HSMMC2 S5PV310_PA_HSMMC(2) | ||
77 | #define S3C_PA_HSMMC3 S5PV310_PA_HSMMC(3) | ||
66 | #define S3C_PA_IIC S5PV310_PA_IIC0 | 78 | #define S3C_PA_IIC S5PV310_PA_IIC0 |
67 | #define S3C_PA_WDT S5PV310_PA_WATCHDOG | 79 | #define S3C_PA_WDT S5PV310_PA_WATCHDOG |
68 | 80 | ||
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-clock.h b/arch/arm/mach-s5pv310/include/mach/regs-clock.h index 59e3a7e94d8..4013553cd9b 100644 --- a/arch/arm/mach-s5pv310/include/mach/regs-clock.h +++ b/arch/arm/mach-s5pv310/include/mach/regs-clock.h | |||
@@ -15,48 +15,49 @@ | |||
15 | 15 | ||
16 | #include <mach/map.h> | 16 | #include <mach/map.h> |
17 | 17 | ||
18 | #define S5P_CLKREG(x) (S3C_VA_SYS + (x)) | 18 | #define S5P_CLKREG(x) (S5P_VA_CMU + (x)) |
19 | 19 | ||
20 | #define S5P_INFORM0 S5P_CLKREG(0x800) | 20 | #define S5P_INFORM0 S5P_CLKREG(0x800) |
21 | 21 | ||
22 | #define S5P_EPLL_CON0 S5P_CLKREG(0x1C110) | 22 | #define S5P_EPLL_CON0 S5P_CLKREG(0x0C110) |
23 | #define S5P_EPLL_CON1 S5P_CLKREG(0x1C114) | 23 | #define S5P_EPLL_CON1 S5P_CLKREG(0x0C114) |
24 | #define S5P_VPLL_CON0 S5P_CLKREG(0x1C120) | 24 | #define S5P_VPLL_CON0 S5P_CLKREG(0x0C120) |
25 | #define S5P_VPLL_CON1 S5P_CLKREG(0x1C124) | 25 | #define S5P_VPLL_CON1 S5P_CLKREG(0x0C124) |
26 | 26 | ||
27 | #define S5P_CLKSRC_TOP0 S5P_CLKREG(0x1C210) | 27 | #define S5P_CLKSRC_TOP0 S5P_CLKREG(0x0C210) |
28 | #define S5P_CLKSRC_TOP1 S5P_CLKREG(0x1C214) | 28 | #define S5P_CLKSRC_TOP1 S5P_CLKREG(0x0C214) |
29 | 29 | ||
30 | #define S5P_CLKSRC_PERIL0 S5P_CLKREG(0x1C250) | 30 | #define S5P_CLKSRC_PERIL0 S5P_CLKREG(0x0C250) |
31 | 31 | ||
32 | #define S5P_CLKDIV_TOP S5P_CLKREG(0x1C510) | 32 | #define S5P_CLKDIV_TOP S5P_CLKREG(0x0C510) |
33 | 33 | ||
34 | #define S5P_CLKDIV_PERIL0 S5P_CLKREG(0x1C550) | 34 | #define S5P_CLKDIV_PERIL0 S5P_CLKREG(0x0C550) |
35 | #define S5P_CLKDIV_PERIL1 S5P_CLKREG(0x1C554) | 35 | #define S5P_CLKDIV_PERIL1 S5P_CLKREG(0x0C554) |
36 | #define S5P_CLKDIV_PERIL2 S5P_CLKREG(0x1C558) | 36 | #define S5P_CLKDIV_PERIL2 S5P_CLKREG(0x0C558) |
37 | #define S5P_CLKDIV_PERIL3 S5P_CLKREG(0x1C55C) | 37 | #define S5P_CLKDIV_PERIL3 S5P_CLKREG(0x0C55C) |
38 | #define S5P_CLKDIV_PERIL4 S5P_CLKREG(0x1C560) | 38 | #define S5P_CLKDIV_PERIL4 S5P_CLKREG(0x0C560) |
39 | #define S5P_CLKDIV_PERIL5 S5P_CLKREG(0x1C564) | 39 | #define S5P_CLKDIV_PERIL5 S5P_CLKREG(0x0C564) |
40 | 40 | ||
41 | #define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x1C950) | 41 | #define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350) |
42 | 42 | ||
43 | #define S5P_CLKSRC_CORE S5P_CLKREG(0x20200) | 43 | #define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950) |
44 | 44 | ||
45 | #define S5P_CLKDIV_CORE0 S5P_CLKREG(0x20500) | 45 | #define S5P_CLKSRC_CORE S5P_CLKREG(0x10200) |
46 | #define S5P_CLKDIV_CORE0 S5P_CLKREG(0x10500) | ||
46 | 47 | ||
47 | #define S5P_APLL_LOCK S5P_CLKREG(0x24000) | 48 | #define S5P_APLL_LOCK S5P_CLKREG(0x14000) |
48 | #define S5P_MPLL_LOCK S5P_CLKREG(0x24004) | 49 | #define S5P_MPLL_LOCK S5P_CLKREG(0x14004) |
49 | #define S5P_APLL_CON0 S5P_CLKREG(0x24100) | 50 | #define S5P_APLL_CON0 S5P_CLKREG(0x14100) |
50 | #define S5P_APLL_CON1 S5P_CLKREG(0x24104) | 51 | #define S5P_APLL_CON1 S5P_CLKREG(0x14104) |
51 | #define S5P_MPLL_CON0 S5P_CLKREG(0x24108) | 52 | #define S5P_MPLL_CON0 S5P_CLKREG(0x14108) |
52 | #define S5P_MPLL_CON1 S5P_CLKREG(0x2410C) | 53 | #define S5P_MPLL_CON1 S5P_CLKREG(0x1410C) |
53 | 54 | ||
54 | #define S5P_CLKSRC_CPU S5P_CLKREG(0x24200) | 55 | #define S5P_CLKSRC_CPU S5P_CLKREG(0x14200) |
55 | #define S5P_CLKMUX_STATCPU S5P_CLKREG(0x24400) | 56 | #define S5P_CLKMUX_STATCPU S5P_CLKREG(0x14400) |
56 | 57 | ||
57 | #define S5P_CLKDIV_CPU S5P_CLKREG(0x24500) | 58 | #define S5P_CLKDIV_CPU S5P_CLKREG(0x14500) |
58 | #define S5P_CLKDIV_STATCPU S5P_CLKREG(0x24600) | 59 | #define S5P_CLKDIV_STATCPU S5P_CLKREG(0x14600) |
59 | 60 | ||
60 | #define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x24800) | 61 | #define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800) |
61 | 62 | ||
62 | #endif /* __ASM_ARCH_REGS_CLOCK_H */ | 63 | #endif /* __ASM_ARCH_REGS_CLOCK_H */ |
diff --git a/arch/arm/mach-s5pv310/include/mach/vmalloc.h b/arch/arm/mach-s5pv310/include/mach/vmalloc.h index 3f565ebb7da..256f221edf3 100644 --- a/arch/arm/mach-s5pv310/include/mach/vmalloc.h +++ b/arch/arm/mach-s5pv310/include/mach/vmalloc.h | |||
@@ -17,6 +17,6 @@ | |||
17 | #ifndef __ASM_ARCH_VMALLOC_H | 17 | #ifndef __ASM_ARCH_VMALLOC_H |
18 | #define __ASM_ARCH_VMALLOC_H __FILE__ | 18 | #define __ASM_ARCH_VMALLOC_H __FILE__ |
19 | 19 | ||
20 | #define VMALLOC_END (0xF0000000) | 20 | #define VMALLOC_END (0xF0000000UL) |
21 | 21 | ||
22 | #endif /* __ASM_ARCH_VMALLOC_H */ | 22 | #endif /* __ASM_ARCH_VMALLOC_H */ |
diff --git a/arch/arm/mach-s5pv310/platsmp.c b/arch/arm/mach-s5pv310/platsmp.c index fe9469abd00..d357c198ede 100644 --- a/arch/arm/mach-s5pv310/platsmp.c +++ b/arch/arm/mach-s5pv310/platsmp.c | |||
@@ -187,6 +187,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
187 | * until it receives a soft interrupt, and then the | 187 | * until it receives a soft interrupt, and then the |
188 | * secondary CPU branches to this address. | 188 | * secondary CPU branches to this address. |
189 | */ | 189 | */ |
190 | __raw_writel(BSYM(virt_to_phys(s5pv310_secondary_startup)), S5P_INFORM0); | 190 | __raw_writel(BSYM(virt_to_phys(s5pv310_secondary_startup)), S5P_VA_SYSRAM); |
191 | } | 191 | } |
192 | } | 192 | } |
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c index 05e78dd9b50..9e305de56be 100644 --- a/arch/arm/mach-tegra/board-harmony.c +++ b/arch/arm/mach-tegra/board-harmony.c | |||
@@ -91,10 +91,8 @@ static void __init tegra_harmony_fixup(struct machine_desc *desc, | |||
91 | { | 91 | { |
92 | mi->nr_banks = 2; | 92 | mi->nr_banks = 2; |
93 | mi->bank[0].start = PHYS_OFFSET; | 93 | mi->bank[0].start = PHYS_OFFSET; |
94 | mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET); | ||
95 | mi->bank[0].size = 448 * SZ_1M; | 94 | mi->bank[0].size = 448 * SZ_1M; |
96 | mi->bank[1].start = SZ_512M; | 95 | mi->bank[1].start = SZ_512M; |
97 | mi->bank[1].node = PHYS_TO_NID(SZ_512M); | ||
98 | mi->bank[1].size = SZ_512M; | 96 | mi->bank[1].size = SZ_512M; |
99 | } | 97 | } |
100 | 98 | ||
diff --git a/arch/arm/mach-tegra/include/mach/vmalloc.h b/arch/arm/mach-tegra/include/mach/vmalloc.h index 267a141730d..fd6aa65b2dc 100644 --- a/arch/arm/mach-tegra/include/mach/vmalloc.h +++ b/arch/arm/mach-tegra/include/mach/vmalloc.h | |||
@@ -23,6 +23,6 @@ | |||
23 | 23 | ||
24 | #include <asm/sizes.h> | 24 | #include <asm/sizes.h> |
25 | 25 | ||
26 | #define VMALLOC_END 0xFE000000 | 26 | #define VMALLOC_END 0xFE000000UL |
27 | 27 | ||
28 | #endif | 28 | #endif |
diff --git a/arch/arm/plat-omap/include/plat/smp.h b/arch/arm/plat-omap/include/plat/smp.h index 6a3ff65c030..5177a9c5a25 100644 --- a/arch/arm/plat-omap/include/plat/smp.h +++ b/arch/arm/plat-omap/include/plat/smp.h | |||
@@ -19,13 +19,6 @@ | |||
19 | 19 | ||
20 | #include <asm/hardware/gic.h> | 20 | #include <asm/hardware/gic.h> |
21 | 21 | ||
22 | /* | ||
23 | * set_event() is used to wake up secondary core from wfe using sev. ROM | ||
24 | * code puts the second core into wfe(standby). | ||
25 | * | ||
26 | */ | ||
27 | #define set_event() __asm__ __volatile__ ("sev" : : : "memory") | ||
28 | |||
29 | /* Needed for secondary core boot */ | 22 | /* Needed for secondary core boot */ |
30 | extern void omap_secondary_startup(void); | 23 | extern void omap_secondary_startup(void); |
31 | extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); | 24 | extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); |
diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h index 54e9fb9d315..c4ff88bf647 100644 --- a/arch/arm/plat-s5p/include/plat/map-s5p.h +++ b/arch/arm/plat-s5p/include/plat/map-s5p.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #define S5P_VA_GPIO S3C_ADDR(0x00500000) | 17 | #define S5P_VA_GPIO S3C_ADDR(0x00500000) |
18 | #define S5P_VA_SYSTIMER S3C_ADDR(0x01200000) | 18 | #define S5P_VA_SYSTIMER S3C_ADDR(0x01200000) |
19 | #define S5P_VA_SROMC S3C_ADDR(0x01100000) | 19 | #define S5P_VA_SROMC S3C_ADDR(0x01100000) |
20 | #define S5P_VA_SYSRAM S3C_ADDR(0x01180000) | ||
20 | 21 | ||
21 | #define S5P_VA_COMBINER_BASE S3C_ADDR(0x00600000) | 22 | #define S5P_VA_COMBINER_BASE S3C_ADDR(0x00600000) |
22 | #define S5P_VA_COMBINER(x) (S5P_VA_COMBINER_BASE + ((x) >> 2) * 0x10) | 23 | #define S5P_VA_COMBINER(x) (S5P_VA_COMBINER_BASE + ((x) >> 2) * 0x10) |
@@ -29,6 +30,7 @@ | |||
29 | #define S5P_VA_GIC_DIST S5P_VA_COREPERI(0x1000) | 30 | #define S5P_VA_GIC_DIST S5P_VA_COREPERI(0x1000) |
30 | 31 | ||
31 | #define S5P_VA_L2CC S3C_ADDR(0x00900000) | 32 | #define S5P_VA_L2CC S3C_ADDR(0x00900000) |
33 | #define S5P_VA_CMU S3C_ADDR(0x00920000) | ||
32 | 34 | ||
33 | #define S5P_VA_UART(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET)) | 35 | #define S5P_VA_UART(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET)) |
34 | #define S5P_VA_UART0 S5P_VA_UART(0) | 36 | #define S5P_VA_UART0 S5P_VA_UART(0) |
diff --git a/arch/arm/plat-samsung/dev-hsmmc.c b/arch/arm/plat-samsung/dev-hsmmc.c index b0f93f11e28..9d2be094141 100644 --- a/arch/arm/plat-samsung/dev-hsmmc.c +++ b/arch/arm/plat-samsung/dev-hsmmc.c | |||
@@ -70,4 +70,6 @@ void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd) | |||
70 | set->cfg_gpio = pd->cfg_gpio; | 70 | set->cfg_gpio = pd->cfg_gpio; |
71 | if (pd->cfg_card) | 71 | if (pd->cfg_card) |
72 | set->cfg_card = pd->cfg_card; | 72 | set->cfg_card = pd->cfg_card; |
73 | if (pd->host_caps) | ||
74 | set->host_caps = pd->host_caps; | ||
73 | } | 75 | } |
diff --git a/arch/arm/plat-samsung/dev-hsmmc1.c b/arch/arm/plat-samsung/dev-hsmmc1.c index 1504fd80286..a6c8295840a 100644 --- a/arch/arm/plat-samsung/dev-hsmmc1.c +++ b/arch/arm/plat-samsung/dev-hsmmc1.c | |||
@@ -70,4 +70,6 @@ void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd) | |||
70 | set->cfg_gpio = pd->cfg_gpio; | 70 | set->cfg_gpio = pd->cfg_gpio; |
71 | if (pd->cfg_card) | 71 | if (pd->cfg_card) |
72 | set->cfg_card = pd->cfg_card; | 72 | set->cfg_card = pd->cfg_card; |
73 | if (pd->host_caps) | ||
74 | set->host_caps = pd->host_caps; | ||
73 | } | 75 | } |
diff --git a/arch/arm/plat-samsung/dev-hsmmc2.c b/arch/arm/plat-samsung/dev-hsmmc2.c index b28ef173444..cb0d7143381 100644 --- a/arch/arm/plat-samsung/dev-hsmmc2.c +++ b/arch/arm/plat-samsung/dev-hsmmc2.c | |||
@@ -71,4 +71,6 @@ void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd) | |||
71 | set->cfg_gpio = pd->cfg_gpio; | 71 | set->cfg_gpio = pd->cfg_gpio; |
72 | if (pd->cfg_card) | 72 | if (pd->cfg_card) |
73 | set->cfg_card = pd->cfg_card; | 73 | set->cfg_card = pd->cfg_card; |
74 | if (pd->host_caps) | ||
75 | set->host_caps = pd->host_caps; | ||
74 | } | 76 | } |
diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c index e5daddff397..9c46aaad11c 100644 --- a/arch/avr32/kernel/process.c +++ b/arch/avr32/kernel/process.c | |||
@@ -384,8 +384,9 @@ asmlinkage int sys_vfork(struct pt_regs *regs) | |||
384 | } | 384 | } |
385 | 385 | ||
386 | asmlinkage int sys_execve(const char __user *ufilename, | 386 | asmlinkage int sys_execve(const char __user *ufilename, |
387 | char __user *__user *uargv, | 387 | const char __user *const __user *uargv, |
388 | char __user *__user *uenvp, struct pt_regs *regs) | 388 | const char __user *const __user *uenvp, |
389 | struct pt_regs *regs) | ||
389 | { | 390 | { |
390 | int error; | 391 | int error; |
391 | char *filename; | 392 | char *filename; |
diff --git a/arch/avr32/kernel/sys_avr32.c b/arch/avr32/kernel/sys_avr32.c index 459349b5ed5..62635a09ae3 100644 --- a/arch/avr32/kernel/sys_avr32.c +++ b/arch/avr32/kernel/sys_avr32.c | |||
@@ -7,7 +7,9 @@ | |||
7 | */ | 7 | */ |
8 | #include <linux/unistd.h> | 8 | #include <linux/unistd.h> |
9 | 9 | ||
10 | int kernel_execve(const char *file, char **argv, char **envp) | 10 | int kernel_execve(const char *file, |
11 | const char *const *argv, | ||
12 | const char *const *envp) | ||
11 | { | 13 | { |
12 | register long scno asm("r8") = __NR_execve; | 14 | register long scno asm("r8") = __NR_execve; |
13 | register long sc1 asm("r12") = (long)file; | 15 | register long sc1 asm("r12") = (long)file; |
diff --git a/arch/blackfin/include/asm/bfin_sport.h b/arch/blackfin/include/asm/bfin_sport.h index 9626cf7e425..d27600c262c 100644 --- a/arch/blackfin/include/asm/bfin_sport.h +++ b/arch/blackfin/include/asm/bfin_sport.h | |||
@@ -115,12 +115,6 @@ struct sport_register { | |||
115 | 115 | ||
116 | #endif | 116 | #endif |
117 | 117 | ||
118 | /* Workaround defBF*.h SPORT MMRs till they get cleansed */ | ||
119 | #undef DTYPE_NORM | ||
120 | #undef SLEN | ||
121 | #undef SP_WOFF | ||
122 | #undef SP_WSIZE | ||
123 | |||
124 | /* SPORT_TCR1 Masks */ | 118 | /* SPORT_TCR1 Masks */ |
125 | #define TSPEN 0x0001 /* TX enable */ | 119 | #define TSPEN 0x0001 /* TX enable */ |
126 | #define ITCLK 0x0002 /* Internal TX Clock Select */ | 120 | #define ITCLK 0x0002 /* Internal TX Clock Select */ |
diff --git a/arch/blackfin/include/asm/bitops.h b/arch/blackfin/include/asm/bitops.h index d5872cd967a..3f7ef4d9779 100644 --- a/arch/blackfin/include/asm/bitops.h +++ b/arch/blackfin/include/asm/bitops.h | |||
@@ -22,7 +22,9 @@ | |||
22 | 22 | ||
23 | #include <asm-generic/bitops/sched.h> | 23 | #include <asm-generic/bitops/sched.h> |
24 | #include <asm-generic/bitops/ffs.h> | 24 | #include <asm-generic/bitops/ffs.h> |
25 | #include <asm-generic/bitops/const_hweight.h> | ||
25 | #include <asm-generic/bitops/lock.h> | 26 | #include <asm-generic/bitops/lock.h> |
27 | |||
26 | #include <asm-generic/bitops/ext2-non-atomic.h> | 28 | #include <asm-generic/bitops/ext2-non-atomic.h> |
27 | #include <asm-generic/bitops/ext2-atomic.h> | 29 | #include <asm-generic/bitops/ext2-atomic.h> |
28 | #include <asm-generic/bitops/minix.h> | 30 | #include <asm-generic/bitops/minix.h> |
@@ -115,7 +117,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr) | |||
115 | * of bits set) of a N-bit word | 117 | * of bits set) of a N-bit word |
116 | */ | 118 | */ |
117 | 119 | ||
118 | static inline unsigned int hweight32(unsigned int w) | 120 | static inline unsigned int __arch_hweight32(unsigned int w) |
119 | { | 121 | { |
120 | unsigned int res; | 122 | unsigned int res; |
121 | 123 | ||
@@ -125,19 +127,20 @@ static inline unsigned int hweight32(unsigned int w) | |||
125 | return res; | 127 | return res; |
126 | } | 128 | } |
127 | 129 | ||
128 | static inline unsigned int hweight64(__u64 w) | 130 | static inline unsigned int __arch_hweight64(__u64 w) |
129 | { | 131 | { |
130 | return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w); | 132 | return __arch_hweight32((unsigned int)(w >> 32)) + |
133 | __arch_hweight32((unsigned int)w); | ||
131 | } | 134 | } |
132 | 135 | ||
133 | static inline unsigned int hweight16(unsigned int w) | 136 | static inline unsigned int __arch_hweight16(unsigned int w) |
134 | { | 137 | { |
135 | return hweight32(w & 0xffff); | 138 | return __arch_hweight32(w & 0xffff); |
136 | } | 139 | } |
137 | 140 | ||
138 | static inline unsigned int hweight8(unsigned int w) | 141 | static inline unsigned int __arch_hweight8(unsigned int w) |
139 | { | 142 | { |
140 | return hweight32(w & 0xff); | 143 | return __arch_hweight32(w & 0xff); |
141 | } | 144 | } |
142 | 145 | ||
143 | #endif /* _BLACKFIN_BITOPS_H */ | 146 | #endif /* _BLACKFIN_BITOPS_H */ |
diff --git a/arch/blackfin/include/asm/unistd.h b/arch/blackfin/include/asm/unistd.h index 22886cbdae7..14fcd254b18 100644 --- a/arch/blackfin/include/asm/unistd.h +++ b/arch/blackfin/include/asm/unistd.h | |||
@@ -389,8 +389,11 @@ | |||
389 | #define __NR_rt_tgsigqueueinfo 368 | 389 | #define __NR_rt_tgsigqueueinfo 368 |
390 | #define __NR_perf_event_open 369 | 390 | #define __NR_perf_event_open 369 |
391 | #define __NR_recvmmsg 370 | 391 | #define __NR_recvmmsg 370 |
392 | #define __NR_fanotify_init 371 | ||
393 | #define __NR_fanotify_mark 372 | ||
394 | #define __NR_prlimit64 373 | ||
392 | 395 | ||
393 | #define __NR_syscall 371 | 396 | #define __NR_syscall 374 |
394 | #define NR_syscalls __NR_syscall | 397 | #define NR_syscalls __NR_syscall |
395 | 398 | ||
396 | /* Old optional stuff no one actually uses */ | 399 | /* Old optional stuff no one actually uses */ |
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index a566f61c002..01f98cb964d 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c | |||
@@ -209,7 +209,9 @@ copy_thread(unsigned long clone_flags, | |||
209 | /* | 209 | /* |
210 | * sys_execve() executes a new program. | 210 | * sys_execve() executes a new program. |
211 | */ | 211 | */ |
212 | asmlinkage int sys_execve(const char __user *name, char __user * __user *argv, char __user * __user *envp) | 212 | asmlinkage int sys_execve(const char __user *name, |
213 | const char __user *const __user *argv, | ||
214 | const char __user *const __user *envp) | ||
213 | { | 215 | { |
214 | int error; | 216 | int error; |
215 | char *filename; | 217 | char *filename; |
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h index 2bc8f4f9801..037a51fd8e9 100644 --- a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h +++ b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h | |||
@@ -913,88 +913,6 @@ | |||
913 | #define PH6 0x0040 | 913 | #define PH6 0x0040 |
914 | #define PH7 0x0080 | 914 | #define PH7 0x0080 |
915 | 915 | ||
916 | |||
917 | /* ******************* SERIAL PORT MASKS **************************************/ | ||
918 | /* SPORTx_TCR1 Masks */ | ||
919 | #define TSPEN 0x0001 /* Transmit Enable */ | ||
920 | #define ITCLK 0x0002 /* Internal Transmit Clock Select */ | ||
921 | #define DTYPE_NORM 0x0004 /* Data Format Normal */ | ||
922 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
923 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
924 | #define TLSBIT 0x0010 /* Transmit Bit Order */ | ||
925 | #define ITFS 0x0200 /* Internal Transmit Frame Sync Select */ | ||
926 | #define TFSR 0x0400 /* Transmit Frame Sync Required Select */ | ||
927 | #define DITFS 0x0800 /* Data-Independent Transmit Frame Sync Select */ | ||
928 | #define LTFS 0x1000 /* Low Transmit Frame Sync Select */ | ||
929 | #define LATFS 0x2000 /* Late Transmit Frame Sync Select */ | ||
930 | #define TCKFE 0x4000 /* Clock Falling Edge Select */ | ||
931 | |||
932 | /* SPORTx_TCR2 Masks and Macro */ | ||
933 | #define SLEN(x) ((x)&0x1F) /* SPORT TX Word Length (2 - 31) */ | ||
934 | #define TXSE 0x0100 /* TX Secondary Enable */ | ||
935 | #define TSFSE 0x0200 /* Transmit Stereo Frame Sync Enable */ | ||
936 | #define TRFST 0x0400 /* Left/Right Order (1 = Right Channel 1st) */ | ||
937 | |||
938 | /* SPORTx_RCR1 Masks */ | ||
939 | #define RSPEN 0x0001 /* Receive Enable */ | ||
940 | #define IRCLK 0x0002 /* Internal Receive Clock Select */ | ||
941 | #define DTYPE_NORM 0x0004 /* Data Format Normal */ | ||
942 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
943 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
944 | #define RLSBIT 0x0010 /* Receive Bit Order */ | ||
945 | #define IRFS 0x0200 /* Internal Receive Frame Sync Select */ | ||
946 | #define RFSR 0x0400 /* Receive Frame Sync Required Select */ | ||
947 | #define LRFS 0x1000 /* Low Receive Frame Sync Select */ | ||
948 | #define LARFS 0x2000 /* Late Receive Frame Sync Select */ | ||
949 | #define RCKFE 0x4000 /* Clock Falling Edge Select */ | ||
950 | |||
951 | /* SPORTx_RCR2 Masks */ | ||
952 | #define SLEN(x) ((x)&0x1F) /* SPORT RX Word Length (2 - 31) */ | ||
953 | #define RXSE 0x0100 /* RX Secondary Enable */ | ||
954 | #define RSFSE 0x0200 /* RX Stereo Frame Sync Enable */ | ||
955 | #define RRFST 0x0400 /* Right-First Data Order */ | ||
956 | |||
957 | /* SPORTx_STAT Masks */ | ||
958 | #define RXNE 0x0001 /* Receive FIFO Not Empty Status */ | ||
959 | #define RUVF 0x0002 /* Sticky Receive Underflow Status */ | ||
960 | #define ROVF 0x0004 /* Sticky Receive Overflow Status */ | ||
961 | #define TXF 0x0008 /* Transmit FIFO Full Status */ | ||
962 | #define TUVF 0x0010 /* Sticky Transmit Underflow Status */ | ||
963 | #define TOVF 0x0020 /* Sticky Transmit Overflow Status */ | ||
964 | #define TXHRE 0x0040 /* Transmit Hold Register Empty */ | ||
965 | |||
966 | /* SPORTx_MCMC1 Macros */ | ||
967 | #define SP_WOFF(x) ((x) & 0x3FF) /* Multichannel Window Offset Field */ | ||
968 | |||
969 | /* Only use WSIZE Macro With Logic OR While Setting Lower Order Bits */ | ||
970 | #define SP_WSIZE(x) (((((x)>>0x3)-1)&0xF) << 0xC) /* Multichannel Window Size = (x/8)-1 */ | ||
971 | |||
972 | /* SPORTx_MCMC2 Masks */ | ||
973 | #define REC_BYPASS 0x0000 /* Bypass Mode (No Clock Recovery) */ | ||
974 | #define REC_2FROM4 0x0002 /* Recover 2 MHz Clock from 4 MHz Clock */ | ||
975 | #define REC_8FROM16 0x0003 /* Recover 8 MHz Clock from 16 MHz Clock */ | ||
976 | #define MCDTXPE 0x0004 /* Multichannel DMA Transmit Packing */ | ||
977 | #define MCDRXPE 0x0008 /* Multichannel DMA Receive Packing */ | ||
978 | #define MCMEN 0x0010 /* Multichannel Frame Mode Enable */ | ||
979 | #define FSDR 0x0080 /* Multichannel Frame Sync to Data Relationship */ | ||
980 | #define MFD_0 0x0000 /* Multichannel Frame Delay = 0 */ | ||
981 | #define MFD_1 0x1000 /* Multichannel Frame Delay = 1 */ | ||
982 | #define MFD_2 0x2000 /* Multichannel Frame Delay = 2 */ | ||
983 | #define MFD_3 0x3000 /* Multichannel Frame Delay = 3 */ | ||
984 | #define MFD_4 0x4000 /* Multichannel Frame Delay = 4 */ | ||
985 | #define MFD_5 0x5000 /* Multichannel Frame Delay = 5 */ | ||
986 | #define MFD_6 0x6000 /* Multichannel Frame Delay = 6 */ | ||
987 | #define MFD_7 0x7000 /* Multichannel Frame Delay = 7 */ | ||
988 | #define MFD_8 0x8000 /* Multichannel Frame Delay = 8 */ | ||
989 | #define MFD_9 0x9000 /* Multichannel Frame Delay = 9 */ | ||
990 | #define MFD_10 0xA000 /* Multichannel Frame Delay = 10 */ | ||
991 | #define MFD_11 0xB000 /* Multichannel Frame Delay = 11 */ | ||
992 | #define MFD_12 0xC000 /* Multichannel Frame Delay = 12 */ | ||
993 | #define MFD_13 0xD000 /* Multichannel Frame Delay = 13 */ | ||
994 | #define MFD_14 0xE000 /* Multichannel Frame Delay = 14 */ | ||
995 | #define MFD_15 0xF000 /* Multichannel Frame Delay = 15 */ | ||
996 | |||
997 | |||
998 | /* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS *************************/ | 916 | /* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS *************************/ |
999 | /* EBIU_AMGCTL Masks */ | 917 | /* EBIU_AMGCTL Masks */ |
1000 | #define AMCKEN 0x0001 /* Enable CLKOUT */ | 918 | #define AMCKEN 0x0001 /* Enable CLKOUT */ |
diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c index f392af64165..645ba5c8077 100644 --- a/arch/blackfin/mach-bf527/boards/cm_bf527.c +++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c | |||
@@ -145,7 +145,6 @@ static struct mtd_partition partition_info[] = { | |||
145 | }; | 145 | }; |
146 | 146 | ||
147 | static struct bf5xx_nand_platform bf5xx_nand_platform = { | 147 | static struct bf5xx_nand_platform bf5xx_nand_platform = { |
148 | .page_size = NFC_PG_SIZE_256, | ||
149 | .data_width = NFC_NWIDTH_8, | 148 | .data_width = NFC_NWIDTH_8, |
150 | .partitions = partition_info, | 149 | .partitions = partition_info, |
151 | .nr_partitions = ARRAY_SIZE(partition_info), | 150 | .nr_partitions = ARRAY_SIZE(partition_info), |
diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c index 606eb36b9d6..c975fe88eba 100644 --- a/arch/blackfin/mach-bf527/boards/ezbrd.c +++ b/arch/blackfin/mach-bf527/boards/ezbrd.c | |||
@@ -149,7 +149,6 @@ static struct mtd_partition partition_info[] = { | |||
149 | }; | 149 | }; |
150 | 150 | ||
151 | static struct bf5xx_nand_platform bf5xx_nand_platform = { | 151 | static struct bf5xx_nand_platform bf5xx_nand_platform = { |
152 | .page_size = NFC_PG_SIZE_256, | ||
153 | .data_width = NFC_NWIDTH_8, | 152 | .data_width = NFC_NWIDTH_8, |
154 | .partitions = partition_info, | 153 | .partitions = partition_info, |
155 | .nr_partitions = ARRAY_SIZE(partition_info), | 154 | .nr_partitions = ARRAY_SIZE(partition_info), |
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index a05c967a24c..87b41e994ba 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c | |||
@@ -234,7 +234,6 @@ static struct mtd_partition partition_info[] = { | |||
234 | }; | 234 | }; |
235 | 235 | ||
236 | static struct bf5xx_nand_platform bf5xx_nand_platform = { | 236 | static struct bf5xx_nand_platform bf5xx_nand_platform = { |
237 | .page_size = NFC_PG_SIZE_256, | ||
238 | .data_width = NFC_NWIDTH_8, | 237 | .data_width = NFC_NWIDTH_8, |
239 | .partitions = partition_info, | 238 | .partitions = partition_info, |
240 | .nr_partitions = ARRAY_SIZE(partition_info), | 239 | .nr_partitions = ARRAY_SIZE(partition_info), |
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h index 5f97f01fcda..3e000756aac 100644 --- a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h +++ b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h | |||
@@ -922,88 +922,6 @@ | |||
922 | #define PH14 0x4000 | 922 | #define PH14 0x4000 |
923 | #define PH15 0x8000 | 923 | #define PH15 0x8000 |
924 | 924 | ||
925 | |||
926 | /* ******************* SERIAL PORT MASKS **************************************/ | ||
927 | /* SPORTx_TCR1 Masks */ | ||
928 | #define TSPEN 0x0001 /* Transmit Enable */ | ||
929 | #define ITCLK 0x0002 /* Internal Transmit Clock Select */ | ||
930 | #define DTYPE_NORM 0x0004 /* Data Format Normal */ | ||
931 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
932 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
933 | #define TLSBIT 0x0010 /* Transmit Bit Order */ | ||
934 | #define ITFS 0x0200 /* Internal Transmit Frame Sync Select */ | ||
935 | #define TFSR 0x0400 /* Transmit Frame Sync Required Select */ | ||
936 | #define DITFS 0x0800 /* Data-Independent Transmit Frame Sync Select */ | ||
937 | #define LTFS 0x1000 /* Low Transmit Frame Sync Select */ | ||
938 | #define LATFS 0x2000 /* Late Transmit Frame Sync Select */ | ||
939 | #define TCKFE 0x4000 /* Clock Falling Edge Select */ | ||
940 | |||
941 | /* SPORTx_TCR2 Masks and Macro */ | ||
942 | #define SLEN(x) ((x)&0x1F) /* SPORT TX Word Length (2 - 31) */ | ||
943 | #define TXSE 0x0100 /* TX Secondary Enable */ | ||
944 | #define TSFSE 0x0200 /* Transmit Stereo Frame Sync Enable */ | ||
945 | #define TRFST 0x0400 /* Left/Right Order (1 = Right Channel 1st) */ | ||
946 | |||
947 | /* SPORTx_RCR1 Masks */ | ||
948 | #define RSPEN 0x0001 /* Receive Enable */ | ||
949 | #define IRCLK 0x0002 /* Internal Receive Clock Select */ | ||
950 | #define DTYPE_NORM 0x0004 /* Data Format Normal */ | ||
951 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
952 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
953 | #define RLSBIT 0x0010 /* Receive Bit Order */ | ||
954 | #define IRFS 0x0200 /* Internal Receive Frame Sync Select */ | ||
955 | #define RFSR 0x0400 /* Receive Frame Sync Required Select */ | ||
956 | #define LRFS 0x1000 /* Low Receive Frame Sync Select */ | ||
957 | #define LARFS 0x2000 /* Late Receive Frame Sync Select */ | ||
958 | #define RCKFE 0x4000 /* Clock Falling Edge Select */ | ||
959 | |||
960 | /* SPORTx_RCR2 Masks */ | ||
961 | #define SLEN(x) ((x)&0x1F) /* SPORT RX Word Length (2 - 31) */ | ||
962 | #define RXSE 0x0100 /* RX Secondary Enable */ | ||
963 | #define RSFSE 0x0200 /* RX Stereo Frame Sync Enable */ | ||
964 | #define RRFST 0x0400 /* Right-First Data Order */ | ||
965 | |||
966 | /* SPORTx_STAT Masks */ | ||
967 | #define RXNE 0x0001 /* Receive FIFO Not Empty Status */ | ||
968 | #define RUVF 0x0002 /* Sticky Receive Underflow Status */ | ||
969 | #define ROVF 0x0004 /* Sticky Receive Overflow Status */ | ||
970 | #define TXF 0x0008 /* Transmit FIFO Full Status */ | ||
971 | #define TUVF 0x0010 /* Sticky Transmit Underflow Status */ | ||
972 | #define TOVF 0x0020 /* Sticky Transmit Overflow Status */ | ||
973 | #define TXHRE 0x0040 /* Transmit Hold Register Empty */ | ||
974 | |||
975 | /* SPORTx_MCMC1 Macros */ | ||
976 | #define SP_WOFF(x) ((x) & 0x3FF) /* Multichannel Window Offset Field */ | ||
977 | |||
978 | /* Only use WSIZE Macro With Logic OR While Setting Lower Order Bits */ | ||
979 | #define SP_WSIZE(x) (((((x)>>0x3)-1)&0xF) << 0xC) /* Multichannel Window Size = (x/8)-1 */ | ||
980 | |||
981 | /* SPORTx_MCMC2 Masks */ | ||
982 | #define REC_BYPASS 0x0000 /* Bypass Mode (No Clock Recovery) */ | ||
983 | #define REC_2FROM4 0x0002 /* Recover 2 MHz Clock from 4 MHz Clock */ | ||
984 | #define REC_8FROM16 0x0003 /* Recover 8 MHz Clock from 16 MHz Clock */ | ||
985 | #define MCDTXPE 0x0004 /* Multichannel DMA Transmit Packing */ | ||
986 | #define MCDRXPE 0x0008 /* Multichannel DMA Receive Packing */ | ||
987 | #define MCMEN 0x0010 /* Multichannel Frame Mode Enable */ | ||
988 | #define FSDR 0x0080 /* Multichannel Frame Sync to Data Relationship */ | ||
989 | #define MFD_0 0x0000 /* Multichannel Frame Delay = 0 */ | ||
990 | #define MFD_1 0x1000 /* Multichannel Frame Delay = 1 */ | ||
991 | #define MFD_2 0x2000 /* Multichannel Frame Delay = 2 */ | ||
992 | #define MFD_3 0x3000 /* Multichannel Frame Delay = 3 */ | ||
993 | #define MFD_4 0x4000 /* Multichannel Frame Delay = 4 */ | ||
994 | #define MFD_5 0x5000 /* Multichannel Frame Delay = 5 */ | ||
995 | #define MFD_6 0x6000 /* Multichannel Frame Delay = 6 */ | ||
996 | #define MFD_7 0x7000 /* Multichannel Frame Delay = 7 */ | ||
997 | #define MFD_8 0x8000 /* Multichannel Frame Delay = 8 */ | ||
998 | #define MFD_9 0x9000 /* Multichannel Frame Delay = 9 */ | ||
999 | #define MFD_10 0xA000 /* Multichannel Frame Delay = 10 */ | ||
1000 | #define MFD_11 0xB000 /* Multichannel Frame Delay = 11 */ | ||
1001 | #define MFD_12 0xC000 /* Multichannel Frame Delay = 12 */ | ||
1002 | #define MFD_13 0xD000 /* Multichannel Frame Delay = 13 */ | ||
1003 | #define MFD_14 0xE000 /* Multichannel Frame Delay = 14 */ | ||
1004 | #define MFD_15 0xF000 /* Multichannel Frame Delay = 15 */ | ||
1005 | |||
1006 | |||
1007 | /* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS *************************/ | 925 | /* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS *************************/ |
1008 | /* EBIU_AMGCTL Masks */ | 926 | /* EBIU_AMGCTL Masks */ |
1009 | #define AMCKEN 0x0001 /* Enable CLKOUT */ | 927 | #define AMCKEN 0x0001 /* Enable CLKOUT */ |
diff --git a/arch/blackfin/mach-bf533/include/mach/defBF532.h b/arch/blackfin/mach-bf533/include/mach/defBF532.h index e9ff491c095..04acf1ed10f 100644 --- a/arch/blackfin/mach-bf533/include/mach/defBF532.h +++ b/arch/blackfin/mach-bf533/include/mach/defBF532.h | |||
@@ -509,98 +509,6 @@ | |||
509 | #define IREN_P 0x01 | 509 | #define IREN_P 0x01 |
510 | #define UCEN_P 0x00 | 510 | #define UCEN_P 0x00 |
511 | 511 | ||
512 | /* ********** SERIAL PORT MASKS ********************** */ | ||
513 | |||
514 | /* SPORTx_TCR1 Masks */ | ||
515 | #define TSPEN 0x0001 /* TX enable */ | ||
516 | #define ITCLK 0x0002 /* Internal TX Clock Select */ | ||
517 | #define TDTYPE 0x000C /* TX Data Formatting Select */ | ||
518 | #define DTYPE_NORM 0x0000 /* Data Format Normal */ | ||
519 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
520 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
521 | #define TLSBIT 0x0010 /* TX Bit Order */ | ||
522 | #define ITFS 0x0200 /* Internal TX Frame Sync Select */ | ||
523 | #define TFSR 0x0400 /* TX Frame Sync Required Select */ | ||
524 | #define DITFS 0x0800 /* Data Independent TX Frame Sync Select */ | ||
525 | #define LTFS 0x1000 /* Low TX Frame Sync Select */ | ||
526 | #define LATFS 0x2000 /* Late TX Frame Sync Select */ | ||
527 | #define TCKFE 0x4000 /* TX Clock Falling Edge Select */ | ||
528 | |||
529 | /* SPORTx_TCR2 Masks */ | ||
530 | #if defined(__ADSPBF531__) || defined(__ADSPBF532__) || \ | ||
531 | defined(__ADSPBF533__) | ||
532 | # define SLEN 0x001F /*TX Word Length */ | ||
533 | #else | ||
534 | # define SLEN(x) ((x)&0x1F) /* SPORT TX Word Length (2 - 31) */ | ||
535 | #endif | ||
536 | #define TXSE 0x0100 /*TX Secondary Enable */ | ||
537 | #define TSFSE 0x0200 /*TX Stereo Frame Sync Enable */ | ||
538 | #define TRFST 0x0400 /*TX Right-First Data Order */ | ||
539 | |||
540 | /* SPORTx_RCR1 Masks */ | ||
541 | #define RSPEN 0x0001 /* RX enable */ | ||
542 | #define IRCLK 0x0002 /* Internal RX Clock Select */ | ||
543 | #define RDTYPE 0x000C /* RX Data Formatting Select */ | ||
544 | #define DTYPE_NORM 0x0000 /* no companding */ | ||
545 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
546 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
547 | #define RLSBIT 0x0010 /* RX Bit Order */ | ||
548 | #define IRFS 0x0200 /* Internal RX Frame Sync Select */ | ||
549 | #define RFSR 0x0400 /* RX Frame Sync Required Select */ | ||
550 | #define LRFS 0x1000 /* Low RX Frame Sync Select */ | ||
551 | #define LARFS 0x2000 /* Late RX Frame Sync Select */ | ||
552 | #define RCKFE 0x4000 /* RX Clock Falling Edge Select */ | ||
553 | |||
554 | /* SPORTx_RCR2 Masks */ | ||
555 | /* SLEN defined above */ | ||
556 | #define RXSE 0x0100 /*RX Secondary Enable */ | ||
557 | #define RSFSE 0x0200 /*RX Stereo Frame Sync Enable */ | ||
558 | #define RRFST 0x0400 /*Right-First Data Order */ | ||
559 | |||
560 | /*SPORTx_STAT Masks */ | ||
561 | #define RXNE 0x0001 /*RX FIFO Not Empty Status */ | ||
562 | #define RUVF 0x0002 /*RX Underflow Status */ | ||
563 | #define ROVF 0x0004 /*RX Overflow Status */ | ||
564 | #define TXF 0x0008 /*TX FIFO Full Status */ | ||
565 | #define TUVF 0x0010 /*TX Underflow Status */ | ||
566 | #define TOVF 0x0020 /*TX Overflow Status */ | ||
567 | #define TXHRE 0x0040 /*TX Hold Register Empty */ | ||
568 | |||
569 | /*SPORTx_MCMC1 Masks */ | ||
570 | #define SP_WSIZE 0x0000F000 /*Multichannel Window Size Field */ | ||
571 | #define SP_WOFF 0x000003FF /*Multichannel Window Offset Field */ | ||
572 | /* SPORTx_MCMC1 Macros */ | ||
573 | #define SET_SP_WOFF(x) ((x) & 0x3FF) /* Multichannel Window Offset Field */ | ||
574 | /* Only use SET_WSIZE Macro With Logic OR While Setting Lower Order Bits */ | ||
575 | #define SET_SP_WSIZE(x) (((((x)>>0x3)-1)&0xF) << 0xC) /* Multichannel Window Size = (x/8)-1 */ | ||
576 | |||
577 | /*SPORTx_MCMC2 Masks */ | ||
578 | #define MCCRM 0x00000003 /*Multichannel Clock Recovery Mode */ | ||
579 | #define REC_BYPASS 0x0000 /* Bypass Mode (No Clock Recovery) */ | ||
580 | #define REC_2FROM4 0x0002 /* Recover 2 MHz Clock from 4 MHz Clock */ | ||
581 | #define REC_8FROM16 0x0003 /* Recover 8 MHz Clock from 16 MHz Clock */ | ||
582 | #define MCDTXPE 0x00000004 /*Multichannel DMA Transmit Packing */ | ||
583 | #define MCDRXPE 0x00000008 /*Multichannel DMA Receive Packing */ | ||
584 | #define MCMEN 0x00000010 /*Multichannel Frame Mode Enable */ | ||
585 | #define FSDR 0x00000080 /*Multichannel Frame Sync to Data Relationship */ | ||
586 | #define MFD 0x0000F000 /*Multichannel Frame Delay */ | ||
587 | #define MFD_0 0x0000 /* Multichannel Frame Delay = 0 */ | ||
588 | #define MFD_1 0x1000 /* Multichannel Frame Delay = 1 */ | ||
589 | #define MFD_2 0x2000 /* Multichannel Frame Delay = 2 */ | ||
590 | #define MFD_3 0x3000 /* Multichannel Frame Delay = 3 */ | ||
591 | #define MFD_4 0x4000 /* Multichannel Frame Delay = 4 */ | ||
592 | #define MFD_5 0x5000 /* Multichannel Frame Delay = 5 */ | ||
593 | #define MFD_6 0x6000 /* Multichannel Frame Delay = 6 */ | ||
594 | #define MFD_7 0x7000 /* Multichannel Frame Delay = 7 */ | ||
595 | #define MFD_8 0x8000 /* Multichannel Frame Delay = 8 */ | ||
596 | #define MFD_9 0x9000 /* Multichannel Frame Delay = 9 */ | ||
597 | #define MFD_10 0xA000 /* Multichannel Frame Delay = 10 */ | ||
598 | #define MFD_11 0xB000 /* Multichannel Frame Delay = 11 */ | ||
599 | #define MFD_12 0xC000 /* Multichannel Frame Delay = 12 */ | ||
600 | #define MFD_13 0xD000 /* Multichannel Frame Delay = 13 */ | ||
601 | #define MFD_14 0xE000 /* Multichannel Frame Delay = 14 */ | ||
602 | #define MFD_15 0xF000 /* Multichannel Frame Delay = 15 */ | ||
603 | |||
604 | /* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */ | 512 | /* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */ |
605 | 513 | ||
606 | /* PPI_CONTROL Masks */ | 514 | /* PPI_CONTROL Masks */ |
diff --git a/arch/blackfin/mach-bf537/include/mach/defBF534.h b/arch/blackfin/mach-bf537/include/mach/defBF534.h index aad61b88737..6f56907a18c 100644 --- a/arch/blackfin/mach-bf537/include/mach/defBF534.h +++ b/arch/blackfin/mach-bf537/include/mach/defBF534.h | |||
@@ -1241,86 +1241,6 @@ | |||
1241 | #define PH14 0x4000 | 1241 | #define PH14 0x4000 |
1242 | #define PH15 0x8000 | 1242 | #define PH15 0x8000 |
1243 | 1243 | ||
1244 | /* ******************* SERIAL PORT MASKS **************************************/ | ||
1245 | /* SPORTx_TCR1 Masks */ | ||
1246 | #define TSPEN 0x0001 /* Transmit Enable */ | ||
1247 | #define ITCLK 0x0002 /* Internal Transmit Clock Select */ | ||
1248 | #define DTYPE_NORM 0x0004 /* Data Format Normal */ | ||
1249 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
1250 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
1251 | #define TLSBIT 0x0010 /* Transmit Bit Order */ | ||
1252 | #define ITFS 0x0200 /* Internal Transmit Frame Sync Select */ | ||
1253 | #define TFSR 0x0400 /* Transmit Frame Sync Required Select */ | ||
1254 | #define DITFS 0x0800 /* Data-Independent Transmit Frame Sync Select */ | ||
1255 | #define LTFS 0x1000 /* Low Transmit Frame Sync Select */ | ||
1256 | #define LATFS 0x2000 /* Late Transmit Frame Sync Select */ | ||
1257 | #define TCKFE 0x4000 /* Clock Falling Edge Select */ | ||
1258 | |||
1259 | /* SPORTx_TCR2 Masks and Macro */ | ||
1260 | #define SLEN(x) ((x)&0x1F) /* SPORT TX Word Length (2 - 31) */ | ||
1261 | #define TXSE 0x0100 /* TX Secondary Enable */ | ||
1262 | #define TSFSE 0x0200 /* Transmit Stereo Frame Sync Enable */ | ||
1263 | #define TRFST 0x0400 /* Left/Right Order (1 = Right Channel 1st) */ | ||
1264 | |||
1265 | /* SPORTx_RCR1 Masks */ | ||
1266 | #define RSPEN 0x0001 /* Receive Enable */ | ||
1267 | #define IRCLK 0x0002 /* Internal Receive Clock Select */ | ||
1268 | #define DTYPE_NORM 0x0004 /* Data Format Normal */ | ||
1269 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
1270 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
1271 | #define RLSBIT 0x0010 /* Receive Bit Order */ | ||
1272 | #define IRFS 0x0200 /* Internal Receive Frame Sync Select */ | ||
1273 | #define RFSR 0x0400 /* Receive Frame Sync Required Select */ | ||
1274 | #define LRFS 0x1000 /* Low Receive Frame Sync Select */ | ||
1275 | #define LARFS 0x2000 /* Late Receive Frame Sync Select */ | ||
1276 | #define RCKFE 0x4000 /* Clock Falling Edge Select */ | ||
1277 | |||
1278 | /* SPORTx_RCR2 Masks */ | ||
1279 | #define SLEN(x) ((x)&0x1F) /* SPORT RX Word Length (2 - 31) */ | ||
1280 | #define RXSE 0x0100 /* RX Secondary Enable */ | ||
1281 | #define RSFSE 0x0200 /* RX Stereo Frame Sync Enable */ | ||
1282 | #define RRFST 0x0400 /* Right-First Data Order */ | ||
1283 | |||
1284 | /* SPORTx_STAT Masks */ | ||
1285 | #define RXNE 0x0001 /* Receive FIFO Not Empty Status */ | ||
1286 | #define RUVF 0x0002 /* Sticky Receive Underflow Status */ | ||
1287 | #define ROVF 0x0004 /* Sticky Receive Overflow Status */ | ||
1288 | #define TXF 0x0008 /* Transmit FIFO Full Status */ | ||
1289 | #define TUVF 0x0010 /* Sticky Transmit Underflow Status */ | ||
1290 | #define TOVF 0x0020 /* Sticky Transmit Overflow Status */ | ||
1291 | #define TXHRE 0x0040 /* Transmit Hold Register Empty */ | ||
1292 | |||
1293 | /* SPORTx_MCMC1 Macros */ | ||
1294 | #define SP_WOFF(x) ((x) & 0x3FF) /* Multichannel Window Offset Field */ | ||
1295 | |||
1296 | /* Only use WSIZE Macro With Logic OR While Setting Lower Order Bits */ | ||
1297 | #define SP_WSIZE(x) (((((x)>>0x3)-1)&0xF) << 0xC) /* Multichannel Window Size = (x/8)-1 */ | ||
1298 | |||
1299 | /* SPORTx_MCMC2 Masks */ | ||
1300 | #define REC_BYPASS 0x0000 /* Bypass Mode (No Clock Recovery) */ | ||
1301 | #define REC_2FROM4 0x0002 /* Recover 2 MHz Clock from 4 MHz Clock */ | ||
1302 | #define REC_8FROM16 0x0003 /* Recover 8 MHz Clock from 16 MHz Clock */ | ||
1303 | #define MCDTXPE 0x0004 /* Multichannel DMA Transmit Packing */ | ||
1304 | #define MCDRXPE 0x0008 /* Multichannel DMA Receive Packing */ | ||
1305 | #define MCMEN 0x0010 /* Multichannel Frame Mode Enable */ | ||
1306 | #define FSDR 0x0080 /* Multichannel Frame Sync to Data Relationship */ | ||
1307 | #define MFD_0 0x0000 /* Multichannel Frame Delay = 0 */ | ||
1308 | #define MFD_1 0x1000 /* Multichannel Frame Delay = 1 */ | ||
1309 | #define MFD_2 0x2000 /* Multichannel Frame Delay = 2 */ | ||
1310 | #define MFD_3 0x3000 /* Multichannel Frame Delay = 3 */ | ||
1311 | #define MFD_4 0x4000 /* Multichannel Frame Delay = 4 */ | ||
1312 | #define MFD_5 0x5000 /* Multichannel Frame Delay = 5 */ | ||
1313 | #define MFD_6 0x6000 /* Multichannel Frame Delay = 6 */ | ||
1314 | #define MFD_7 0x7000 /* Multichannel Frame Delay = 7 */ | ||
1315 | #define MFD_8 0x8000 /* Multichannel Frame Delay = 8 */ | ||
1316 | #define MFD_9 0x9000 /* Multichannel Frame Delay = 9 */ | ||
1317 | #define MFD_10 0xA000 /* Multichannel Frame Delay = 10 */ | ||
1318 | #define MFD_11 0xB000 /* Multichannel Frame Delay = 11 */ | ||
1319 | #define MFD_12 0xC000 /* Multichannel Frame Delay = 12 */ | ||
1320 | #define MFD_13 0xD000 /* Multichannel Frame Delay = 13 */ | ||
1321 | #define MFD_14 0xE000 /* Multichannel Frame Delay = 14 */ | ||
1322 | #define MFD_15 0xF000 /* Multichannel Frame Delay = 15 */ | ||
1323 | |||
1324 | /* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS *************************/ | 1244 | /* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS *************************/ |
1325 | /* EBIU_AMGCTL Masks */ | 1245 | /* EBIU_AMGCTL Masks */ |
1326 | #define AMCKEN 0x0001 /* Enable CLKOUT */ | 1246 | #define AMCKEN 0x0001 /* Enable CLKOUT */ |
diff --git a/arch/blackfin/mach-bf538/include/mach/defBF539.h b/arch/blackfin/mach-bf538/include/mach/defBF539.h index b674a1c4aef..fe43062b497 100644 --- a/arch/blackfin/mach-bf538/include/mach/defBF539.h +++ b/arch/blackfin/mach-bf538/include/mach/defBF539.h | |||
@@ -1610,113 +1610,6 @@ | |||
1610 | #define UCEN_P 0x00 | 1610 | #define UCEN_P 0x00 |
1611 | 1611 | ||
1612 | 1612 | ||
1613 | /* ********** SERIAL PORT MASKS ********************** */ | ||
1614 | /* SPORTx_TCR1 Masks */ | ||
1615 | #define TSPEN 0x0001 /* TX enable */ | ||
1616 | #define ITCLK 0x0002 /* Internal TX Clock Select */ | ||
1617 | #define TDTYPE 0x000C /* TX Data Formatting Select */ | ||
1618 | #define DTYPE_NORM 0x0000 /* Data Format Normal */ | ||
1619 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
1620 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
1621 | #define TLSBIT 0x0010 /* TX Bit Order */ | ||
1622 | #define ITFS 0x0200 /* Internal TX Frame Sync Select */ | ||
1623 | #define TFSR 0x0400 /* TX Frame Sync Required Select */ | ||
1624 | #define DITFS 0x0800 /* Data Independent TX Frame Sync Select */ | ||
1625 | #define LTFS 0x1000 /* Low TX Frame Sync Select */ | ||
1626 | #define LATFS 0x2000 /* Late TX Frame Sync Select */ | ||
1627 | #define TCKFE 0x4000 /* TX Clock Falling Edge Select */ | ||
1628 | /* SPORTx_RCR1 Deprecated Masks */ | ||
1629 | #define TULAW DTYPE_ULAW /* Compand Using u-Law */ | ||
1630 | #define TALAW DTYPE_ALAW /* Compand Using A-Law */ | ||
1631 | |||
1632 | /* SPORTx_TCR2 Masks */ | ||
1633 | #ifdef _MISRA_RULES | ||
1634 | #define SLEN(x) ((x)&0x1Fu) /* SPORT TX Word Length (2 - 31) */ | ||
1635 | #else | ||
1636 | #define SLEN(x) ((x)&0x1F) /* SPORT TX Word Length (2 - 31) */ | ||
1637 | #endif /* _MISRA_RULES */ | ||
1638 | #define TXSE 0x0100 /*TX Secondary Enable */ | ||
1639 | #define TSFSE 0x0200 /*TX Stereo Frame Sync Enable */ | ||
1640 | #define TRFST 0x0400 /*TX Right-First Data Order */ | ||
1641 | |||
1642 | /* SPORTx_RCR1 Masks */ | ||
1643 | #define RSPEN 0x0001 /* RX enable */ | ||
1644 | #define IRCLK 0x0002 /* Internal RX Clock Select */ | ||
1645 | #define RDTYPE 0x000C /* RX Data Formatting Select */ | ||
1646 | #define DTYPE_NORM 0x0000 /* no companding */ | ||
1647 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
1648 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
1649 | #define RLSBIT 0x0010 /* RX Bit Order */ | ||
1650 | #define IRFS 0x0200 /* Internal RX Frame Sync Select */ | ||
1651 | #define RFSR 0x0400 /* RX Frame Sync Required Select */ | ||
1652 | #define LRFS 0x1000 /* Low RX Frame Sync Select */ | ||
1653 | #define LARFS 0x2000 /* Late RX Frame Sync Select */ | ||
1654 | #define RCKFE 0x4000 /* RX Clock Falling Edge Select */ | ||
1655 | /* SPORTx_RCR1 Deprecated Masks */ | ||
1656 | #define RULAW DTYPE_ULAW /* Compand Using u-Law */ | ||
1657 | #define RALAW DTYPE_ALAW /* Compand Using A-Law */ | ||
1658 | |||
1659 | /* SPORTx_RCR2 Masks */ | ||
1660 | #ifdef _MISRA_RULES | ||
1661 | #define SLEN(x) ((x)&0x1Fu) /* SPORT RX Word Length (2 - 31) */ | ||
1662 | #else | ||
1663 | #define SLEN(x) ((x)&0x1F) /* SPORT RX Word Length (2 - 31) */ | ||
1664 | #endif /* _MISRA_RULES */ | ||
1665 | #define RXSE 0x0100 /*RX Secondary Enable */ | ||
1666 | #define RSFSE 0x0200 /*RX Stereo Frame Sync Enable */ | ||
1667 | #define RRFST 0x0400 /*Right-First Data Order */ | ||
1668 | |||
1669 | /*SPORTx_STAT Masks */ | ||
1670 | #define RXNE 0x0001 /*RX FIFO Not Empty Status */ | ||
1671 | #define RUVF 0x0002 /*RX Underflow Status */ | ||
1672 | #define ROVF 0x0004 /*RX Overflow Status */ | ||
1673 | #define TXF 0x0008 /*TX FIFO Full Status */ | ||
1674 | #define TUVF 0x0010 /*TX Underflow Status */ | ||
1675 | #define TOVF 0x0020 /*TX Overflow Status */ | ||
1676 | #define TXHRE 0x0040 /*TX Hold Register Empty */ | ||
1677 | |||
1678 | /*SPORTx_MCMC1 Masks */ | ||
1679 | #define WOFF 0x000003FF /*Multichannel Window Offset Field */ | ||
1680 | /* SPORTx_MCMC1 Macros */ | ||
1681 | #ifdef _MISRA_RULES | ||
1682 | #define SET_WOFF(x) ((x) & 0x3FFu) /* Multichannel Window Offset Field */ | ||
1683 | /* Only use SET_WSIZE Macro With Logic OR While Setting Lower Order Bits */ | ||
1684 | #define SET_WSIZE(x) (((((x)>>0x3)-1u)&0xFu) << 0xC) /* Multichannel Window Size = (x/8)-1 */ | ||
1685 | #else | ||
1686 | #define SET_WOFF(x) ((x) & 0x3FF) /* Multichannel Window Offset Field */ | ||
1687 | /* Only use SET_WSIZE Macro With Logic OR While Setting Lower Order Bits */ | ||
1688 | #define SET_WSIZE(x) (((((x)>>0x3)-1)&0xF) << 0xC) /* Multichannel Window Size = (x/8)-1 */ | ||
1689 | #endif /* _MISRA_RULES */ | ||
1690 | |||
1691 | |||
1692 | /*SPORTx_MCMC2 Masks */ | ||
1693 | #define MCCRM 0x0003 /*Multichannel Clock Recovery Mode */ | ||
1694 | #define REC_BYPASS 0x0000 /* Bypass Mode (No Clock Recovery) */ | ||
1695 | #define REC_2FROM4 0x0002 /* Recover 2 MHz Clock from 4 MHz Clock */ | ||
1696 | #define REC_8FROM16 0x0003 /* Recover 8 MHz Clock from 16 MHz Clock */ | ||
1697 | #define MCDTXPE 0x0004 /*Multichannel DMA Transmit Packing */ | ||
1698 | #define MCDRXPE 0x0008 /*Multichannel DMA Receive Packing */ | ||
1699 | #define MCMEN 0x0010 /*Multichannel Frame Mode Enable */ | ||
1700 | #define FSDR 0x0080 /*Multichannel Frame Sync to Data Relationship */ | ||
1701 | #define MFD 0xF000 /*Multichannel Frame Delay */ | ||
1702 | #define MFD_0 0x0000 /* Multichannel Frame Delay = 0 */ | ||
1703 | #define MFD_1 0x1000 /* Multichannel Frame Delay = 1 */ | ||
1704 | #define MFD_2 0x2000 /* Multichannel Frame Delay = 2 */ | ||
1705 | #define MFD_3 0x3000 /* Multichannel Frame Delay = 3 */ | ||
1706 | #define MFD_4 0x4000 /* Multichannel Frame Delay = 4 */ | ||
1707 | #define MFD_5 0x5000 /* Multichannel Frame Delay = 5 */ | ||
1708 | #define MFD_6 0x6000 /* Multichannel Frame Delay = 6 */ | ||
1709 | #define MFD_7 0x7000 /* Multichannel Frame Delay = 7 */ | ||
1710 | #define MFD_8 0x8000 /* Multichannel Frame Delay = 8 */ | ||
1711 | #define MFD_9 0x9000 /* Multichannel Frame Delay = 9 */ | ||
1712 | #define MFD_10 0xA000 /* Multichannel Frame Delay = 10 */ | ||
1713 | #define MFD_11 0xB000 /* Multichannel Frame Delay = 11 */ | ||
1714 | #define MFD_12 0xC000 /* Multichannel Frame Delay = 12 */ | ||
1715 | #define MFD_13 0xD000 /* Multichannel Frame Delay = 13 */ | ||
1716 | #define MFD_14 0xE000 /* Multichannel Frame Delay = 14 */ | ||
1717 | #define MFD_15 0xF000 /* Multichannel Frame Delay = 15 */ | ||
1718 | |||
1719 | |||
1720 | /* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */ | 1613 | /* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */ |
1721 | /* PPI_CONTROL Masks */ | 1614 | /* PPI_CONTROL Masks */ |
1722 | #define PORT_EN 0x0001 /* PPI Port Enable */ | 1615 | #define PORT_EN 0x0001 /* PPI Port Enable */ |
diff --git a/arch/blackfin/mach-bf548/boards/cm_bf548.c b/arch/blackfin/mach-bf548/boards/cm_bf548.c index dbb6b1d83f6..0c38eec9ade 100644 --- a/arch/blackfin/mach-bf548/boards/cm_bf548.c +++ b/arch/blackfin/mach-bf548/boards/cm_bf548.c | |||
@@ -706,7 +706,6 @@ static struct mtd_partition partition_info[] = { | |||
706 | }; | 706 | }; |
707 | 707 | ||
708 | static struct bf5xx_nand_platform bf5xx_nand_platform = { | 708 | static struct bf5xx_nand_platform bf5xx_nand_platform = { |
709 | .page_size = NFC_PG_SIZE_256, | ||
710 | .data_width = NFC_NWIDTH_8, | 709 | .data_width = NFC_NWIDTH_8, |
711 | .partitions = partition_info, | 710 | .partitions = partition_info, |
712 | .nr_partitions = ARRAY_SIZE(partition_info), | 711 | .nr_partitions = ARRAY_SIZE(partition_info), |
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 6fcfb9187c3..56682a36e42 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c | |||
@@ -849,7 +849,6 @@ static struct mtd_partition partition_info[] = { | |||
849 | }; | 849 | }; |
850 | 850 | ||
851 | static struct bf5xx_nand_platform bf5xx_nand_platform = { | 851 | static struct bf5xx_nand_platform bf5xx_nand_platform = { |
852 | .page_size = NFC_PG_SIZE_256, | ||
853 | .data_width = NFC_NWIDTH_8, | 852 | .data_width = NFC_NWIDTH_8, |
854 | .partitions = partition_info, | 853 | .partitions = partition_info, |
855 | .nr_partitions = ARRAY_SIZE(partition_info), | 854 | .nr_partitions = ARRAY_SIZE(partition_info), |
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h index 95ff44601fd..7866197f548 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h | |||
@@ -2221,73 +2221,6 @@ | |||
2221 | 2221 | ||
2222 | #define RCVDATA16 0xffff /* Receive FIFO 16-Bit Data */ | 2222 | #define RCVDATA16 0xffff /* Receive FIFO 16-Bit Data */ |
2223 | 2223 | ||
2224 | /* Bit masks for SPORTx_TCR1 */ | ||
2225 | |||
2226 | #define TCKFE 0x4000 /* Clock Falling Edge Select */ | ||
2227 | #define LATFS 0x2000 /* Late Transmit Frame Sync */ | ||
2228 | #define LTFS 0x1000 /* Low Transmit Frame Sync Select */ | ||
2229 | #define DITFS 0x800 /* Data-Independent Transmit Frame Sync Select */ | ||
2230 | #define TFSR 0x400 /* Transmit Frame Sync Required Select */ | ||
2231 | #define ITFS 0x200 /* Internal Transmit Frame Sync Select */ | ||
2232 | #define TLSBIT 0x10 /* Transmit Bit Order */ | ||
2233 | #define TDTYPE 0xc /* Data Formatting Type Select */ | ||
2234 | #define ITCLK 0x2 /* Internal Transmit Clock Select */ | ||
2235 | #define TSPEN 0x1 /* Transmit Enable */ | ||
2236 | |||
2237 | /* Bit masks for SPORTx_TCR2 */ | ||
2238 | |||
2239 | #define TRFST 0x400 /* Left/Right Order */ | ||
2240 | #define TSFSE 0x200 /* Transmit Stereo Frame Sync Enable */ | ||
2241 | #define TXSE 0x100 /* TxSEC Enable */ | ||
2242 | #define SLEN_T 0x1f /* SPORT Word Length */ | ||
2243 | |||
2244 | /* Bit masks for SPORTx_RCR1 */ | ||
2245 | |||
2246 | #define RCKFE 0x4000 /* Clock Falling Edge Select */ | ||
2247 | #define LARFS 0x2000 /* Late Receive Frame Sync */ | ||
2248 | #define LRFS 0x1000 /* Low Receive Frame Sync Select */ | ||
2249 | #define RFSR 0x400 /* Receive Frame Sync Required Select */ | ||
2250 | #define IRFS 0x200 /* Internal Receive Frame Sync Select */ | ||
2251 | #define RLSBIT 0x10 /* Receive Bit Order */ | ||
2252 | #define RDTYPE 0xc /* Data Formatting Type Select */ | ||
2253 | #define IRCLK 0x2 /* Internal Receive Clock Select */ | ||
2254 | #define RSPEN 0x1 /* Receive Enable */ | ||
2255 | |||
2256 | /* Bit masks for SPORTx_RCR2 */ | ||
2257 | |||
2258 | #define RRFST 0x400 /* Left/Right Order */ | ||
2259 | #define RSFSE 0x200 /* Receive Stereo Frame Sync Enable */ | ||
2260 | #define RXSE 0x100 /* RxSEC Enable */ | ||
2261 | #define SLEN_R 0x1f /* SPORT Word Length */ | ||
2262 | |||
2263 | /* Bit masks for SPORTx_STAT */ | ||
2264 | |||
2265 | #define TXHRE 0x40 /* Transmit Hold Register Empty */ | ||
2266 | #define TOVF 0x20 /* Sticky Transmit Overflow Status */ | ||
2267 | #define TUVF 0x10 /* Sticky Transmit Underflow Status */ | ||
2268 | #define TXF 0x8 /* Transmit FIFO Full Status */ | ||
2269 | #define ROVF 0x4 /* Sticky Receive Overflow Status */ | ||
2270 | #define RUVF 0x2 /* Sticky Receive Underflow Status */ | ||
2271 | #define RXNE 0x1 /* Receive FIFO Not Empty Status */ | ||
2272 | |||
2273 | /* Bit masks for SPORTx_MCMC1 */ | ||
2274 | |||
2275 | #define SP_WSIZE 0xf000 /* Window Size */ | ||
2276 | #define SP_WOFF 0x3ff /* Windows Offset */ | ||
2277 | |||
2278 | /* Bit masks for SPORTx_MCMC2 */ | ||
2279 | |||
2280 | #define MFD 0xf000 /* Multi channel Frame Delay */ | ||
2281 | #define FSDR 0x80 /* Frame Sync to Data Relationship */ | ||
2282 | #define MCMEN 0x10 /* Multi channel Frame Mode Enable */ | ||
2283 | #define MCDRXPE 0x8 /* Multi channel DMA Receive Packing */ | ||
2284 | #define MCDTXPE 0x4 /* Multi channel DMA Transmit Packing */ | ||
2285 | #define MCCRM 0x3 /* 2X Clock Recovery Mode */ | ||
2286 | |||
2287 | /* Bit masks for SPORTx_CHNL */ | ||
2288 | |||
2289 | #define CUR_CHNL 0x3ff /* Current Channel Indicator */ | ||
2290 | |||
2291 | /* Bit masks for UARTx_LCR */ | 2224 | /* Bit masks for UARTx_LCR */ |
2292 | 2225 | ||
2293 | #if 0 | 2226 | #if 0 |
diff --git a/arch/blackfin/mach-bf561/include/mach/defBF561.h b/arch/blackfin/mach-bf561/include/mach/defBF561.h index 4c8e36b7fb3..2674f009757 100644 --- a/arch/blackfin/mach-bf561/include/mach/defBF561.h +++ b/arch/blackfin/mach-bf561/include/mach/defBF561.h | |||
@@ -1007,66 +1007,6 @@ | |||
1007 | #define IREN_P 0x01 | 1007 | #define IREN_P 0x01 |
1008 | #define UCEN_P 0x00 | 1008 | #define UCEN_P 0x00 |
1009 | 1009 | ||
1010 | /* ********** SERIAL PORT MASKS ********************** */ | ||
1011 | |||
1012 | /* SPORTx_TCR1 Masks */ | ||
1013 | #define TSPEN 0x0001 /* TX enable */ | ||
1014 | #define ITCLK 0x0002 /* Internal TX Clock Select */ | ||
1015 | #define TDTYPE 0x000C /* TX Data Formatting Select */ | ||
1016 | #define TLSBIT 0x0010 /* TX Bit Order */ | ||
1017 | #define ITFS 0x0200 /* Internal TX Frame Sync Select */ | ||
1018 | #define TFSR 0x0400 /* TX Frame Sync Required Select */ | ||
1019 | #define DITFS 0x0800 /* Data Independent TX Frame Sync Select */ | ||
1020 | #define LTFS 0x1000 /* Low TX Frame Sync Select */ | ||
1021 | #define LATFS 0x2000 /* Late TX Frame Sync Select */ | ||
1022 | #define TCKFE 0x4000 /* TX Clock Falling Edge Select */ | ||
1023 | |||
1024 | /* SPORTx_TCR2 Masks */ | ||
1025 | #define SLEN 0x001F /*TX Word Length */ | ||
1026 | #define TXSE 0x0100 /*TX Secondary Enable */ | ||
1027 | #define TSFSE 0x0200 /*TX Stereo Frame Sync Enable */ | ||
1028 | #define TRFST 0x0400 /*TX Right-First Data Order */ | ||
1029 | |||
1030 | /* SPORTx_RCR1 Masks */ | ||
1031 | #define RSPEN 0x0001 /* RX enable */ | ||
1032 | #define IRCLK 0x0002 /* Internal RX Clock Select */ | ||
1033 | #define RDTYPE 0x000C /* RX Data Formatting Select */ | ||
1034 | #define RULAW 0x0008 /* u-Law enable */ | ||
1035 | #define RALAW 0x000C /* A-Law enable */ | ||
1036 | #define RLSBIT 0x0010 /* RX Bit Order */ | ||
1037 | #define IRFS 0x0200 /* Internal RX Frame Sync Select */ | ||
1038 | #define RFSR 0x0400 /* RX Frame Sync Required Select */ | ||
1039 | #define LRFS 0x1000 /* Low RX Frame Sync Select */ | ||
1040 | #define LARFS 0x2000 /* Late RX Frame Sync Select */ | ||
1041 | #define RCKFE 0x4000 /* RX Clock Falling Edge Select */ | ||
1042 | |||
1043 | /* SPORTx_RCR2 Masks */ | ||
1044 | #define SLEN 0x001F /*RX Word Length */ | ||
1045 | #define RXSE 0x0100 /*RX Secondary Enable */ | ||
1046 | #define RSFSE 0x0200 /*RX Stereo Frame Sync Enable */ | ||
1047 | #define RRFST 0x0400 /*Right-First Data Order */ | ||
1048 | |||
1049 | /*SPORTx_STAT Masks */ | ||
1050 | #define RXNE 0x0001 /*RX FIFO Not Empty Status */ | ||
1051 | #define RUVF 0x0002 /*RX Underflow Status */ | ||
1052 | #define ROVF 0x0004 /*RX Overflow Status */ | ||
1053 | #define TXF 0x0008 /*TX FIFO Full Status */ | ||
1054 | #define TUVF 0x0010 /*TX Underflow Status */ | ||
1055 | #define TOVF 0x0020 /*TX Overflow Status */ | ||
1056 | #define TXHRE 0x0040 /*TX Hold Register Empty */ | ||
1057 | |||
1058 | /*SPORTx_MCMC1 Masks */ | ||
1059 | #define SP_WSIZE 0x0000F000 /*Multichannel Window Size Field */ | ||
1060 | #define SP_WOFF 0x000003FF /*Multichannel Window Offset Field */ | ||
1061 | |||
1062 | /*SPORTx_MCMC2 Masks */ | ||
1063 | #define MCCRM 0x00000003 /*Multichannel Clock Recovery Mode */ | ||
1064 | #define MCDTXPE 0x00000004 /*Multichannel DMA Transmit Packing */ | ||
1065 | #define MCDRXPE 0x00000008 /*Multichannel DMA Receive Packing */ | ||
1066 | #define MCMEN 0x00000010 /*Multichannel Frame Mode Enable */ | ||
1067 | #define FSDR 0x00000080 /*Multichannel Frame Sync to Data Relationship */ | ||
1068 | #define MFD 0x0000F000 /*Multichannel Frame Delay */ | ||
1069 | |||
1070 | /* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */ | 1010 | /* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */ |
1071 | 1011 | ||
1072 | /* PPI_CONTROL Masks */ | 1012 | /* PPI_CONTROL Masks */ |
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index a5847f5d67c..af1bffa21dc 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S | |||
@@ -1628,6 +1628,9 @@ ENTRY(_sys_call_table) | |||
1628 | .long _sys_rt_tgsigqueueinfo | 1628 | .long _sys_rt_tgsigqueueinfo |
1629 | .long _sys_perf_event_open | 1629 | .long _sys_perf_event_open |
1630 | .long _sys_recvmmsg /* 370 */ | 1630 | .long _sys_recvmmsg /* 370 */ |
1631 | .long _sys_fanotify_init | ||
1632 | .long _sys_fanotify_mark | ||
1633 | .long _sys_prlimit64 | ||
1631 | 1634 | ||
1632 | .rept NR_syscalls-(.-_sys_call_table)/4 | 1635 | .rept NR_syscalls-(.-_sys_call_table)/4 |
1633 | .long _sys_ni_syscall | 1636 | .long _sys_ni_syscall |
diff --git a/arch/cris/arch-v10/kernel/process.c b/arch/cris/arch-v10/kernel/process.c index 93f0f64b132..9a57db6907f 100644 --- a/arch/cris/arch-v10/kernel/process.c +++ b/arch/cris/arch-v10/kernel/process.c | |||
@@ -204,7 +204,9 @@ asmlinkage int sys_vfork(long r10, long r11, long r12, long r13, long mof, long | |||
204 | /* | 204 | /* |
205 | * sys_execve() executes a new program. | 205 | * sys_execve() executes a new program. |
206 | */ | 206 | */ |
207 | asmlinkage int sys_execve(const char *fname, char **argv, char **envp, | 207 | asmlinkage int sys_execve(const char *fname, |
208 | const char *const *argv, | ||
209 | const char *const *envp, | ||
208 | long r13, long mof, long srp, | 210 | long r13, long mof, long srp, |
209 | struct pt_regs *regs) | 211 | struct pt_regs *regs) |
210 | { | 212 | { |
diff --git a/arch/cris/arch-v32/kernel/process.c b/arch/cris/arch-v32/kernel/process.c index 2661a9529d7..562f8471890 100644 --- a/arch/cris/arch-v32/kernel/process.c +++ b/arch/cris/arch-v32/kernel/process.c | |||
@@ -218,8 +218,10 @@ sys_vfork(long r10, long r11, long r12, long r13, long mof, long srp, | |||
218 | 218 | ||
219 | /* sys_execve() executes a new program. */ | 219 | /* sys_execve() executes a new program. */ |
220 | asmlinkage int | 220 | asmlinkage int |
221 | sys_execve(const char *fname, char **argv, char **envp, long r13, long mof, long srp, | 221 | sys_execve(const char *fname, |
222 | struct pt_regs *regs) | 222 | const char *const *argv, |
223 | const char *const *envp, long r13, long mof, long srp, | ||
224 | struct pt_regs *regs) | ||
223 | { | 225 | { |
224 | int error; | 226 | int error; |
225 | char *filename; | 227 | char *filename; |
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c index 428931cf2f0..2b63b0191f5 100644 --- a/arch/frv/kernel/process.c +++ b/arch/frv/kernel/process.c | |||
@@ -250,8 +250,9 @@ int copy_thread(unsigned long clone_flags, | |||
250 | /* | 250 | /* |
251 | * sys_execve() executes a new program. | 251 | * sys_execve() executes a new program. |
252 | */ | 252 | */ |
253 | asmlinkage int sys_execve(const char __user *name, char __user * __user *argv, | 253 | asmlinkage int sys_execve(const char __user *name, |
254 | char __user * __user *envp) | 254 | const char __user *const __user *argv, |
255 | const char __user *const __user *envp) | ||
255 | { | 256 | { |
256 | int error; | 257 | int error; |
257 | char * filename; | 258 | char * filename; |
diff --git a/arch/h8300/include/asm/atomic.h b/arch/h8300/include/asm/atomic.h index e936804b750..984221abb66 100644 --- a/arch/h8300/include/asm/atomic.h +++ b/arch/h8300/include/asm/atomic.h | |||
@@ -18,7 +18,8 @@ | |||
18 | 18 | ||
19 | static __inline__ int atomic_add_return(int i, atomic_t *v) | 19 | static __inline__ int atomic_add_return(int i, atomic_t *v) |
20 | { | 20 | { |
21 | int ret,flags; | 21 | unsigned long flags; |
22 | int ret; | ||
22 | local_irq_save(flags); | 23 | local_irq_save(flags); |
23 | ret = v->counter += i; | 24 | ret = v->counter += i; |
24 | local_irq_restore(flags); | 25 | local_irq_restore(flags); |
@@ -30,7 +31,8 @@ static __inline__ int atomic_add_return(int i, atomic_t *v) | |||
30 | 31 | ||
31 | static __inline__ int atomic_sub_return(int i, atomic_t *v) | 32 | static __inline__ int atomic_sub_return(int i, atomic_t *v) |
32 | { | 33 | { |
33 | int ret,flags; | 34 | unsigned long flags; |
35 | int ret; | ||
34 | local_irq_save(flags); | 36 | local_irq_save(flags); |
35 | ret = v->counter -= i; | 37 | ret = v->counter -= i; |
36 | local_irq_restore(flags); | 38 | local_irq_restore(flags); |
@@ -42,7 +44,8 @@ static __inline__ int atomic_sub_return(int i, atomic_t *v) | |||
42 | 44 | ||
43 | static __inline__ int atomic_inc_return(atomic_t *v) | 45 | static __inline__ int atomic_inc_return(atomic_t *v) |
44 | { | 46 | { |
45 | int ret,flags; | 47 | unsigned long flags; |
48 | int ret; | ||
46 | local_irq_save(flags); | 49 | local_irq_save(flags); |
47 | v->counter++; | 50 | v->counter++; |
48 | ret = v->counter; | 51 | ret = v->counter; |
@@ -64,7 +67,8 @@ static __inline__ int atomic_inc_return(atomic_t *v) | |||
64 | 67 | ||
65 | static __inline__ int atomic_dec_return(atomic_t *v) | 68 | static __inline__ int atomic_dec_return(atomic_t *v) |
66 | { | 69 | { |
67 | int ret,flags; | 70 | unsigned long flags; |
71 | int ret; | ||
68 | local_irq_save(flags); | 72 | local_irq_save(flags); |
69 | --v->counter; | 73 | --v->counter; |
70 | ret = v->counter; | 74 | ret = v->counter; |
@@ -76,7 +80,8 @@ static __inline__ int atomic_dec_return(atomic_t *v) | |||
76 | 80 | ||
77 | static __inline__ int atomic_dec_and_test(atomic_t *v) | 81 | static __inline__ int atomic_dec_and_test(atomic_t *v) |
78 | { | 82 | { |
79 | int ret,flags; | 83 | unsigned long flags; |
84 | int ret; | ||
80 | local_irq_save(flags); | 85 | local_irq_save(flags); |
81 | --v->counter; | 86 | --v->counter; |
82 | ret = v->counter; | 87 | ret = v->counter; |
diff --git a/arch/h8300/include/asm/system.h b/arch/h8300/include/asm/system.h index d98d97685f0..16bf1560ff6 100644 --- a/arch/h8300/include/asm/system.h +++ b/arch/h8300/include/asm/system.h | |||
@@ -3,6 +3,8 @@ | |||
3 | 3 | ||
4 | #include <linux/linkage.h> | 4 | #include <linux/linkage.h> |
5 | 5 | ||
6 | struct pt_regs; | ||
7 | |||
6 | /* | 8 | /* |
7 | * switch_to(n) should switch tasks to task ptr, first checking that | 9 | * switch_to(n) should switch tasks to task ptr, first checking that |
8 | * ptr isn't the current task, in which case it does nothing. This | 10 | * ptr isn't the current task, in which case it does nothing. This |
@@ -155,6 +157,6 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz | |||
155 | 157 | ||
156 | #define arch_align_stack(x) (x) | 158 | #define arch_align_stack(x) (x) |
157 | 159 | ||
158 | void die(char *str, struct pt_regs *fp, unsigned long err); | 160 | extern void die(const char *str, struct pt_regs *fp, unsigned long err); |
159 | 161 | ||
160 | #endif /* _H8300_SYSTEM_H */ | 162 | #endif /* _H8300_SYSTEM_H */ |
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c index 8b7b78d77d5..97478138e36 100644 --- a/arch/h8300/kernel/process.c +++ b/arch/h8300/kernel/process.c | |||
@@ -212,7 +212,10 @@ int copy_thread(unsigned long clone_flags, | |||
212 | /* | 212 | /* |
213 | * sys_execve() executes a new program. | 213 | * sys_execve() executes a new program. |
214 | */ | 214 | */ |
215 | asmlinkage int sys_execve(const char *name, char **argv, char **envp,int dummy,...) | 215 | asmlinkage int sys_execve(const char *name, |
216 | const char *const *argv, | ||
217 | const char *const *envp, | ||
218 | int dummy, ...) | ||
216 | { | 219 | { |
217 | int error; | 220 | int error; |
218 | char * filename; | 221 | char * filename; |
diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c index f9b3f44da69..aaf5e5a48f9 100644 --- a/arch/h8300/kernel/sys_h8300.c +++ b/arch/h8300/kernel/sys_h8300.c | |||
@@ -51,11 +51,13 @@ asmlinkage void syscall_print(void *dummy,...) | |||
51 | * Do a system call from kernel instead of calling sys_execve so we | 51 | * Do a system call from kernel instead of calling sys_execve so we |
52 | * end up with proper pt_regs. | 52 | * end up with proper pt_regs. |
53 | */ | 53 | */ |
54 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | 54 | int kernel_execve(const char *filename, |
55 | const char *const argv[], | ||
56 | const char *const envp[]) | ||
55 | { | 57 | { |
56 | register long res __asm__("er0"); | 58 | register long res __asm__("er0"); |
57 | register char *const *_c __asm__("er3") = envp; | 59 | register const char *const *_c __asm__("er3") = envp; |
58 | register char *const *_b __asm__("er2") = argv; | 60 | register const char *const *_b __asm__("er2") = argv; |
59 | register const char * _a __asm__("er1") = filename; | 61 | register const char * _a __asm__("er1") = filename; |
60 | __asm__ __volatile__ ("mov.l %1,er0\n\t" | 62 | __asm__ __volatile__ ("mov.l %1,er0\n\t" |
61 | "trapa #0\n\t" | 63 | "trapa #0\n\t" |
diff --git a/arch/h8300/kernel/traps.c b/arch/h8300/kernel/traps.c index 3c0b66bc669..dfa05bd908b 100644 --- a/arch/h8300/kernel/traps.c +++ b/arch/h8300/kernel/traps.c | |||
@@ -96,7 +96,7 @@ static void dump(struct pt_regs *fp) | |||
96 | printk("\n\n"); | 96 | printk("\n\n"); |
97 | } | 97 | } |
98 | 98 | ||
99 | void die(char *str, struct pt_regs *fp, unsigned long err) | 99 | void die(const char *str, struct pt_regs *fp, unsigned long err) |
100 | { | 100 | { |
101 | static int diecount; | 101 | static int diecount; |
102 | 102 | ||
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index 2bef5261d96..1e8d71ad93e 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c | |||
@@ -149,7 +149,7 @@ static void receive_chars(struct tty_struct *tty) | |||
149 | ch = ia64_ssc(0, 0, 0, 0, | 149 | ch = ia64_ssc(0, 0, 0, 0, |
150 | SSC_GETCHAR); | 150 | SSC_GETCHAR); |
151 | while (!ch); | 151 | while (!ch); |
152 | handle_sysrq(ch, NULL); | 152 | handle_sysrq(ch); |
153 | } | 153 | } |
154 | #endif | 154 | #endif |
155 | seen_esc = 0; | 155 | seen_esc = 0; |
diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h index 87f1bd1efc8..954d398a54b 100644 --- a/arch/ia64/include/asm/unistd.h +++ b/arch/ia64/include/asm/unistd.h | |||
@@ -356,8 +356,6 @@ asmlinkage unsigned long sys_mmap2( | |||
356 | int fd, long pgoff); | 356 | int fd, long pgoff); |
357 | struct pt_regs; | 357 | struct pt_regs; |
358 | struct sigaction; | 358 | struct sigaction; |
359 | long sys_execve(const char __user *filename, char __user * __user *argv, | ||
360 | char __user * __user *envp, struct pt_regs *regs); | ||
361 | asmlinkage long sys_ia64_pipe(void); | 359 | asmlinkage long sys_ia64_pipe(void); |
362 | asmlinkage long sys_rt_sigaction(int sig, | 360 | asmlinkage long sys_rt_sigaction(int sig, |
363 | const struct sigaction __user *act, | 361 | const struct sigaction __user *act, |
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index a879c03b7f1..16f1c7b04c6 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c | |||
@@ -633,7 +633,9 @@ dump_fpu (struct pt_regs *pt, elf_fpregset_t dst) | |||
633 | } | 633 | } |
634 | 634 | ||
635 | long | 635 | long |
636 | sys_execve (const char __user *filename, char __user * __user *argv, char __user * __user *envp, | 636 | sys_execve (const char __user *filename, |
637 | const char __user *const __user *argv, | ||
638 | const char __user *const __user *envp, | ||
637 | struct pt_regs *regs) | 639 | struct pt_regs *regs) |
638 | { | 640 | { |
639 | char *fname; | 641 | char *fname; |
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c index 8665a4d868e..422bea9f1db 100644 --- a/arch/m32r/kernel/process.c +++ b/arch/m32r/kernel/process.c | |||
@@ -289,8 +289,8 @@ asmlinkage int sys_vfork(unsigned long r0, unsigned long r1, unsigned long r2, | |||
289 | * sys_execve() executes a new program. | 289 | * sys_execve() executes a new program. |
290 | */ | 290 | */ |
291 | asmlinkage int sys_execve(const char __user *ufilename, | 291 | asmlinkage int sys_execve(const char __user *ufilename, |
292 | char __user * __user *uargv, | 292 | const char __user *const __user *uargv, |
293 | char __user * __user *uenvp, | 293 | const char __user *const __user *uenvp, |
294 | unsigned long r3, unsigned long r4, unsigned long r5, | 294 | unsigned long r3, unsigned long r4, unsigned long r5, |
295 | unsigned long r6, struct pt_regs regs) | 295 | unsigned long r6, struct pt_regs regs) |
296 | { | 296 | { |
diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c index 0a00f467edf..d841fb6cc70 100644 --- a/arch/m32r/kernel/sys_m32r.c +++ b/arch/m32r/kernel/sys_m32r.c | |||
@@ -93,7 +93,9 @@ asmlinkage int sys_cachectl(char *addr, int nbytes, int op) | |||
93 | * Do a system call from kernel instead of calling sys_execve so we | 93 | * Do a system call from kernel instead of calling sys_execve so we |
94 | * end up with proper pt_regs. | 94 | * end up with proper pt_regs. |
95 | */ | 95 | */ |
96 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | 96 | int kernel_execve(const char *filename, |
97 | const char *const argv[], | ||
98 | const char *const envp[]) | ||
97 | { | 99 | { |
98 | register long __scno __asm__ ("r7") = __NR_execve; | 100 | register long __scno __asm__ ("r7") = __NR_execve; |
99 | register long __arg3 __asm__ ("r2") = (long)(envp); | 101 | register long __arg3 __asm__ ("r2") = (long)(envp); |
diff --git a/arch/m68k/include/asm/ide.h b/arch/m68k/include/asm/ide.h index 3958726664b..492fee8a1ab 100644 --- a/arch/m68k/include/asm/ide.h +++ b/arch/m68k/include/asm/ide.h | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/include/asm-m68k/ide.h | ||
3 | * | ||
4 | * Copyright (C) 1994-1996 Linus Torvalds & authors | 2 | * Copyright (C) 1994-1996 Linus Torvalds & authors |
5 | */ | 3 | */ |
6 | 4 | ||
@@ -34,6 +32,8 @@ | |||
34 | #include <asm/io.h> | 32 | #include <asm/io.h> |
35 | #include <asm/irq.h> | 33 | #include <asm/irq.h> |
36 | 34 | ||
35 | #ifdef CONFIG_MMU | ||
36 | |||
37 | /* | 37 | /* |
38 | * Get rid of defs from io.h - ide has its private and conflicting versions | 38 | * Get rid of defs from io.h - ide has its private and conflicting versions |
39 | * Since so far no single m68k platform uses ISA/PCI I/O space for IDE, we | 39 | * Since so far no single m68k platform uses ISA/PCI I/O space for IDE, we |
@@ -53,5 +53,14 @@ | |||
53 | #define __ide_mm_outsw(port, addr, n) raw_outsw((u16 *)port, addr, n) | 53 | #define __ide_mm_outsw(port, addr, n) raw_outsw((u16 *)port, addr, n) |
54 | #define __ide_mm_outsl(port, addr, n) raw_outsl((u32 *)port, addr, n) | 54 | #define __ide_mm_outsl(port, addr, n) raw_outsl((u32 *)port, addr, n) |
55 | 55 | ||
56 | #else | ||
57 | |||
58 | #define __ide_mm_insw(port, addr, n) io_insw((unsigned int)port, addr, n) | ||
59 | #define __ide_mm_insl(port, addr, n) io_insl((unsigned int)port, addr, n) | ||
60 | #define __ide_mm_outsw(port, addr, n) io_outsw((unsigned int)port, addr, n) | ||
61 | #define __ide_mm_outsl(port, addr, n) io_outsl((unsigned int)port, addr, n) | ||
62 | |||
63 | #endif /* CONFIG_MMU */ | ||
64 | |||
56 | #endif /* __KERNEL__ */ | 65 | #endif /* __KERNEL__ */ |
57 | #endif /* _M68K_IDE_H */ | 66 | #endif /* _M68K_IDE_H */ |
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c index 221d0b71ce3..18732ab2329 100644 --- a/arch/m68k/kernel/process.c +++ b/arch/m68k/kernel/process.c | |||
@@ -315,7 +315,9 @@ EXPORT_SYMBOL(dump_fpu); | |||
315 | /* | 315 | /* |
316 | * sys_execve() executes a new program. | 316 | * sys_execve() executes a new program. |
317 | */ | 317 | */ |
318 | asmlinkage int sys_execve(const char __user *name, char __user * __user *argv, char __user * __user *envp) | 318 | asmlinkage int sys_execve(const char __user *name, |
319 | const char __user *const __user *argv, | ||
320 | const char __user *const __user *envp) | ||
319 | { | 321 | { |
320 | int error; | 322 | int error; |
321 | char * filename; | 323 | char * filename; |
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c index 77896692eb0..2f431ece7b5 100644 --- a/arch/m68k/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k.c | |||
@@ -459,7 +459,9 @@ asmlinkage int sys_getpagesize(void) | |||
459 | * Do a system call from kernel instead of calling sys_execve so we | 459 | * Do a system call from kernel instead of calling sys_execve so we |
460 | * end up with proper pt_regs. | 460 | * end up with proper pt_regs. |
461 | */ | 461 | */ |
462 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | 462 | int kernel_execve(const char *filename, |
463 | const char *const argv[], | ||
464 | const char *const envp[]) | ||
463 | { | 465 | { |
464 | register long __res asm ("%d0") = __NR_execve; | 466 | register long __res asm ("%d0") = __NR_execve; |
465 | register long __a asm ("%d1") = (long)(filename); | 467 | register long __a asm ("%d1") = (long)(filename); |
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c index 6350f68cd02..6d3390590e5 100644 --- a/arch/m68knommu/kernel/process.c +++ b/arch/m68knommu/kernel/process.c | |||
@@ -316,14 +316,14 @@ void dump(struct pt_regs *fp) | |||
316 | fp->d0, fp->d1, fp->d2, fp->d3); | 316 | fp->d0, fp->d1, fp->d2, fp->d3); |
317 | printk(KERN_EMERG "d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", | 317 | printk(KERN_EMERG "d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", |
318 | fp->d4, fp->d5, fp->a0, fp->a1); | 318 | fp->d4, fp->d5, fp->a0, fp->a1); |
319 | printk(KERN_EMERG "\nUSP: %08x TRAPFRAME: %08x\n", | 319 | printk(KERN_EMERG "\nUSP: %08x TRAPFRAME: %p\n", |
320 | (unsigned int) rdusp(), (unsigned int) fp); | 320 | (unsigned int) rdusp(), fp); |
321 | 321 | ||
322 | printk(KERN_EMERG "\nCODE:"); | 322 | printk(KERN_EMERG "\nCODE:"); |
323 | tp = ((unsigned char *) fp->pc) - 0x20; | 323 | tp = ((unsigned char *) fp->pc) - 0x20; |
324 | for (sp = (unsigned long *) tp, i = 0; (i < 0x40); i += 4) { | 324 | for (sp = (unsigned long *) tp, i = 0; (i < 0x40); i += 4) { |
325 | if ((i % 0x10) == 0) | 325 | if ((i % 0x10) == 0) |
326 | printk(KERN_EMERG "%08x: ", (int) (tp + i)); | 326 | printk(KERN_EMERG "%p: ", tp + i); |
327 | printk("%08x ", (int) *sp++); | 327 | printk("%08x ", (int) *sp++); |
328 | } | 328 | } |
329 | printk(KERN_EMERG "\n"); | 329 | printk(KERN_EMERG "\n"); |
@@ -332,7 +332,7 @@ void dump(struct pt_regs *fp) | |||
332 | tp = ((unsigned char *) fp) - 0x40; | 332 | tp = ((unsigned char *) fp) - 0x40; |
333 | for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) { | 333 | for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) { |
334 | if ((i % 0x10) == 0) | 334 | if ((i % 0x10) == 0) |
335 | printk(KERN_EMERG "%08x: ", (int) (tp + i)); | 335 | printk(KERN_EMERG "%p: ", tp + i); |
336 | printk("%08x ", (int) *sp++); | 336 | printk("%08x ", (int) *sp++); |
337 | } | 337 | } |
338 | printk(KERN_EMERG "\n"); | 338 | printk(KERN_EMERG "\n"); |
@@ -341,7 +341,7 @@ void dump(struct pt_regs *fp) | |||
341 | tp = (unsigned char *) (rdusp() - 0x10); | 341 | tp = (unsigned char *) (rdusp() - 0x10); |
342 | for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) { | 342 | for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) { |
343 | if ((i % 0x10) == 0) | 343 | if ((i % 0x10) == 0) |
344 | printk(KERN_EMERG "%08x: ", (int) (tp + i)); | 344 | printk(KERN_EMERG "%p: ", tp + i); |
345 | printk("%08x ", (int) *sp++); | 345 | printk("%08x ", (int) *sp++); |
346 | } | 346 | } |
347 | printk(KERN_EMERG "\n"); | 347 | printk(KERN_EMERG "\n"); |
@@ -350,7 +350,9 @@ void dump(struct pt_regs *fp) | |||
350 | /* | 350 | /* |
351 | * sys_execve() executes a new program. | 351 | * sys_execve() executes a new program. |
352 | */ | 352 | */ |
353 | asmlinkage int sys_execve(const char *name, char **argv, char **envp) | 353 | asmlinkage int sys_execve(const char *name, |
354 | const char *const *argv, | ||
355 | const char *const *envp) | ||
354 | { | 356 | { |
355 | int error; | 357 | int error; |
356 | char * filename; | 358 | char * filename; |
diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c index d65e9c4c930..68488ae47f0 100644 --- a/arch/m68knommu/kernel/sys_m68k.c +++ b/arch/m68knommu/kernel/sys_m68k.c | |||
@@ -44,7 +44,9 @@ asmlinkage int sys_getpagesize(void) | |||
44 | * Do a system call from kernel instead of calling sys_execve so we | 44 | * Do a system call from kernel instead of calling sys_execve so we |
45 | * end up with proper pt_regs. | 45 | * end up with proper pt_regs. |
46 | */ | 46 | */ |
47 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | 47 | int kernel_execve(const char *filename, |
48 | const char *const argv[], | ||
49 | const char *const envp[]) | ||
48 | { | 50 | { |
49 | register long __res asm ("%d0") = __NR_execve; | 51 | register long __res asm ("%d0") = __NR_execve; |
50 | register long __a asm ("%d1") = (long)(filename); | 52 | register long __a asm ("%d1") = (long)(filename); |
diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S index a91b2713451..ef332136f96 100644 --- a/arch/m68knommu/kernel/vmlinux.lds.S +++ b/arch/m68knommu/kernel/vmlinux.lds.S | |||
@@ -150,6 +150,8 @@ SECTIONS { | |||
150 | _sdata = . ; | 150 | _sdata = . ; |
151 | DATA_DATA | 151 | DATA_DATA |
152 | CACHELINE_ALIGNED_DATA(32) | 152 | CACHELINE_ALIGNED_DATA(32) |
153 | PAGE_ALIGNED_DATA(PAGE_SIZE) | ||
154 | *(.data..shared_aligned) | ||
153 | INIT_TASK_DATA(THREAD_SIZE) | 155 | INIT_TASK_DATA(THREAD_SIZE) |
154 | _edata = . ; | 156 | _edata = . ; |
155 | } > DATA | 157 | } > DATA |
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c index d33ba17601f..99d9b61cccb 100644 --- a/arch/microblaze/kernel/prom_parse.c +++ b/arch/microblaze/kernel/prom_parse.c | |||
@@ -73,7 +73,7 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) | |||
73 | /* We can only get here if we hit a P2P bridge with no node, | 73 | /* We can only get here if we hit a P2P bridge with no node, |
74 | * let's do standard swizzling and try again | 74 | * let's do standard swizzling and try again |
75 | */ | 75 | */ |
76 | lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec); | 76 | lspec = pci_swizzle_interrupt_pin(pdev, lspec); |
77 | pdev = ppdev; | 77 | pdev = ppdev; |
78 | } | 78 | } |
79 | 79 | ||
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c index 6abab6ebedb..2250fe9d269 100644 --- a/arch/microblaze/kernel/sys_microblaze.c +++ b/arch/microblaze/kernel/sys_microblaze.c | |||
@@ -47,8 +47,10 @@ asmlinkage long microblaze_clone(int flags, unsigned long stack, struct pt_regs | |||
47 | return do_fork(flags, stack, regs, 0, NULL, NULL); | 47 | return do_fork(flags, stack, regs, 0, NULL, NULL); |
48 | } | 48 | } |
49 | 49 | ||
50 | asmlinkage long microblaze_execve(const char __user *filenamei, char __user *__user *argv, | 50 | asmlinkage long microblaze_execve(const char __user *filenamei, |
51 | char __user *__user *envp, struct pt_regs *regs) | 51 | const char __user *const __user *argv, |
52 | const char __user *const __user *envp, | ||
53 | struct pt_regs *regs) | ||
52 | { | 54 | { |
53 | int error; | 55 | int error; |
54 | char *filename; | 56 | char *filename; |
@@ -77,7 +79,9 @@ asmlinkage long sys_mmap(unsigned long addr, unsigned long len, | |||
77 | * Do a system call from kernel instead of calling sys_execve so we | 79 | * Do a system call from kernel instead of calling sys_execve so we |
78 | * end up with proper pt_regs. | 80 | * end up with proper pt_regs. |
79 | */ | 81 | */ |
80 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | 82 | int kernel_execve(const char *filename, |
83 | const char *const argv[], | ||
84 | const char *const envp[]) | ||
81 | { | 85 | { |
82 | register const char *__a __asm__("r5") = filename; | 86 | register const char *__a __asm__("r5") = filename; |
83 | register const void *__b __asm__("r6") = argv; | 87 | register const void *__b __asm__("r6") = argv; |
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 23be25fec4d..55ef532f32b 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c | |||
@@ -27,10 +27,11 @@ | |||
27 | #include <linux/irq.h> | 27 | #include <linux/irq.h> |
28 | #include <linux/vmalloc.h> | 28 | #include <linux/vmalloc.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/of.h> | ||
31 | #include <linux/of_address.h> | ||
30 | 32 | ||
31 | #include <asm/processor.h> | 33 | #include <asm/processor.h> |
32 | #include <asm/io.h> | 34 | #include <asm/io.h> |
33 | #include <asm/prom.h> | ||
34 | #include <asm/pci-bridge.h> | 35 | #include <asm/pci-bridge.h> |
35 | #include <asm/byteorder.h> | 36 | #include <asm/byteorder.h> |
36 | 37 | ||
@@ -1077,7 +1078,7 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) | |||
1077 | struct dev_archdata *sd = &dev->dev.archdata; | 1078 | struct dev_archdata *sd = &dev->dev.archdata; |
1078 | 1079 | ||
1079 | /* Setup OF node pointer in archdata */ | 1080 | /* Setup OF node pointer in archdata */ |
1080 | sd->of_node = pci_device_to_OF_node(dev); | 1081 | dev->dev.of_node = pci_device_to_OF_node(dev); |
1081 | 1082 | ||
1082 | /* Fixup NUMA node as it may not be setup yet by the generic | 1083 | /* Fixup NUMA node as it may not be setup yet by the generic |
1083 | * code and is needed by the DMA init | 1084 | * code and is needed by the DMA init |
diff --git a/arch/microblaze/pci/xilinx_pci.c b/arch/microblaze/pci/xilinx_pci.c index 7869a41b0f9..0687a42a5bd 100644 --- a/arch/microblaze/pci/xilinx_pci.c +++ b/arch/microblaze/pci/xilinx_pci.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/ioport.h> | 17 | #include <linux/ioport.h> |
18 | #include <linux/of.h> | 18 | #include <linux/of.h> |
19 | #include <linux/of_address.h> | ||
19 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
20 | #include <asm/io.h> | 21 | #include <asm/io.h> |
21 | 22 | ||
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index bddce0bca19..1dc6edff45e 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c | |||
@@ -258,8 +258,10 @@ asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs) | |||
258 | error = PTR_ERR(filename); | 258 | error = PTR_ERR(filename); |
259 | if (IS_ERR(filename)) | 259 | if (IS_ERR(filename)) |
260 | goto out; | 260 | goto out; |
261 | error = do_execve(filename, (char __user *__user *) (long)regs.regs[5], | 261 | error = do_execve(filename, |
262 | (char __user *__user *) (long)regs.regs[6], ®s); | 262 | (const char __user *const __user *) (long)regs.regs[5], |
263 | (const char __user *const __user *) (long)regs.regs[6], | ||
264 | ®s); | ||
263 | putname(filename); | 265 | putname(filename); |
264 | 266 | ||
265 | out: | 267 | out: |
@@ -436,7 +438,9 @@ asmlinkage void bad_stack(void) | |||
436 | * Do a system call from kernel instead of calling sys_execve so we | 438 | * Do a system call from kernel instead of calling sys_execve so we |
437 | * end up with proper pt_regs. | 439 | * end up with proper pt_regs. |
438 | */ | 440 | */ |
439 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | 441 | int kernel_execve(const char *filename, |
442 | const char *const argv[], | ||
443 | const char *const envp[]) | ||
440 | { | 444 | { |
441 | register unsigned long __a0 asm("$4") = (unsigned long) filename; | 445 | register unsigned long __a0 asm("$4") = (unsigned long) filename; |
442 | register unsigned long __a1 asm("$5") = (unsigned long) argv; | 446 | register unsigned long __a1 asm("$5") = (unsigned long) argv; |
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c index 762eb325b94..f48373e2bc1 100644 --- a/arch/mn10300/kernel/process.c +++ b/arch/mn10300/kernel/process.c | |||
@@ -269,8 +269,8 @@ asmlinkage long sys_vfork(void) | |||
269 | } | 269 | } |
270 | 270 | ||
271 | asmlinkage long sys_execve(const char __user *name, | 271 | asmlinkage long sys_execve(const char __user *name, |
272 | char __user * __user *argv, | 272 | const char __user *const __user *argv, |
273 | char __user * __user *envp) | 273 | const char __user *const __user *envp) |
274 | { | 274 | { |
275 | char *filename; | 275 | char *filename; |
276 | int error; | 276 | int error; |
diff --git a/arch/mn10300/mm/dma-alloc.c b/arch/mn10300/mm/dma-alloc.c index 4e34880bea0..159acb02cfd 100644 --- a/arch/mn10300/mm/dma-alloc.c +++ b/arch/mn10300/mm/dma-alloc.c | |||
@@ -25,7 +25,8 @@ void *dma_alloc_coherent(struct device *dev, size_t size, | |||
25 | unsigned long addr; | 25 | unsigned long addr; |
26 | void *ret; | 26 | void *ret; |
27 | 27 | ||
28 | printk("dma_alloc_coherent(%s,%zu,,%x)\n", dev_name(dev), size, gfp); | 28 | pr_debug("dma_alloc_coherent(%s,%zu,%x)\n", |
29 | dev ? dev_name(dev) : "?", size, gfp); | ||
29 | 30 | ||
30 | if (0xbe000000 - pci_sram_allocated >= size) { | 31 | if (0xbe000000 - pci_sram_allocated >= size) { |
31 | size = (size + 255) & ~255; | 32 | size = (size + 255) & ~255; |
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c index 1444875a761..0dc8543acb4 100644 --- a/arch/parisc/hpux/fs.c +++ b/arch/parisc/hpux/fs.c | |||
@@ -41,8 +41,10 @@ int hpux_execve(struct pt_regs *regs) | |||
41 | if (IS_ERR(filename)) | 41 | if (IS_ERR(filename)) |
42 | goto out; | 42 | goto out; |
43 | 43 | ||
44 | error = do_execve(filename, (char __user * __user *) regs->gr[25], | 44 | error = do_execve(filename, |
45 | (char __user * __user *) regs->gr[24], regs); | 45 | (const char __user *const __user *) regs->gr[25], |
46 | (const char __user *const __user *) regs->gr[24], | ||
47 | regs); | ||
46 | 48 | ||
47 | putname(filename); | 49 | putname(filename); |
48 | 50 | ||
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 76332dadc6e..4b4b9181a1a 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c | |||
@@ -348,17 +348,22 @@ asmlinkage int sys_execve(struct pt_regs *regs) | |||
348 | error = PTR_ERR(filename); | 348 | error = PTR_ERR(filename); |
349 | if (IS_ERR(filename)) | 349 | if (IS_ERR(filename)) |
350 | goto out; | 350 | goto out; |
351 | error = do_execve(filename, (char __user * __user *) regs->gr[25], | 351 | error = do_execve(filename, |
352 | (char __user * __user *) regs->gr[24], regs); | 352 | (const char __user *const __user *) regs->gr[25], |
353 | (const char __user *const __user *) regs->gr[24], | ||
354 | regs); | ||
353 | putname(filename); | 355 | putname(filename); |
354 | out: | 356 | out: |
355 | 357 | ||
356 | return error; | 358 | return error; |
357 | } | 359 | } |
358 | 360 | ||
359 | extern int __execve(const char *filename, char *const argv[], | 361 | extern int __execve(const char *filename, |
360 | char *const envp[], struct task_struct *task); | 362 | const char *const argv[], |
361 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | 363 | const char *const envp[], struct task_struct *task); |
364 | int kernel_execve(const char *filename, | ||
365 | const char *const argv[], | ||
366 | const char *const envp[]) | ||
362 | { | 367 | { |
363 | return __execve(filename, argv, envp, current); | 368 | return __execve(filename, argv, envp, current); |
364 | } | 369 | } |
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index e3ea151c959..b7212b619c5 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
@@ -164,7 +164,7 @@ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ | |||
164 | all: zImage | 164 | all: zImage |
165 | 165 | ||
166 | # With make 3.82 we cannot mix normal and wildcard targets | 166 | # With make 3.82 we cannot mix normal and wildcard targets |
167 | BOOT_TARGETS1 := zImage zImage.initrd uImaged | 167 | BOOT_TARGETS1 := zImage zImage.initrd uImage |
168 | BOOT_TARGETS2 := zImage% dtbImage% treeImage.% cuImage.% simpleImage.% | 168 | BOOT_TARGETS2 := zImage% dtbImage% treeImage.% cuImage.% simpleImage.% |
169 | 169 | ||
170 | PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2) | 170 | PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2) |
diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts index 5806ef0b860..a3037039625 100644 --- a/arch/powerpc/boot/dts/canyonlands.dts +++ b/arch/powerpc/boot/dts/canyonlands.dts | |||
@@ -163,6 +163,14 @@ | |||
163 | interrupts = <0x1e 4>; | 163 | interrupts = <0x1e 4>; |
164 | }; | 164 | }; |
165 | 165 | ||
166 | SATA0: sata@bffd1000 { | ||
167 | compatible = "amcc,sata-460ex"; | ||
168 | reg = <4 0xbffd1000 0x800 4 0xbffd0800 0x400>; | ||
169 | interrupt-parent = <&UIC3>; | ||
170 | interrupts = <0x0 0x4 /* SATA */ | ||
171 | 0x5 0x4>; /* AHBDMA */ | ||
172 | }; | ||
173 | |||
166 | POB0: opb { | 174 | POB0: opb { |
167 | compatible = "ibm,opb-460ex", "ibm,opb"; | 175 | compatible = "ibm,opb-460ex", "ibm,opb"; |
168 | #address-cells = <1>; | 176 | #address-cells = <1>; |
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h index 0e398cfee2c..acac35d5b38 100644 --- a/arch/powerpc/include/asm/mmu-hash64.h +++ b/arch/powerpc/include/asm/mmu-hash64.h | |||
@@ -433,7 +433,7 @@ typedef struct { | |||
433 | * with. However gcc is not clever enough to compute the | 433 | * with. However gcc is not clever enough to compute the |
434 | * modulus (2^n-1) without a second multiply. | 434 | * modulus (2^n-1) without a second multiply. |
435 | */ | 435 | */ |
436 | #define vsid_scrample(protovsid, size) \ | 436 | #define vsid_scramble(protovsid, size) \ |
437 | ((((protovsid) * VSID_MULTIPLIER_##size) % VSID_MODULUS_##size)) | 437 | ((((protovsid) * VSID_MULTIPLIER_##size) % VSID_MODULUS_##size)) |
438 | 438 | ||
439 | #else /* 1 */ | 439 | #else /* 1 */ |
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index d8be016d2ed..ff0005eec7d 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
@@ -951,7 +951,14 @@ | |||
951 | #ifdef CONFIG_PPC64 | 951 | #ifdef CONFIG_PPC64 |
952 | 952 | ||
953 | extern void ppc64_runlatch_on(void); | 953 | extern void ppc64_runlatch_on(void); |
954 | extern void ppc64_runlatch_off(void); | 954 | extern void __ppc64_runlatch_off(void); |
955 | |||
956 | #define ppc64_runlatch_off() \ | ||
957 | do { \ | ||
958 | if (cpu_has_feature(CPU_FTR_CTRL) && \ | ||
959 | test_thread_flag(TIF_RUNLATCH)) \ | ||
960 | __ppc64_runlatch_off(); \ | ||
961 | } while (0) | ||
955 | 962 | ||
956 | extern unsigned long scom970_read(unsigned int address); | 963 | extern unsigned long scom970_read(unsigned int address); |
957 | extern void scom970_write(unsigned int address, unsigned long value); | 964 | extern void scom970_write(unsigned int address, unsigned long value); |
diff --git a/arch/powerpc/include/asm/rwsem.h b/arch/powerpc/include/asm/rwsem.h index 24cd9281ec3..8447d89fbe7 100644 --- a/arch/powerpc/include/asm/rwsem.h +++ b/arch/powerpc/include/asm/rwsem.h | |||
@@ -21,15 +21,20 @@ | |||
21 | /* | 21 | /* |
22 | * the semaphore definition | 22 | * the semaphore definition |
23 | */ | 23 | */ |
24 | struct rw_semaphore { | 24 | #ifdef CONFIG_PPC64 |
25 | /* XXX this should be able to be an atomic_t -- paulus */ | 25 | # define RWSEM_ACTIVE_MASK 0xffffffffL |
26 | signed int count; | 26 | #else |
27 | #define RWSEM_UNLOCKED_VALUE 0x00000000 | 27 | # define RWSEM_ACTIVE_MASK 0x0000ffffL |
28 | #define RWSEM_ACTIVE_BIAS 0x00000001 | 28 | #endif |
29 | #define RWSEM_ACTIVE_MASK 0x0000ffff | 29 | |
30 | #define RWSEM_WAITING_BIAS (-0x00010000) | 30 | #define RWSEM_UNLOCKED_VALUE 0x00000000L |
31 | #define RWSEM_ACTIVE_BIAS 0x00000001L | ||
32 | #define RWSEM_WAITING_BIAS (-RWSEM_ACTIVE_MASK-1) | ||
31 | #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS | 33 | #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS |
32 | #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) | 34 | #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) |
35 | |||
36 | struct rw_semaphore { | ||
37 | long count; | ||
33 | spinlock_t wait_lock; | 38 | spinlock_t wait_lock; |
34 | struct list_head wait_list; | 39 | struct list_head wait_list; |
35 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 40 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
@@ -43,9 +48,13 @@ struct rw_semaphore { | |||
43 | # define __RWSEM_DEP_MAP_INIT(lockname) | 48 | # define __RWSEM_DEP_MAP_INIT(lockname) |
44 | #endif | 49 | #endif |
45 | 50 | ||
46 | #define __RWSEM_INITIALIZER(name) \ | 51 | #define __RWSEM_INITIALIZER(name) \ |
47 | { RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait_lock), \ | 52 | { \ |
48 | LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) } | 53 | RWSEM_UNLOCKED_VALUE, \ |
54 | __SPIN_LOCK_UNLOCKED((name).wait_lock), \ | ||
55 | LIST_HEAD_INIT((name).wait_list) \ | ||
56 | __RWSEM_DEP_MAP_INIT(name) \ | ||
57 | } | ||
49 | 58 | ||
50 | #define DECLARE_RWSEM(name) \ | 59 | #define DECLARE_RWSEM(name) \ |
51 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) | 60 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) |
@@ -70,13 +79,13 @@ extern void __init_rwsem(struct rw_semaphore *sem, const char *name, | |||
70 | */ | 79 | */ |
71 | static inline void __down_read(struct rw_semaphore *sem) | 80 | static inline void __down_read(struct rw_semaphore *sem) |
72 | { | 81 | { |
73 | if (unlikely(atomic_inc_return((atomic_t *)(&sem->count)) <= 0)) | 82 | if (unlikely(atomic_long_inc_return((atomic_long_t *)&sem->count) <= 0)) |
74 | rwsem_down_read_failed(sem); | 83 | rwsem_down_read_failed(sem); |
75 | } | 84 | } |
76 | 85 | ||
77 | static inline int __down_read_trylock(struct rw_semaphore *sem) | 86 | static inline int __down_read_trylock(struct rw_semaphore *sem) |
78 | { | 87 | { |
79 | int tmp; | 88 | long tmp; |
80 | 89 | ||
81 | while ((tmp = sem->count) >= 0) { | 90 | while ((tmp = sem->count) >= 0) { |
82 | if (tmp == cmpxchg(&sem->count, tmp, | 91 | if (tmp == cmpxchg(&sem->count, tmp, |
@@ -92,10 +101,10 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) | |||
92 | */ | 101 | */ |
93 | static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) | 102 | static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) |
94 | { | 103 | { |
95 | int tmp; | 104 | long tmp; |
96 | 105 | ||
97 | tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS, | 106 | tmp = atomic_long_add_return(RWSEM_ACTIVE_WRITE_BIAS, |
98 | (atomic_t *)(&sem->count)); | 107 | (atomic_long_t *)&sem->count); |
99 | if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS)) | 108 | if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS)) |
100 | rwsem_down_write_failed(sem); | 109 | rwsem_down_write_failed(sem); |
101 | } | 110 | } |
@@ -107,7 +116,7 @@ static inline void __down_write(struct rw_semaphore *sem) | |||
107 | 116 | ||
108 | static inline int __down_write_trylock(struct rw_semaphore *sem) | 117 | static inline int __down_write_trylock(struct rw_semaphore *sem) |
109 | { | 118 | { |
110 | int tmp; | 119 | long tmp; |
111 | 120 | ||
112 | tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE, | 121 | tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE, |
113 | RWSEM_ACTIVE_WRITE_BIAS); | 122 | RWSEM_ACTIVE_WRITE_BIAS); |
@@ -119,9 +128,9 @@ static inline int __down_write_trylock(struct rw_semaphore *sem) | |||
119 | */ | 128 | */ |
120 | static inline void __up_read(struct rw_semaphore *sem) | 129 | static inline void __up_read(struct rw_semaphore *sem) |
121 | { | 130 | { |
122 | int tmp; | 131 | long tmp; |
123 | 132 | ||
124 | tmp = atomic_dec_return((atomic_t *)(&sem->count)); | 133 | tmp = atomic_long_dec_return((atomic_long_t *)&sem->count); |
125 | if (unlikely(tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0)) | 134 | if (unlikely(tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0)) |
126 | rwsem_wake(sem); | 135 | rwsem_wake(sem); |
127 | } | 136 | } |
@@ -131,17 +140,17 @@ static inline void __up_read(struct rw_semaphore *sem) | |||
131 | */ | 140 | */ |
132 | static inline void __up_write(struct rw_semaphore *sem) | 141 | static inline void __up_write(struct rw_semaphore *sem) |
133 | { | 142 | { |
134 | if (unlikely(atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS, | 143 | if (unlikely(atomic_long_sub_return(RWSEM_ACTIVE_WRITE_BIAS, |
135 | (atomic_t *)(&sem->count)) < 0)) | 144 | (atomic_long_t *)&sem->count) < 0)) |
136 | rwsem_wake(sem); | 145 | rwsem_wake(sem); |
137 | } | 146 | } |
138 | 147 | ||
139 | /* | 148 | /* |
140 | * implement atomic add functionality | 149 | * implement atomic add functionality |
141 | */ | 150 | */ |
142 | static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) | 151 | static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem) |
143 | { | 152 | { |
144 | atomic_add(delta, (atomic_t *)(&sem->count)); | 153 | atomic_long_add(delta, (atomic_long_t *)&sem->count); |
145 | } | 154 | } |
146 | 155 | ||
147 | /* | 156 | /* |
@@ -149,9 +158,10 @@ static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) | |||
149 | */ | 158 | */ |
150 | static inline void __downgrade_write(struct rw_semaphore *sem) | 159 | static inline void __downgrade_write(struct rw_semaphore *sem) |
151 | { | 160 | { |
152 | int tmp; | 161 | long tmp; |
153 | 162 | ||
154 | tmp = atomic_add_return(-RWSEM_WAITING_BIAS, (atomic_t *)(&sem->count)); | 163 | tmp = atomic_long_add_return(-RWSEM_WAITING_BIAS, |
164 | (atomic_long_t *)&sem->count); | ||
155 | if (tmp < 0) | 165 | if (tmp < 0) |
156 | rwsem_downgrade_wake(sem); | 166 | rwsem_downgrade_wake(sem); |
157 | } | 167 | } |
@@ -159,14 +169,14 @@ static inline void __downgrade_write(struct rw_semaphore *sem) | |||
159 | /* | 169 | /* |
160 | * implement exchange and add functionality | 170 | * implement exchange and add functionality |
161 | */ | 171 | */ |
162 | static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem) | 172 | static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem) |
163 | { | 173 | { |
164 | return atomic_add_return(delta, (atomic_t *)(&sem->count)); | 174 | return atomic_long_add_return(delta, (atomic_long_t *)&sem->count); |
165 | } | 175 | } |
166 | 176 | ||
167 | static inline int rwsem_is_locked(struct rw_semaphore *sem) | 177 | static inline int rwsem_is_locked(struct rw_semaphore *sem) |
168 | { | 178 | { |
169 | return (sem->count != 0); | 179 | return sem->count != 0; |
170 | } | 180 | } |
171 | 181 | ||
172 | #endif /* __KERNEL__ */ | 182 | #endif /* __KERNEL__ */ |
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index a5ee345b6a5..3d212669a13 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h | |||
@@ -326,3 +326,6 @@ SYSCALL_SPU(perf_event_open) | |||
326 | COMPAT_SYS_SPU(preadv) | 326 | COMPAT_SYS_SPU(preadv) |
327 | COMPAT_SYS_SPU(pwritev) | 327 | COMPAT_SYS_SPU(pwritev) |
328 | COMPAT_SYS(rt_tgsigqueueinfo) | 328 | COMPAT_SYS(rt_tgsigqueueinfo) |
329 | SYSCALL(fanotify_init) | ||
330 | COMPAT_SYS(fanotify_mark) | ||
331 | SYSCALL_SPU(prlimit64) | ||
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index f0a10266e7f..597e6f9d094 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h | |||
@@ -345,10 +345,13 @@ | |||
345 | #define __NR_preadv 320 | 345 | #define __NR_preadv 320 |
346 | #define __NR_pwritev 321 | 346 | #define __NR_pwritev 321 |
347 | #define __NR_rt_tgsigqueueinfo 322 | 347 | #define __NR_rt_tgsigqueueinfo 322 |
348 | #define __NR_fanotify_init 323 | ||
349 | #define __NR_fanotify_mark 324 | ||
350 | #define __NR_prlimit64 325 | ||
348 | 351 | ||
349 | #ifdef __KERNEL__ | 352 | #ifdef __KERNEL__ |
350 | 353 | ||
351 | #define __NR_syscalls 323 | 354 | #define __NR_syscalls 326 |
352 | 355 | ||
353 | #define __NR__exit __NR_exit | 356 | #define __NR__exit __NR_exit |
354 | #define NR_syscalls __NR_syscalls | 357 | #define NR_syscalls __NR_syscalls |
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 65e2b4e10f9..1f9123f412e 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
@@ -1826,7 +1826,6 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1826 | .cpu_features = CPU_FTRS_47X, | 1826 | .cpu_features = CPU_FTRS_47X, |
1827 | .cpu_user_features = COMMON_USER_BOOKE | | 1827 | .cpu_user_features = COMMON_USER_BOOKE | |
1828 | PPC_FEATURE_HAS_FPU, | 1828 | PPC_FEATURE_HAS_FPU, |
1829 | .cpu_user_features = COMMON_USER_BOOKE, | ||
1830 | .mmu_features = MMU_FTR_TYPE_47x | | 1829 | .mmu_features = MMU_FTR_TYPE_47x | |
1831 | MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL, | 1830 | MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL, |
1832 | .icache_bsize = 32, | 1831 | .icache_bsize = 32, |
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 417f7b05a9c..4457382f866 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c | |||
@@ -402,6 +402,18 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
402 | */ | 402 | */ |
403 | hard_irq_disable(); | 403 | hard_irq_disable(); |
404 | 404 | ||
405 | /* | ||
406 | * Make a note of crashing cpu. Will be used in machine_kexec | ||
407 | * such that another IPI will not be sent. | ||
408 | */ | ||
409 | crashing_cpu = smp_processor_id(); | ||
410 | crash_save_cpu(regs, crashing_cpu); | ||
411 | crash_kexec_prepare_cpus(crashing_cpu); | ||
412 | cpu_set(crashing_cpu, cpus_in_crash); | ||
413 | #if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP) | ||
414 | crash_kexec_wait_realmode(crashing_cpu); | ||
415 | #endif | ||
416 | |||
405 | for_each_irq(i) { | 417 | for_each_irq(i) { |
406 | struct irq_desc *desc = irq_to_desc(i); | 418 | struct irq_desc *desc = irq_to_desc(i); |
407 | 419 | ||
@@ -438,18 +450,8 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
438 | crash_shutdown_cpu = -1; | 450 | crash_shutdown_cpu = -1; |
439 | __debugger_fault_handler = old_handler; | 451 | __debugger_fault_handler = old_handler; |
440 | 452 | ||
441 | /* | ||
442 | * Make a note of crashing cpu. Will be used in machine_kexec | ||
443 | * such that another IPI will not be sent. | ||
444 | */ | ||
445 | crashing_cpu = smp_processor_id(); | ||
446 | crash_save_cpu(regs, crashing_cpu); | ||
447 | crash_kexec_prepare_cpus(crashing_cpu); | ||
448 | cpu_set(crashing_cpu, cpus_in_crash); | ||
449 | crash_kexec_stop_spus(); | 453 | crash_kexec_stop_spus(); |
450 | #if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP) | 454 | |
451 | crash_kexec_wait_realmode(crashing_cpu); | ||
452 | #endif | ||
453 | if (ppc_md.kexec_cpu_down) | 455 | if (ppc_md.kexec_cpu_down) |
454 | ppc_md.kexec_cpu_down(1, 0); | 456 | ppc_md.kexec_cpu_down(1, 0); |
455 | } | 457 | } |
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index 5ab484ef06a..562305b40a8 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S | |||
@@ -113,6 +113,10 @@ _ENTRY(_start); | |||
113 | stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */ | 113 | stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */ |
114 | stw r6, 0(r5) | 114 | stw r6, 0(r5) |
115 | 115 | ||
116 | /* Clear the Machine Check Syndrome Register */ | ||
117 | li r0,0 | ||
118 | mtspr SPRN_MCSR,r0 | ||
119 | |||
116 | /* Let's move on */ | 120 | /* Let's move on */ |
117 | lis r4,start_kernel@h | 121 | lis r4,start_kernel@h |
118 | ori r4,r4,start_kernel@l | 122 | ori r4,r4,start_kernel@l |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 844a44b6447..c571cd3c145 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -572,15 +572,21 @@ __secondary_start: | |||
572 | /* Set thread priority to MEDIUM */ | 572 | /* Set thread priority to MEDIUM */ |
573 | HMT_MEDIUM | 573 | HMT_MEDIUM |
574 | 574 | ||
575 | /* Do early setup for that CPU (stab, slb, hash table pointer) */ | ||
576 | bl .early_setup_secondary | ||
577 | |||
578 | /* Initialize the kernel stack. Just a repeat for iSeries. */ | 575 | /* Initialize the kernel stack. Just a repeat for iSeries. */ |
579 | LOAD_REG_ADDR(r3, current_set) | 576 | LOAD_REG_ADDR(r3, current_set) |
580 | sldi r28,r24,3 /* get current_set[cpu#] */ | 577 | sldi r28,r24,3 /* get current_set[cpu#] */ |
581 | ldx r1,r3,r28 | 578 | ldx r14,r3,r28 |
582 | addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD | 579 | addi r14,r14,THREAD_SIZE-STACK_FRAME_OVERHEAD |
583 | std r1,PACAKSAVE(r13) | 580 | std r14,PACAKSAVE(r13) |
581 | |||
582 | /* Do early setup for that CPU (stab, slb, hash table pointer) */ | ||
583 | bl .early_setup_secondary | ||
584 | |||
585 | /* | ||
586 | * setup the new stack pointer, but *don't* use this until | ||
587 | * translation is on. | ||
588 | */ | ||
589 | mr r1, r14 | ||
584 | 590 | ||
585 | /* Clear backchain so we get nice backtraces */ | 591 | /* Clear backchain so we get nice backtraces */ |
586 | li r7,0 | 592 | li r7,0 |
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c index 049dda60e47..39a2baa6ad5 100644 --- a/arch/powerpc/kernel/idle.c +++ b/arch/powerpc/kernel/idle.c | |||
@@ -94,9 +94,9 @@ void cpu_idle(void) | |||
94 | HMT_medium(); | 94 | HMT_medium(); |
95 | ppc64_runlatch_on(); | 95 | ppc64_runlatch_on(); |
96 | tick_nohz_restart_sched_tick(); | 96 | tick_nohz_restart_sched_tick(); |
97 | preempt_enable_no_resched(); | ||
97 | if (cpu_should_die()) | 98 | if (cpu_should_die()) |
98 | cpu_die(); | 99 | cpu_die(); |
99 | preempt_enable_no_resched(); | ||
100 | schedule(); | 100 | schedule(); |
101 | preempt_disable(); | 101 | preempt_disable(); |
102 | } | 102 | } |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index d3ce67cf03b..4a65386995d 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -67,6 +67,7 @@ | |||
67 | #include <asm/machdep.h> | 67 | #include <asm/machdep.h> |
68 | #include <asm/udbg.h> | 68 | #include <asm/udbg.h> |
69 | #include <asm/dbell.h> | 69 | #include <asm/dbell.h> |
70 | #include <asm/smp.h> | ||
70 | 71 | ||
71 | #ifdef CONFIG_PPC64 | 72 | #ifdef CONFIG_PPC64 |
72 | #include <asm/paca.h> | 73 | #include <asm/paca.h> |
@@ -446,22 +447,23 @@ struct thread_info *mcheckirq_ctx[NR_CPUS] __read_mostly; | |||
446 | void exc_lvl_ctx_init(void) | 447 | void exc_lvl_ctx_init(void) |
447 | { | 448 | { |
448 | struct thread_info *tp; | 449 | struct thread_info *tp; |
449 | int i; | 450 | int i, hw_cpu; |
450 | 451 | ||
451 | for_each_possible_cpu(i) { | 452 | for_each_possible_cpu(i) { |
452 | memset((void *)critirq_ctx[i], 0, THREAD_SIZE); | 453 | hw_cpu = get_hard_smp_processor_id(i); |
453 | tp = critirq_ctx[i]; | 454 | memset((void *)critirq_ctx[hw_cpu], 0, THREAD_SIZE); |
455 | tp = critirq_ctx[hw_cpu]; | ||
454 | tp->cpu = i; | 456 | tp->cpu = i; |
455 | tp->preempt_count = 0; | 457 | tp->preempt_count = 0; |
456 | 458 | ||
457 | #ifdef CONFIG_BOOKE | 459 | #ifdef CONFIG_BOOKE |
458 | memset((void *)dbgirq_ctx[i], 0, THREAD_SIZE); | 460 | memset((void *)dbgirq_ctx[hw_cpu], 0, THREAD_SIZE); |
459 | tp = dbgirq_ctx[i]; | 461 | tp = dbgirq_ctx[hw_cpu]; |
460 | tp->cpu = i; | 462 | tp->cpu = i; |
461 | tp->preempt_count = 0; | 463 | tp->preempt_count = 0; |
462 | 464 | ||
463 | memset((void *)mcheckirq_ctx[i], 0, THREAD_SIZE); | 465 | memset((void *)mcheckirq_ctx[hw_cpu], 0, THREAD_SIZE); |
464 | tp = mcheckirq_ctx[i]; | 466 | tp = mcheckirq_ctx[hw_cpu]; |
465 | tp->cpu = i; | 467 | tp->cpu = i; |
466 | tp->preempt_count = HARDIRQ_OFFSET; | 468 | tp->preempt_count = HARDIRQ_OFFSET; |
467 | #endif | 469 | #endif |
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 6bbd7a604d2..a7a570dcdd5 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
@@ -810,6 +810,9 @@ relocate_new_kernel: | |||
810 | isync | 810 | isync |
811 | sync | 811 | sync |
812 | 812 | ||
813 | mfspr r3, SPRN_PIR /* current core we are running on */ | ||
814 | mr r4, r5 /* load physical address of chunk called */ | ||
815 | |||
813 | /* jump to the entry point, usually the setup routine */ | 816 | /* jump to the entry point, usually the setup routine */ |
814 | mtlr r5 | 817 | mtlr r5 |
815 | blrl | 818 | blrl |
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 6ddb795f83e..e751506323b 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c | |||
@@ -336,7 +336,7 @@ static void __devinit __of_scan_bus(struct device_node *node, | |||
336 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || | 336 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || |
337 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { | 337 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { |
338 | struct device_node *child = pci_device_to_OF_node(dev); | 338 | struct device_node *child = pci_device_to_OF_node(dev); |
339 | if (dev) | 339 | if (child) |
340 | of_scan_pci_bridge(child, dev); | 340 | of_scan_pci_bridge(child, dev); |
341 | } | 341 | } |
342 | } | 342 | } |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index feacfb78968..b1c648a36b0 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -728,7 +728,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
728 | p->thread.regs = childregs; | 728 | p->thread.regs = childregs; |
729 | if (clone_flags & CLONE_SETTLS) { | 729 | if (clone_flags & CLONE_SETTLS) { |
730 | #ifdef CONFIG_PPC64 | 730 | #ifdef CONFIG_PPC64 |
731 | if (!test_thread_flag(TIF_32BIT)) | 731 | if (!is_32bit_task()) |
732 | childregs->gpr[13] = childregs->gpr[6]; | 732 | childregs->gpr[13] = childregs->gpr[6]; |
733 | else | 733 | else |
734 | #endif | 734 | #endif |
@@ -823,7 +823,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) | |||
823 | regs->nip = start; | 823 | regs->nip = start; |
824 | regs->msr = MSR_USER; | 824 | regs->msr = MSR_USER; |
825 | #else | 825 | #else |
826 | if (!test_thread_flag(TIF_32BIT)) { | 826 | if (!is_32bit_task()) { |
827 | unsigned long entry, toc; | 827 | unsigned long entry, toc; |
828 | 828 | ||
829 | /* start is a relocated pointer to the function descriptor for | 829 | /* start is a relocated pointer to the function descriptor for |
@@ -995,7 +995,7 @@ int sys_clone(unsigned long clone_flags, unsigned long usp, | |||
995 | if (usp == 0) | 995 | if (usp == 0) |
996 | usp = regs->gpr[1]; /* stack pointer for child */ | 996 | usp = regs->gpr[1]; /* stack pointer for child */ |
997 | #ifdef CONFIG_PPC64 | 997 | #ifdef CONFIG_PPC64 |
998 | if (test_thread_flag(TIF_32BIT)) { | 998 | if (is_32bit_task()) { |
999 | parent_tidp = TRUNC_PTR(parent_tidp); | 999 | parent_tidp = TRUNC_PTR(parent_tidp); |
1000 | child_tidp = TRUNC_PTR(child_tidp); | 1000 | child_tidp = TRUNC_PTR(child_tidp); |
1001 | } | 1001 | } |
@@ -1034,8 +1034,9 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, | |||
1034 | flush_fp_to_thread(current); | 1034 | flush_fp_to_thread(current); |
1035 | flush_altivec_to_thread(current); | 1035 | flush_altivec_to_thread(current); |
1036 | flush_spe_to_thread(current); | 1036 | flush_spe_to_thread(current); |
1037 | error = do_execve(filename, (char __user * __user *) a1, | 1037 | error = do_execve(filename, |
1038 | (char __user * __user *) a2, regs); | 1038 | (const char __user *const __user *) a1, |
1039 | (const char __user *const __user *) a2, regs); | ||
1039 | putname(filename); | 1040 | putname(filename); |
1040 | out: | 1041 | out: |
1041 | return error; | 1042 | return error; |
@@ -1198,19 +1199,17 @@ void ppc64_runlatch_on(void) | |||
1198 | } | 1199 | } |
1199 | } | 1200 | } |
1200 | 1201 | ||
1201 | void ppc64_runlatch_off(void) | 1202 | void __ppc64_runlatch_off(void) |
1202 | { | 1203 | { |
1203 | unsigned long ctrl; | 1204 | unsigned long ctrl; |
1204 | 1205 | ||
1205 | if (cpu_has_feature(CPU_FTR_CTRL) && test_thread_flag(TIF_RUNLATCH)) { | 1206 | HMT_medium(); |
1206 | HMT_medium(); | ||
1207 | 1207 | ||
1208 | clear_thread_flag(TIF_RUNLATCH); | 1208 | clear_thread_flag(TIF_RUNLATCH); |
1209 | 1209 | ||
1210 | ctrl = mfspr(SPRN_CTRLF); | 1210 | ctrl = mfspr(SPRN_CTRLF); |
1211 | ctrl &= ~CTRL_RUNLATCH; | 1211 | ctrl &= ~CTRL_RUNLATCH; |
1212 | mtspr(SPRN_CTRLT, ctrl); | 1212 | mtspr(SPRN_CTRLT, ctrl); |
1213 | } | ||
1214 | } | 1213 | } |
1215 | #endif | 1214 | #endif |
1216 | 1215 | ||
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index a10ffc85ada..93666f9cabf 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
@@ -258,17 +258,18 @@ static void __init irqstack_early_init(void) | |||
258 | #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) | 258 | #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) |
259 | static void __init exc_lvl_early_init(void) | 259 | static void __init exc_lvl_early_init(void) |
260 | { | 260 | { |
261 | unsigned int i; | 261 | unsigned int i, hw_cpu; |
262 | 262 | ||
263 | /* interrupt stacks must be in lowmem, we get that for free on ppc32 | 263 | /* interrupt stacks must be in lowmem, we get that for free on ppc32 |
264 | * as the memblock is limited to lowmem by MEMBLOCK_REAL_LIMIT */ | 264 | * as the memblock is limited to lowmem by MEMBLOCK_REAL_LIMIT */ |
265 | for_each_possible_cpu(i) { | 265 | for_each_possible_cpu(i) { |
266 | critirq_ctx[i] = (struct thread_info *) | 266 | hw_cpu = get_hard_smp_processor_id(i); |
267 | critirq_ctx[hw_cpu] = (struct thread_info *) | ||
267 | __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); | 268 | __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); |
268 | #ifdef CONFIG_BOOKE | 269 | #ifdef CONFIG_BOOKE |
269 | dbgirq_ctx[i] = (struct thread_info *) | 270 | dbgirq_ctx[hw_cpu] = (struct thread_info *) |
270 | __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); | 271 | __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); |
271 | mcheckirq_ctx[i] = (struct thread_info *) | 272 | mcheckirq_ctx[hw_cpu] = (struct thread_info *) |
272 | __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); | 273 | __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); |
273 | #endif | 274 | #endif |
274 | } | 275 | } |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 1bee4b68fa4..e72690ec9b8 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -95,7 +95,7 @@ int ucache_bsize; | |||
95 | 95 | ||
96 | #ifdef CONFIG_SMP | 96 | #ifdef CONFIG_SMP |
97 | 97 | ||
98 | static int smt_enabled_cmdline; | 98 | static char *smt_enabled_cmdline; |
99 | 99 | ||
100 | /* Look for ibm,smt-enabled OF option */ | 100 | /* Look for ibm,smt-enabled OF option */ |
101 | static void check_smt_enabled(void) | 101 | static void check_smt_enabled(void) |
@@ -103,37 +103,46 @@ static void check_smt_enabled(void) | |||
103 | struct device_node *dn; | 103 | struct device_node *dn; |
104 | const char *smt_option; | 104 | const char *smt_option; |
105 | 105 | ||
106 | /* Allow the command line to overrule the OF option */ | 106 | /* Default to enabling all threads */ |
107 | if (smt_enabled_cmdline) | 107 | smt_enabled_at_boot = threads_per_core; |
108 | return; | ||
109 | |||
110 | dn = of_find_node_by_path("/options"); | ||
111 | |||
112 | if (dn) { | ||
113 | smt_option = of_get_property(dn, "ibm,smt-enabled", NULL); | ||
114 | 108 | ||
115 | if (smt_option) { | 109 | /* Allow the command line to overrule the OF option */ |
116 | if (!strcmp(smt_option, "on")) | 110 | if (smt_enabled_cmdline) { |
117 | smt_enabled_at_boot = 1; | 111 | if (!strcmp(smt_enabled_cmdline, "on")) |
118 | else if (!strcmp(smt_option, "off")) | 112 | smt_enabled_at_boot = threads_per_core; |
119 | smt_enabled_at_boot = 0; | 113 | else if (!strcmp(smt_enabled_cmdline, "off")) |
120 | } | 114 | smt_enabled_at_boot = 0; |
121 | } | 115 | else { |
116 | long smt; | ||
117 | int rc; | ||
118 | |||
119 | rc = strict_strtol(smt_enabled_cmdline, 10, &smt); | ||
120 | if (!rc) | ||
121 | smt_enabled_at_boot = | ||
122 | min(threads_per_core, (int)smt); | ||
123 | } | ||
124 | } else { | ||
125 | dn = of_find_node_by_path("/options"); | ||
126 | if (dn) { | ||
127 | smt_option = of_get_property(dn, "ibm,smt-enabled", | ||
128 | NULL); | ||
129 | |||
130 | if (smt_option) { | ||
131 | if (!strcmp(smt_option, "on")) | ||
132 | smt_enabled_at_boot = threads_per_core; | ||
133 | else if (!strcmp(smt_option, "off")) | ||
134 | smt_enabled_at_boot = 0; | ||
135 | } | ||
136 | |||
137 | of_node_put(dn); | ||
138 | } | ||
139 | } | ||
122 | } | 140 | } |
123 | 141 | ||
124 | /* Look for smt-enabled= cmdline option */ | 142 | /* Look for smt-enabled= cmdline option */ |
125 | static int __init early_smt_enabled(char *p) | 143 | static int __init early_smt_enabled(char *p) |
126 | { | 144 | { |
127 | smt_enabled_cmdline = 1; | 145 | smt_enabled_cmdline = p; |
128 | |||
129 | if (!p) | ||
130 | return 0; | ||
131 | |||
132 | if (!strcmp(p, "on") || !strcmp(p, "1")) | ||
133 | smt_enabled_at_boot = 1; | ||
134 | else if (!strcmp(p, "off") || !strcmp(p, "0")) | ||
135 | smt_enabled_at_boot = 0; | ||
136 | |||
137 | return 0; | 146 | return 0; |
138 | } | 147 | } |
139 | early_param("smt-enabled", early_smt_enabled); | 148 | early_param("smt-enabled", early_smt_enabled); |
@@ -380,8 +389,8 @@ void __init setup_system(void) | |||
380 | */ | 389 | */ |
381 | xmon_setup(); | 390 | xmon_setup(); |
382 | 391 | ||
383 | check_smt_enabled(); | ||
384 | smp_setup_cpu_maps(); | 392 | smp_setup_cpu_maps(); |
393 | check_smt_enabled(); | ||
385 | 394 | ||
386 | #ifdef CONFIG_SMP | 395 | #ifdef CONFIG_SMP |
387 | /* Release secondary cpus out of their spinloops at 0x60 now that | 396 | /* Release secondary cpus out of their spinloops at 0x60 now that |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index a61b3ddd7bb..0008bc58e82 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -427,11 +427,11 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
427 | #endif | 427 | #endif |
428 | 428 | ||
429 | if (!cpu_callin_map[cpu]) { | 429 | if (!cpu_callin_map[cpu]) { |
430 | printk("Processor %u is stuck.\n", cpu); | 430 | printk(KERN_ERR "Processor %u is stuck.\n", cpu); |
431 | return -ENOENT; | 431 | return -ENOENT; |
432 | } | 432 | } |
433 | 433 | ||
434 | printk("Processor %u found.\n", cpu); | 434 | DBG("Processor %u found.\n", cpu); |
435 | 435 | ||
436 | if (smp_ops->give_timebase) | 436 | if (smp_ops->give_timebase) |
437 | smp_ops->give_timebase(); | 437 | smp_ops->give_timebase(); |
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index 20fd701a686..b1b6043a56c 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c | |||
@@ -616,3 +616,11 @@ asmlinkage long compat_sys_sync_file_range2(int fd, unsigned int flags, | |||
616 | 616 | ||
617 | return sys_sync_file_range(fd, offset, nbytes, flags); | 617 | return sys_sync_file_range(fd, offset, nbytes, flags); |
618 | } | 618 | } |
619 | |||
620 | asmlinkage long compat_sys_fanotify_mark(int fanotify_fd, unsigned int flags, | ||
621 | unsigned mask_hi, unsigned mask_lo, | ||
622 | int dfd, const char __user *pathname) | ||
623 | { | ||
624 | u64 mask = ((u64)mask_hi << 32) | mask_lo; | ||
625 | return sys_fanotify_mark(fanotify_fd, flags, mask, dfd, pathname); | ||
626 | } | ||
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index ce53dfa7130..8533b3b83f5 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -577,20 +577,11 @@ void timer_interrupt(struct pt_regs * regs) | |||
577 | * some CPUs will continuue to take decrementer exceptions */ | 577 | * some CPUs will continuue to take decrementer exceptions */ |
578 | set_dec(DECREMENTER_MAX); | 578 | set_dec(DECREMENTER_MAX); |
579 | 579 | ||
580 | #ifdef CONFIG_PPC32 | 580 | #if defined(CONFIG_PPC32) && defined(CONFIG_PMAC) |
581 | if (atomic_read(&ppc_n_lost_interrupts) != 0) | 581 | if (atomic_read(&ppc_n_lost_interrupts) != 0) |
582 | do_IRQ(regs); | 582 | do_IRQ(regs); |
583 | #endif | 583 | #endif |
584 | 584 | ||
585 | now = get_tb_or_rtc(); | ||
586 | if (now < decrementer->next_tb) { | ||
587 | /* not time for this event yet */ | ||
588 | now = decrementer->next_tb - now; | ||
589 | if (now <= DECREMENTER_MAX) | ||
590 | set_dec((int)now); | ||
591 | trace_timer_interrupt_exit(regs); | ||
592 | return; | ||
593 | } | ||
594 | old_regs = set_irq_regs(regs); | 585 | old_regs = set_irq_regs(regs); |
595 | irq_enter(); | 586 | irq_enter(); |
596 | 587 | ||
@@ -606,8 +597,16 @@ void timer_interrupt(struct pt_regs * regs) | |||
606 | get_lppaca()->int_dword.fields.decr_int = 0; | 597 | get_lppaca()->int_dword.fields.decr_int = 0; |
607 | #endif | 598 | #endif |
608 | 599 | ||
609 | if (evt->event_handler) | 600 | now = get_tb_or_rtc(); |
610 | evt->event_handler(evt); | 601 | if (now >= decrementer->next_tb) { |
602 | decrementer->next_tb = ~(u64)0; | ||
603 | if (evt->event_handler) | ||
604 | evt->event_handler(evt); | ||
605 | } else { | ||
606 | now = decrementer->next_tb - now; | ||
607 | if (now <= DECREMENTER_MAX) | ||
608 | set_dec((int)now); | ||
609 | } | ||
611 | 610 | ||
612 | #ifdef CONFIG_PPC_ISERIES | 611 | #ifdef CONFIG_PPC_ISERIES |
613 | if (firmware_has_feature(FW_FEATURE_ISERIES) && hvlpevent_is_pending()) | 612 | if (firmware_has_feature(FW_FEATURE_ISERIES) && hvlpevent_is_pending()) |
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 00b9436f765..fa3469ddaef 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
@@ -1059,7 +1059,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) | |||
1059 | if (!dma_window) | 1059 | if (!dma_window) |
1060 | return NULL; | 1060 | return NULL; |
1061 | 1061 | ||
1062 | tbl = kmalloc(sizeof(*tbl), GFP_KERNEL); | 1062 | tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); |
1063 | if (tbl == NULL) | 1063 | if (tbl == NULL) |
1064 | return NULL; | 1064 | return NULL; |
1065 | 1065 | ||
@@ -1072,6 +1072,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) | |||
1072 | tbl->it_offset = offset >> IOMMU_PAGE_SHIFT; | 1072 | tbl->it_offset = offset >> IOMMU_PAGE_SHIFT; |
1073 | tbl->it_busno = 0; | 1073 | tbl->it_busno = 0; |
1074 | tbl->it_type = TCE_VB; | 1074 | tbl->it_type = TCE_VB; |
1075 | tbl->it_blocksize = 16; | ||
1075 | 1076 | ||
1076 | return iommu_init_table(tbl, -1); | 1077 | return iommu_init_table(tbl, -1); |
1077 | } | 1078 | } |
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 71f1415e247..ace85fa74b2 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c | |||
@@ -79,7 +79,9 @@ | |||
79 | #endif /* CONFIG_PPC_STD_MMU_64 */ | 79 | #endif /* CONFIG_PPC_STD_MMU_64 */ |
80 | 80 | ||
81 | phys_addr_t memstart_addr = ~0; | 81 | phys_addr_t memstart_addr = ~0; |
82 | EXPORT_SYMBOL_GPL(memstart_addr); | ||
82 | phys_addr_t kernstart_addr; | 83 | phys_addr_t kernstart_addr; |
84 | EXPORT_SYMBOL_GPL(kernstart_addr); | ||
83 | 85 | ||
84 | void free_initmem(void) | 86 | void free_initmem(void) |
85 | { | 87 | { |
diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S index cfa768203d0..b9d9fed8f36 100644 --- a/arch/powerpc/mm/tlb_nohash_low.S +++ b/arch/powerpc/mm/tlb_nohash_low.S | |||
@@ -200,6 +200,7 @@ _GLOBAL(_tlbivax_bcast) | |||
200 | rlwimi r5,r4,0,16,31 | 200 | rlwimi r5,r4,0,16,31 |
201 | wrteei 0 | 201 | wrteei 0 |
202 | mtspr SPRN_MMUCR,r5 | 202 | mtspr SPRN_MMUCR,r5 |
203 | isync | ||
203 | /* tlbivax 0,r3 - use .long to avoid binutils deps */ | 204 | /* tlbivax 0,r3 - use .long to avoid binutils deps */ |
204 | .long 0x7c000624 | (r3 << 11) | 205 | .long 0x7c000624 | (r3 << 11) |
205 | isync | 206 | isync |
diff --git a/arch/powerpc/platforms/83xx/mpc837x_mds.c b/arch/powerpc/platforms/83xx/mpc837x_mds.c index f9751c8905b..83068322abd 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c | |||
@@ -48,8 +48,10 @@ static int mpc837xmds_usb_cfg(void) | |||
48 | return -1; | 48 | return -1; |
49 | 49 | ||
50 | np = of_find_node_by_name(NULL, "usb"); | 50 | np = of_find_node_by_name(NULL, "usb"); |
51 | if (!np) | 51 | if (!np) { |
52 | return -ENODEV; | 52 | ret = -ENODEV; |
53 | goto out; | ||
54 | } | ||
53 | phy_type = of_get_property(np, "phy_type", NULL); | 55 | phy_type = of_get_property(np, "phy_type", NULL); |
54 | if (phy_type && !strcmp(phy_type, "ulpi")) { | 56 | if (phy_type && !strcmp(phy_type, "ulpi")) { |
55 | clrbits8(bcsr_regs + 12, BCSR12_USB_SER_PIN); | 57 | clrbits8(bcsr_regs + 12, BCSR12_USB_SER_PIN); |
@@ -65,8 +67,9 @@ static int mpc837xmds_usb_cfg(void) | |||
65 | } | 67 | } |
66 | 68 | ||
67 | of_node_put(np); | 69 | of_node_put(np); |
70 | out: | ||
68 | iounmap(bcsr_regs); | 71 | iounmap(bcsr_regs); |
69 | return 0; | 72 | return ret; |
70 | } | 73 | } |
71 | 74 | ||
72 | /* ************************************************************************ | 75 | /* ************************************************************************ |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index da64be19d09..aa34cac4eb5 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c | |||
@@ -357,6 +357,7 @@ static void __init mpc85xx_mds_setup_arch(void) | |||
357 | { | 357 | { |
358 | #ifdef CONFIG_PCI | 358 | #ifdef CONFIG_PCI |
359 | struct pci_controller *hose; | 359 | struct pci_controller *hose; |
360 | struct device_node *np; | ||
360 | #endif | 361 | #endif |
361 | dma_addr_t max = 0xffffffff; | 362 | dma_addr_t max = 0xffffffff; |
362 | 363 | ||
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c index e1467c93745..34e00902ce8 100644 --- a/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/arch/powerpc/platforms/85xx/p1022_ds.c | |||
@@ -19,7 +19,7 @@ | |||
19 | 19 | ||
20 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
21 | #include <linux/of_platform.h> | 21 | #include <linux/of_platform.h> |
22 | #include <linux/lmb.h> | 22 | #include <linux/memblock.h> |
23 | 23 | ||
24 | #include <asm/mpic.h> | 24 | #include <asm/mpic.h> |
25 | #include <asm/swiotlb.h> | 25 | #include <asm/swiotlb.h> |
@@ -97,7 +97,7 @@ static void __init p1022_ds_setup_arch(void) | |||
97 | #endif | 97 | #endif |
98 | 98 | ||
99 | #ifdef CONFIG_SWIOTLB | 99 | #ifdef CONFIG_SWIOTLB |
100 | if (lmb_end_of_DRAM() > max) { | 100 | if (memblock_end_of_DRAM() > max) { |
101 | ppc_swiotlb_enable = 1; | 101 | ppc_swiotlb_enable = 1; |
102 | set_pci_dma_ops(&swiotlb_dma_ops); | 102 | set_pci_dma_ops(&swiotlb_dma_ops); |
103 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; | 103 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; |
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index d1663db7810..81c9208025f 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig | |||
@@ -106,8 +106,7 @@ config MMIO_NVRAM | |||
106 | 106 | ||
107 | config MPIC_U3_HT_IRQS | 107 | config MPIC_U3_HT_IRQS |
108 | bool | 108 | bool |
109 | depends on PPC_MAPLE | 109 | default n |
110 | default y | ||
111 | 110 | ||
112 | config MPIC_BROKEN_REGREAD | 111 | config MPIC_BROKEN_REGREAD |
113 | bool | 112 | bool |
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 58b13ce3847..26a067122a5 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c | |||
@@ -477,7 +477,7 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np, | |||
477 | 477 | ||
478 | ioid = cell_iommu_get_ioid(np); | 478 | ioid = cell_iommu_get_ioid(np); |
479 | 479 | ||
480 | window = kmalloc_node(sizeof(*window), GFP_KERNEL, iommu->nid); | 480 | window = kzalloc_node(sizeof(*window), GFP_KERNEL, iommu->nid); |
481 | BUG_ON(window == NULL); | 481 | BUG_ON(window == NULL); |
482 | 482 | ||
483 | window->offset = offset; | 483 | window->offset = offset; |
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index ce61cea0afb..d8b76335bd1 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c | |||
@@ -184,7 +184,7 @@ static void pci_dma_dev_setup_iseries(struct pci_dev *pdev) | |||
184 | 184 | ||
185 | BUG_ON(lsn == NULL); | 185 | BUG_ON(lsn == NULL); |
186 | 186 | ||
187 | tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); | 187 | tbl = kzalloc(sizeof(struct iommu_table), GFP_KERNEL); |
188 | 188 | ||
189 | iommu_table_getparms_iSeries(pdn->busno, *lsn, 0, tbl); | 189 | iommu_table_getparms_iSeries(pdn->busno, *lsn, 0, tbl); |
190 | 190 | ||
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index 39df6ab1735..df423993f17 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c | |||
@@ -2873,12 +2873,11 @@ set_initial_features(void) | |||
2873 | 2873 | ||
2874 | /* Switch airport off */ | 2874 | /* Switch airport off */ |
2875 | for_each_node_by_name(np, "radio") { | 2875 | for_each_node_by_name(np, "radio") { |
2876 | if (np && np->parent == macio_chips[0].of_node) { | 2876 | if (np->parent == macio_chips[0].of_node) { |
2877 | macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON; | 2877 | macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON; |
2878 | core99_airport_enable(np, 0, 0); | 2878 | core99_airport_enable(np, 0, 0); |
2879 | } | 2879 | } |
2880 | } | 2880 | } |
2881 | of_node_put(np); | ||
2882 | } | 2881 | } |
2883 | 2882 | ||
2884 | /* On all machines that support sound PM, switch sound off */ | 2883 | /* On all machines that support sound PM, switch sound off */ |
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index ab2027cdf89..3bc075c788e 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c | |||
@@ -1155,13 +1155,11 @@ void __init pmac_pcibios_after_init(void) | |||
1155 | pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0); | 1155 | pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0); |
1156 | } | 1156 | } |
1157 | } | 1157 | } |
1158 | of_node_put(nd); | ||
1159 | for_each_node_by_name(nd, "ethernet") { | 1158 | for_each_node_by_name(nd, "ethernet") { |
1160 | if (nd->parent && of_device_is_compatible(nd, "gmac") | 1159 | if (nd->parent && of_device_is_compatible(nd, "gmac") |
1161 | && of_device_is_compatible(nd->parent, "uni-north")) | 1160 | && of_device_is_compatible(nd->parent, "uni-north")) |
1162 | pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0); | 1161 | pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0); |
1163 | } | 1162 | } |
1164 | of_node_put(nd); | ||
1165 | } | 1163 | } |
1166 | 1164 | ||
1167 | void pmac_pci_fixup_cardbus(struct pci_dev* dev) | 1165 | void pmac_pci_fixup_cardbus(struct pci_dev* dev) |
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 227c1c3d585..72d8054fa73 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c | |||
@@ -129,20 +129,35 @@ struct device_node *dlpar_configure_connector(u32 drc_index) | |||
129 | struct property *property; | 129 | struct property *property; |
130 | struct property *last_property = NULL; | 130 | struct property *last_property = NULL; |
131 | struct cc_workarea *ccwa; | 131 | struct cc_workarea *ccwa; |
132 | char *data_buf; | ||
132 | int cc_token; | 133 | int cc_token; |
133 | int rc; | 134 | int rc = -1; |
134 | 135 | ||
135 | cc_token = rtas_token("ibm,configure-connector"); | 136 | cc_token = rtas_token("ibm,configure-connector"); |
136 | if (cc_token == RTAS_UNKNOWN_SERVICE) | 137 | if (cc_token == RTAS_UNKNOWN_SERVICE) |
137 | return NULL; | 138 | return NULL; |
138 | 139 | ||
139 | spin_lock(&rtas_data_buf_lock); | 140 | data_buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); |
140 | ccwa = (struct cc_workarea *)&rtas_data_buf[0]; | 141 | if (!data_buf) |
142 | return NULL; | ||
143 | |||
144 | ccwa = (struct cc_workarea *)&data_buf[0]; | ||
141 | ccwa->drc_index = drc_index; | 145 | ccwa->drc_index = drc_index; |
142 | ccwa->zero = 0; | 146 | ccwa->zero = 0; |
143 | 147 | ||
144 | rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL); | 148 | do { |
145 | while (rc) { | 149 | /* Since we release the rtas_data_buf lock between configure |
150 | * connector calls we want to re-populate the rtas_data_buffer | ||
151 | * with the contents of the previous call. | ||
152 | */ | ||
153 | spin_lock(&rtas_data_buf_lock); | ||
154 | |||
155 | memcpy(rtas_data_buf, data_buf, RTAS_DATA_BUF_SIZE); | ||
156 | rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL); | ||
157 | memcpy(data_buf, rtas_data_buf, RTAS_DATA_BUF_SIZE); | ||
158 | |||
159 | spin_unlock(&rtas_data_buf_lock); | ||
160 | |||
146 | switch (rc) { | 161 | switch (rc) { |
147 | case NEXT_SIBLING: | 162 | case NEXT_SIBLING: |
148 | dn = dlpar_parse_cc_node(ccwa); | 163 | dn = dlpar_parse_cc_node(ccwa); |
@@ -197,18 +212,19 @@ struct device_node *dlpar_configure_connector(u32 drc_index) | |||
197 | "returned from configure-connector\n", rc); | 212 | "returned from configure-connector\n", rc); |
198 | goto cc_error; | 213 | goto cc_error; |
199 | } | 214 | } |
215 | } while (rc); | ||
200 | 216 | ||
201 | rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL); | 217 | cc_error: |
218 | kfree(data_buf); | ||
219 | |||
220 | if (rc) { | ||
221 | if (first_dn) | ||
222 | dlpar_free_cc_nodes(first_dn); | ||
223 | |||
224 | return NULL; | ||
202 | } | 225 | } |
203 | 226 | ||
204 | spin_unlock(&rtas_data_buf_lock); | ||
205 | return first_dn; | 227 | return first_dn; |
206 | |||
207 | cc_error: | ||
208 | if (first_dn) | ||
209 | dlpar_free_cc_nodes(first_dn); | ||
210 | spin_unlock(&rtas_data_buf_lock); | ||
211 | return NULL; | ||
212 | } | 228 | } |
213 | 229 | ||
214 | static struct device_node *derive_parent(const char *path) | 230 | static struct device_node *derive_parent(const char *path) |
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 395848e30c5..a77bcaed80a 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
@@ -403,7 +403,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus) | |||
403 | pci->phb->dma_window_size = 0x8000000ul; | 403 | pci->phb->dma_window_size = 0x8000000ul; |
404 | pci->phb->dma_window_base_cur = 0x8000000ul; | 404 | pci->phb->dma_window_base_cur = 0x8000000ul; |
405 | 405 | ||
406 | tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, | 406 | tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, |
407 | pci->phb->node); | 407 | pci->phb->node); |
408 | 408 | ||
409 | iommu_table_setparms(pci->phb, dn, tbl); | 409 | iommu_table_setparms(pci->phb, dn, tbl); |
@@ -448,7 +448,7 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus) | |||
448 | pdn->full_name, ppci->iommu_table); | 448 | pdn->full_name, ppci->iommu_table); |
449 | 449 | ||
450 | if (!ppci->iommu_table) { | 450 | if (!ppci->iommu_table) { |
451 | tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, | 451 | tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, |
452 | ppci->phb->node); | 452 | ppci->phb->node); |
453 | iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window, | 453 | iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window, |
454 | bus->number); | 454 | bus->number); |
@@ -478,7 +478,7 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev) | |||
478 | struct pci_controller *phb = PCI_DN(dn)->phb; | 478 | struct pci_controller *phb = PCI_DN(dn)->phb; |
479 | 479 | ||
480 | pr_debug(" --> first child, no bridge. Allocating iommu table.\n"); | 480 | pr_debug(" --> first child, no bridge. Allocating iommu table.\n"); |
481 | tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, | 481 | tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, |
482 | phb->node); | 482 | phb->node); |
483 | iommu_table_setparms(phb, dn, tbl); | 483 | iommu_table_setparms(phb, dn, tbl); |
484 | PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node); | 484 | PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node); |
@@ -544,7 +544,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) | |||
544 | 544 | ||
545 | pci = PCI_DN(pdn); | 545 | pci = PCI_DN(pdn); |
546 | if (!pci->iommu_table) { | 546 | if (!pci->iommu_table) { |
547 | tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, | 547 | tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, |
548 | pci->phb->node); | 548 | pci->phb->node); |
549 | iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window, | 549 | iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window, |
550 | pci->phb->bus->number); | 550 | pci->phb->bus->number); |
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 3b1bf61c45b..0317cce877c 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c | |||
@@ -182,10 +182,13 @@ static int smp_pSeries_cpu_bootable(unsigned int nr) | |||
182 | /* Special case - we inhibit secondary thread startup | 182 | /* Special case - we inhibit secondary thread startup |
183 | * during boot if the user requests it. | 183 | * during boot if the user requests it. |
184 | */ | 184 | */ |
185 | if (system_state < SYSTEM_RUNNING && | 185 | if (system_state < SYSTEM_RUNNING && cpu_has_feature(CPU_FTR_SMT)) { |
186 | cpu_has_feature(CPU_FTR_SMT) && | 186 | if (!smt_enabled_at_boot && cpu_thread_in_core(nr) != 0) |
187 | !smt_enabled_at_boot && cpu_thread_in_core(nr) != 0) | 187 | return 0; |
188 | return 0; | 188 | if (smt_enabled_at_boot |
189 | && cpu_thread_in_core(nr) >= smt_enabled_at_boot) | ||
190 | return 0; | ||
191 | } | ||
189 | 192 | ||
190 | return 1; | 193 | return 1; |
191 | } | 194 | } |
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index 5b22b07c8f6..93834b0d827 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c | |||
@@ -928,8 +928,10 @@ void xics_migrate_irqs_away(void) | |||
928 | if (xics_status[0] != hw_cpu) | 928 | if (xics_status[0] != hw_cpu) |
929 | goto unlock; | 929 | goto unlock; |
930 | 930 | ||
931 | printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n", | 931 | /* This is expected during cpu offline. */ |
932 | virq, cpu); | 932 | if (cpu_online(cpu)) |
933 | printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n", | ||
934 | virq, cpu); | ||
933 | 935 | ||
934 | /* Reset affinity to all cpus */ | 936 | /* Reset affinity to all cpus */ |
935 | cpumask_setall(irq_to_desc(virq)->affinity); | 937 | cpumask_setall(irq_to_desc(virq)->affinity); |
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 209384b6e03..4ae93322525 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c | |||
@@ -399,6 +399,8 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1013E, quirk_fsl_pcie_header); | |||
399 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1013, quirk_fsl_pcie_header); | 399 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1013, quirk_fsl_pcie_header); |
400 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1020E, quirk_fsl_pcie_header); | 400 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1020E, quirk_fsl_pcie_header); |
401 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1020, quirk_fsl_pcie_header); | 401 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1020, quirk_fsl_pcie_header); |
402 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1021E, quirk_fsl_pcie_header); | ||
403 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1021, quirk_fsl_pcie_header); | ||
402 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1022E, quirk_fsl_pcie_header); | 404 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1022E, quirk_fsl_pcie_header); |
403 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1022, quirk_fsl_pcie_header); | 405 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1022, quirk_fsl_pcie_header); |
404 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2010E, quirk_fsl_pcie_header); | 406 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2010E, quirk_fsl_pcie_header); |
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 6425abe5b7d..3017532319c 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c | |||
@@ -240,12 +240,13 @@ struct rio_priv { | |||
240 | 240 | ||
241 | static void __iomem *rio_regs_win; | 241 | static void __iomem *rio_regs_win; |
242 | 242 | ||
243 | #ifdef CONFIG_E500 | ||
243 | static int (*saved_mcheck_exception)(struct pt_regs *regs); | 244 | static int (*saved_mcheck_exception)(struct pt_regs *regs); |
244 | 245 | ||
245 | static int fsl_rio_mcheck_exception(struct pt_regs *regs) | 246 | static int fsl_rio_mcheck_exception(struct pt_regs *regs) |
246 | { | 247 | { |
247 | const struct exception_table_entry *entry = NULL; | 248 | const struct exception_table_entry *entry = NULL; |
248 | unsigned long reason = (mfspr(SPRN_MCSR) & MCSR_MASK); | 249 | unsigned long reason = mfspr(SPRN_MCSR); |
249 | 250 | ||
250 | if (reason & MCSR_BUS_RBERR) { | 251 | if (reason & MCSR_BUS_RBERR) { |
251 | reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR)); | 252 | reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR)); |
@@ -269,6 +270,7 @@ static int fsl_rio_mcheck_exception(struct pt_regs *regs) | |||
269 | else | 270 | else |
270 | return cur_cpu_spec->machine_check(regs); | 271 | return cur_cpu_spec->machine_check(regs); |
271 | } | 272 | } |
273 | #endif | ||
272 | 274 | ||
273 | /** | 275 | /** |
274 | * fsl_rio_doorbell_send - Send a MPC85xx doorbell message | 276 | * fsl_rio_doorbell_send - Send a MPC85xx doorbell message |
@@ -1517,8 +1519,10 @@ int fsl_rio_setup(struct platform_device *dev) | |||
1517 | fsl_rio_doorbell_init(port); | 1519 | fsl_rio_doorbell_init(port); |
1518 | fsl_rio_port_write_init(port); | 1520 | fsl_rio_port_write_init(port); |
1519 | 1521 | ||
1522 | #ifdef CONFIG_E500 | ||
1520 | saved_mcheck_exception = ppc_md.machine_check_exception; | 1523 | saved_mcheck_exception = ppc_md.machine_check_exception; |
1521 | ppc_md.machine_check_exception = fsl_rio_mcheck_exception; | 1524 | ppc_md.machine_check_exception = fsl_rio_mcheck_exception; |
1525 | #endif | ||
1522 | /* Ensure that RFXE is set */ | 1526 | /* Ensure that RFXE is set */ |
1523 | mtspr(SPRN_HID1, (mfspr(SPRN_HID1) | 0x20000)); | 1527 | mtspr(SPRN_HID1, (mfspr(SPRN_HID1) | 0x20000)); |
1524 | 1528 | ||
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 3da8014931c..90020de4dcf 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c | |||
@@ -640,6 +640,7 @@ unsigned int qe_get_num_of_snums(void) | |||
640 | if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) { | 640 | if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) { |
641 | /* No QE ever has fewer than 28 SNUMs */ | 641 | /* No QE ever has fewer than 28 SNUMs */ |
642 | pr_err("QE: number of snum is invalid\n"); | 642 | pr_err("QE: number of snum is invalid\n"); |
643 | of_node_put(qe); | ||
643 | return -EINVAL; | 644 | return -EINVAL; |
644 | } | 645 | } |
645 | } | 646 | } |
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 0554445200b..d17d04cfb2c 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c | |||
@@ -2880,15 +2880,14 @@ static void xmon_init(int enable) | |||
2880 | } | 2880 | } |
2881 | 2881 | ||
2882 | #ifdef CONFIG_MAGIC_SYSRQ | 2882 | #ifdef CONFIG_MAGIC_SYSRQ |
2883 | static void sysrq_handle_xmon(int key, struct tty_struct *tty) | 2883 | static void sysrq_handle_xmon(int key) |
2884 | { | 2884 | { |
2885 | /* ensure xmon is enabled */ | 2885 | /* ensure xmon is enabled */ |
2886 | xmon_init(1); | 2886 | xmon_init(1); |
2887 | debugger(get_irq_regs()); | 2887 | debugger(get_irq_regs()); |
2888 | } | 2888 | } |
2889 | 2889 | ||
2890 | static struct sysrq_key_op sysrq_xmon_op = | 2890 | static struct sysrq_key_op sysrq_xmon_op = { |
2891 | { | ||
2892 | .handler = sysrq_handle_xmon, | 2891 | .handler = sysrq_handle_xmon, |
2893 | .help_msg = "Xmon", | 2892 | .help_msg = "Xmon", |
2894 | .action_msg = "Entering xmon", | 2893 | .action_msg = "Entering xmon", |
diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h index 670a1d1745d..bb8343d157b 100644 --- a/arch/s390/include/asm/hugetlb.h +++ b/arch/s390/include/asm/hugetlb.h | |||
@@ -97,6 +97,7 @@ static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, | |||
97 | { | 97 | { |
98 | pte_t pte = huge_ptep_get(ptep); | 98 | pte_t pte = huge_ptep_get(ptep); |
99 | 99 | ||
100 | mm->context.flush_mm = 1; | ||
100 | pmd_clear((pmd_t *) ptep); | 101 | pmd_clear((pmd_t *) ptep); |
101 | return pte; | 102 | return pte; |
102 | } | 103 | } |
@@ -167,7 +168,8 @@ static inline void huge_ptep_invalidate(struct mm_struct *mm, | |||
167 | ({ \ | 168 | ({ \ |
168 | pte_t __pte = huge_ptep_get(__ptep); \ | 169 | pte_t __pte = huge_ptep_get(__ptep); \ |
169 | if (pte_write(__pte)) { \ | 170 | if (pte_write(__pte)) { \ |
170 | if (atomic_read(&(__mm)->mm_users) > 1 || \ | 171 | (__mm)->context.flush_mm = 1; \ |
172 | if (atomic_read(&(__mm)->context.attach_count) > 1 || \ | ||
171 | (__mm) != current->active_mm) \ | 173 | (__mm) != current->active_mm) \ |
172 | huge_ptep_invalidate(__mm, __addr, __ptep); \ | 174 | huge_ptep_invalidate(__mm, __addr, __ptep); \ |
173 | set_huge_pte_at(__mm, __addr, __ptep, \ | 175 | set_huge_pte_at(__mm, __addr, __ptep, \ |
diff --git a/arch/s390/include/asm/mmu.h b/arch/s390/include/asm/mmu.h index 99e3409102b..78522cdefdd 100644 --- a/arch/s390/include/asm/mmu.h +++ b/arch/s390/include/asm/mmu.h | |||
@@ -2,6 +2,8 @@ | |||
2 | #define __MMU_H | 2 | #define __MMU_H |
3 | 3 | ||
4 | typedef struct { | 4 | typedef struct { |
5 | atomic_t attach_count; | ||
6 | unsigned int flush_mm; | ||
5 | spinlock_t list_lock; | 7 | spinlock_t list_lock; |
6 | struct list_head crst_list; | 8 | struct list_head crst_list; |
7 | struct list_head pgtable_list; | 9 | struct list_head pgtable_list; |
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index 976e273988c..a6f0e7cc9cd 100644 --- a/arch/s390/include/asm/mmu_context.h +++ b/arch/s390/include/asm/mmu_context.h | |||
@@ -11,11 +11,14 @@ | |||
11 | 11 | ||
12 | #include <asm/pgalloc.h> | 12 | #include <asm/pgalloc.h> |
13 | #include <asm/uaccess.h> | 13 | #include <asm/uaccess.h> |
14 | #include <asm/tlbflush.h> | ||
14 | #include <asm-generic/mm_hooks.h> | 15 | #include <asm-generic/mm_hooks.h> |
15 | 16 | ||
16 | static inline int init_new_context(struct task_struct *tsk, | 17 | static inline int init_new_context(struct task_struct *tsk, |
17 | struct mm_struct *mm) | 18 | struct mm_struct *mm) |
18 | { | 19 | { |
20 | atomic_set(&mm->context.attach_count, 0); | ||
21 | mm->context.flush_mm = 0; | ||
19 | mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS; | 22 | mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS; |
20 | #ifdef CONFIG_64BIT | 23 | #ifdef CONFIG_64BIT |
21 | mm->context.asce_bits |= _ASCE_TYPE_REGION3; | 24 | mm->context.asce_bits |= _ASCE_TYPE_REGION3; |
@@ -76,6 +79,12 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | |||
76 | { | 79 | { |
77 | cpumask_set_cpu(smp_processor_id(), mm_cpumask(next)); | 80 | cpumask_set_cpu(smp_processor_id(), mm_cpumask(next)); |
78 | update_mm(next, tsk); | 81 | update_mm(next, tsk); |
82 | atomic_dec(&prev->context.attach_count); | ||
83 | WARN_ON(atomic_read(&prev->context.attach_count) < 0); | ||
84 | atomic_inc(&next->context.attach_count); | ||
85 | /* Check for TLBs not flushed yet */ | ||
86 | if (next->context.flush_mm) | ||
87 | __tlb_flush_mm(next); | ||
79 | } | 88 | } |
80 | 89 | ||
81 | #define enter_lazy_tlb(mm,tsk) do { } while (0) | 90 | #define enter_lazy_tlb(mm,tsk) do { } while (0) |
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 89a504c3f12..3157441ee1d 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -880,7 +880,8 @@ static inline void ptep_invalidate(struct mm_struct *mm, | |||
880 | #define ptep_get_and_clear(__mm, __address, __ptep) \ | 880 | #define ptep_get_and_clear(__mm, __address, __ptep) \ |
881 | ({ \ | 881 | ({ \ |
882 | pte_t __pte = *(__ptep); \ | 882 | pte_t __pte = *(__ptep); \ |
883 | if (atomic_read(&(__mm)->mm_users) > 1 || \ | 883 | (__mm)->context.flush_mm = 1; \ |
884 | if (atomic_read(&(__mm)->context.attach_count) > 1 || \ | ||
884 | (__mm) != current->active_mm) \ | 885 | (__mm) != current->active_mm) \ |
885 | ptep_invalidate(__mm, __address, __ptep); \ | 886 | ptep_invalidate(__mm, __address, __ptep); \ |
886 | else \ | 887 | else \ |
@@ -923,7 +924,8 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, | |||
923 | ({ \ | 924 | ({ \ |
924 | pte_t __pte = *(__ptep); \ | 925 | pte_t __pte = *(__ptep); \ |
925 | if (pte_write(__pte)) { \ | 926 | if (pte_write(__pte)) { \ |
926 | if (atomic_read(&(__mm)->mm_users) > 1 || \ | 927 | (__mm)->context.flush_mm = 1; \ |
928 | if (atomic_read(&(__mm)->context.attach_count) > 1 || \ | ||
927 | (__mm) != current->active_mm) \ | 929 | (__mm) != current->active_mm) \ |
928 | ptep_invalidate(__mm, __addr, __ptep); \ | 930 | ptep_invalidate(__mm, __addr, __ptep); \ |
929 | set_pte_at(__mm, __addr, __ptep, pte_wrprotect(__pte)); \ | 931 | set_pte_at(__mm, __addr, __ptep, pte_wrprotect(__pte)); \ |
diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h index 81150b05368..fd1c00d08bf 100644 --- a/arch/s390/include/asm/tlb.h +++ b/arch/s390/include/asm/tlb.h | |||
@@ -50,8 +50,7 @@ static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, | |||
50 | struct mmu_gather *tlb = &get_cpu_var(mmu_gathers); | 50 | struct mmu_gather *tlb = &get_cpu_var(mmu_gathers); |
51 | 51 | ||
52 | tlb->mm = mm; | 52 | tlb->mm = mm; |
53 | tlb->fullmm = full_mm_flush || (num_online_cpus() == 1) || | 53 | tlb->fullmm = full_mm_flush; |
54 | (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm); | ||
55 | tlb->nr_ptes = 0; | 54 | tlb->nr_ptes = 0; |
56 | tlb->nr_pxds = TLB_NR_PTRS; | 55 | tlb->nr_pxds = TLB_NR_PTRS; |
57 | if (tlb->fullmm) | 56 | if (tlb->fullmm) |
diff --git a/arch/s390/include/asm/tlbflush.h b/arch/s390/include/asm/tlbflush.h index 304cffa623e..29d5d6d4bec 100644 --- a/arch/s390/include/asm/tlbflush.h +++ b/arch/s390/include/asm/tlbflush.h | |||
@@ -94,8 +94,12 @@ static inline void __tlb_flush_mm(struct mm_struct * mm) | |||
94 | 94 | ||
95 | static inline void __tlb_flush_mm_cond(struct mm_struct * mm) | 95 | static inline void __tlb_flush_mm_cond(struct mm_struct * mm) |
96 | { | 96 | { |
97 | if (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm) | 97 | spin_lock(&mm->page_table_lock); |
98 | if (mm->context.flush_mm) { | ||
98 | __tlb_flush_mm(mm); | 99 | __tlb_flush_mm(mm); |
100 | mm->context.flush_mm = 0; | ||
101 | } | ||
102 | spin_unlock(&mm->page_table_lock); | ||
99 | } | 103 | } |
100 | 104 | ||
101 | /* | 105 | /* |
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index 403fb430a89..ff579b6bde0 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h | |||
@@ -42,8 +42,8 @@ long sys_clone(unsigned long newsp, unsigned long clone_flags, | |||
42 | int __user *parent_tidptr, int __user *child_tidptr); | 42 | int __user *parent_tidptr, int __user *child_tidptr); |
43 | long sys_vfork(void); | 43 | long sys_vfork(void); |
44 | void execve_tail(void); | 44 | void execve_tail(void); |
45 | long sys_execve(const char __user *name, char __user * __user *argv, | 45 | long sys_execve(const char __user *name, const char __user *const __user *argv, |
46 | char __user * __user *envp); | 46 | const char __user *const __user *envp); |
47 | long sys_sigsuspend(int history0, int history1, old_sigset_t mask); | 47 | long sys_sigsuspend(int history0, int history1, old_sigset_t mask); |
48 | long sys_sigaction(int sig, const struct old_sigaction __user *act, | 48 | long sys_sigaction(int sig, const struct old_sigaction __user *act, |
49 | struct old_sigaction __user *oact); | 49 | struct old_sigaction __user *oact); |
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 7eafaf2662b..d3a2d1c6438 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
@@ -267,8 +267,9 @@ asmlinkage void execve_tail(void) | |||
267 | /* | 267 | /* |
268 | * sys_execve() executes a new program. | 268 | * sys_execve() executes a new program. |
269 | */ | 269 | */ |
270 | SYSCALL_DEFINE3(execve, const char __user *, name, char __user * __user *, argv, | 270 | SYSCALL_DEFINE3(execve, const char __user *, name, |
271 | char __user * __user *, envp) | 271 | const char __user *const __user *, argv, |
272 | const char __user *const __user *, envp) | ||
272 | { | 273 | { |
273 | struct pt_regs *regs = task_pt_regs(current); | 274 | struct pt_regs *regs = task_pt_regs(current); |
274 | char *filename; | 275 | char *filename; |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 541053ed234..8127ebd59c4 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -583,6 +583,7 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
583 | sf->gprs[9] = (unsigned long) sf; | 583 | sf->gprs[9] = (unsigned long) sf; |
584 | cpu_lowcore->save_area[15] = (unsigned long) sf; | 584 | cpu_lowcore->save_area[15] = (unsigned long) sf; |
585 | __ctl_store(cpu_lowcore->cregs_save_area, 0, 15); | 585 | __ctl_store(cpu_lowcore->cregs_save_area, 0, 15); |
586 | atomic_inc(&init_mm.context.attach_count); | ||
586 | asm volatile( | 587 | asm volatile( |
587 | " stam 0,15,0(%0)" | 588 | " stam 0,15,0(%0)" |
588 | : : "a" (&cpu_lowcore->access_regs_save_area) : "memory"); | 589 | : : "a" (&cpu_lowcore->access_regs_save_area) : "memory"); |
@@ -659,6 +660,7 @@ void __cpu_die(unsigned int cpu) | |||
659 | while (sigp_p(0, cpu, sigp_set_prefix) == sigp_busy) | 660 | while (sigp_p(0, cpu, sigp_set_prefix) == sigp_busy) |
660 | udelay(10); | 661 | udelay(10); |
661 | smp_free_lowcore(cpu); | 662 | smp_free_lowcore(cpu); |
663 | atomic_dec(&init_mm.context.attach_count); | ||
662 | pr_info("Processor %d stopped\n", cpu); | 664 | pr_info("Processor %d stopped\n", cpu); |
663 | } | 665 | } |
664 | 666 | ||
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index acc91c75bc9..30eb6d02ddb 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c | |||
@@ -74,6 +74,8 @@ void __init paging_init(void) | |||
74 | __ctl_load(S390_lowcore.kernel_asce, 13, 13); | 74 | __ctl_load(S390_lowcore.kernel_asce, 13, 13); |
75 | __raw_local_irq_ssm(ssm_mask); | 75 | __raw_local_irq_ssm(ssm_mask); |
76 | 76 | ||
77 | atomic_set(&init_mm.context.attach_count, 1); | ||
78 | |||
77 | sparse_memory_present_with_active_regions(MAX_NUMNODES); | 79 | sparse_memory_present_with_active_regions(MAX_NUMNODES); |
78 | sparse_init(); | 80 | sparse_init(); |
79 | memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); | 81 | memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); |
diff --git a/arch/score/kernel/sys_score.c b/arch/score/kernel/sys_score.c index 651096ff8db..e478bf9a7e9 100644 --- a/arch/score/kernel/sys_score.c +++ b/arch/score/kernel/sys_score.c | |||
@@ -99,8 +99,10 @@ score_execve(struct pt_regs *regs) | |||
99 | if (IS_ERR(filename)) | 99 | if (IS_ERR(filename)) |
100 | return error; | 100 | return error; |
101 | 101 | ||
102 | error = do_execve(filename, (char __user *__user*)regs->regs[5], | 102 | error = do_execve(filename, |
103 | (char __user *__user *) regs->regs[6], regs); | 103 | (const char __user *const __user *)regs->regs[5], |
104 | (const char __user *const __user *)regs->regs[6], | ||
105 | regs); | ||
104 | 106 | ||
105 | putname(filename); | 107 | putname(filename); |
106 | return error; | 108 | return error; |
@@ -110,7 +112,9 @@ score_execve(struct pt_regs *regs) | |||
110 | * Do a system call from kernel instead of calling sys_execve so we | 112 | * Do a system call from kernel instead of calling sys_execve so we |
111 | * end up with proper pt_regs. | 113 | * end up with proper pt_regs. |
112 | */ | 114 | */ |
113 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | 115 | int kernel_execve(const char *filename, |
116 | const char *const argv[], | ||
117 | const char *const envp[]) | ||
114 | { | 118 | { |
115 | register unsigned long __r4 asm("r4") = (unsigned long) filename; | 119 | register unsigned long __r4 asm("r4") = (unsigned long) filename; |
116 | register unsigned long __r5 asm("r5") = (unsigned long) argv; | 120 | register unsigned long __r5 asm("r5") = (unsigned long) argv; |
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index 052981972ae..762a13984bb 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c | |||
@@ -296,9 +296,10 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5, | |||
296 | /* | 296 | /* |
297 | * sys_execve() executes a new program. | 297 | * sys_execve() executes a new program. |
298 | */ | 298 | */ |
299 | asmlinkage int sys_execve(char __user *ufilename, char __user * __user *uargv, | 299 | asmlinkage int sys_execve(const char __user *ufilename, |
300 | char __user * __user *uenvp, unsigned long r7, | 300 | const char __user *const __user *uargv, |
301 | struct pt_regs __regs) | 301 | const char __user *const __user *uenvp, |
302 | unsigned long r7, struct pt_regs __regs) | ||
302 | { | 303 | { |
303 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | 304 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); |
304 | int error; | 305 | int error; |
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c index 68d128d651b..210c1cabcb7 100644 --- a/arch/sh/kernel/process_64.c +++ b/arch/sh/kernel/process_64.c | |||
@@ -497,8 +497,8 @@ asmlinkage int sys_execve(const char *ufilename, char **uargv, | |||
497 | goto out; | 497 | goto out; |
498 | 498 | ||
499 | error = do_execve(filename, | 499 | error = do_execve(filename, |
500 | (char __user * __user *)uargv, | 500 | (const char __user *const __user *)uargv, |
501 | (char __user * __user *)uenvp, | 501 | (const char __user *const __user *)uenvp, |
502 | pregs); | 502 | pregs); |
503 | putname(filename); | 503 | putname(filename); |
504 | out: | 504 | out: |
diff --git a/arch/sh/kernel/sys_sh32.c b/arch/sh/kernel/sys_sh32.c index eb68bfdd86e..f56b6fe5c5d 100644 --- a/arch/sh/kernel/sys_sh32.c +++ b/arch/sh/kernel/sys_sh32.c | |||
@@ -71,7 +71,9 @@ asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1, | |||
71 | * Do a system call from kernel instead of calling sys_execve so we | 71 | * Do a system call from kernel instead of calling sys_execve so we |
72 | * end up with proper pt_regs. | 72 | * end up with proper pt_regs. |
73 | */ | 73 | */ |
74 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | 74 | int kernel_execve(const char *filename, |
75 | const char *const argv[], | ||
76 | const char *const envp[]) | ||
75 | { | 77 | { |
76 | register long __sc0 __asm__ ("r3") = __NR_execve; | 78 | register long __sc0 __asm__ ("r3") = __NR_execve; |
77 | register long __sc4 __asm__ ("r4") = (long) filename; | 79 | register long __sc4 __asm__ ("r4") = (long) filename; |
diff --git a/arch/sh/kernel/sys_sh64.c b/arch/sh/kernel/sys_sh64.c index 287235768bc..c5a38c4bf41 100644 --- a/arch/sh/kernel/sys_sh64.c +++ b/arch/sh/kernel/sys_sh64.c | |||
@@ -33,7 +33,9 @@ | |||
33 | * Do a system call from kernel instead of calling sys_execve so we | 33 | * Do a system call from kernel instead of calling sys_execve so we |
34 | * end up with proper pt_regs. | 34 | * end up with proper pt_regs. |
35 | */ | 35 | */ |
36 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | 36 | int kernel_execve(const char *filename, |
37 | const char *const argv[], | ||
38 | const char *const envp[]) | ||
37 | { | 39 | { |
38 | register unsigned long __sc0 __asm__ ("r9") = ((0x13 << 16) | __NR_execve); | 40 | register unsigned long __sc0 __asm__ ("r9") = ((0x13 << 16) | __NR_execve); |
39 | register unsigned long __sc2 __asm__ ("r2") = (unsigned long) filename; | 41 | register unsigned long __sc2 __asm__ ("r2") = (unsigned long) filename; |
diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h index 2050ca02c42..bdb2ff880bd 100644 --- a/arch/sparc/include/asm/atomic_64.h +++ b/arch/sparc/include/asm/atomic_64.h | |||
@@ -20,14 +20,14 @@ | |||
20 | #define atomic64_set(v, i) (((v)->counter) = i) | 20 | #define atomic64_set(v, i) (((v)->counter) = i) |
21 | 21 | ||
22 | extern void atomic_add(int, atomic_t *); | 22 | extern void atomic_add(int, atomic_t *); |
23 | extern void atomic64_add(int, atomic64_t *); | 23 | extern void atomic64_add(long, atomic64_t *); |
24 | extern void atomic_sub(int, atomic_t *); | 24 | extern void atomic_sub(int, atomic_t *); |
25 | extern void atomic64_sub(int, atomic64_t *); | 25 | extern void atomic64_sub(long, atomic64_t *); |
26 | 26 | ||
27 | extern int atomic_add_ret(int, atomic_t *); | 27 | extern int atomic_add_ret(int, atomic_t *); |
28 | extern int atomic64_add_ret(int, atomic64_t *); | 28 | extern long atomic64_add_ret(long, atomic64_t *); |
29 | extern int atomic_sub_ret(int, atomic_t *); | 29 | extern int atomic_sub_ret(int, atomic_t *); |
30 | extern int atomic64_sub_ret(int, atomic64_t *); | 30 | extern long atomic64_sub_ret(long, atomic64_t *); |
31 | 31 | ||
32 | #define atomic_dec_return(v) atomic_sub_ret(1, v) | 32 | #define atomic_dec_return(v) atomic_sub_ret(1, v) |
33 | #define atomic64_dec_return(v) atomic64_sub_ret(1, v) | 33 | #define atomic64_dec_return(v) atomic64_sub_ret(1, v) |
@@ -91,7 +91,7 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) | |||
91 | ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n))) | 91 | ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n))) |
92 | #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) | 92 | #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) |
93 | 93 | ||
94 | static inline int atomic64_add_unless(atomic64_t *v, long a, long u) | 94 | static inline long atomic64_add_unless(atomic64_t *v, long a, long u) |
95 | { | 95 | { |
96 | long c, old; | 96 | long c, old; |
97 | c = atomic64_read(v); | 97 | c = atomic64_read(v); |
diff --git a/arch/sparc/include/asm/backoff.h b/arch/sparc/include/asm/backoff.h index fa1fdf67e35..db3af0d30fb 100644 --- a/arch/sparc/include/asm/backoff.h +++ b/arch/sparc/include/asm/backoff.h | |||
@@ -8,6 +8,9 @@ | |||
8 | #define BACKOFF_SETUP(reg) \ | 8 | #define BACKOFF_SETUP(reg) \ |
9 | mov 1, reg | 9 | mov 1, reg |
10 | 10 | ||
11 | #define BACKOFF_LABEL(spin_label, continue_label) \ | ||
12 | spin_label | ||
13 | |||
11 | #define BACKOFF_SPIN(reg, tmp, label) \ | 14 | #define BACKOFF_SPIN(reg, tmp, label) \ |
12 | mov reg, tmp; \ | 15 | mov reg, tmp; \ |
13 | 88: brnz,pt tmp, 88b; \ | 16 | 88: brnz,pt tmp, 88b; \ |
@@ -22,9 +25,11 @@ | |||
22 | #else | 25 | #else |
23 | 26 | ||
24 | #define BACKOFF_SETUP(reg) | 27 | #define BACKOFF_SETUP(reg) |
25 | #define BACKOFF_SPIN(reg, tmp, label) \ | 28 | |
26 | ba,pt %xcc, label; \ | 29 | #define BACKOFF_LABEL(spin_label, continue_label) \ |
27 | nop; | 30 | continue_label |
31 | |||
32 | #define BACKOFF_SPIN(reg, tmp, label) | ||
28 | 33 | ||
29 | #endif | 34 | #endif |
30 | 35 | ||
diff --git a/arch/sparc/include/asm/fb.h b/arch/sparc/include/asm/fb.h index e834880be20..2173432ad7f 100644 --- a/arch/sparc/include/asm/fb.h +++ b/arch/sparc/include/asm/fb.h | |||
@@ -1,5 +1,6 @@ | |||
1 | #ifndef _SPARC_FB_H_ | 1 | #ifndef _SPARC_FB_H_ |
2 | #define _SPARC_FB_H_ | 2 | #define _SPARC_FB_H_ |
3 | #include <linux/console.h> | ||
3 | #include <linux/fb.h> | 4 | #include <linux/fb.h> |
4 | #include <linux/fs.h> | 5 | #include <linux/fs.h> |
5 | #include <asm/page.h> | 6 | #include <asm/page.h> |
@@ -18,6 +19,9 @@ static inline int fb_is_primary_device(struct fb_info *info) | |||
18 | struct device *dev = info->device; | 19 | struct device *dev = info->device; |
19 | struct device_node *node; | 20 | struct device_node *node; |
20 | 21 | ||
22 | if (console_set_on_cmdline) | ||
23 | return 0; | ||
24 | |||
21 | node = dev->of_node; | 25 | node = dev->of_node; |
22 | if (node && | 26 | if (node && |
23 | node == of_console_device) | 27 | node == of_console_device) |
diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index a5db0317b5f..3e0b2d62303 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h | |||
@@ -185,9 +185,8 @@ extern int prom_getunumber(int syndrome_code, | |||
185 | char *buf, int buflen); | 185 | char *buf, int buflen); |
186 | 186 | ||
187 | /* Retain physical memory to the caller across soft resets. */ | 187 | /* Retain physical memory to the caller across soft resets. */ |
188 | extern unsigned long prom_retain(const char *name, | 188 | extern int prom_retain(const char *name, unsigned long size, |
189 | unsigned long pa_low, unsigned long pa_high, | 189 | unsigned long align, unsigned long *paddr); |
190 | long size, long align); | ||
191 | 190 | ||
192 | /* Load explicit I/D TLB entries into the calling processor. */ | 191 | /* Load explicit I/D TLB entries into the calling processor. */ |
193 | extern long prom_itlb_load(unsigned long index, | 192 | extern long prom_itlb_load(unsigned long index, |
@@ -287,26 +286,6 @@ extern void prom_sun4v_guest_soft_state(void); | |||
287 | extern int prom_ihandle2path(int handle, char *buffer, int bufsize); | 286 | extern int prom_ihandle2path(int handle, char *buffer, int bufsize); |
288 | 287 | ||
289 | /* Client interface level routines. */ | 288 | /* Client interface level routines. */ |
290 | extern long p1275_cmd(const char *, long, ...); | 289 | extern void p1275_cmd_direct(unsigned long *); |
291 | |||
292 | #if 0 | ||
293 | #define P1275_SIZE(x) ((((long)((x) / 32)) << 32) | (x)) | ||
294 | #else | ||
295 | #define P1275_SIZE(x) x | ||
296 | #endif | ||
297 | |||
298 | /* We support at most 16 input and 1 output argument */ | ||
299 | #define P1275_ARG_NUMBER 0 | ||
300 | #define P1275_ARG_IN_STRING 1 | ||
301 | #define P1275_ARG_OUT_BUF 2 | ||
302 | #define P1275_ARG_OUT_32B 3 | ||
303 | #define P1275_ARG_IN_FUNCTION 4 | ||
304 | #define P1275_ARG_IN_BUF 5 | ||
305 | #define P1275_ARG_IN_64B 6 | ||
306 | |||
307 | #define P1275_IN(x) ((x) & 0xf) | ||
308 | #define P1275_OUT(x) (((x) << 4) & 0xf0) | ||
309 | #define P1275_INOUT(i,o) (P1275_IN(i)|P1275_OUT(o)) | ||
310 | #define P1275_ARG(n,x) ((x) << ((n)*3 + 8)) | ||
311 | 290 | ||
312 | #endif /* !(__SPARC64_OPLIB_H) */ | 291 | #endif /* !(__SPARC64_OPLIB_H) */ |
diff --git a/arch/sparc/include/asm/rwsem-const.h b/arch/sparc/include/asm/rwsem-const.h deleted file mode 100644 index a303c9d64d8..00000000000 --- a/arch/sparc/include/asm/rwsem-const.h +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | /* rwsem-const.h: RW semaphore counter constants. */ | ||
2 | #ifndef _SPARC64_RWSEM_CONST_H | ||
3 | #define _SPARC64_RWSEM_CONST_H | ||
4 | |||
5 | #define RWSEM_UNLOCKED_VALUE 0x00000000 | ||
6 | #define RWSEM_ACTIVE_BIAS 0x00000001 | ||
7 | #define RWSEM_ACTIVE_MASK 0x0000ffff | ||
8 | #define RWSEM_WAITING_BIAS 0xffff0000 | ||
9 | #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS | ||
10 | #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) | ||
11 | |||
12 | #endif /* _SPARC64_RWSEM_CONST_H */ | ||
diff --git a/arch/sparc/include/asm/rwsem.h b/arch/sparc/include/asm/rwsem.h index 6e5621006f8..a2b4302869b 100644 --- a/arch/sparc/include/asm/rwsem.h +++ b/arch/sparc/include/asm/rwsem.h | |||
@@ -15,16 +15,21 @@ | |||
15 | 15 | ||
16 | #include <linux/list.h> | 16 | #include <linux/list.h> |
17 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
18 | #include <asm/rwsem-const.h> | ||
19 | 18 | ||
20 | struct rwsem_waiter; | 19 | struct rwsem_waiter; |
21 | 20 | ||
22 | struct rw_semaphore { | 21 | struct rw_semaphore { |
23 | signed int count; | 22 | signed long count; |
24 | spinlock_t wait_lock; | 23 | #define RWSEM_UNLOCKED_VALUE 0x00000000L |
25 | struct list_head wait_list; | 24 | #define RWSEM_ACTIVE_BIAS 0x00000001L |
25 | #define RWSEM_ACTIVE_MASK 0xffffffffL | ||
26 | #define RWSEM_WAITING_BIAS (-RWSEM_ACTIVE_MASK-1) | ||
27 | #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS | ||
28 | #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) | ||
29 | spinlock_t wait_lock; | ||
30 | struct list_head wait_list; | ||
26 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 31 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
27 | struct lockdep_map dep_map; | 32 | struct lockdep_map dep_map; |
28 | #endif | 33 | #endif |
29 | }; | 34 | }; |
30 | 35 | ||
@@ -41,6 +46,11 @@ struct rw_semaphore { | |||
41 | #define DECLARE_RWSEM(name) \ | 46 | #define DECLARE_RWSEM(name) \ |
42 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) | 47 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) |
43 | 48 | ||
49 | extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem); | ||
50 | extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem); | ||
51 | extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem); | ||
52 | extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem); | ||
53 | |||
44 | extern void __init_rwsem(struct rw_semaphore *sem, const char *name, | 54 | extern void __init_rwsem(struct rw_semaphore *sem, const char *name, |
45 | struct lock_class_key *key); | 55 | struct lock_class_key *key); |
46 | 56 | ||
@@ -51,27 +61,103 @@ do { \ | |||
51 | __init_rwsem((sem), #sem, &__key); \ | 61 | __init_rwsem((sem), #sem, &__key); \ |
52 | } while (0) | 62 | } while (0) |
53 | 63 | ||
54 | extern void __down_read(struct rw_semaphore *sem); | 64 | /* |
55 | extern int __down_read_trylock(struct rw_semaphore *sem); | 65 | * lock for reading |
56 | extern void __down_write(struct rw_semaphore *sem); | 66 | */ |
57 | extern int __down_write_trylock(struct rw_semaphore *sem); | 67 | static inline void __down_read(struct rw_semaphore *sem) |
58 | extern void __up_read(struct rw_semaphore *sem); | 68 | { |
59 | extern void __up_write(struct rw_semaphore *sem); | 69 | if (unlikely(atomic64_inc_return((atomic64_t *)(&sem->count)) <= 0L)) |
60 | extern void __downgrade_write(struct rw_semaphore *sem); | 70 | rwsem_down_read_failed(sem); |
71 | } | ||
72 | |||
73 | static inline int __down_read_trylock(struct rw_semaphore *sem) | ||
74 | { | ||
75 | long tmp; | ||
76 | |||
77 | while ((tmp = sem->count) >= 0L) { | ||
78 | if (tmp == cmpxchg(&sem->count, tmp, | ||
79 | tmp + RWSEM_ACTIVE_READ_BIAS)) { | ||
80 | return 1; | ||
81 | } | ||
82 | } | ||
83 | return 0; | ||
84 | } | ||
61 | 85 | ||
86 | /* | ||
87 | * lock for writing | ||
88 | */ | ||
62 | static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) | 89 | static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) |
63 | { | 90 | { |
64 | __down_write(sem); | 91 | long tmp; |
92 | |||
93 | tmp = atomic64_add_return(RWSEM_ACTIVE_WRITE_BIAS, | ||
94 | (atomic64_t *)(&sem->count)); | ||
95 | if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS)) | ||
96 | rwsem_down_write_failed(sem); | ||
65 | } | 97 | } |
66 | 98 | ||
67 | static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem) | 99 | static inline void __down_write(struct rw_semaphore *sem) |
68 | { | 100 | { |
69 | return atomic_add_return(delta, (atomic_t *)(&sem->count)); | 101 | __down_write_nested(sem, 0); |
102 | } | ||
103 | |||
104 | static inline int __down_write_trylock(struct rw_semaphore *sem) | ||
105 | { | ||
106 | long tmp; | ||
107 | |||
108 | tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE, | ||
109 | RWSEM_ACTIVE_WRITE_BIAS); | ||
110 | return tmp == RWSEM_UNLOCKED_VALUE; | ||
70 | } | 111 | } |
71 | 112 | ||
72 | static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) | 113 | /* |
114 | * unlock after reading | ||
115 | */ | ||
116 | static inline void __up_read(struct rw_semaphore *sem) | ||
117 | { | ||
118 | long tmp; | ||
119 | |||
120 | tmp = atomic64_dec_return((atomic64_t *)(&sem->count)); | ||
121 | if (unlikely(tmp < -1L && (tmp & RWSEM_ACTIVE_MASK) == 0L)) | ||
122 | rwsem_wake(sem); | ||
123 | } | ||
124 | |||
125 | /* | ||
126 | * unlock after writing | ||
127 | */ | ||
128 | static inline void __up_write(struct rw_semaphore *sem) | ||
129 | { | ||
130 | if (unlikely(atomic64_sub_return(RWSEM_ACTIVE_WRITE_BIAS, | ||
131 | (atomic64_t *)(&sem->count)) < 0L)) | ||
132 | rwsem_wake(sem); | ||
133 | } | ||
134 | |||
135 | /* | ||
136 | * implement atomic add functionality | ||
137 | */ | ||
138 | static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem) | ||
139 | { | ||
140 | atomic64_add(delta, (atomic64_t *)(&sem->count)); | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * downgrade write lock to read lock | ||
145 | */ | ||
146 | static inline void __downgrade_write(struct rw_semaphore *sem) | ||
147 | { | ||
148 | long tmp; | ||
149 | |||
150 | tmp = atomic64_add_return(-RWSEM_WAITING_BIAS, (atomic64_t *)(&sem->count)); | ||
151 | if (tmp < 0L) | ||
152 | rwsem_downgrade_wake(sem); | ||
153 | } | ||
154 | |||
155 | /* | ||
156 | * implement exchange and add functionality | ||
157 | */ | ||
158 | static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem) | ||
73 | { | 159 | { |
74 | atomic_add(delta, (atomic_t *)(&sem->count)); | 160 | return atomic64_add_return(delta, (atomic64_t *)(&sem->count)); |
75 | } | 161 | } |
76 | 162 | ||
77 | static inline int rwsem_is_locked(struct rw_semaphore *sem) | 163 | static inline int rwsem_is_locked(struct rw_semaphore *sem) |
diff --git a/arch/sparc/include/asm/system_64.h b/arch/sparc/include/asm/system_64.h index d24cfe16afc..e3b65d8cf41 100644 --- a/arch/sparc/include/asm/system_64.h +++ b/arch/sparc/include/asm/system_64.h | |||
@@ -106,6 +106,7 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \ | |||
106 | */ | 106 | */ |
107 | #define write_pic(__p) \ | 107 | #define write_pic(__p) \ |
108 | __asm__ __volatile__("ba,pt %%xcc, 99f\n\t" \ | 108 | __asm__ __volatile__("ba,pt %%xcc, 99f\n\t" \ |
109 | " nop\n\t" \ | ||
109 | ".align 64\n" \ | 110 | ".align 64\n" \ |
110 | "99:wr %0, 0x0, %%pic\n\t" \ | 111 | "99:wr %0, 0x0, %%pic\n\t" \ |
111 | "rd %%pic, %%g0" : : "r" (__p)) | 112 | "rd %%pic, %%g0" : : "r" (__p)) |
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h index d0b3b01ac9d..03eb5a8f6f9 100644 --- a/arch/sparc/include/asm/unistd.h +++ b/arch/sparc/include/asm/unistd.h | |||
@@ -397,8 +397,11 @@ | |||
397 | #define __NR_rt_tgsigqueueinfo 326 | 397 | #define __NR_rt_tgsigqueueinfo 326 |
398 | #define __NR_perf_event_open 327 | 398 | #define __NR_perf_event_open 327 |
399 | #define __NR_recvmmsg 328 | 399 | #define __NR_recvmmsg 328 |
400 | #define __NR_fanotify_init 329 | ||
401 | #define __NR_fanotify_mark 330 | ||
402 | #define __NR_prlimit64 331 | ||
400 | 403 | ||
401 | #define NR_syscalls 329 | 404 | #define NR_syscalls 332 |
402 | 405 | ||
403 | #ifdef __32bit_syscall_numbers__ | 406 | #ifdef __32bit_syscall_numbers__ |
404 | /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, | 407 | /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, |
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index 40e29fc8a4d..17529298c50 100644 --- a/arch/sparc/kernel/process_32.c +++ b/arch/sparc/kernel/process_32.c | |||
@@ -633,8 +633,10 @@ asmlinkage int sparc_execve(struct pt_regs *regs) | |||
633 | if(IS_ERR(filename)) | 633 | if(IS_ERR(filename)) |
634 | goto out; | 634 | goto out; |
635 | error = do_execve(filename, | 635 | error = do_execve(filename, |
636 | (char __user * __user *)regs->u_regs[base + UREG_I1], | 636 | (const char __user *const __user *) |
637 | (char __user * __user *)regs->u_regs[base + UREG_I2], | 637 | regs->u_regs[base + UREG_I1], |
638 | (const char __user *const __user *) | ||
639 | regs->u_regs[base + UREG_I2], | ||
638 | regs); | 640 | regs); |
639 | putname(filename); | 641 | putname(filename); |
640 | out: | 642 | out: |
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index dbe81a368b4..c158a95ec66 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c | |||
@@ -303,7 +303,7 @@ void arch_trigger_all_cpu_backtrace(void) | |||
303 | 303 | ||
304 | #ifdef CONFIG_MAGIC_SYSRQ | 304 | #ifdef CONFIG_MAGIC_SYSRQ |
305 | 305 | ||
306 | static void sysrq_handle_globreg(int key, struct tty_struct *tty) | 306 | static void sysrq_handle_globreg(int key) |
307 | { | 307 | { |
308 | arch_trigger_all_cpu_backtrace(); | 308 | arch_trigger_all_cpu_backtrace(); |
309 | } | 309 | } |
@@ -739,9 +739,9 @@ asmlinkage int sparc_execve(struct pt_regs *regs) | |||
739 | if (IS_ERR(filename)) | 739 | if (IS_ERR(filename)) |
740 | goto out; | 740 | goto out; |
741 | error = do_execve(filename, | 741 | error = do_execve(filename, |
742 | (char __user * __user *) | 742 | (const char __user *const __user *) |
743 | regs->u_regs[base + UREG_I1], | 743 | regs->u_regs[base + UREG_I1], |
744 | (char __user * __user *) | 744 | (const char __user *const __user *) |
745 | regs->u_regs[base + UREG_I2], regs); | 745 | regs->u_regs[base + UREG_I2], regs); |
746 | putname(filename); | 746 | putname(filename); |
747 | if (!error) { | 747 | if (!error) { |
diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S index 46a76ba3fb4..44e5faf1ad5 100644 --- a/arch/sparc/kernel/sys32.S +++ b/arch/sparc/kernel/sys32.S | |||
@@ -330,6 +330,15 @@ do_sys_accept4: /* sys_accept4(int, struct sockaddr *, int *, int) */ | |||
330 | nop | 330 | nop |
331 | nop | 331 | nop |
332 | 332 | ||
333 | .globl sys32_fanotify_mark | ||
334 | sys32_fanotify_mark: | ||
335 | sethi %hi(sys_fanotify_mark), %g1 | ||
336 | sllx %o2, 32, %o2 | ||
337 | or %o2, %o3, %o2 | ||
338 | mov %o4, %o3 | ||
339 | jmpl %g1 + %lo(sys_fanotify_mark), %g0 | ||
340 | mov %o5, %o4 | ||
341 | |||
333 | .section __ex_table,"a" | 342 | .section __ex_table,"a" |
334 | .align 4 | 343 | .align 4 |
335 | .word 1b, __retl_efault, 2b, __retl_efault | 344 | .word 1b, __retl_efault, 2b, __retl_efault |
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c index ee995b7dae7..50794137d71 100644 --- a/arch/sparc/kernel/sys_sparc_32.c +++ b/arch/sparc/kernel/sys_sparc_32.c | |||
@@ -282,7 +282,9 @@ out: | |||
282 | * Do a system call from kernel instead of calling sys_execve so we | 282 | * Do a system call from kernel instead of calling sys_execve so we |
283 | * end up with proper pt_regs. | 283 | * end up with proper pt_regs. |
284 | */ | 284 | */ |
285 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | 285 | int kernel_execve(const char *filename, |
286 | const char *const argv[], | ||
287 | const char *const envp[]) | ||
286 | { | 288 | { |
287 | long __res; | 289 | long __res; |
288 | register long __g1 __asm__ ("g1") = __NR_execve; | 290 | register long __g1 __asm__ ("g1") = __NR_execve; |
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 3d435c42e6d..f836f4e93af 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c | |||
@@ -758,7 +758,9 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act, | |||
758 | * Do a system call from kernel instead of calling sys_execve so we | 758 | * Do a system call from kernel instead of calling sys_execve so we |
759 | * end up with proper pt_regs. | 759 | * end up with proper pt_regs. |
760 | */ | 760 | */ |
761 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | 761 | int kernel_execve(const char *filename, |
762 | const char *const argv[], | ||
763 | const char *const envp[]) | ||
762 | { | 764 | { |
763 | long __res; | 765 | long __res; |
764 | register long __g1 __asm__ ("g1") = __NR_execve; | 766 | register long __g1 __asm__ ("g1") = __NR_execve; |
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 801fc8e5a0e..ec396e1916b 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S | |||
@@ -82,5 +82,6 @@ sys_call_table: | |||
82 | /*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate | 82 | /*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate |
83 | /*315*/ .long sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1 | 83 | /*315*/ .long sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1 |
84 | /*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv | 84 | /*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv |
85 | /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg | 85 | /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init |
86 | /*330*/ .long sys_fanotify_mark, sys_prlimit64 | ||
86 | 87 | ||
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 9db058dd039..8cfcaa54958 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S | |||
@@ -83,7 +83,8 @@ sys_call_table32: | |||
83 | /*310*/ .word compat_sys_utimensat, compat_sys_signalfd, sys_timerfd_create, sys_eventfd, compat_sys_fallocate | 83 | /*310*/ .word compat_sys_utimensat, compat_sys_signalfd, sys_timerfd_create, sys_eventfd, compat_sys_fallocate |
84 | .word compat_sys_timerfd_settime, compat_sys_timerfd_gettime, compat_sys_signalfd4, sys_eventfd2, sys_epoll_create1 | 84 | .word compat_sys_timerfd_settime, compat_sys_timerfd_gettime, compat_sys_signalfd4, sys_eventfd2, sys_epoll_create1 |
85 | /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv | 85 | /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv |
86 | .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg | 86 | .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init |
87 | /*330*/ .word sys32_fanotify_mark, sys_prlimit64 | ||
87 | 88 | ||
88 | #endif /* CONFIG_COMPAT */ | 89 | #endif /* CONFIG_COMPAT */ |
89 | 90 | ||
@@ -158,4 +159,5 @@ sys_call_table: | |||
158 | /*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate | 159 | /*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate |
159 | .word sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1 | 160 | .word sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1 |
160 | /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv | 161 | /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv |
161 | .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg | 162 | .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init |
163 | /*330*/ .word sys_fanotify_mark, sys_prlimit64 | ||
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index c4b5e03af11..846d1c4374e 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile | |||
@@ -15,7 +15,7 @@ lib-$(CONFIG_SPARC32) += divdi3.o udivdi3.o | |||
15 | lib-$(CONFIG_SPARC32) += copy_user.o locks.o | 15 | lib-$(CONFIG_SPARC32) += copy_user.o locks.o |
16 | lib-y += atomic_$(BITS).o | 16 | lib-y += atomic_$(BITS).o |
17 | lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o | 17 | lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o |
18 | lib-y += rwsem_$(BITS).o | 18 | lib-$(CONFIG_SPARC32) += rwsem_32.o |
19 | lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o | 19 | lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o |
20 | 20 | ||
21 | lib-$(CONFIG_SPARC64) += copy_page.o clear_page.o bzero.o | 21 | lib-$(CONFIG_SPARC64) += copy_page.o clear_page.o bzero.o |
diff --git a/arch/sparc/lib/atomic_64.S b/arch/sparc/lib/atomic_64.S index 0268210ca16..59186e0fcf3 100644 --- a/arch/sparc/lib/atomic_64.S +++ b/arch/sparc/lib/atomic_64.S | |||
@@ -21,7 +21,7 @@ atomic_add: /* %o0 = increment, %o1 = atomic_ptr */ | |||
21 | add %g1, %o0, %g7 | 21 | add %g1, %o0, %g7 |
22 | cas [%o1], %g1, %g7 | 22 | cas [%o1], %g1, %g7 |
23 | cmp %g1, %g7 | 23 | cmp %g1, %g7 |
24 | bne,pn %icc, 2f | 24 | bne,pn %icc, BACKOFF_LABEL(2f, 1b) |
25 | nop | 25 | nop |
26 | retl | 26 | retl |
27 | nop | 27 | nop |
@@ -36,7 +36,7 @@ atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */ | |||
36 | sub %g1, %o0, %g7 | 36 | sub %g1, %o0, %g7 |
37 | cas [%o1], %g1, %g7 | 37 | cas [%o1], %g1, %g7 |
38 | cmp %g1, %g7 | 38 | cmp %g1, %g7 |
39 | bne,pn %icc, 2f | 39 | bne,pn %icc, BACKOFF_LABEL(2f, 1b) |
40 | nop | 40 | nop |
41 | retl | 41 | retl |
42 | nop | 42 | nop |
@@ -51,11 +51,10 @@ atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ | |||
51 | add %g1, %o0, %g7 | 51 | add %g1, %o0, %g7 |
52 | cas [%o1], %g1, %g7 | 52 | cas [%o1], %g1, %g7 |
53 | cmp %g1, %g7 | 53 | cmp %g1, %g7 |
54 | bne,pn %icc, 2f | 54 | bne,pn %icc, BACKOFF_LABEL(2f, 1b) |
55 | add %g7, %o0, %g7 | 55 | add %g1, %o0, %g1 |
56 | sra %g7, 0, %o0 | ||
57 | retl | 56 | retl |
58 | nop | 57 | sra %g1, 0, %o0 |
59 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | 58 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
60 | .size atomic_add_ret, .-atomic_add_ret | 59 | .size atomic_add_ret, .-atomic_add_ret |
61 | 60 | ||
@@ -67,11 +66,10 @@ atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ | |||
67 | sub %g1, %o0, %g7 | 66 | sub %g1, %o0, %g7 |
68 | cas [%o1], %g1, %g7 | 67 | cas [%o1], %g1, %g7 |
69 | cmp %g1, %g7 | 68 | cmp %g1, %g7 |
70 | bne,pn %icc, 2f | 69 | bne,pn %icc, BACKOFF_LABEL(2f, 1b) |
71 | sub %g7, %o0, %g7 | 70 | sub %g1, %o0, %g1 |
72 | sra %g7, 0, %o0 | ||
73 | retl | 71 | retl |
74 | nop | 72 | sra %g1, 0, %o0 |
75 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | 73 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
76 | .size atomic_sub_ret, .-atomic_sub_ret | 74 | .size atomic_sub_ret, .-atomic_sub_ret |
77 | 75 | ||
@@ -83,7 +81,7 @@ atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */ | |||
83 | add %g1, %o0, %g7 | 81 | add %g1, %o0, %g7 |
84 | casx [%o1], %g1, %g7 | 82 | casx [%o1], %g1, %g7 |
85 | cmp %g1, %g7 | 83 | cmp %g1, %g7 |
86 | bne,pn %xcc, 2f | 84 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
87 | nop | 85 | nop |
88 | retl | 86 | retl |
89 | nop | 87 | nop |
@@ -98,7 +96,7 @@ atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */ | |||
98 | sub %g1, %o0, %g7 | 96 | sub %g1, %o0, %g7 |
99 | casx [%o1], %g1, %g7 | 97 | casx [%o1], %g1, %g7 |
100 | cmp %g1, %g7 | 98 | cmp %g1, %g7 |
101 | bne,pn %xcc, 2f | 99 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
102 | nop | 100 | nop |
103 | retl | 101 | retl |
104 | nop | 102 | nop |
@@ -113,11 +111,10 @@ atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ | |||
113 | add %g1, %o0, %g7 | 111 | add %g1, %o0, %g7 |
114 | casx [%o1], %g1, %g7 | 112 | casx [%o1], %g1, %g7 |
115 | cmp %g1, %g7 | 113 | cmp %g1, %g7 |
116 | bne,pn %xcc, 2f | 114 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
117 | add %g7, %o0, %g7 | ||
118 | mov %g7, %o0 | ||
119 | retl | ||
120 | nop | 115 | nop |
116 | retl | ||
117 | add %g1, %o0, %o0 | ||
121 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | 118 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
122 | .size atomic64_add_ret, .-atomic64_add_ret | 119 | .size atomic64_add_ret, .-atomic64_add_ret |
123 | 120 | ||
@@ -129,10 +126,9 @@ atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ | |||
129 | sub %g1, %o0, %g7 | 126 | sub %g1, %o0, %g7 |
130 | casx [%o1], %g1, %g7 | 127 | casx [%o1], %g1, %g7 |
131 | cmp %g1, %g7 | 128 | cmp %g1, %g7 |
132 | bne,pn %xcc, 2f | 129 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
133 | sub %g7, %o0, %g7 | ||
134 | mov %g7, %o0 | ||
135 | retl | ||
136 | nop | 130 | nop |
131 | retl | ||
132 | sub %g1, %o0, %o0 | ||
137 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | 133 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
138 | .size atomic64_sub_ret, .-atomic64_sub_ret | 134 | .size atomic64_sub_ret, .-atomic64_sub_ret |
diff --git a/arch/sparc/lib/bitops.S b/arch/sparc/lib/bitops.S index 2b7228cb8c2..3dc61d5537c 100644 --- a/arch/sparc/lib/bitops.S +++ b/arch/sparc/lib/bitops.S | |||
@@ -22,7 +22,7 @@ test_and_set_bit: /* %o0=nr, %o1=addr */ | |||
22 | or %g7, %o2, %g1 | 22 | or %g7, %o2, %g1 |
23 | casx [%o1], %g7, %g1 | 23 | casx [%o1], %g7, %g1 |
24 | cmp %g7, %g1 | 24 | cmp %g7, %g1 |
25 | bne,pn %xcc, 2f | 25 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
26 | and %g7, %o2, %g2 | 26 | and %g7, %o2, %g2 |
27 | clr %o0 | 27 | clr %o0 |
28 | movrne %g2, 1, %o0 | 28 | movrne %g2, 1, %o0 |
@@ -45,7 +45,7 @@ test_and_clear_bit: /* %o0=nr, %o1=addr */ | |||
45 | andn %g7, %o2, %g1 | 45 | andn %g7, %o2, %g1 |
46 | casx [%o1], %g7, %g1 | 46 | casx [%o1], %g7, %g1 |
47 | cmp %g7, %g1 | 47 | cmp %g7, %g1 |
48 | bne,pn %xcc, 2f | 48 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
49 | and %g7, %o2, %g2 | 49 | and %g7, %o2, %g2 |
50 | clr %o0 | 50 | clr %o0 |
51 | movrne %g2, 1, %o0 | 51 | movrne %g2, 1, %o0 |
@@ -68,7 +68,7 @@ test_and_change_bit: /* %o0=nr, %o1=addr */ | |||
68 | xor %g7, %o2, %g1 | 68 | xor %g7, %o2, %g1 |
69 | casx [%o1], %g7, %g1 | 69 | casx [%o1], %g7, %g1 |
70 | cmp %g7, %g1 | 70 | cmp %g7, %g1 |
71 | bne,pn %xcc, 2f | 71 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
72 | and %g7, %o2, %g2 | 72 | and %g7, %o2, %g2 |
73 | clr %o0 | 73 | clr %o0 |
74 | movrne %g2, 1, %o0 | 74 | movrne %g2, 1, %o0 |
@@ -91,7 +91,7 @@ set_bit: /* %o0=nr, %o1=addr */ | |||
91 | or %g7, %o2, %g1 | 91 | or %g7, %o2, %g1 |
92 | casx [%o1], %g7, %g1 | 92 | casx [%o1], %g7, %g1 |
93 | cmp %g7, %g1 | 93 | cmp %g7, %g1 |
94 | bne,pn %xcc, 2f | 94 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
95 | nop | 95 | nop |
96 | retl | 96 | retl |
97 | nop | 97 | nop |
@@ -112,7 +112,7 @@ clear_bit: /* %o0=nr, %o1=addr */ | |||
112 | andn %g7, %o2, %g1 | 112 | andn %g7, %o2, %g1 |
113 | casx [%o1], %g7, %g1 | 113 | casx [%o1], %g7, %g1 |
114 | cmp %g7, %g1 | 114 | cmp %g7, %g1 |
115 | bne,pn %xcc, 2f | 115 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
116 | nop | 116 | nop |
117 | retl | 117 | retl |
118 | nop | 118 | nop |
@@ -133,7 +133,7 @@ change_bit: /* %o0=nr, %o1=addr */ | |||
133 | xor %g7, %o2, %g1 | 133 | xor %g7, %o2, %g1 |
134 | casx [%o1], %g7, %g1 | 134 | casx [%o1], %g7, %g1 |
135 | cmp %g7, %g1 | 135 | cmp %g7, %g1 |
136 | bne,pn %xcc, 2f | 136 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
137 | nop | 137 | nop |
138 | retl | 138 | retl |
139 | nop | 139 | nop |
diff --git a/arch/sparc/lib/rwsem_64.S b/arch/sparc/lib/rwsem_64.S deleted file mode 100644 index 91a7d29a79d..00000000000 --- a/arch/sparc/lib/rwsem_64.S +++ /dev/null | |||
@@ -1,163 +0,0 @@ | |||
1 | /* rwsem.S: RW semaphore assembler. | ||
2 | * | ||
3 | * Written by David S. Miller (davem@redhat.com), 2001. | ||
4 | * Derived from asm-i386/rwsem.h | ||
5 | */ | ||
6 | |||
7 | #include <asm/rwsem-const.h> | ||
8 | |||
9 | .section .sched.text, "ax" | ||
10 | |||
11 | .globl __down_read | ||
12 | __down_read: | ||
13 | 1: lduw [%o0], %g1 | ||
14 | add %g1, 1, %g7 | ||
15 | cas [%o0], %g1, %g7 | ||
16 | cmp %g1, %g7 | ||
17 | bne,pn %icc, 1b | ||
18 | add %g7, 1, %g7 | ||
19 | cmp %g7, 0 | ||
20 | bl,pn %icc, 3f | ||
21 | nop | ||
22 | 2: | ||
23 | retl | ||
24 | nop | ||
25 | 3: | ||
26 | save %sp, -192, %sp | ||
27 | call rwsem_down_read_failed | ||
28 | mov %i0, %o0 | ||
29 | ret | ||
30 | restore | ||
31 | .size __down_read, .-__down_read | ||
32 | |||
33 | .globl __down_read_trylock | ||
34 | __down_read_trylock: | ||
35 | 1: lduw [%o0], %g1 | ||
36 | add %g1, 1, %g7 | ||
37 | cmp %g7, 0 | ||
38 | bl,pn %icc, 2f | ||
39 | mov 0, %o1 | ||
40 | cas [%o0], %g1, %g7 | ||
41 | cmp %g1, %g7 | ||
42 | bne,pn %icc, 1b | ||
43 | mov 1, %o1 | ||
44 | 2: retl | ||
45 | mov %o1, %o0 | ||
46 | .size __down_read_trylock, .-__down_read_trylock | ||
47 | |||
48 | .globl __down_write | ||
49 | __down_write: | ||
50 | sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1 | ||
51 | or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1 | ||
52 | 1: | ||
53 | lduw [%o0], %g3 | ||
54 | add %g3, %g1, %g7 | ||
55 | cas [%o0], %g3, %g7 | ||
56 | cmp %g3, %g7 | ||
57 | bne,pn %icc, 1b | ||
58 | cmp %g7, 0 | ||
59 | bne,pn %icc, 3f | ||
60 | nop | ||
61 | 2: retl | ||
62 | nop | ||
63 | 3: | ||
64 | save %sp, -192, %sp | ||
65 | call rwsem_down_write_failed | ||
66 | mov %i0, %o0 | ||
67 | ret | ||
68 | restore | ||
69 | .size __down_write, .-__down_write | ||
70 | |||
71 | .globl __down_write_trylock | ||
72 | __down_write_trylock: | ||
73 | sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1 | ||
74 | or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1 | ||
75 | 1: | ||
76 | lduw [%o0], %g3 | ||
77 | cmp %g3, 0 | ||
78 | bne,pn %icc, 2f | ||
79 | mov 0, %o1 | ||
80 | add %g3, %g1, %g7 | ||
81 | cas [%o0], %g3, %g7 | ||
82 | cmp %g3, %g7 | ||
83 | bne,pn %icc, 1b | ||
84 | mov 1, %o1 | ||
85 | 2: retl | ||
86 | mov %o1, %o0 | ||
87 | .size __down_write_trylock, .-__down_write_trylock | ||
88 | |||
89 | .globl __up_read | ||
90 | __up_read: | ||
91 | 1: | ||
92 | lduw [%o0], %g1 | ||
93 | sub %g1, 1, %g7 | ||
94 | cas [%o0], %g1, %g7 | ||
95 | cmp %g1, %g7 | ||
96 | bne,pn %icc, 1b | ||
97 | cmp %g7, 0 | ||
98 | bl,pn %icc, 3f | ||
99 | nop | ||
100 | 2: retl | ||
101 | nop | ||
102 | 3: sethi %hi(RWSEM_ACTIVE_MASK), %g1 | ||
103 | sub %g7, 1, %g7 | ||
104 | or %g1, %lo(RWSEM_ACTIVE_MASK), %g1 | ||
105 | andcc %g7, %g1, %g0 | ||
106 | bne,pn %icc, 2b | ||
107 | nop | ||
108 | save %sp, -192, %sp | ||
109 | call rwsem_wake | ||
110 | mov %i0, %o0 | ||
111 | ret | ||
112 | restore | ||
113 | .size __up_read, .-__up_read | ||
114 | |||
115 | .globl __up_write | ||
116 | __up_write: | ||
117 | sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1 | ||
118 | or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1 | ||
119 | 1: | ||
120 | lduw [%o0], %g3 | ||
121 | sub %g3, %g1, %g7 | ||
122 | cas [%o0], %g3, %g7 | ||
123 | cmp %g3, %g7 | ||
124 | bne,pn %icc, 1b | ||
125 | sub %g7, %g1, %g7 | ||
126 | cmp %g7, 0 | ||
127 | bl,pn %icc, 3f | ||
128 | nop | ||
129 | 2: | ||
130 | retl | ||
131 | nop | ||
132 | 3: | ||
133 | save %sp, -192, %sp | ||
134 | call rwsem_wake | ||
135 | mov %i0, %o0 | ||
136 | ret | ||
137 | restore | ||
138 | .size __up_write, .-__up_write | ||
139 | |||
140 | .globl __downgrade_write | ||
141 | __downgrade_write: | ||
142 | sethi %hi(RWSEM_WAITING_BIAS), %g1 | ||
143 | or %g1, %lo(RWSEM_WAITING_BIAS), %g1 | ||
144 | 1: | ||
145 | lduw [%o0], %g3 | ||
146 | sub %g3, %g1, %g7 | ||
147 | cas [%o0], %g3, %g7 | ||
148 | cmp %g3, %g7 | ||
149 | bne,pn %icc, 1b | ||
150 | sub %g7, %g1, %g7 | ||
151 | cmp %g7, 0 | ||
152 | bl,pn %icc, 3f | ||
153 | nop | ||
154 | 2: | ||
155 | retl | ||
156 | nop | ||
157 | 3: | ||
158 | save %sp, -192, %sp | ||
159 | call rwsem_downgrade_wake | ||
160 | mov %i0, %o0 | ||
161 | ret | ||
162 | restore | ||
163 | .size __downgrade_write, .-__downgrade_write | ||
diff --git a/arch/sparc/prom/cif.S b/arch/sparc/prom/cif.S index 5f27ad779c0..9c86b4b7d42 100644 --- a/arch/sparc/prom/cif.S +++ b/arch/sparc/prom/cif.S | |||
@@ -9,18 +9,18 @@ | |||
9 | #include <asm/thread_info.h> | 9 | #include <asm/thread_info.h> |
10 | 10 | ||
11 | .text | 11 | .text |
12 | .globl prom_cif_interface | 12 | .globl prom_cif_direct |
13 | prom_cif_interface: | 13 | prom_cif_direct: |
14 | sethi %hi(p1275buf), %o0 | 14 | sethi %hi(p1275buf), %o1 |
15 | or %o0, %lo(p1275buf), %o0 | 15 | or %o1, %lo(p1275buf), %o1 |
16 | ldx [%o0 + 0x010], %o1 ! prom_cif_stack | 16 | ldx [%o1 + 0x0010], %o2 ! prom_cif_stack |
17 | save %o1, -192, %sp | 17 | save %o2, -192, %sp |
18 | ldx [%i0 + 0x008], %l2 ! prom_cif_handler | 18 | ldx [%i1 + 0x0008], %l2 ! prom_cif_handler |
19 | mov %g4, %l0 | 19 | mov %g4, %l0 |
20 | mov %g5, %l1 | 20 | mov %g5, %l1 |
21 | mov %g6, %l3 | 21 | mov %g6, %l3 |
22 | call %l2 | 22 | call %l2 |
23 | add %i0, 0x018, %o0 ! prom_args | 23 | mov %i0, %o0 ! prom_args |
24 | mov %l0, %g4 | 24 | mov %l0, %g4 |
25 | mov %l1, %g5 | 25 | mov %l1, %g5 |
26 | mov %l3, %g6 | 26 | mov %l3, %g6 |
diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c index f55d58a8a15..10322dc2f55 100644 --- a/arch/sparc/prom/console_64.c +++ b/arch/sparc/prom/console_64.c | |||
@@ -21,14 +21,22 @@ extern int prom_stdin, prom_stdout; | |||
21 | inline int | 21 | inline int |
22 | prom_nbgetchar(void) | 22 | prom_nbgetchar(void) |
23 | { | 23 | { |
24 | unsigned long args[7]; | ||
24 | char inc; | 25 | char inc; |
25 | 26 | ||
26 | if (p1275_cmd("read", P1275_ARG(1,P1275_ARG_OUT_BUF)| | 27 | args[0] = (unsigned long) "read"; |
27 | P1275_INOUT(3,1), | 28 | args[1] = 3; |
28 | prom_stdin, &inc, P1275_SIZE(1)) == 1) | 29 | args[2] = 1; |
30 | args[3] = (unsigned int) prom_stdin; | ||
31 | args[4] = (unsigned long) &inc; | ||
32 | args[5] = 1; | ||
33 | args[6] = (unsigned long) -1; | ||
34 | |||
35 | p1275_cmd_direct(args); | ||
36 | |||
37 | if (args[6] == 1) | ||
29 | return inc; | 38 | return inc; |
30 | else | 39 | return -1; |
31 | return -1; | ||
32 | } | 40 | } |
33 | 41 | ||
34 | /* Non blocking put character to console device, returns -1 if | 42 | /* Non blocking put character to console device, returns -1 if |
@@ -37,12 +45,22 @@ prom_nbgetchar(void) | |||
37 | inline int | 45 | inline int |
38 | prom_nbputchar(char c) | 46 | prom_nbputchar(char c) |
39 | { | 47 | { |
48 | unsigned long args[7]; | ||
40 | char outc; | 49 | char outc; |
41 | 50 | ||
42 | outc = c; | 51 | outc = c; |
43 | if (p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)| | 52 | |
44 | P1275_INOUT(3,1), | 53 | args[0] = (unsigned long) "write"; |
45 | prom_stdout, &outc, P1275_SIZE(1)) == 1) | 54 | args[1] = 3; |
55 | args[2] = 1; | ||
56 | args[3] = (unsigned int) prom_stdout; | ||
57 | args[4] = (unsigned long) &outc; | ||
58 | args[5] = 1; | ||
59 | args[6] = (unsigned long) -1; | ||
60 | |||
61 | p1275_cmd_direct(args); | ||
62 | |||
63 | if (args[6] == 1) | ||
46 | return 0; | 64 | return 0; |
47 | else | 65 | else |
48 | return -1; | 66 | return -1; |
@@ -67,7 +85,15 @@ prom_putchar(char c) | |||
67 | void | 85 | void |
68 | prom_puts(const char *s, int len) | 86 | prom_puts(const char *s, int len) |
69 | { | 87 | { |
70 | p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)| | 88 | unsigned long args[7]; |
71 | P1275_INOUT(3,1), | 89 | |
72 | prom_stdout, s, P1275_SIZE(len)); | 90 | args[0] = (unsigned long) "write"; |
91 | args[1] = 3; | ||
92 | args[2] = 1; | ||
93 | args[3] = (unsigned int) prom_stdout; | ||
94 | args[4] = (unsigned long) s; | ||
95 | args[5] = len; | ||
96 | args[6] = (unsigned long) -1; | ||
97 | |||
98 | p1275_cmd_direct(args); | ||
73 | } | 99 | } |
diff --git a/arch/sparc/prom/devops_64.c b/arch/sparc/prom/devops_64.c index 9dbd803e46e..a017119e7ef 100644 --- a/arch/sparc/prom/devops_64.c +++ b/arch/sparc/prom/devops_64.c | |||
@@ -18,16 +18,32 @@ | |||
18 | int | 18 | int |
19 | prom_devopen(const char *dstr) | 19 | prom_devopen(const char *dstr) |
20 | { | 20 | { |
21 | return p1275_cmd ("open", P1275_ARG(0,P1275_ARG_IN_STRING)| | 21 | unsigned long args[5]; |
22 | P1275_INOUT(1,1), | 22 | |
23 | dstr); | 23 | args[0] = (unsigned long) "open"; |
24 | args[1] = 1; | ||
25 | args[2] = 1; | ||
26 | args[3] = (unsigned long) dstr; | ||
27 | args[4] = (unsigned long) -1; | ||
28 | |||
29 | p1275_cmd_direct(args); | ||
30 | |||
31 | return (int) args[4]; | ||
24 | } | 32 | } |
25 | 33 | ||
26 | /* Close the device described by device handle 'dhandle'. */ | 34 | /* Close the device described by device handle 'dhandle'. */ |
27 | int | 35 | int |
28 | prom_devclose(int dhandle) | 36 | prom_devclose(int dhandle) |
29 | { | 37 | { |
30 | p1275_cmd ("close", P1275_INOUT(1,0), dhandle); | 38 | unsigned long args[4]; |
39 | |||
40 | args[0] = (unsigned long) "close"; | ||
41 | args[1] = 1; | ||
42 | args[2] = 0; | ||
43 | args[3] = (unsigned int) dhandle; | ||
44 | |||
45 | p1275_cmd_direct(args); | ||
46 | |||
31 | return 0; | 47 | return 0; |
32 | } | 48 | } |
33 | 49 | ||
@@ -37,5 +53,15 @@ prom_devclose(int dhandle) | |||
37 | void | 53 | void |
38 | prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) | 54 | prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) |
39 | { | 55 | { |
40 | p1275_cmd ("seek", P1275_INOUT(3,1), dhandle, seekhi, seeklo); | 56 | unsigned long args[7]; |
57 | |||
58 | args[0] = (unsigned long) "seek"; | ||
59 | args[1] = 3; | ||
60 | args[2] = 1; | ||
61 | args[3] = (unsigned int) dhandle; | ||
62 | args[4] = seekhi; | ||
63 | args[5] = seeklo; | ||
64 | args[6] = (unsigned long) -1; | ||
65 | |||
66 | p1275_cmd_direct(args); | ||
41 | } | 67 | } |
diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c index 39fc6af21b7..6cb1581d6ae 100644 --- a/arch/sparc/prom/misc_64.c +++ b/arch/sparc/prom/misc_64.c | |||
@@ -20,10 +20,17 @@ | |||
20 | 20 | ||
21 | int prom_service_exists(const char *service_name) | 21 | int prom_service_exists(const char *service_name) |
22 | { | 22 | { |
23 | int err = p1275_cmd("test", P1275_ARG(0, P1275_ARG_IN_STRING) | | 23 | unsigned long args[5]; |
24 | P1275_INOUT(1, 1), service_name); | ||
25 | 24 | ||
26 | if (err) | 25 | args[0] = (unsigned long) "test"; |
26 | args[1] = 1; | ||
27 | args[2] = 1; | ||
28 | args[3] = (unsigned long) service_name; | ||
29 | args[4] = (unsigned long) -1; | ||
30 | |||
31 | p1275_cmd_direct(args); | ||
32 | |||
33 | if (args[4]) | ||
27 | return 0; | 34 | return 0; |
28 | return 1; | 35 | return 1; |
29 | } | 36 | } |
@@ -31,30 +38,47 @@ int prom_service_exists(const char *service_name) | |||
31 | void prom_sun4v_guest_soft_state(void) | 38 | void prom_sun4v_guest_soft_state(void) |
32 | { | 39 | { |
33 | const char *svc = "SUNW,soft-state-supported"; | 40 | const char *svc = "SUNW,soft-state-supported"; |
41 | unsigned long args[3]; | ||
34 | 42 | ||
35 | if (!prom_service_exists(svc)) | 43 | if (!prom_service_exists(svc)) |
36 | return; | 44 | return; |
37 | p1275_cmd(svc, P1275_INOUT(0, 0)); | 45 | args[0] = (unsigned long) svc; |
46 | args[1] = 0; | ||
47 | args[2] = 0; | ||
48 | p1275_cmd_direct(args); | ||
38 | } | 49 | } |
39 | 50 | ||
40 | /* Reset and reboot the machine with the command 'bcommand'. */ | 51 | /* Reset and reboot the machine with the command 'bcommand'. */ |
41 | void prom_reboot(const char *bcommand) | 52 | void prom_reboot(const char *bcommand) |
42 | { | 53 | { |
54 | unsigned long args[4]; | ||
55 | |||
43 | #ifdef CONFIG_SUN_LDOMS | 56 | #ifdef CONFIG_SUN_LDOMS |
44 | if (ldom_domaining_enabled) | 57 | if (ldom_domaining_enabled) |
45 | ldom_reboot(bcommand); | 58 | ldom_reboot(bcommand); |
46 | #endif | 59 | #endif |
47 | p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) | | 60 | args[0] = (unsigned long) "boot"; |
48 | P1275_INOUT(1, 0), bcommand); | 61 | args[1] = 1; |
62 | args[2] = 0; | ||
63 | args[3] = (unsigned long) bcommand; | ||
64 | |||
65 | p1275_cmd_direct(args); | ||
49 | } | 66 | } |
50 | 67 | ||
51 | /* Forth evaluate the expression contained in 'fstring'. */ | 68 | /* Forth evaluate the expression contained in 'fstring'. */ |
52 | void prom_feval(const char *fstring) | 69 | void prom_feval(const char *fstring) |
53 | { | 70 | { |
71 | unsigned long args[5]; | ||
72 | |||
54 | if (!fstring || fstring[0] == 0) | 73 | if (!fstring || fstring[0] == 0) |
55 | return; | 74 | return; |
56 | p1275_cmd("interpret", P1275_ARG(0, P1275_ARG_IN_STRING) | | 75 | args[0] = (unsigned long) "interpret"; |
57 | P1275_INOUT(1, 1), fstring); | 76 | args[1] = 1; |
77 | args[2] = 1; | ||
78 | args[3] = (unsigned long) fstring; | ||
79 | args[4] = (unsigned long) -1; | ||
80 | |||
81 | p1275_cmd_direct(args); | ||
58 | } | 82 | } |
59 | EXPORT_SYMBOL(prom_feval); | 83 | EXPORT_SYMBOL(prom_feval); |
60 | 84 | ||
@@ -68,6 +92,7 @@ extern void smp_release(void); | |||
68 | */ | 92 | */ |
69 | void prom_cmdline(void) | 93 | void prom_cmdline(void) |
70 | { | 94 | { |
95 | unsigned long args[3]; | ||
71 | unsigned long flags; | 96 | unsigned long flags; |
72 | 97 | ||
73 | local_irq_save(flags); | 98 | local_irq_save(flags); |
@@ -76,7 +101,11 @@ void prom_cmdline(void) | |||
76 | smp_capture(); | 101 | smp_capture(); |
77 | #endif | 102 | #endif |
78 | 103 | ||
79 | p1275_cmd("enter", P1275_INOUT(0, 0)); | 104 | args[0] = (unsigned long) "enter"; |
105 | args[1] = 0; | ||
106 | args[2] = 0; | ||
107 | |||
108 | p1275_cmd_direct(args); | ||
80 | 109 | ||
81 | #ifdef CONFIG_SMP | 110 | #ifdef CONFIG_SMP |
82 | smp_release(); | 111 | smp_release(); |
@@ -90,22 +119,32 @@ void prom_cmdline(void) | |||
90 | */ | 119 | */ |
91 | void notrace prom_halt(void) | 120 | void notrace prom_halt(void) |
92 | { | 121 | { |
122 | unsigned long args[3]; | ||
123 | |||
93 | #ifdef CONFIG_SUN_LDOMS | 124 | #ifdef CONFIG_SUN_LDOMS |
94 | if (ldom_domaining_enabled) | 125 | if (ldom_domaining_enabled) |
95 | ldom_power_off(); | 126 | ldom_power_off(); |
96 | #endif | 127 | #endif |
97 | again: | 128 | again: |
98 | p1275_cmd("exit", P1275_INOUT(0, 0)); | 129 | args[0] = (unsigned long) "exit"; |
130 | args[1] = 0; | ||
131 | args[2] = 0; | ||
132 | p1275_cmd_direct(args); | ||
99 | goto again; /* PROM is out to get me -DaveM */ | 133 | goto again; /* PROM is out to get me -DaveM */ |
100 | } | 134 | } |
101 | 135 | ||
102 | void prom_halt_power_off(void) | 136 | void prom_halt_power_off(void) |
103 | { | 137 | { |
138 | unsigned long args[3]; | ||
139 | |||
104 | #ifdef CONFIG_SUN_LDOMS | 140 | #ifdef CONFIG_SUN_LDOMS |
105 | if (ldom_domaining_enabled) | 141 | if (ldom_domaining_enabled) |
106 | ldom_power_off(); | 142 | ldom_power_off(); |
107 | #endif | 143 | #endif |
108 | p1275_cmd("SUNW,power-off", P1275_INOUT(0, 0)); | 144 | args[0] = (unsigned long) "SUNW,power-off"; |
145 | args[1] = 0; | ||
146 | args[2] = 0; | ||
147 | p1275_cmd_direct(args); | ||
109 | 148 | ||
110 | /* if nothing else helps, we just halt */ | 149 | /* if nothing else helps, we just halt */ |
111 | prom_halt(); | 150 | prom_halt(); |
@@ -114,10 +153,15 @@ void prom_halt_power_off(void) | |||
114 | /* Set prom sync handler to call function 'funcp'. */ | 153 | /* Set prom sync handler to call function 'funcp'. */ |
115 | void prom_setcallback(callback_func_t funcp) | 154 | void prom_setcallback(callback_func_t funcp) |
116 | { | 155 | { |
156 | unsigned long args[5]; | ||
117 | if (!funcp) | 157 | if (!funcp) |
118 | return; | 158 | return; |
119 | p1275_cmd("set-callback", P1275_ARG(0, P1275_ARG_IN_FUNCTION) | | 159 | args[0] = (unsigned long) "set-callback"; |
120 | P1275_INOUT(1, 1), funcp); | 160 | args[1] = 1; |
161 | args[2] = 1; | ||
162 | args[3] = (unsigned long) funcp; | ||
163 | args[4] = (unsigned long) -1; | ||
164 | p1275_cmd_direct(args); | ||
121 | } | 165 | } |
122 | 166 | ||
123 | /* Get the idprom and stuff it into buffer 'idbuf'. Returns the | 167 | /* Get the idprom and stuff it into buffer 'idbuf'. Returns the |
@@ -173,57 +217,61 @@ static int prom_get_memory_ihandle(void) | |||
173 | } | 217 | } |
174 | 218 | ||
175 | /* Load explicit I/D TLB entries. */ | 219 | /* Load explicit I/D TLB entries. */ |
220 | static long tlb_load(const char *type, unsigned long index, | ||
221 | unsigned long tte_data, unsigned long vaddr) | ||
222 | { | ||
223 | unsigned long args[9]; | ||
224 | |||
225 | args[0] = (unsigned long) prom_callmethod_name; | ||
226 | args[1] = 5; | ||
227 | args[2] = 1; | ||
228 | args[3] = (unsigned long) type; | ||
229 | args[4] = (unsigned int) prom_get_mmu_ihandle(); | ||
230 | args[5] = vaddr; | ||
231 | args[6] = tte_data; | ||
232 | args[7] = index; | ||
233 | args[8] = (unsigned long) -1; | ||
234 | |||
235 | p1275_cmd_direct(args); | ||
236 | |||
237 | return (long) args[8]; | ||
238 | } | ||
239 | |||
176 | long prom_itlb_load(unsigned long index, | 240 | long prom_itlb_load(unsigned long index, |
177 | unsigned long tte_data, | 241 | unsigned long tte_data, |
178 | unsigned long vaddr) | 242 | unsigned long vaddr) |
179 | { | 243 | { |
180 | return p1275_cmd(prom_callmethod_name, | 244 | return tlb_load("SUNW,itlb-load", index, tte_data, vaddr); |
181 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | ||
182 | P1275_ARG(2, P1275_ARG_IN_64B) | | ||
183 | P1275_ARG(3, P1275_ARG_IN_64B) | | ||
184 | P1275_INOUT(5, 1)), | ||
185 | "SUNW,itlb-load", | ||
186 | prom_get_mmu_ihandle(), | ||
187 | /* And then our actual args are pushed backwards. */ | ||
188 | vaddr, | ||
189 | tte_data, | ||
190 | index); | ||
191 | } | 245 | } |
192 | 246 | ||
193 | long prom_dtlb_load(unsigned long index, | 247 | long prom_dtlb_load(unsigned long index, |
194 | unsigned long tte_data, | 248 | unsigned long tte_data, |
195 | unsigned long vaddr) | 249 | unsigned long vaddr) |
196 | { | 250 | { |
197 | return p1275_cmd(prom_callmethod_name, | 251 | return tlb_load("SUNW,dtlb-load", index, tte_data, vaddr); |
198 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | ||
199 | P1275_ARG(2, P1275_ARG_IN_64B) | | ||
200 | P1275_ARG(3, P1275_ARG_IN_64B) | | ||
201 | P1275_INOUT(5, 1)), | ||
202 | "SUNW,dtlb-load", | ||
203 | prom_get_mmu_ihandle(), | ||
204 | /* And then our actual args are pushed backwards. */ | ||
205 | vaddr, | ||
206 | tte_data, | ||
207 | index); | ||
208 | } | 252 | } |
209 | 253 | ||
210 | int prom_map(int mode, unsigned long size, | 254 | int prom_map(int mode, unsigned long size, |
211 | unsigned long vaddr, unsigned long paddr) | 255 | unsigned long vaddr, unsigned long paddr) |
212 | { | 256 | { |
213 | int ret = p1275_cmd(prom_callmethod_name, | 257 | unsigned long args[11]; |
214 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | 258 | int ret; |
215 | P1275_ARG(3, P1275_ARG_IN_64B) | | 259 | |
216 | P1275_ARG(4, P1275_ARG_IN_64B) | | 260 | args[0] = (unsigned long) prom_callmethod_name; |
217 | P1275_ARG(6, P1275_ARG_IN_64B) | | 261 | args[1] = 7; |
218 | P1275_INOUT(7, 1)), | 262 | args[2] = 1; |
219 | prom_map_name, | 263 | args[3] = (unsigned long) prom_map_name; |
220 | prom_get_mmu_ihandle(), | 264 | args[4] = (unsigned int) prom_get_mmu_ihandle(); |
221 | mode, | 265 | args[5] = (unsigned int) mode; |
222 | size, | 266 | args[6] = size; |
223 | vaddr, | 267 | args[7] = vaddr; |
224 | 0, | 268 | args[8] = 0; |
225 | paddr); | 269 | args[9] = paddr; |
226 | 270 | args[10] = (unsigned long) -1; | |
271 | |||
272 | p1275_cmd_direct(args); | ||
273 | |||
274 | ret = (int) args[10]; | ||
227 | if (ret == 0) | 275 | if (ret == 0) |
228 | ret = -1; | 276 | ret = -1; |
229 | return ret; | 277 | return ret; |
@@ -231,40 +279,51 @@ int prom_map(int mode, unsigned long size, | |||
231 | 279 | ||
232 | void prom_unmap(unsigned long size, unsigned long vaddr) | 280 | void prom_unmap(unsigned long size, unsigned long vaddr) |
233 | { | 281 | { |
234 | p1275_cmd(prom_callmethod_name, | 282 | unsigned long args[7]; |
235 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | 283 | |
236 | P1275_ARG(2, P1275_ARG_IN_64B) | | 284 | args[0] = (unsigned long) prom_callmethod_name; |
237 | P1275_ARG(3, P1275_ARG_IN_64B) | | 285 | args[1] = 4; |
238 | P1275_INOUT(4, 0)), | 286 | args[2] = 0; |
239 | prom_unmap_name, | 287 | args[3] = (unsigned long) prom_unmap_name; |
240 | prom_get_mmu_ihandle(), | 288 | args[4] = (unsigned int) prom_get_mmu_ihandle(); |
241 | size, | 289 | args[5] = size; |
242 | vaddr); | 290 | args[6] = vaddr; |
291 | |||
292 | p1275_cmd_direct(args); | ||
243 | } | 293 | } |
244 | 294 | ||
245 | /* Set aside physical memory which is not touched or modified | 295 | /* Set aside physical memory which is not touched or modified |
246 | * across soft resets. | 296 | * across soft resets. |
247 | */ | 297 | */ |
248 | unsigned long prom_retain(const char *name, | 298 | int prom_retain(const char *name, unsigned long size, |
249 | unsigned long pa_low, unsigned long pa_high, | 299 | unsigned long align, unsigned long *paddr) |
250 | long size, long align) | ||
251 | { | 300 | { |
252 | /* XXX I don't think we return multiple values correctly. | 301 | unsigned long args[11]; |
253 | * XXX OBP supposedly returns pa_low/pa_high here, how does | 302 | |
254 | * XXX it work? | 303 | args[0] = (unsigned long) prom_callmethod_name; |
304 | args[1] = 5; | ||
305 | args[2] = 3; | ||
306 | args[3] = (unsigned long) "SUNW,retain"; | ||
307 | args[4] = (unsigned int) prom_get_memory_ihandle(); | ||
308 | args[5] = align; | ||
309 | args[6] = size; | ||
310 | args[7] = (unsigned long) name; | ||
311 | args[8] = (unsigned long) -1; | ||
312 | args[9] = (unsigned long) -1; | ||
313 | args[10] = (unsigned long) -1; | ||
314 | |||
315 | p1275_cmd_direct(args); | ||
316 | |||
317 | if (args[8]) | ||
318 | return (int) args[8]; | ||
319 | |||
320 | /* Next we get "phys_high" then "phys_low". On 64-bit | ||
321 | * the phys_high cell is don't care since the phys_low | ||
322 | * cell has the full value. | ||
255 | */ | 323 | */ |
324 | *paddr = args[10]; | ||
256 | 325 | ||
257 | /* If align is zero, the pa_low/pa_high args are passed, | 326 | return 0; |
258 | * else they are not. | ||
259 | */ | ||
260 | if (align == 0) | ||
261 | return p1275_cmd("SUNW,retain", | ||
262 | (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(5, 2)), | ||
263 | name, pa_low, pa_high, size, align); | ||
264 | else | ||
265 | return p1275_cmd("SUNW,retain", | ||
266 | (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(3, 2)), | ||
267 | name, size, align); | ||
268 | } | 327 | } |
269 | 328 | ||
270 | /* Get "Unumber" string for the SIMM at the given | 329 | /* Get "Unumber" string for the SIMM at the given |
@@ -277,62 +336,129 @@ int prom_getunumber(int syndrome_code, | |||
277 | unsigned long phys_addr, | 336 | unsigned long phys_addr, |
278 | char *buf, int buflen) | 337 | char *buf, int buflen) |
279 | { | 338 | { |
280 | return p1275_cmd(prom_callmethod_name, | 339 | unsigned long args[12]; |
281 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | 340 | |
282 | P1275_ARG(3, P1275_ARG_OUT_BUF) | | 341 | args[0] = (unsigned long) prom_callmethod_name; |
283 | P1275_ARG(6, P1275_ARG_IN_64B) | | 342 | args[1] = 7; |
284 | P1275_INOUT(8, 2)), | 343 | args[2] = 2; |
285 | "SUNW,get-unumber", prom_get_memory_ihandle(), | 344 | args[3] = (unsigned long) "SUNW,get-unumber"; |
286 | buflen, buf, P1275_SIZE(buflen), | 345 | args[4] = (unsigned int) prom_get_memory_ihandle(); |
287 | 0, phys_addr, syndrome_code); | 346 | args[5] = buflen; |
347 | args[6] = (unsigned long) buf; | ||
348 | args[7] = 0; | ||
349 | args[8] = phys_addr; | ||
350 | args[9] = (unsigned int) syndrome_code; | ||
351 | args[10] = (unsigned long) -1; | ||
352 | args[11] = (unsigned long) -1; | ||
353 | |||
354 | p1275_cmd_direct(args); | ||
355 | |||
356 | return (int) args[10]; | ||
288 | } | 357 | } |
289 | 358 | ||
290 | /* Power management extensions. */ | 359 | /* Power management extensions. */ |
291 | void prom_sleepself(void) | 360 | void prom_sleepself(void) |
292 | { | 361 | { |
293 | p1275_cmd("SUNW,sleep-self", P1275_INOUT(0, 0)); | 362 | unsigned long args[3]; |
363 | |||
364 | args[0] = (unsigned long) "SUNW,sleep-self"; | ||
365 | args[1] = 0; | ||
366 | args[2] = 0; | ||
367 | p1275_cmd_direct(args); | ||
294 | } | 368 | } |
295 | 369 | ||
296 | int prom_sleepsystem(void) | 370 | int prom_sleepsystem(void) |
297 | { | 371 | { |
298 | return p1275_cmd("SUNW,sleep-system", P1275_INOUT(0, 1)); | 372 | unsigned long args[4]; |
373 | |||
374 | args[0] = (unsigned long) "SUNW,sleep-system"; | ||
375 | args[1] = 0; | ||
376 | args[2] = 1; | ||
377 | args[3] = (unsigned long) -1; | ||
378 | p1275_cmd_direct(args); | ||
379 | |||
380 | return (int) args[3]; | ||
299 | } | 381 | } |
300 | 382 | ||
301 | int prom_wakeupsystem(void) | 383 | int prom_wakeupsystem(void) |
302 | { | 384 | { |
303 | return p1275_cmd("SUNW,wakeup-system", P1275_INOUT(0, 1)); | 385 | unsigned long args[4]; |
386 | |||
387 | args[0] = (unsigned long) "SUNW,wakeup-system"; | ||
388 | args[1] = 0; | ||
389 | args[2] = 1; | ||
390 | args[3] = (unsigned long) -1; | ||
391 | p1275_cmd_direct(args); | ||
392 | |||
393 | return (int) args[3]; | ||
304 | } | 394 | } |
305 | 395 | ||
306 | #ifdef CONFIG_SMP | 396 | #ifdef CONFIG_SMP |
307 | void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg) | 397 | void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg) |
308 | { | 398 | { |
309 | p1275_cmd("SUNW,start-cpu", P1275_INOUT(3, 0), cpunode, pc, arg); | 399 | unsigned long args[6]; |
400 | |||
401 | args[0] = (unsigned long) "SUNW,start-cpu"; | ||
402 | args[1] = 3; | ||
403 | args[2] = 0; | ||
404 | args[3] = (unsigned int) cpunode; | ||
405 | args[4] = pc; | ||
406 | args[5] = arg; | ||
407 | p1275_cmd_direct(args); | ||
310 | } | 408 | } |
311 | 409 | ||
312 | void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg) | 410 | void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg) |
313 | { | 411 | { |
314 | p1275_cmd("SUNW,start-cpu-by-cpuid", P1275_INOUT(3, 0), | 412 | unsigned long args[6]; |
315 | cpuid, pc, arg); | 413 | |
414 | args[0] = (unsigned long) "SUNW,start-cpu-by-cpuid"; | ||
415 | args[1] = 3; | ||
416 | args[2] = 0; | ||
417 | args[3] = (unsigned int) cpuid; | ||
418 | args[4] = pc; | ||
419 | args[5] = arg; | ||
420 | p1275_cmd_direct(args); | ||
316 | } | 421 | } |
317 | 422 | ||
318 | void prom_stopcpu_cpuid(int cpuid) | 423 | void prom_stopcpu_cpuid(int cpuid) |
319 | { | 424 | { |
320 | p1275_cmd("SUNW,stop-cpu-by-cpuid", P1275_INOUT(1, 0), | 425 | unsigned long args[4]; |
321 | cpuid); | 426 | |
427 | args[0] = (unsigned long) "SUNW,stop-cpu-by-cpuid"; | ||
428 | args[1] = 1; | ||
429 | args[2] = 0; | ||
430 | args[3] = (unsigned int) cpuid; | ||
431 | p1275_cmd_direct(args); | ||
322 | } | 432 | } |
323 | 433 | ||
324 | void prom_stopself(void) | 434 | void prom_stopself(void) |
325 | { | 435 | { |
326 | p1275_cmd("SUNW,stop-self", P1275_INOUT(0, 0)); | 436 | unsigned long args[3]; |
437 | |||
438 | args[0] = (unsigned long) "SUNW,stop-self"; | ||
439 | args[1] = 0; | ||
440 | args[2] = 0; | ||
441 | p1275_cmd_direct(args); | ||
327 | } | 442 | } |
328 | 443 | ||
329 | void prom_idleself(void) | 444 | void prom_idleself(void) |
330 | { | 445 | { |
331 | p1275_cmd("SUNW,idle-self", P1275_INOUT(0, 0)); | 446 | unsigned long args[3]; |
447 | |||
448 | args[0] = (unsigned long) "SUNW,idle-self"; | ||
449 | args[1] = 0; | ||
450 | args[2] = 0; | ||
451 | p1275_cmd_direct(args); | ||
332 | } | 452 | } |
333 | 453 | ||
334 | void prom_resumecpu(int cpunode) | 454 | void prom_resumecpu(int cpunode) |
335 | { | 455 | { |
336 | p1275_cmd("SUNW,resume-cpu", P1275_INOUT(1, 0), cpunode); | 456 | unsigned long args[4]; |
457 | |||
458 | args[0] = (unsigned long) "SUNW,resume-cpu"; | ||
459 | args[1] = 1; | ||
460 | args[2] = 0; | ||
461 | args[3] = (unsigned int) cpunode; | ||
462 | p1275_cmd_direct(args); | ||
337 | } | 463 | } |
338 | #endif | 464 | #endif |
diff --git a/arch/sparc/prom/p1275.c b/arch/sparc/prom/p1275.c index 2d8b70d397f..fa6e4e219b9 100644 --- a/arch/sparc/prom/p1275.c +++ b/arch/sparc/prom/p1275.c | |||
@@ -22,13 +22,11 @@ struct { | |||
22 | long prom_callback; /* 0x00 */ | 22 | long prom_callback; /* 0x00 */ |
23 | void (*prom_cif_handler)(long *); /* 0x08 */ | 23 | void (*prom_cif_handler)(long *); /* 0x08 */ |
24 | unsigned long prom_cif_stack; /* 0x10 */ | 24 | unsigned long prom_cif_stack; /* 0x10 */ |
25 | unsigned long prom_args [23]; /* 0x18 */ | ||
26 | char prom_buffer [3000]; | ||
27 | } p1275buf; | 25 | } p1275buf; |
28 | 26 | ||
29 | extern void prom_world(int); | 27 | extern void prom_world(int); |
30 | 28 | ||
31 | extern void prom_cif_interface(void); | 29 | extern void prom_cif_direct(unsigned long *args); |
32 | extern void prom_cif_callback(void); | 30 | extern void prom_cif_callback(void); |
33 | 31 | ||
34 | /* | 32 | /* |
@@ -36,114 +34,20 @@ extern void prom_cif_callback(void); | |||
36 | */ | 34 | */ |
37 | DEFINE_RAW_SPINLOCK(prom_entry_lock); | 35 | DEFINE_RAW_SPINLOCK(prom_entry_lock); |
38 | 36 | ||
39 | long p1275_cmd(const char *service, long fmt, ...) | 37 | void p1275_cmd_direct(unsigned long *args) |
40 | { | 38 | { |
41 | char *p, *q; | ||
42 | unsigned long flags; | 39 | unsigned long flags; |
43 | int nargs, nrets, i; | ||
44 | va_list list; | ||
45 | long attrs, x; | ||
46 | |||
47 | p = p1275buf.prom_buffer; | ||
48 | 40 | ||
49 | raw_local_save_flags(flags); | 41 | raw_local_save_flags(flags); |
50 | raw_local_irq_restore(PIL_NMI); | 42 | raw_local_irq_restore(PIL_NMI); |
51 | raw_spin_lock(&prom_entry_lock); | 43 | raw_spin_lock(&prom_entry_lock); |
52 | 44 | ||
53 | p1275buf.prom_args[0] = (unsigned long)p; /* service */ | ||
54 | strcpy (p, service); | ||
55 | p = (char *)(((long)(strchr (p, 0) + 8)) & ~7); | ||
56 | p1275buf.prom_args[1] = nargs = (fmt & 0x0f); /* nargs */ | ||
57 | p1275buf.prom_args[2] = nrets = ((fmt & 0xf0) >> 4); /* nrets */ | ||
58 | attrs = fmt >> 8; | ||
59 | va_start(list, fmt); | ||
60 | for (i = 0; i < nargs; i++, attrs >>= 3) { | ||
61 | switch (attrs & 0x7) { | ||
62 | case P1275_ARG_NUMBER: | ||
63 | p1275buf.prom_args[i + 3] = | ||
64 | (unsigned)va_arg(list, long); | ||
65 | break; | ||
66 | case P1275_ARG_IN_64B: | ||
67 | p1275buf.prom_args[i + 3] = | ||
68 | va_arg(list, unsigned long); | ||
69 | break; | ||
70 | case P1275_ARG_IN_STRING: | ||
71 | strcpy (p, va_arg(list, char *)); | ||
72 | p1275buf.prom_args[i + 3] = (unsigned long)p; | ||
73 | p = (char *)(((long)(strchr (p, 0) + 8)) & ~7); | ||
74 | break; | ||
75 | case P1275_ARG_OUT_BUF: | ||
76 | (void) va_arg(list, char *); | ||
77 | p1275buf.prom_args[i + 3] = (unsigned long)p; | ||
78 | x = va_arg(list, long); | ||
79 | i++; attrs >>= 3; | ||
80 | p = (char *)(((long)(p + (int)x + 7)) & ~7); | ||
81 | p1275buf.prom_args[i + 3] = x; | ||
82 | break; | ||
83 | case P1275_ARG_IN_BUF: | ||
84 | q = va_arg(list, char *); | ||
85 | p1275buf.prom_args[i + 3] = (unsigned long)p; | ||
86 | x = va_arg(list, long); | ||
87 | i++; attrs >>= 3; | ||
88 | memcpy (p, q, (int)x); | ||
89 | p = (char *)(((long)(p + (int)x + 7)) & ~7); | ||
90 | p1275buf.prom_args[i + 3] = x; | ||
91 | break; | ||
92 | case P1275_ARG_OUT_32B: | ||
93 | (void) va_arg(list, char *); | ||
94 | p1275buf.prom_args[i + 3] = (unsigned long)p; | ||
95 | p += 32; | ||
96 | break; | ||
97 | case P1275_ARG_IN_FUNCTION: | ||
98 | p1275buf.prom_args[i + 3] = | ||
99 | (unsigned long)prom_cif_callback; | ||
100 | p1275buf.prom_callback = va_arg(list, long); | ||
101 | break; | ||
102 | } | ||
103 | } | ||
104 | va_end(list); | ||
105 | |||
106 | prom_world(1); | 45 | prom_world(1); |
107 | prom_cif_interface(); | 46 | prom_cif_direct(args); |
108 | prom_world(0); | 47 | prom_world(0); |
109 | 48 | ||
110 | attrs = fmt >> 8; | ||
111 | va_start(list, fmt); | ||
112 | for (i = 0; i < nargs; i++, attrs >>= 3) { | ||
113 | switch (attrs & 0x7) { | ||
114 | case P1275_ARG_NUMBER: | ||
115 | (void) va_arg(list, long); | ||
116 | break; | ||
117 | case P1275_ARG_IN_STRING: | ||
118 | (void) va_arg(list, char *); | ||
119 | break; | ||
120 | case P1275_ARG_IN_FUNCTION: | ||
121 | (void) va_arg(list, long); | ||
122 | break; | ||
123 | case P1275_ARG_IN_BUF: | ||
124 | (void) va_arg(list, char *); | ||
125 | (void) va_arg(list, long); | ||
126 | i++; attrs >>= 3; | ||
127 | break; | ||
128 | case P1275_ARG_OUT_BUF: | ||
129 | p = va_arg(list, char *); | ||
130 | x = va_arg(list, long); | ||
131 | memcpy (p, (char *)(p1275buf.prom_args[i + 3]), (int)x); | ||
132 | i++; attrs >>= 3; | ||
133 | break; | ||
134 | case P1275_ARG_OUT_32B: | ||
135 | p = va_arg(list, char *); | ||
136 | memcpy (p, (char *)(p1275buf.prom_args[i + 3]), 32); | ||
137 | break; | ||
138 | } | ||
139 | } | ||
140 | va_end(list); | ||
141 | x = p1275buf.prom_args [nargs + 3]; | ||
142 | |||
143 | raw_spin_unlock(&prom_entry_lock); | 49 | raw_spin_unlock(&prom_entry_lock); |
144 | raw_local_irq_restore(flags); | 50 | raw_local_irq_restore(flags); |
145 | |||
146 | return x; | ||
147 | } | 51 | } |
148 | 52 | ||
149 | void prom_cif_init(void *cif_handler, void *cif_stack) | 53 | void prom_cif_init(void *cif_handler, void *cif_stack) |
diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c index 3c0d2dd9f69..9d3f9137a43 100644 --- a/arch/sparc/prom/tree_64.c +++ b/arch/sparc/prom/tree_64.c | |||
@@ -16,22 +16,39 @@ | |||
16 | #include <asm/oplib.h> | 16 | #include <asm/oplib.h> |
17 | #include <asm/ldc.h> | 17 | #include <asm/ldc.h> |
18 | 18 | ||
19 | static int prom_node_to_node(const char *type, int node) | ||
20 | { | ||
21 | unsigned long args[5]; | ||
22 | |||
23 | args[0] = (unsigned long) type; | ||
24 | args[1] = 1; | ||
25 | args[2] = 1; | ||
26 | args[3] = (unsigned int) node; | ||
27 | args[4] = (unsigned long) -1; | ||
28 | |||
29 | p1275_cmd_direct(args); | ||
30 | |||
31 | return (int) args[4]; | ||
32 | } | ||
33 | |||
19 | /* Return the child of node 'node' or zero if no this node has no | 34 | /* Return the child of node 'node' or zero if no this node has no |
20 | * direct descendent. | 35 | * direct descendent. |
21 | */ | 36 | */ |
22 | inline int __prom_getchild(int node) | 37 | inline int __prom_getchild(int node) |
23 | { | 38 | { |
24 | return p1275_cmd ("child", P1275_INOUT(1, 1), node); | 39 | return prom_node_to_node("child", node); |
25 | } | 40 | } |
26 | 41 | ||
27 | inline int prom_getchild(int node) | 42 | inline int prom_getchild(int node) |
28 | { | 43 | { |
29 | int cnode; | 44 | int cnode; |
30 | 45 | ||
31 | if(node == -1) return 0; | 46 | if (node == -1) |
47 | return 0; | ||
32 | cnode = __prom_getchild(node); | 48 | cnode = __prom_getchild(node); |
33 | if(cnode == -1) return 0; | 49 | if (cnode == -1) |
34 | return (int)cnode; | 50 | return 0; |
51 | return cnode; | ||
35 | } | 52 | } |
36 | EXPORT_SYMBOL(prom_getchild); | 53 | EXPORT_SYMBOL(prom_getchild); |
37 | 54 | ||
@@ -39,10 +56,12 @@ inline int prom_getparent(int node) | |||
39 | { | 56 | { |
40 | int cnode; | 57 | int cnode; |
41 | 58 | ||
42 | if(node == -1) return 0; | 59 | if (node == -1) |
43 | cnode = p1275_cmd ("parent", P1275_INOUT(1, 1), node); | 60 | return 0; |
44 | if(cnode == -1) return 0; | 61 | cnode = prom_node_to_node("parent", node); |
45 | return (int)cnode; | 62 | if (cnode == -1) |
63 | return 0; | ||
64 | return cnode; | ||
46 | } | 65 | } |
47 | 66 | ||
48 | /* Return the next sibling of node 'node' or zero if no more siblings | 67 | /* Return the next sibling of node 'node' or zero if no more siblings |
@@ -50,7 +69,7 @@ inline int prom_getparent(int node) | |||
50 | */ | 69 | */ |
51 | inline int __prom_getsibling(int node) | 70 | inline int __prom_getsibling(int node) |
52 | { | 71 | { |
53 | return p1275_cmd(prom_peer_name, P1275_INOUT(1, 1), node); | 72 | return prom_node_to_node(prom_peer_name, node); |
54 | } | 73 | } |
55 | 74 | ||
56 | inline int prom_getsibling(int node) | 75 | inline int prom_getsibling(int node) |
@@ -72,11 +91,21 @@ EXPORT_SYMBOL(prom_getsibling); | |||
72 | */ | 91 | */ |
73 | inline int prom_getproplen(int node, const char *prop) | 92 | inline int prom_getproplen(int node, const char *prop) |
74 | { | 93 | { |
75 | if((!node) || (!prop)) return -1; | 94 | unsigned long args[6]; |
76 | return p1275_cmd ("getproplen", | 95 | |
77 | P1275_ARG(1,P1275_ARG_IN_STRING)| | 96 | if (!node || !prop) |
78 | P1275_INOUT(2, 1), | 97 | return -1; |
79 | node, prop); | 98 | |
99 | args[0] = (unsigned long) "getproplen"; | ||
100 | args[1] = 2; | ||
101 | args[2] = 1; | ||
102 | args[3] = (unsigned int) node; | ||
103 | args[4] = (unsigned long) prop; | ||
104 | args[5] = (unsigned long) -1; | ||
105 | |||
106 | p1275_cmd_direct(args); | ||
107 | |||
108 | return (int) args[5]; | ||
80 | } | 109 | } |
81 | EXPORT_SYMBOL(prom_getproplen); | 110 | EXPORT_SYMBOL(prom_getproplen); |
82 | 111 | ||
@@ -87,19 +116,25 @@ EXPORT_SYMBOL(prom_getproplen); | |||
87 | inline int prom_getproperty(int node, const char *prop, | 116 | inline int prom_getproperty(int node, const char *prop, |
88 | char *buffer, int bufsize) | 117 | char *buffer, int bufsize) |
89 | { | 118 | { |
119 | unsigned long args[8]; | ||
90 | int plen; | 120 | int plen; |
91 | 121 | ||
92 | plen = prom_getproplen(node, prop); | 122 | plen = prom_getproplen(node, prop); |
93 | if ((plen > bufsize) || (plen == 0) || (plen == -1)) { | 123 | if ((plen > bufsize) || (plen == 0) || (plen == -1)) |
94 | return -1; | 124 | return -1; |
95 | } else { | 125 | |
96 | /* Ok, things seem all right. */ | 126 | args[0] = (unsigned long) prom_getprop_name; |
97 | return p1275_cmd(prom_getprop_name, | 127 | args[1] = 4; |
98 | P1275_ARG(1,P1275_ARG_IN_STRING)| | 128 | args[2] = 1; |
99 | P1275_ARG(2,P1275_ARG_OUT_BUF)| | 129 | args[3] = (unsigned int) node; |
100 | P1275_INOUT(4, 1), | 130 | args[4] = (unsigned long) prop; |
101 | node, prop, buffer, P1275_SIZE(plen)); | 131 | args[5] = (unsigned long) buffer; |
102 | } | 132 | args[6] = bufsize; |
133 | args[7] = (unsigned long) -1; | ||
134 | |||
135 | p1275_cmd_direct(args); | ||
136 | |||
137 | return (int) args[7]; | ||
103 | } | 138 | } |
104 | EXPORT_SYMBOL(prom_getproperty); | 139 | EXPORT_SYMBOL(prom_getproperty); |
105 | 140 | ||
@@ -110,7 +145,7 @@ inline int prom_getint(int node, const char *prop) | |||
110 | { | 145 | { |
111 | int intprop; | 146 | int intprop; |
112 | 147 | ||
113 | if(prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1) | 148 | if (prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1) |
114 | return intprop; | 149 | return intprop; |
115 | 150 | ||
116 | return -1; | 151 | return -1; |
@@ -126,7 +161,8 @@ int prom_getintdefault(int node, const char *property, int deflt) | |||
126 | int retval; | 161 | int retval; |
127 | 162 | ||
128 | retval = prom_getint(node, property); | 163 | retval = prom_getint(node, property); |
129 | if(retval == -1) return deflt; | 164 | if (retval == -1) |
165 | return deflt; | ||
130 | 166 | ||
131 | return retval; | 167 | return retval; |
132 | } | 168 | } |
@@ -138,7 +174,8 @@ int prom_getbool(int node, const char *prop) | |||
138 | int retval; | 174 | int retval; |
139 | 175 | ||
140 | retval = prom_getproplen(node, prop); | 176 | retval = prom_getproplen(node, prop); |
141 | if(retval == -1) return 0; | 177 | if (retval == -1) |
178 | return 0; | ||
142 | return 1; | 179 | return 1; |
143 | } | 180 | } |
144 | EXPORT_SYMBOL(prom_getbool); | 181 | EXPORT_SYMBOL(prom_getbool); |
@@ -152,7 +189,8 @@ void prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size) | |||
152 | int len; | 189 | int len; |
153 | 190 | ||
154 | len = prom_getproperty(node, prop, user_buf, ubuf_size); | 191 | len = prom_getproperty(node, prop, user_buf, ubuf_size); |
155 | if(len != -1) return; | 192 | if (len != -1) |
193 | return; | ||
156 | user_buf[0] = 0; | 194 | user_buf[0] = 0; |
157 | } | 195 | } |
158 | EXPORT_SYMBOL(prom_getstring); | 196 | EXPORT_SYMBOL(prom_getstring); |
@@ -164,7 +202,8 @@ int prom_nodematch(int node, const char *name) | |||
164 | { | 202 | { |
165 | char namebuf[128]; | 203 | char namebuf[128]; |
166 | prom_getproperty(node, "name", namebuf, sizeof(namebuf)); | 204 | prom_getproperty(node, "name", namebuf, sizeof(namebuf)); |
167 | if(strcmp(namebuf, name) == 0) return 1; | 205 | if (strcmp(namebuf, name) == 0) |
206 | return 1; | ||
168 | return 0; | 207 | return 0; |
169 | } | 208 | } |
170 | 209 | ||
@@ -190,16 +229,29 @@ int prom_searchsiblings(int node_start, const char *nodename) | |||
190 | } | 229 | } |
191 | EXPORT_SYMBOL(prom_searchsiblings); | 230 | EXPORT_SYMBOL(prom_searchsiblings); |
192 | 231 | ||
232 | static const char *prom_nextprop_name = "nextprop"; | ||
233 | |||
193 | /* Return the first property type for node 'node'. | 234 | /* Return the first property type for node 'node'. |
194 | * buffer should be at least 32B in length | 235 | * buffer should be at least 32B in length |
195 | */ | 236 | */ |
196 | inline char *prom_firstprop(int node, char *buffer) | 237 | inline char *prom_firstprop(int node, char *buffer) |
197 | { | 238 | { |
239 | unsigned long args[7]; | ||
240 | |||
198 | *buffer = 0; | 241 | *buffer = 0; |
199 | if(node == -1) return buffer; | 242 | if (node == -1) |
200 | p1275_cmd ("nextprop", P1275_ARG(2,P1275_ARG_OUT_32B)| | 243 | return buffer; |
201 | P1275_INOUT(3, 0), | 244 | |
202 | node, (char *) 0x0, buffer); | 245 | args[0] = (unsigned long) prom_nextprop_name; |
246 | args[1] = 3; | ||
247 | args[2] = 1; | ||
248 | args[3] = (unsigned int) node; | ||
249 | args[4] = 0; | ||
250 | args[5] = (unsigned long) buffer; | ||
251 | args[6] = (unsigned long) -1; | ||
252 | |||
253 | p1275_cmd_direct(args); | ||
254 | |||
203 | return buffer; | 255 | return buffer; |
204 | } | 256 | } |
205 | EXPORT_SYMBOL(prom_firstprop); | 257 | EXPORT_SYMBOL(prom_firstprop); |
@@ -210,9 +262,10 @@ EXPORT_SYMBOL(prom_firstprop); | |||
210 | */ | 262 | */ |
211 | inline char *prom_nextprop(int node, const char *oprop, char *buffer) | 263 | inline char *prom_nextprop(int node, const char *oprop, char *buffer) |
212 | { | 264 | { |
265 | unsigned long args[7]; | ||
213 | char buf[32]; | 266 | char buf[32]; |
214 | 267 | ||
215 | if(node == -1) { | 268 | if (node == -1) { |
216 | *buffer = 0; | 269 | *buffer = 0; |
217 | return buffer; | 270 | return buffer; |
218 | } | 271 | } |
@@ -220,10 +273,17 @@ inline char *prom_nextprop(int node, const char *oprop, char *buffer) | |||
220 | strcpy (buf, oprop); | 273 | strcpy (buf, oprop); |
221 | oprop = buf; | 274 | oprop = buf; |
222 | } | 275 | } |
223 | p1275_cmd ("nextprop", P1275_ARG(1,P1275_ARG_IN_STRING)| | 276 | |
224 | P1275_ARG(2,P1275_ARG_OUT_32B)| | 277 | args[0] = (unsigned long) prom_nextprop_name; |
225 | P1275_INOUT(3, 0), | 278 | args[1] = 3; |
226 | node, oprop, buffer); | 279 | args[2] = 1; |
280 | args[3] = (unsigned int) node; | ||
281 | args[4] = (unsigned long) oprop; | ||
282 | args[5] = (unsigned long) buffer; | ||
283 | args[6] = (unsigned long) -1; | ||
284 | |||
285 | p1275_cmd_direct(args); | ||
286 | |||
227 | return buffer; | 287 | return buffer; |
228 | } | 288 | } |
229 | EXPORT_SYMBOL(prom_nextprop); | 289 | EXPORT_SYMBOL(prom_nextprop); |
@@ -231,12 +291,19 @@ EXPORT_SYMBOL(prom_nextprop); | |||
231 | int | 291 | int |
232 | prom_finddevice(const char *name) | 292 | prom_finddevice(const char *name) |
233 | { | 293 | { |
294 | unsigned long args[5]; | ||
295 | |||
234 | if (!name) | 296 | if (!name) |
235 | return 0; | 297 | return 0; |
236 | return p1275_cmd(prom_finddev_name, | 298 | args[0] = (unsigned long) "finddevice"; |
237 | P1275_ARG(0,P1275_ARG_IN_STRING)| | 299 | args[1] = 1; |
238 | P1275_INOUT(1, 1), | 300 | args[2] = 1; |
239 | name); | 301 | args[3] = (unsigned long) name; |
302 | args[4] = (unsigned long) -1; | ||
303 | |||
304 | p1275_cmd_direct(args); | ||
305 | |||
306 | return (int) args[4]; | ||
240 | } | 307 | } |
241 | EXPORT_SYMBOL(prom_finddevice); | 308 | EXPORT_SYMBOL(prom_finddevice); |
242 | 309 | ||
@@ -247,7 +314,7 @@ int prom_node_has_property(int node, const char *prop) | |||
247 | *buf = 0; | 314 | *buf = 0; |
248 | do { | 315 | do { |
249 | prom_nextprop(node, buf, buf); | 316 | prom_nextprop(node, buf, buf); |
250 | if(!strcmp(buf, prop)) | 317 | if (!strcmp(buf, prop)) |
251 | return 1; | 318 | return 1; |
252 | } while (*buf); | 319 | } while (*buf); |
253 | return 0; | 320 | return 0; |
@@ -260,6 +327,8 @@ EXPORT_SYMBOL(prom_node_has_property); | |||
260 | int | 327 | int |
261 | prom_setprop(int node, const char *pname, char *value, int size) | 328 | prom_setprop(int node, const char *pname, char *value, int size) |
262 | { | 329 | { |
330 | unsigned long args[8]; | ||
331 | |||
263 | if (size == 0) | 332 | if (size == 0) |
264 | return 0; | 333 | return 0; |
265 | if ((pname == 0) || (value == 0)) | 334 | if ((pname == 0) || (value == 0)) |
@@ -271,19 +340,37 @@ prom_setprop(int node, const char *pname, char *value, int size) | |||
271 | return 0; | 340 | return 0; |
272 | } | 341 | } |
273 | #endif | 342 | #endif |
274 | return p1275_cmd ("setprop", P1275_ARG(1,P1275_ARG_IN_STRING)| | 343 | args[0] = (unsigned long) "setprop"; |
275 | P1275_ARG(2,P1275_ARG_IN_BUF)| | 344 | args[1] = 4; |
276 | P1275_INOUT(4, 1), | 345 | args[2] = 1; |
277 | node, pname, value, P1275_SIZE(size)); | 346 | args[3] = (unsigned int) node; |
347 | args[4] = (unsigned long) pname; | ||
348 | args[5] = (unsigned long) value; | ||
349 | args[6] = size; | ||
350 | args[7] = (unsigned long) -1; | ||
351 | |||
352 | p1275_cmd_direct(args); | ||
353 | |||
354 | return (int) args[7]; | ||
278 | } | 355 | } |
279 | EXPORT_SYMBOL(prom_setprop); | 356 | EXPORT_SYMBOL(prom_setprop); |
280 | 357 | ||
281 | inline int prom_inst2pkg(int inst) | 358 | inline int prom_inst2pkg(int inst) |
282 | { | 359 | { |
360 | unsigned long args[5]; | ||
283 | int node; | 361 | int node; |
284 | 362 | ||
285 | node = p1275_cmd ("instance-to-package", P1275_INOUT(1, 1), inst); | 363 | args[0] = (unsigned long) "instance-to-package"; |
286 | if (node == -1) return 0; | 364 | args[1] = 1; |
365 | args[2] = 1; | ||
366 | args[3] = (unsigned int) inst; | ||
367 | args[4] = (unsigned long) -1; | ||
368 | |||
369 | p1275_cmd_direct(args); | ||
370 | |||
371 | node = (int) args[4]; | ||
372 | if (node == -1) | ||
373 | return 0; | ||
287 | return node; | 374 | return node; |
288 | } | 375 | } |
289 | 376 | ||
@@ -296,17 +383,28 @@ prom_pathtoinode(const char *path) | |||
296 | int node, inst; | 383 | int node, inst; |
297 | 384 | ||
298 | inst = prom_devopen (path); | 385 | inst = prom_devopen (path); |
299 | if (inst == 0) return 0; | 386 | if (inst == 0) |
300 | node = prom_inst2pkg (inst); | 387 | return 0; |
301 | prom_devclose (inst); | 388 | node = prom_inst2pkg(inst); |
302 | if (node == -1) return 0; | 389 | prom_devclose(inst); |
390 | if (node == -1) | ||
391 | return 0; | ||
303 | return node; | 392 | return node; |
304 | } | 393 | } |
305 | 394 | ||
306 | int prom_ihandle2path(int handle, char *buffer, int bufsize) | 395 | int prom_ihandle2path(int handle, char *buffer, int bufsize) |
307 | { | 396 | { |
308 | return p1275_cmd("instance-to-path", | 397 | unsigned long args[7]; |
309 | P1275_ARG(1,P1275_ARG_OUT_BUF)| | 398 | |
310 | P1275_INOUT(3, 1), | 399 | args[0] = (unsigned long) "instance-to-path"; |
311 | handle, buffer, P1275_SIZE(bufsize)); | 400 | args[1] = 3; |
401 | args[2] = 1; | ||
402 | args[3] = (unsigned int) handle; | ||
403 | args[4] = (unsigned long) buffer; | ||
404 | args[5] = bufsize; | ||
405 | args[6] = (unsigned long) -1; | ||
406 | |||
407 | p1275_cmd_direct(args); | ||
408 | |||
409 | return (int) args[6]; | ||
312 | } | 410 | } |
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c index ed590ad0acd..985cc28c74c 100644 --- a/arch/tile/kernel/process.c +++ b/arch/tile/kernel/process.c | |||
@@ -543,8 +543,9 @@ long _sys_vfork(struct pt_regs *regs) | |||
543 | /* | 543 | /* |
544 | * sys_execve() executes a new program. | 544 | * sys_execve() executes a new program. |
545 | */ | 545 | */ |
546 | long _sys_execve(char __user *path, char __user *__user *argv, | 546 | long _sys_execve(const char __user *path, |
547 | char __user *__user *envp, struct pt_regs *regs) | 547 | const char __user *const __user *argv, |
548 | const char __user *const __user *envp, struct pt_regs *regs) | ||
548 | { | 549 | { |
549 | long error; | 550 | long error; |
550 | char *filename; | 551 | char *filename; |
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index de317d0c329..ebc680717e5 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c | |||
@@ -690,7 +690,7 @@ static void with_console(struct mc_request *req, void (*proc)(void *), | |||
690 | static void sysrq_proc(void *arg) | 690 | static void sysrq_proc(void *arg) |
691 | { | 691 | { |
692 | char *op = arg; | 692 | char *op = arg; |
693 | handle_sysrq(*op, NULL); | 693 | handle_sysrq(*op); |
694 | } | 694 | } |
695 | 695 | ||
696 | void mconsole_sysrq(struct mc_request *req) | 696 | void mconsole_sysrq(struct mc_request *req) |
diff --git a/arch/um/include/asm/dma-mapping.h b/arch/um/include/asm/dma-mapping.h index 17a2cb5a417..1f469e80fdd 100644 --- a/arch/um/include/asm/dma-mapping.h +++ b/arch/um/include/asm/dma-mapping.h | |||
@@ -95,13 +95,6 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, | |||
95 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) | 95 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) |
96 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) | 96 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) |
97 | 97 | ||
98 | static inline int | ||
99 | dma_get_cache_alignment(void) | ||
100 | { | ||
101 | BUG(); | ||
102 | return(0); | ||
103 | } | ||
104 | |||
105 | static inline void | 98 | static inline void |
106 | dma_cache_sync(struct device *dev, void *vaddr, size_t size, | 99 | dma_cache_sync(struct device *dev, void *vaddr, size_t size, |
107 | enum dma_data_direction direction) | 100 | enum dma_data_direction direction) |
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 59b20d93b6d..cd145eda357 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c | |||
@@ -44,8 +44,9 @@ void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) | |||
44 | PT_REGS_SP(regs) = esp; | 44 | PT_REGS_SP(regs) = esp; |
45 | } | 45 | } |
46 | 46 | ||
47 | static long execve1(const char *file, char __user * __user *argv, | 47 | static long execve1(const char *file, |
48 | char __user *__user *env) | 48 | const char __user *const __user *argv, |
49 | const char __user *const __user *env) | ||
49 | { | 50 | { |
50 | long error; | 51 | long error; |
51 | 52 | ||
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c index 7427c0b1930..5ddb246626d 100644 --- a/arch/um/kernel/syscall.c +++ b/arch/um/kernel/syscall.c | |||
@@ -51,7 +51,9 @@ long old_mmap(unsigned long addr, unsigned long len, | |||
51 | return err; | 51 | return err; |
52 | } | 52 | } |
53 | 53 | ||
54 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | 54 | int kernel_execve(const char *filename, |
55 | const char *const argv[], | ||
56 | const char *const envp[]) | ||
55 | { | 57 | { |
56 | mm_segment_t fs; | 58 | mm_segment_t fs; |
57 | int ret; | 59 | int ret; |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index a84fc34c8f7..cea0cd9a316 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -245,6 +245,11 @@ config ARCH_HWEIGHT_CFLAGS | |||
245 | 245 | ||
246 | config KTIME_SCALAR | 246 | config KTIME_SCALAR |
247 | def_bool X86_32 | 247 | def_bool X86_32 |
248 | |||
249 | config ARCH_CPU_PROBE_RELEASE | ||
250 | def_bool y | ||
251 | depends on HOTPLUG_CPU | ||
252 | |||
248 | source "init/Kconfig" | 253 | source "init/Kconfig" |
249 | source "kernel/Kconfig.freezer" | 254 | source "kernel/Kconfig.freezer" |
250 | 255 | ||
@@ -749,11 +754,11 @@ config IOMMU_API | |||
749 | def_bool (AMD_IOMMU || DMAR) | 754 | def_bool (AMD_IOMMU || DMAR) |
750 | 755 | ||
751 | config MAXSMP | 756 | config MAXSMP |
752 | bool "Configure Maximum number of SMP Processors and NUMA Nodes" | 757 | bool "Enable Maximum number of SMP Processors and NUMA Nodes" |
753 | depends on X86_64 && SMP && DEBUG_KERNEL && EXPERIMENTAL | 758 | depends on X86_64 && SMP && DEBUG_KERNEL && EXPERIMENTAL |
754 | select CPUMASK_OFFSTACK | 759 | select CPUMASK_OFFSTACK |
755 | ---help--- | 760 | ---help--- |
756 | Configure maximum number of CPUS and NUMA Nodes for this architecture. | 761 | Enable maximum number of CPUS and NUMA Nodes for this architecture. |
757 | If unsure, say N. | 762 | If unsure, say N. |
758 | 763 | ||
759 | config NR_CPUS | 764 | config NR_CPUS |
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index 404a880ea32..d395540ff89 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h | |||
@@ -27,6 +27,9 @@ extern struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, | |||
27 | int node); | 27 | int node); |
28 | extern struct pci_bus *pci_scan_bus_with_sysdata(int busno); | 28 | extern struct pci_bus *pci_scan_bus_with_sysdata(int busno); |
29 | 29 | ||
30 | #ifdef CONFIG_PCI | ||
31 | |||
32 | #ifdef CONFIG_PCI_DOMAINS | ||
30 | static inline int pci_domain_nr(struct pci_bus *bus) | 33 | static inline int pci_domain_nr(struct pci_bus *bus) |
31 | { | 34 | { |
32 | struct pci_sysdata *sd = bus->sysdata; | 35 | struct pci_sysdata *sd = bus->sysdata; |
@@ -37,13 +40,12 @@ static inline int pci_proc_domain(struct pci_bus *bus) | |||
37 | { | 40 | { |
38 | return pci_domain_nr(bus); | 41 | return pci_domain_nr(bus); |
39 | } | 42 | } |
40 | 43 | #endif | |
41 | 44 | ||
42 | /* Can be used to override the logic in pci_scan_bus for skipping | 45 | /* Can be used to override the logic in pci_scan_bus for skipping |
43 | already-configured bus numbers - to be used for buggy BIOSes | 46 | already-configured bus numbers - to be used for buggy BIOSes |
44 | or architectures with incomplete PCI setup by the loader */ | 47 | or architectures with incomplete PCI setup by the loader */ |
45 | 48 | ||
46 | #ifdef CONFIG_PCI | ||
47 | extern unsigned int pcibios_assign_all_busses(void); | 49 | extern unsigned int pcibios_assign_all_busses(void); |
48 | extern int pci_legacy_init(void); | 50 | extern int pci_legacy_init(void); |
49 | # ifdef CONFIG_ACPI | 51 | # ifdef CONFIG_ACPI |
diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h index 2984a25ff38..f686f49e8b7 100644 --- a/arch/x86/include/asm/pgtable_32.h +++ b/arch/x86/include/asm/pgtable_32.h | |||
@@ -26,6 +26,7 @@ struct mm_struct; | |||
26 | struct vm_area_struct; | 26 | struct vm_area_struct; |
27 | 27 | ||
28 | extern pgd_t swapper_pg_dir[1024]; | 28 | extern pgd_t swapper_pg_dir[1024]; |
29 | extern pgd_t trampoline_pg_dir[1024]; | ||
29 | 30 | ||
30 | static inline void pgtable_cache_init(void) { } | 31 | static inline void pgtable_cache_init(void) { } |
31 | static inline void check_pgt_cache(void) { } | 32 | static inline void check_pgt_cache(void) { } |
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h index feb2ff9bfc2..f1d8b441fc7 100644 --- a/arch/x86/include/asm/syscalls.h +++ b/arch/x86/include/asm/syscalls.h | |||
@@ -23,8 +23,9 @@ long sys_iopl(unsigned int, struct pt_regs *); | |||
23 | /* kernel/process.c */ | 23 | /* kernel/process.c */ |
24 | int sys_fork(struct pt_regs *); | 24 | int sys_fork(struct pt_regs *); |
25 | int sys_vfork(struct pt_regs *); | 25 | int sys_vfork(struct pt_regs *); |
26 | long sys_execve(const char __user *, char __user * __user *, | 26 | long sys_execve(const char __user *, |
27 | char __user * __user *, struct pt_regs *); | 27 | const char __user *const __user *, |
28 | const char __user *const __user *, struct pt_regs *); | ||
28 | long sys_clone(unsigned long, unsigned long, void __user *, | 29 | long sys_clone(unsigned long, unsigned long, void __user *, |
29 | void __user *, struct pt_regs *); | 30 | void __user *, struct pt_regs *); |
30 | 31 | ||
diff --git a/arch/x86/include/asm/trampoline.h b/arch/x86/include/asm/trampoline.h index cb507bb05d7..4dde797c057 100644 --- a/arch/x86/include/asm/trampoline.h +++ b/arch/x86/include/asm/trampoline.h | |||
@@ -13,14 +13,17 @@ extern unsigned char *trampoline_base; | |||
13 | 13 | ||
14 | extern unsigned long init_rsp; | 14 | extern unsigned long init_rsp; |
15 | extern unsigned long initial_code; | 15 | extern unsigned long initial_code; |
16 | extern unsigned long initial_page_table; | ||
16 | extern unsigned long initial_gs; | 17 | extern unsigned long initial_gs; |
17 | 18 | ||
18 | #define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE) | 19 | #define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE) |
19 | 20 | ||
20 | extern unsigned long setup_trampoline(void); | 21 | extern unsigned long setup_trampoline(void); |
22 | extern void __init setup_trampoline_page_table(void); | ||
21 | extern void __init reserve_trampoline_memory(void); | 23 | extern void __init reserve_trampoline_memory(void); |
22 | #else | 24 | #else |
23 | static inline void reserve_trampoline_memory(void) {}; | 25 | static inline void setup_trampoline_page_table(void) {} |
26 | static inline void reserve_trampoline_memory(void) {} | ||
24 | #endif /* CONFIG_X86_TRAMPOLINE */ | 27 | #endif /* CONFIG_X86_TRAMPOLINE */ |
25 | 28 | ||
26 | #endif /* __ASSEMBLY__ */ | 29 | #endif /* __ASSEMBLY__ */ |
diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h index c0427295e8f..1ca132fc0d0 100644 --- a/arch/x86/include/asm/tsc.h +++ b/arch/x86/include/asm/tsc.h | |||
@@ -59,5 +59,7 @@ extern void check_tsc_sync_source(int cpu); | |||
59 | extern void check_tsc_sync_target(void); | 59 | extern void check_tsc_sync_target(void); |
60 | 60 | ||
61 | extern int notsc_setup(char *); | 61 | extern int notsc_setup(char *); |
62 | extern void save_sched_clock_state(void); | ||
63 | extern void restore_sched_clock_state(void); | ||
62 | 64 | ||
63 | #endif /* _ASM_X86_TSC_H */ | 65 | #endif /* _ASM_X86_TSC_H */ |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 4dc0084ec1b..f1efebaf551 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -1728,6 +1728,8 @@ __apicdebuginit(void) print_IO_APIC(void) | |||
1728 | struct irq_pin_list *entry; | 1728 | struct irq_pin_list *entry; |
1729 | 1729 | ||
1730 | cfg = desc->chip_data; | 1730 | cfg = desc->chip_data; |
1731 | if (!cfg) | ||
1732 | continue; | ||
1731 | entry = cfg->irq_2_pin; | 1733 | entry = cfg->irq_2_pin; |
1732 | if (!entry) | 1734 | if (!entry) |
1733 | continue; | 1735 | continue; |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 60a57b13082..ba5f62f45f0 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
@@ -669,7 +669,7 @@ bool cpu_has_amd_erratum(const int *erratum) | |||
669 | } | 669 | } |
670 | 670 | ||
671 | /* OSVW unavailable or ID unknown, match family-model-stepping range */ | 671 | /* OSVW unavailable or ID unknown, match family-model-stepping range */ |
672 | ms = (cpu->x86_model << 8) | cpu->x86_mask; | 672 | ms = (cpu->x86_model << 4) | cpu->x86_mask; |
673 | while ((range = *erratum++)) | 673 | while ((range = *erratum++)) |
674 | if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) && | 674 | if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) && |
675 | (ms >= AMD_MODEL_RANGE_START(range)) && | 675 | (ms >= AMD_MODEL_RANGE_START(range)) && |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 214ac860ebe..d8d86d01400 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -491,33 +491,78 @@ static void intel_pmu_enable_all(int added) | |||
491 | * Intel Errata AAP53 (model 30) | 491 | * Intel Errata AAP53 (model 30) |
492 | * Intel Errata BD53 (model 44) | 492 | * Intel Errata BD53 (model 44) |
493 | * | 493 | * |
494 | * These chips need to be 'reset' when adding counters by programming | 494 | * The official story: |
495 | * the magic three (non counting) events 0x4300D2, 0x4300B1 and 0x4300B5 | 495 | * These chips need to be 'reset' when adding counters by programming the |
496 | * either in sequence on the same PMC or on different PMCs. | 496 | * magic three (non-counting) events 0x4300B5, 0x4300D2, and 0x4300B1 either |
497 | * in sequence on the same PMC or on different PMCs. | ||
498 | * | ||
499 | * In practise it appears some of these events do in fact count, and | ||
500 | * we need to programm all 4 events. | ||
497 | */ | 501 | */ |
498 | static void intel_pmu_nhm_enable_all(int added) | 502 | static void intel_pmu_nhm_workaround(void) |
499 | { | 503 | { |
500 | if (added) { | 504 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
501 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 505 | static const unsigned long nhm_magic[4] = { |
502 | int i; | 506 | 0x4300B5, |
507 | 0x4300D2, | ||
508 | 0x4300B1, | ||
509 | 0x4300B1 | ||
510 | }; | ||
511 | struct perf_event *event; | ||
512 | int i; | ||
513 | |||
514 | /* | ||
515 | * The Errata requires below steps: | ||
516 | * 1) Clear MSR_IA32_PEBS_ENABLE and MSR_CORE_PERF_GLOBAL_CTRL; | ||
517 | * 2) Configure 4 PERFEVTSELx with the magic events and clear | ||
518 | * the corresponding PMCx; | ||
519 | * 3) set bit0~bit3 of MSR_CORE_PERF_GLOBAL_CTRL; | ||
520 | * 4) Clear MSR_CORE_PERF_GLOBAL_CTRL; | ||
521 | * 5) Clear 4 pairs of ERFEVTSELx and PMCx; | ||
522 | */ | ||
523 | |||
524 | /* | ||
525 | * The real steps we choose are a little different from above. | ||
526 | * A) To reduce MSR operations, we don't run step 1) as they | ||
527 | * are already cleared before this function is called; | ||
528 | * B) Call x86_perf_event_update to save PMCx before configuring | ||
529 | * PERFEVTSELx with magic number; | ||
530 | * C) With step 5), we do clear only when the PERFEVTSELx is | ||
531 | * not used currently. | ||
532 | * D) Call x86_perf_event_set_period to restore PMCx; | ||
533 | */ | ||
503 | 534 | ||
504 | wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 0, 0x4300D2); | 535 | /* We always operate 4 pairs of PERF Counters */ |
505 | wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 1, 0x4300B1); | 536 | for (i = 0; i < 4; i++) { |
506 | wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 2, 0x4300B5); | 537 | event = cpuc->events[i]; |
538 | if (event) | ||
539 | x86_perf_event_update(event); | ||
540 | } | ||
507 | 541 | ||
508 | wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x3); | 542 | for (i = 0; i < 4; i++) { |
509 | wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x0); | 543 | wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + i, nhm_magic[i]); |
544 | wrmsrl(MSR_ARCH_PERFMON_PERFCTR0 + i, 0x0); | ||
545 | } | ||
510 | 546 | ||
511 | for (i = 0; i < 3; i++) { | 547 | wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0xf); |
512 | struct perf_event *event = cpuc->events[i]; | 548 | wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x0); |
513 | 549 | ||
514 | if (!event) | 550 | for (i = 0; i < 4; i++) { |
515 | continue; | 551 | event = cpuc->events[i]; |
516 | 552 | ||
553 | if (event) { | ||
554 | x86_perf_event_set_period(event); | ||
517 | __x86_pmu_enable_event(&event->hw, | 555 | __x86_pmu_enable_event(&event->hw, |
518 | ARCH_PERFMON_EVENTSEL_ENABLE); | 556 | ARCH_PERFMON_EVENTSEL_ENABLE); |
519 | } | 557 | } else |
558 | wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + i, 0x0); | ||
520 | } | 559 | } |
560 | } | ||
561 | |||
562 | static void intel_pmu_nhm_enable_all(int added) | ||
563 | { | ||
564 | if (added) | ||
565 | intel_pmu_nhm_workaround(); | ||
521 | intel_pmu_enable_all(added); | 566 | intel_pmu_enable_all(added); |
522 | } | 567 | } |
523 | 568 | ||
diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index febb12cea79..7e578e9cc58 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c | |||
@@ -497,6 +497,8 @@ static int p4_hw_config(struct perf_event *event) | |||
497 | event->hw.config |= event->attr.config & | 497 | event->hw.config |= event->attr.config & |
498 | (p4_config_pack_escr(P4_ESCR_MASK_HT) | | 498 | (p4_config_pack_escr(P4_ESCR_MASK_HT) | |
499 | p4_config_pack_cccr(P4_CCCR_MASK_HT | P4_CCCR_RESERVED)); | 499 | p4_config_pack_cccr(P4_CCCR_MASK_HT | P4_CCCR_RESERVED)); |
500 | |||
501 | event->hw.config &= ~P4_CCCR_FORCE_OVF; | ||
500 | } | 502 | } |
501 | 503 | ||
502 | rc = x86_setup_perfctr(event); | 504 | rc = x86_setup_perfctr(event); |
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index ff4c453e13f..fa8c1b8e09f 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
@@ -334,7 +334,7 @@ ENTRY(startup_32_smp) | |||
334 | /* | 334 | /* |
335 | * Enable paging | 335 | * Enable paging |
336 | */ | 336 | */ |
337 | movl $pa(swapper_pg_dir),%eax | 337 | movl pa(initial_page_table), %eax |
338 | movl %eax,%cr3 /* set the page table pointer.. */ | 338 | movl %eax,%cr3 /* set the page table pointer.. */ |
339 | movl %cr0,%eax | 339 | movl %cr0,%eax |
340 | orl $X86_CR0_PG,%eax | 340 | orl $X86_CR0_PG,%eax |
@@ -614,6 +614,8 @@ ignore_int: | |||
614 | .align 4 | 614 | .align 4 |
615 | ENTRY(initial_code) | 615 | ENTRY(initial_code) |
616 | .long i386_start_kernel | 616 | .long i386_start_kernel |
617 | ENTRY(initial_page_table) | ||
618 | .long pa(swapper_pg_dir) | ||
617 | 619 | ||
618 | /* | 620 | /* |
619 | * BSS section | 621 | * BSS section |
@@ -629,6 +631,10 @@ ENTRY(swapper_pg_dir) | |||
629 | #endif | 631 | #endif |
630 | swapper_pg_fixmap: | 632 | swapper_pg_fixmap: |
631 | .fill 1024,4,0 | 633 | .fill 1024,4,0 |
634 | #ifdef CONFIG_X86_TRAMPOLINE | ||
635 | ENTRY(trampoline_pg_dir) | ||
636 | .fill 1024,4,0 | ||
637 | #endif | ||
632 | ENTRY(empty_zero_page) | 638 | ENTRY(empty_zero_page) |
633 | .fill 4096,1,0 | 639 | .fill 4096,1,0 |
634 | 640 | ||
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index 1f11f5ce668..a46cb3522c0 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c | |||
@@ -40,6 +40,7 @@ | |||
40 | 40 | ||
41 | static unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu; | 41 | static unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu; |
42 | unsigned int xstate_size; | 42 | unsigned int xstate_size; |
43 | EXPORT_SYMBOL_GPL(xstate_size); | ||
43 | unsigned int sig_xstate_ia32_size = sizeof(struct _fpstate_ia32); | 44 | unsigned int sig_xstate_ia32_size = sizeof(struct _fpstate_ia32); |
44 | static struct i387_fxsave_struct fx_scratch __cpuinitdata; | 45 | static struct i387_fxsave_struct fx_scratch __cpuinitdata; |
45 | 46 | ||
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index ef10940e1af..852b81967a3 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c | |||
@@ -194,7 +194,7 @@ static struct hw_breakpoint { | |||
194 | unsigned long addr; | 194 | unsigned long addr; |
195 | int len; | 195 | int len; |
196 | int type; | 196 | int type; |
197 | struct perf_event **pev; | 197 | struct perf_event * __percpu *pev; |
198 | } breakinfo[HBP_NUM]; | 198 | } breakinfo[HBP_NUM]; |
199 | 199 | ||
200 | static unsigned long early_dr7; | 200 | static unsigned long early_dr7; |
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index 1bfb6cf4dd5..770ebfb349e 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c | |||
@@ -709,6 +709,7 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs) | |||
709 | struct hlist_node *node, *tmp; | 709 | struct hlist_node *node, *tmp; |
710 | unsigned long flags, orig_ret_address = 0; | 710 | unsigned long flags, orig_ret_address = 0; |
711 | unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; | 711 | unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; |
712 | kprobe_opcode_t *correct_ret_addr = NULL; | ||
712 | 713 | ||
713 | INIT_HLIST_HEAD(&empty_rp); | 714 | INIT_HLIST_HEAD(&empty_rp); |
714 | kretprobe_hash_lock(current, &head, &flags); | 715 | kretprobe_hash_lock(current, &head, &flags); |
@@ -740,14 +741,34 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs) | |||
740 | /* another task is sharing our hash bucket */ | 741 | /* another task is sharing our hash bucket */ |
741 | continue; | 742 | continue; |
742 | 743 | ||
744 | orig_ret_address = (unsigned long)ri->ret_addr; | ||
745 | |||
746 | if (orig_ret_address != trampoline_address) | ||
747 | /* | ||
748 | * This is the real return address. Any other | ||
749 | * instances associated with this task are for | ||
750 | * other calls deeper on the call stack | ||
751 | */ | ||
752 | break; | ||
753 | } | ||
754 | |||
755 | kretprobe_assert(ri, orig_ret_address, trampoline_address); | ||
756 | |||
757 | correct_ret_addr = ri->ret_addr; | ||
758 | hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { | ||
759 | if (ri->task != current) | ||
760 | /* another task is sharing our hash bucket */ | ||
761 | continue; | ||
762 | |||
763 | orig_ret_address = (unsigned long)ri->ret_addr; | ||
743 | if (ri->rp && ri->rp->handler) { | 764 | if (ri->rp && ri->rp->handler) { |
744 | __get_cpu_var(current_kprobe) = &ri->rp->kp; | 765 | __get_cpu_var(current_kprobe) = &ri->rp->kp; |
745 | get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; | 766 | get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; |
767 | ri->ret_addr = correct_ret_addr; | ||
746 | ri->rp->handler(ri, regs); | 768 | ri->rp->handler(ri, regs); |
747 | __get_cpu_var(current_kprobe) = NULL; | 769 | __get_cpu_var(current_kprobe) = NULL; |
748 | } | 770 | } |
749 | 771 | ||
750 | orig_ret_address = (unsigned long)ri->ret_addr; | ||
751 | recycle_rp_inst(ri, &empty_rp); | 772 | recycle_rp_inst(ri, &empty_rp); |
752 | 773 | ||
753 | if (orig_ret_address != trampoline_address) | 774 | if (orig_ret_address != trampoline_address) |
@@ -759,8 +780,6 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs) | |||
759 | break; | 780 | break; |
760 | } | 781 | } |
761 | 782 | ||
762 | kretprobe_assert(ri, orig_ret_address, trampoline_address); | ||
763 | |||
764 | kretprobe_hash_unlock(current, &flags); | 783 | kretprobe_hash_unlock(current, &flags); |
765 | 784 | ||
766 | hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { | 785 | hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { |
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 64ecaf0af9a..57d1868a86a 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -301,8 +301,9 @@ EXPORT_SYMBOL(kernel_thread); | |||
301 | /* | 301 | /* |
302 | * sys_execve() executes a new program. | 302 | * sys_execve() executes a new program. |
303 | */ | 303 | */ |
304 | long sys_execve(const char __user *name, char __user * __user *argv, | 304 | long sys_execve(const char __user *name, |
305 | char __user * __user *envp, struct pt_regs *regs) | 305 | const char __user *const __user *argv, |
306 | const char __user *const __user *envp, struct pt_regs *regs) | ||
306 | { | 307 | { |
307 | long error; | 308 | long error; |
308 | char *filename; | 309 | char *filename; |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index b008e788320..c3a4fbb2b99 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -1014,6 +1014,8 @@ void __init setup_arch(char **cmdline_p) | |||
1014 | paging_init(); | 1014 | paging_init(); |
1015 | x86_init.paging.pagetable_setup_done(swapper_pg_dir); | 1015 | x86_init.paging.pagetable_setup_done(swapper_pg_dir); |
1016 | 1016 | ||
1017 | setup_trampoline_page_table(); | ||
1018 | |||
1017 | tboot_probe(); | 1019 | tboot_probe(); |
1018 | 1020 | ||
1019 | #ifdef CONFIG_X86_64 | 1021 | #ifdef CONFIG_X86_64 |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index a5e928b0cb5..8b3bfc4dd70 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -73,7 +73,6 @@ | |||
73 | 73 | ||
74 | #ifdef CONFIG_X86_32 | 74 | #ifdef CONFIG_X86_32 |
75 | u8 apicid_2_node[MAX_APICID]; | 75 | u8 apicid_2_node[MAX_APICID]; |
76 | static int low_mappings; | ||
77 | #endif | 76 | #endif |
78 | 77 | ||
79 | /* State of each CPU */ | 78 | /* State of each CPU */ |
@@ -91,6 +90,25 @@ DEFINE_PER_CPU(int, cpu_state) = { 0 }; | |||
91 | static DEFINE_PER_CPU(struct task_struct *, idle_thread_array); | 90 | static DEFINE_PER_CPU(struct task_struct *, idle_thread_array); |
92 | #define get_idle_for_cpu(x) (per_cpu(idle_thread_array, x)) | 91 | #define get_idle_for_cpu(x) (per_cpu(idle_thread_array, x)) |
93 | #define set_idle_for_cpu(x, p) (per_cpu(idle_thread_array, x) = (p)) | 92 | #define set_idle_for_cpu(x, p) (per_cpu(idle_thread_array, x) = (p)) |
93 | |||
94 | /* | ||
95 | * We need this for trampoline_base protection from concurrent accesses when | ||
96 | * off- and onlining cores wildly. | ||
97 | */ | ||
98 | static DEFINE_MUTEX(x86_cpu_hotplug_driver_mutex); | ||
99 | |||
100 | void cpu_hotplug_driver_lock() | ||
101 | { | ||
102 | mutex_lock(&x86_cpu_hotplug_driver_mutex); | ||
103 | } | ||
104 | |||
105 | void cpu_hotplug_driver_unlock() | ||
106 | { | ||
107 | mutex_unlock(&x86_cpu_hotplug_driver_mutex); | ||
108 | } | ||
109 | |||
110 | ssize_t arch_cpu_probe(const char *buf, size_t count) { return -1; } | ||
111 | ssize_t arch_cpu_release(const char *buf, size_t count) { return -1; } | ||
94 | #else | 112 | #else |
95 | static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ; | 113 | static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ; |
96 | #define get_idle_for_cpu(x) (idle_thread_array[(x)]) | 114 | #define get_idle_for_cpu(x) (idle_thread_array[(x)]) |
@@ -281,6 +299,18 @@ notrace static void __cpuinit start_secondary(void *unused) | |||
281 | * fragile that we want to limit the things done here to the | 299 | * fragile that we want to limit the things done here to the |
282 | * most necessary things. | 300 | * most necessary things. |
283 | */ | 301 | */ |
302 | |||
303 | #ifdef CONFIG_X86_32 | ||
304 | /* | ||
305 | * Switch away from the trampoline page-table | ||
306 | * | ||
307 | * Do this before cpu_init() because it needs to access per-cpu | ||
308 | * data which may not be mapped in the trampoline page-table. | ||
309 | */ | ||
310 | load_cr3(swapper_pg_dir); | ||
311 | __flush_tlb_all(); | ||
312 | #endif | ||
313 | |||
284 | vmi_bringup(); | 314 | vmi_bringup(); |
285 | cpu_init(); | 315 | cpu_init(); |
286 | preempt_disable(); | 316 | preempt_disable(); |
@@ -299,12 +329,6 @@ notrace static void __cpuinit start_secondary(void *unused) | |||
299 | legacy_pic->chip->unmask(0); | 329 | legacy_pic->chip->unmask(0); |
300 | } | 330 | } |
301 | 331 | ||
302 | #ifdef CONFIG_X86_32 | ||
303 | while (low_mappings) | ||
304 | cpu_relax(); | ||
305 | __flush_tlb_all(); | ||
306 | #endif | ||
307 | |||
308 | /* This must be done before setting cpu_online_mask */ | 332 | /* This must be done before setting cpu_online_mask */ |
309 | set_cpu_sibling_map(raw_smp_processor_id()); | 333 | set_cpu_sibling_map(raw_smp_processor_id()); |
310 | wmb(); | 334 | wmb(); |
@@ -750,6 +774,7 @@ do_rest: | |||
750 | #ifdef CONFIG_X86_32 | 774 | #ifdef CONFIG_X86_32 |
751 | /* Stack for startup_32 can be just as for start_secondary onwards */ | 775 | /* Stack for startup_32 can be just as for start_secondary onwards */ |
752 | irq_ctx_init(cpu); | 776 | irq_ctx_init(cpu); |
777 | initial_page_table = __pa(&trampoline_pg_dir); | ||
753 | #else | 778 | #else |
754 | clear_tsk_thread_flag(c_idle.idle, TIF_FORK); | 779 | clear_tsk_thread_flag(c_idle.idle, TIF_FORK); |
755 | initial_gs = per_cpu_offset(cpu); | 780 | initial_gs = per_cpu_offset(cpu); |
@@ -897,20 +922,8 @@ int __cpuinit native_cpu_up(unsigned int cpu) | |||
897 | 922 | ||
898 | per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; | 923 | per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; |
899 | 924 | ||
900 | #ifdef CONFIG_X86_32 | ||
901 | /* init low mem mapping */ | ||
902 | clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY, | ||
903 | min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY)); | ||
904 | flush_tlb_all(); | ||
905 | low_mappings = 1; | ||
906 | |||
907 | err = do_boot_cpu(apicid, cpu); | 925 | err = do_boot_cpu(apicid, cpu); |
908 | 926 | ||
909 | zap_low_mappings(false); | ||
910 | low_mappings = 0; | ||
911 | #else | ||
912 | err = do_boot_cpu(apicid, cpu); | ||
913 | #endif | ||
914 | if (err) { | 927 | if (err) { |
915 | pr_debug("do_boot_cpu failed %d\n", err); | 928 | pr_debug("do_boot_cpu failed %d\n", err); |
916 | return -EIO; | 929 | return -EIO; |
diff --git a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c index 196552bb412..d5e06624e34 100644 --- a/arch/x86/kernel/sys_i386_32.c +++ b/arch/x86/kernel/sys_i386_32.c | |||
@@ -28,7 +28,9 @@ | |||
28 | * Do a system call from kernel instead of calling sys_execve so we | 28 | * Do a system call from kernel instead of calling sys_execve so we |
29 | * end up with proper pt_regs. | 29 | * end up with proper pt_regs. |
30 | */ | 30 | */ |
31 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | 31 | int kernel_execve(const char *filename, |
32 | const char *const argv[], | ||
33 | const char *const envp[]) | ||
32 | { | 34 | { |
33 | long __res; | 35 | long __res; |
34 | asm volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" | 36 | asm volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" |
diff --git a/arch/x86/kernel/trampoline.c b/arch/x86/kernel/trampoline.c index c652ef62742..a874495b367 100644 --- a/arch/x86/kernel/trampoline.c +++ b/arch/x86/kernel/trampoline.c | |||
@@ -1,6 +1,7 @@ | |||
1 | #include <linux/io.h> | 1 | #include <linux/io.h> |
2 | 2 | ||
3 | #include <asm/trampoline.h> | 3 | #include <asm/trampoline.h> |
4 | #include <asm/pgtable.h> | ||
4 | #include <asm/e820.h> | 5 | #include <asm/e820.h> |
5 | 6 | ||
6 | #if defined(CONFIG_X86_64) && defined(CONFIG_ACPI_SLEEP) | 7 | #if defined(CONFIG_X86_64) && defined(CONFIG_ACPI_SLEEP) |
@@ -37,3 +38,20 @@ unsigned long __trampinit setup_trampoline(void) | |||
37 | memcpy(trampoline_base, trampoline_data, TRAMPOLINE_SIZE); | 38 | memcpy(trampoline_base, trampoline_data, TRAMPOLINE_SIZE); |
38 | return virt_to_phys(trampoline_base); | 39 | return virt_to_phys(trampoline_base); |
39 | } | 40 | } |
41 | |||
42 | void __init setup_trampoline_page_table(void) | ||
43 | { | ||
44 | #ifdef CONFIG_X86_32 | ||
45 | /* Copy kernel address range */ | ||
46 | clone_pgd_range(trampoline_pg_dir + KERNEL_PGD_BOUNDARY, | ||
47 | swapper_pg_dir + KERNEL_PGD_BOUNDARY, | ||
48 | min_t(unsigned long, KERNEL_PGD_PTRS, | ||
49 | KERNEL_PGD_BOUNDARY)); | ||
50 | |||
51 | /* Initialize low mappings */ | ||
52 | clone_pgd_range(trampoline_pg_dir, | ||
53 | swapper_pg_dir + KERNEL_PGD_BOUNDARY, | ||
54 | min_t(unsigned long, KERNEL_PGD_PTRS, | ||
55 | KERNEL_PGD_BOUNDARY)); | ||
56 | #endif | ||
57 | } | ||
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index ce8e5023933..d632934cb63 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
@@ -626,6 +626,44 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) | |||
626 | local_irq_restore(flags); | 626 | local_irq_restore(flags); |
627 | } | 627 | } |
628 | 628 | ||
629 | static unsigned long long cyc2ns_suspend; | ||
630 | |||
631 | void save_sched_clock_state(void) | ||
632 | { | ||
633 | if (!sched_clock_stable) | ||
634 | return; | ||
635 | |||
636 | cyc2ns_suspend = sched_clock(); | ||
637 | } | ||
638 | |||
639 | /* | ||
640 | * Even on processors with invariant TSC, TSC gets reset in some the | ||
641 | * ACPI system sleep states. And in some systems BIOS seem to reinit TSC to | ||
642 | * arbitrary value (still sync'd across cpu's) during resume from such sleep | ||
643 | * states. To cope up with this, recompute the cyc2ns_offset for each cpu so | ||
644 | * that sched_clock() continues from the point where it was left off during | ||
645 | * suspend. | ||
646 | */ | ||
647 | void restore_sched_clock_state(void) | ||
648 | { | ||
649 | unsigned long long offset; | ||
650 | unsigned long flags; | ||
651 | int cpu; | ||
652 | |||
653 | if (!sched_clock_stable) | ||
654 | return; | ||
655 | |||
656 | local_irq_save(flags); | ||
657 | |||
658 | get_cpu_var(cyc2ns_offset) = 0; | ||
659 | offset = cyc2ns_suspend - sched_clock(); | ||
660 | |||
661 | for_each_possible_cpu(cpu) | ||
662 | per_cpu(cyc2ns_offset, cpu) = offset; | ||
663 | |||
664 | local_irq_restore(flags); | ||
665 | } | ||
666 | |||
629 | #ifdef CONFIG_CPU_FREQ | 667 | #ifdef CONFIG_CPU_FREQ |
630 | 668 | ||
631 | /* Frequency scaling support. Adjust the TSC based timer when the cpu frequency | 669 | /* Frequency scaling support. Adjust the TSC based timer when the cpu frequency |
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 0fd6378981f..ddeb2314b52 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c | |||
@@ -697,6 +697,7 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags) | |||
697 | pit->wq = create_singlethread_workqueue("kvm-pit-wq"); | 697 | pit->wq = create_singlethread_workqueue("kvm-pit-wq"); |
698 | if (!pit->wq) { | 698 | if (!pit->wq) { |
699 | mutex_unlock(&pit->pit_state.lock); | 699 | mutex_unlock(&pit->pit_state.lock); |
700 | kvm_free_irq_source_id(kvm, pit->irq_source_id); | ||
700 | kfree(pit); | 701 | kfree(pit); |
701 | return NULL; | 702 | return NULL; |
702 | } | 703 | } |
@@ -742,7 +743,7 @@ fail: | |||
742 | kvm_unregister_irq_mask_notifier(kvm, 0, &pit->mask_notifier); | 743 | kvm_unregister_irq_mask_notifier(kvm, 0, &pit->mask_notifier); |
743 | kvm_unregister_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier); | 744 | kvm_unregister_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier); |
744 | kvm_free_irq_source_id(kvm, pit->irq_source_id); | 745 | kvm_free_irq_source_id(kvm, pit->irq_source_id); |
745 | 746 | destroy_workqueue(pit->wq); | |
746 | kfree(pit); | 747 | kfree(pit); |
747 | return NULL; | 748 | return NULL; |
748 | } | 749 | } |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 25f19078b32..3a09c625d52 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -2387,7 +2387,7 @@ static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu, | |||
2387 | if (cpu_has_xsave) | 2387 | if (cpu_has_xsave) |
2388 | memcpy(guest_xsave->region, | 2388 | memcpy(guest_xsave->region, |
2389 | &vcpu->arch.guest_fpu.state->xsave, | 2389 | &vcpu->arch.guest_fpu.state->xsave, |
2390 | sizeof(struct xsave_struct)); | 2390 | xstate_size); |
2391 | else { | 2391 | else { |
2392 | memcpy(guest_xsave->region, | 2392 | memcpy(guest_xsave->region, |
2393 | &vcpu->arch.guest_fpu.state->fxsave, | 2393 | &vcpu->arch.guest_fpu.state->fxsave, |
@@ -2405,7 +2405,7 @@ static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu, | |||
2405 | 2405 | ||
2406 | if (cpu_has_xsave) | 2406 | if (cpu_has_xsave) |
2407 | memcpy(&vcpu->arch.guest_fpu.state->xsave, | 2407 | memcpy(&vcpu->arch.guest_fpu.state->xsave, |
2408 | guest_xsave->region, sizeof(struct xsave_struct)); | 2408 | guest_xsave->region, xstate_size); |
2409 | else { | 2409 | else { |
2410 | if (xstate_bv & ~XSTATE_FPSSE) | 2410 | if (xstate_bv & ~XSTATE_FPSSE) |
2411 | return -EINVAL; | 2411 | return -EINVAL; |
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index e7e8c5f5495..87bb35e34ef 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c | |||
@@ -113,6 +113,7 @@ static void __save_processor_state(struct saved_context *ctxt) | |||
113 | void save_processor_state(void) | 113 | void save_processor_state(void) |
114 | { | 114 | { |
115 | __save_processor_state(&saved_context); | 115 | __save_processor_state(&saved_context); |
116 | save_sched_clock_state(); | ||
116 | } | 117 | } |
117 | #ifdef CONFIG_X86_32 | 118 | #ifdef CONFIG_X86_32 |
118 | EXPORT_SYMBOL(save_processor_state); | 119 | EXPORT_SYMBOL(save_processor_state); |
@@ -229,6 +230,7 @@ static void __restore_processor_state(struct saved_context *ctxt) | |||
229 | void restore_processor_state(void) | 230 | void restore_processor_state(void) |
230 | { | 231 | { |
231 | __restore_processor_state(&saved_context); | 232 | __restore_processor_state(&saved_context); |
233 | restore_sched_clock_state(); | ||
232 | } | 234 | } |
233 | #ifdef CONFIG_X86_32 | 235 | #ifdef CONFIG_X86_32 |
234 | EXPORT_SYMBOL(restore_processor_state); | 236 | EXPORT_SYMBOL(restore_processor_state); |
diff --git a/arch/x86/xen/platform-pci-unplug.c b/arch/x86/xen/platform-pci-unplug.c index 554c002a1e1..0f456386cce 100644 --- a/arch/x86/xen/platform-pci-unplug.c +++ b/arch/x86/xen/platform-pci-unplug.c | |||
@@ -72,13 +72,17 @@ void __init xen_unplug_emulated_devices(void) | |||
72 | { | 72 | { |
73 | int r; | 73 | int r; |
74 | 74 | ||
75 | /* user explicitly requested no unplug */ | ||
76 | if (xen_emul_unplug & XEN_UNPLUG_NEVER) | ||
77 | return; | ||
75 | /* check the version of the xen platform PCI device */ | 78 | /* check the version of the xen platform PCI device */ |
76 | r = check_platform_magic(); | 79 | r = check_platform_magic(); |
77 | /* If the version matches enable the Xen platform PCI driver. | 80 | /* If the version matches enable the Xen platform PCI driver. |
78 | * Also enable the Xen platform PCI driver if the version is really old | 81 | * Also enable the Xen platform PCI driver if the host does |
79 | * and the user told us to ignore it. */ | 82 | * not support the unplug protocol (XEN_PLATFORM_ERR_MAGIC) |
83 | * but the user told us that unplugging is unnecessary. */ | ||
80 | if (r && !(r == XEN_PLATFORM_ERR_MAGIC && | 84 | if (r && !(r == XEN_PLATFORM_ERR_MAGIC && |
81 | (xen_emul_unplug & XEN_UNPLUG_IGNORE))) | 85 | (xen_emul_unplug & XEN_UNPLUG_UNNECESSARY))) |
82 | return; | 86 | return; |
83 | /* Set the default value of xen_emul_unplug depending on whether or | 87 | /* Set the default value of xen_emul_unplug depending on whether or |
84 | * not the Xen PV frontends and the Xen platform PCI driver have | 88 | * not the Xen PV frontends and the Xen platform PCI driver have |
@@ -99,7 +103,7 @@ void __init xen_unplug_emulated_devices(void) | |||
99 | } | 103 | } |
100 | } | 104 | } |
101 | /* Now unplug the emulated devices */ | 105 | /* Now unplug the emulated devices */ |
102 | if (!(xen_emul_unplug & XEN_UNPLUG_IGNORE)) | 106 | if (!(xen_emul_unplug & XEN_UNPLUG_UNNECESSARY)) |
103 | outw(xen_emul_unplug, XEN_IOPORT_UNPLUG); | 107 | outw(xen_emul_unplug, XEN_IOPORT_UNPLUG); |
104 | xen_platform_pci_unplug = xen_emul_unplug; | 108 | xen_platform_pci_unplug = xen_emul_unplug; |
105 | } | 109 | } |
@@ -125,8 +129,10 @@ static int __init parse_xen_emul_unplug(char *arg) | |||
125 | xen_emul_unplug |= XEN_UNPLUG_AUX_IDE_DISKS; | 129 | xen_emul_unplug |= XEN_UNPLUG_AUX_IDE_DISKS; |
126 | else if (!strncmp(p, "nics", l)) | 130 | else if (!strncmp(p, "nics", l)) |
127 | xen_emul_unplug |= XEN_UNPLUG_ALL_NICS; | 131 | xen_emul_unplug |= XEN_UNPLUG_ALL_NICS; |
128 | else if (!strncmp(p, "ignore", l)) | 132 | else if (!strncmp(p, "unnecessary", l)) |
129 | xen_emul_unplug |= XEN_UNPLUG_IGNORE; | 133 | xen_emul_unplug |= XEN_UNPLUG_UNNECESSARY; |
134 | else if (!strncmp(p, "never", l)) | ||
135 | xen_emul_unplug |= XEN_UNPLUG_NEVER; | ||
130 | else | 136 | else |
131 | printk(KERN_WARNING "unrecognised option '%s' " | 137 | printk(KERN_WARNING "unrecognised option '%s' " |
132 | "in parameter 'xen_emul_unplug'\n", p); | 138 | "in parameter 'xen_emul_unplug'\n", p); |
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index 7c2f38f68eb..e3558b9a58b 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c | |||
@@ -318,8 +318,9 @@ long xtensa_clone(unsigned long clone_flags, unsigned long newsp, | |||
318 | */ | 318 | */ |
319 | 319 | ||
320 | asmlinkage | 320 | asmlinkage |
321 | long xtensa_execve(const char __user *name, char __user * __user *argv, | 321 | long xtensa_execve(const char __user *name, |
322 | char __user * __user *envp, | 322 | const char __user *const __user *argv, |
323 | const char __user *const __user *envp, | ||
323 | long a3, long a4, long a5, | 324 | long a3, long a4, long a5, |
324 | struct pt_regs *regs) | 325 | struct pt_regs *regs) |
325 | { | 326 | { |
diff --git a/crypto/Kconfig b/crypto/Kconfig index 1cd497d7a15..e573077f167 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig | |||
@@ -101,13 +101,13 @@ config CRYPTO_MANAGER2 | |||
101 | select CRYPTO_BLKCIPHER2 | 101 | select CRYPTO_BLKCIPHER2 |
102 | select CRYPTO_PCOMP2 | 102 | select CRYPTO_PCOMP2 |
103 | 103 | ||
104 | config CRYPTO_MANAGER_TESTS | 104 | config CRYPTO_MANAGER_DISABLE_TESTS |
105 | bool "Run algolithms' self-tests" | 105 | bool "Disable run-time self tests" |
106 | default y | 106 | default y |
107 | depends on CRYPTO_MANAGER2 | 107 | depends on CRYPTO_MANAGER2 |
108 | help | 108 | help |
109 | Run cryptomanager's tests for the new crypto algorithms being | 109 | Disable run-time self tests that normally take place at |
110 | registered. | 110 | algorithm registration. |
111 | 111 | ||
112 | config CRYPTO_GF128MUL | 112 | config CRYPTO_GF128MUL |
113 | tristate "GF(2^128) multiplication functions (EXPERIMENTAL)" | 113 | tristate "GF(2^128) multiplication functions (EXPERIMENTAL)" |
diff --git a/crypto/ahash.c b/crypto/ahash.c index b8c59b889c6..f669822a7a4 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c | |||
@@ -47,8 +47,11 @@ static int hash_walk_next(struct crypto_hash_walk *walk) | |||
47 | walk->data = crypto_kmap(walk->pg, 0); | 47 | walk->data = crypto_kmap(walk->pg, 0); |
48 | walk->data += offset; | 48 | walk->data += offset; |
49 | 49 | ||
50 | if (offset & alignmask) | 50 | if (offset & alignmask) { |
51 | nbytes = alignmask + 1 - (offset & alignmask); | 51 | unsigned int unaligned = alignmask + 1 - (offset & alignmask); |
52 | if (nbytes > unaligned) | ||
53 | nbytes = unaligned; | ||
54 | } | ||
52 | 55 | ||
53 | walk->entrylen -= nbytes; | 56 | walk->entrylen -= nbytes; |
54 | return nbytes; | 57 | return nbytes; |
diff --git a/crypto/algboss.c b/crypto/algboss.c index 40bd391f34d..791d194958f 100644 --- a/crypto/algboss.c +++ b/crypto/algboss.c | |||
@@ -206,13 +206,16 @@ err: | |||
206 | return NOTIFY_OK; | 206 | return NOTIFY_OK; |
207 | } | 207 | } |
208 | 208 | ||
209 | #ifdef CONFIG_CRYPTO_MANAGER_TESTS | ||
210 | static int cryptomgr_test(void *data) | 209 | static int cryptomgr_test(void *data) |
211 | { | 210 | { |
212 | struct crypto_test_param *param = data; | 211 | struct crypto_test_param *param = data; |
213 | u32 type = param->type; | 212 | u32 type = param->type; |
214 | int err = 0; | 213 | int err = 0; |
215 | 214 | ||
215 | #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS | ||
216 | goto skiptest; | ||
217 | #endif | ||
218 | |||
216 | if (type & CRYPTO_ALG_TESTED) | 219 | if (type & CRYPTO_ALG_TESTED) |
217 | goto skiptest; | 220 | goto skiptest; |
218 | 221 | ||
@@ -267,7 +270,6 @@ err_put_module: | |||
267 | err: | 270 | err: |
268 | return NOTIFY_OK; | 271 | return NOTIFY_OK; |
269 | } | 272 | } |
270 | #endif /* CONFIG_CRYPTO_MANAGER_TESTS */ | ||
271 | 273 | ||
272 | static int cryptomgr_notify(struct notifier_block *this, unsigned long msg, | 274 | static int cryptomgr_notify(struct notifier_block *this, unsigned long msg, |
273 | void *data) | 275 | void *data) |
@@ -275,10 +277,8 @@ static int cryptomgr_notify(struct notifier_block *this, unsigned long msg, | |||
275 | switch (msg) { | 277 | switch (msg) { |
276 | case CRYPTO_MSG_ALG_REQUEST: | 278 | case CRYPTO_MSG_ALG_REQUEST: |
277 | return cryptomgr_schedule_probe(data); | 279 | return cryptomgr_schedule_probe(data); |
278 | #ifdef CONFIG_CRYPTO_MANAGER_TESTS | ||
279 | case CRYPTO_MSG_ALG_REGISTER: | 280 | case CRYPTO_MSG_ALG_REGISTER: |
280 | return cryptomgr_schedule_test(data); | 281 | return cryptomgr_schedule_test(data); |
281 | #endif | ||
282 | } | 282 | } |
283 | 283 | ||
284 | return NOTIFY_DONE; | 284 | return NOTIFY_DONE; |
diff --git a/crypto/testmgr.c b/crypto/testmgr.c index abd980c729e..fa8c8f78c8d 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | #include "internal.h" | 24 | #include "internal.h" |
25 | 25 | ||
26 | #ifndef CONFIG_CRYPTO_MANAGER_TESTS | 26 | #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS |
27 | 27 | ||
28 | /* a perfect nop */ | 28 | /* a perfect nop */ |
29 | int alg_test(const char *driver, const char *alg, u32 type, u32 mask) | 29 | int alg_test(const char *driver, const char *alg, u32 type, u32 mask) |
@@ -2542,6 +2542,6 @@ non_fips_alg: | |||
2542 | return -EINVAL; | 2542 | return -EINVAL; |
2543 | } | 2543 | } |
2544 | 2544 | ||
2545 | #endif /* CONFIG_CRYPTO_MANAGER_TESTS */ | 2545 | #endif /* CONFIG_CRYPTO_MANAGER_DISABLE_TESTS */ |
2546 | 2546 | ||
2547 | EXPORT_SYMBOL_GPL(alg_test); | 2547 | EXPORT_SYMBOL_GPL(alg_test); |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 1f67057af2a..3ba8d1f44a7 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/pm_runtime.h> | 33 | #include <linux/pm_runtime.h> |
34 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
35 | #include <linux/pci-acpi.h> | 35 | #include <linux/pci-acpi.h> |
36 | #include <linux/pci-aspm.h> | ||
37 | #include <linux/acpi.h> | 36 | #include <linux/acpi.h> |
38 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
39 | #include <acpi/acpi_bus.h> | 38 | #include <acpi/acpi_bus.h> |
@@ -226,22 +225,31 @@ static acpi_status acpi_pci_run_osc(acpi_handle handle, | |||
226 | return status; | 225 | return status; |
227 | } | 226 | } |
228 | 227 | ||
229 | static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 flags) | 228 | static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, |
229 | u32 support, | ||
230 | u32 *control) | ||
230 | { | 231 | { |
231 | acpi_status status; | 232 | acpi_status status; |
232 | u32 support_set, result, capbuf[3]; | 233 | u32 result, capbuf[3]; |
234 | |||
235 | support &= OSC_PCI_SUPPORT_MASKS; | ||
236 | support |= root->osc_support_set; | ||
233 | 237 | ||
234 | /* do _OSC query for all possible controls */ | ||
235 | support_set = root->osc_support_set | (flags & OSC_PCI_SUPPORT_MASKS); | ||
236 | capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; | 238 | capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; |
237 | capbuf[OSC_SUPPORT_TYPE] = support_set; | 239 | capbuf[OSC_SUPPORT_TYPE] = support; |
238 | capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS; | 240 | if (control) { |
241 | *control &= OSC_PCI_CONTROL_MASKS; | ||
242 | capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set; | ||
243 | } else { | ||
244 | /* Run _OSC query for all possible controls. */ | ||
245 | capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS; | ||
246 | } | ||
239 | 247 | ||
240 | status = acpi_pci_run_osc(root->device->handle, capbuf, &result); | 248 | status = acpi_pci_run_osc(root->device->handle, capbuf, &result); |
241 | if (ACPI_SUCCESS(status)) { | 249 | if (ACPI_SUCCESS(status)) { |
242 | root->osc_support_set = support_set; | 250 | root->osc_support_set = support; |
243 | root->osc_control_qry = result; | 251 | if (control) |
244 | root->osc_queried = 1; | 252 | *control = result; |
245 | } | 253 | } |
246 | return status; | 254 | return status; |
247 | } | 255 | } |
@@ -255,7 +263,7 @@ static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags) | |||
255 | if (ACPI_FAILURE(status)) | 263 | if (ACPI_FAILURE(status)) |
256 | return status; | 264 | return status; |
257 | mutex_lock(&osc_lock); | 265 | mutex_lock(&osc_lock); |
258 | status = acpi_pci_query_osc(root, flags); | 266 | status = acpi_pci_query_osc(root, flags, NULL); |
259 | mutex_unlock(&osc_lock); | 267 | mutex_unlock(&osc_lock); |
260 | return status; | 268 | return status; |
261 | } | 269 | } |
@@ -365,55 +373,70 @@ out: | |||
365 | EXPORT_SYMBOL_GPL(acpi_get_pci_dev); | 373 | EXPORT_SYMBOL_GPL(acpi_get_pci_dev); |
366 | 374 | ||
367 | /** | 375 | /** |
368 | * acpi_pci_osc_control_set - commit requested control to Firmware | 376 | * acpi_pci_osc_control_set - Request control of PCI root _OSC features. |
369 | * @handle: acpi_handle for the target ACPI object | 377 | * @handle: ACPI handle of a PCI root bridge (or PCIe Root Complex). |
370 | * @flags: driver's requested control bits | 378 | * @mask: Mask of _OSC bits to request control of, place to store control mask. |
379 | * @req: Mask of _OSC bits the control of is essential to the caller. | ||
380 | * | ||
381 | * Run _OSC query for @mask and if that is successful, compare the returned | ||
382 | * mask of control bits with @req. If all of the @req bits are set in the | ||
383 | * returned mask, run _OSC request for it. | ||
371 | * | 384 | * |
372 | * Attempt to take control from Firmware on requested control bits. | 385 | * The variable at the @mask address may be modified regardless of whether or |
386 | * not the function returns success. On success it will contain the mask of | ||
387 | * _OSC bits the BIOS has granted control of, but its contents are meaningless | ||
388 | * on failure. | ||
373 | **/ | 389 | **/ |
374 | acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags) | 390 | acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req) |
375 | { | 391 | { |
392 | struct acpi_pci_root *root; | ||
376 | acpi_status status; | 393 | acpi_status status; |
377 | u32 control_req, result, capbuf[3]; | 394 | u32 ctrl, capbuf[3]; |
378 | acpi_handle tmp; | 395 | acpi_handle tmp; |
379 | struct acpi_pci_root *root; | ||
380 | 396 | ||
381 | status = acpi_get_handle(handle, "_OSC", &tmp); | 397 | if (!mask) |
382 | if (ACPI_FAILURE(status)) | 398 | return AE_BAD_PARAMETER; |
383 | return status; | ||
384 | 399 | ||
385 | control_req = (flags & OSC_PCI_CONTROL_MASKS); | 400 | ctrl = *mask & OSC_PCI_CONTROL_MASKS; |
386 | if (!control_req) | 401 | if ((ctrl & req) != req) |
387 | return AE_TYPE; | 402 | return AE_TYPE; |
388 | 403 | ||
389 | root = acpi_pci_find_root(handle); | 404 | root = acpi_pci_find_root(handle); |
390 | if (!root) | 405 | if (!root) |
391 | return AE_NOT_EXIST; | 406 | return AE_NOT_EXIST; |
392 | 407 | ||
408 | status = acpi_get_handle(handle, "_OSC", &tmp); | ||
409 | if (ACPI_FAILURE(status)) | ||
410 | return status; | ||
411 | |||
393 | mutex_lock(&osc_lock); | 412 | mutex_lock(&osc_lock); |
413 | |||
414 | *mask = ctrl | root->osc_control_set; | ||
394 | /* No need to evaluate _OSC if the control was already granted. */ | 415 | /* No need to evaluate _OSC if the control was already granted. */ |
395 | if ((root->osc_control_set & control_req) == control_req) | 416 | if ((root->osc_control_set & ctrl) == ctrl) |
396 | goto out; | 417 | goto out; |
397 | 418 | ||
398 | /* Need to query controls first before requesting them */ | 419 | /* Need to check the available controls bits before requesting them. */ |
399 | if (!root->osc_queried) { | 420 | while (*mask) { |
400 | status = acpi_pci_query_osc(root, root->osc_support_set); | 421 | status = acpi_pci_query_osc(root, root->osc_support_set, mask); |
401 | if (ACPI_FAILURE(status)) | 422 | if (ACPI_FAILURE(status)) |
402 | goto out; | 423 | goto out; |
424 | if (ctrl == *mask) | ||
425 | break; | ||
426 | ctrl = *mask; | ||
403 | } | 427 | } |
404 | if ((root->osc_control_qry & control_req) != control_req) { | 428 | |
405 | printk(KERN_DEBUG | 429 | if ((ctrl & req) != req) { |
406 | "Firmware did not grant requested _OSC control\n"); | ||
407 | status = AE_SUPPORT; | 430 | status = AE_SUPPORT; |
408 | goto out; | 431 | goto out; |
409 | } | 432 | } |
410 | 433 | ||
411 | capbuf[OSC_QUERY_TYPE] = 0; | 434 | capbuf[OSC_QUERY_TYPE] = 0; |
412 | capbuf[OSC_SUPPORT_TYPE] = root->osc_support_set; | 435 | capbuf[OSC_SUPPORT_TYPE] = root->osc_support_set; |
413 | capbuf[OSC_CONTROL_TYPE] = root->osc_control_set | control_req; | 436 | capbuf[OSC_CONTROL_TYPE] = ctrl; |
414 | status = acpi_pci_run_osc(handle, capbuf, &result); | 437 | status = acpi_pci_run_osc(handle, capbuf, mask); |
415 | if (ACPI_SUCCESS(status)) | 438 | if (ACPI_SUCCESS(status)) |
416 | root->osc_control_set = result; | 439 | root->osc_control_set = *mask; |
417 | out: | 440 | out: |
418 | mutex_unlock(&osc_lock); | 441 | mutex_unlock(&osc_lock); |
419 | return status; | 442 | return status; |
@@ -544,14 +567,6 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
544 | if (flags != base_flags) | 567 | if (flags != base_flags) |
545 | acpi_pci_osc_support(root, flags); | 568 | acpi_pci_osc_support(root, flags); |
546 | 569 | ||
547 | status = acpi_pci_osc_control_set(root->device->handle, | ||
548 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
549 | |||
550 | if (ACPI_FAILURE(status)) { | ||
551 | printk(KERN_INFO "Unable to assume PCIe control: Disabling ASPM\n"); | ||
552 | pcie_no_aspm(); | ||
553 | } | ||
554 | |||
555 | pci_acpi_add_bus_pm_notifier(device, root->bus); | 570 | pci_acpi_add_bus_pm_notifier(device, root->bus); |
556 | if (device->wakeup.flags.run_wake) | 571 | if (device->wakeup.flags.run_wake) |
557 | device_set_run_wake(root->bus->bridge, true); | 572 | device_set_run_wake(root->bus->bridge, true); |
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 65e3e270837..11ec911016c 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -828,6 +828,7 @@ config PATA_SAMSUNG_CF | |||
828 | config PATA_WINBOND_VLB | 828 | config PATA_WINBOND_VLB |
829 | tristate "Winbond W83759A VLB PATA support (Experimental)" | 829 | tristate "Winbond W83759A VLB PATA support (Experimental)" |
830 | depends on ISA && EXPERIMENTAL | 830 | depends on ISA && EXPERIMENTAL |
831 | select PATA_LEGACY | ||
831 | help | 832 | help |
832 | Support for the Winbond W83759A controller on Vesa Local Bus | 833 | Support for the Winbond W83759A controller on Vesa Local Bus |
833 | systems. | 834 | systems. |
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 158eaa961b1..d5df04a395c 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile | |||
@@ -89,7 +89,6 @@ obj-$(CONFIG_PATA_QDI) += pata_qdi.o | |||
89 | obj-$(CONFIG_PATA_RB532) += pata_rb532_cf.o | 89 | obj-$(CONFIG_PATA_RB532) += pata_rb532_cf.o |
90 | obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o | 90 | obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o |
91 | obj-$(CONFIG_PATA_SAMSUNG_CF) += pata_samsung_cf.o | 91 | obj-$(CONFIG_PATA_SAMSUNG_CF) += pata_samsung_cf.o |
92 | obj-$(CONFIG_PATA_WINBOND_VLB) += pata_winbond.o | ||
93 | 92 | ||
94 | obj-$(CONFIG_PATA_PXA) += pata_pxa.o | 93 | obj-$(CONFIG_PATA_PXA) += pata_pxa.o |
95 | 94 | ||
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index fe75d8befc3..013727b2041 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -60,6 +60,7 @@ enum board_ids { | |||
60 | board_ahci, | 60 | board_ahci, |
61 | board_ahci_ign_iferr, | 61 | board_ahci_ign_iferr, |
62 | board_ahci_nosntf, | 62 | board_ahci_nosntf, |
63 | board_ahci_yes_fbs, | ||
63 | 64 | ||
64 | /* board IDs for specific chipsets in alphabetical order */ | 65 | /* board IDs for specific chipsets in alphabetical order */ |
65 | board_ahci_mcp65, | 66 | board_ahci_mcp65, |
@@ -132,6 +133,14 @@ static const struct ata_port_info ahci_port_info[] = { | |||
132 | .udma_mask = ATA_UDMA6, | 133 | .udma_mask = ATA_UDMA6, |
133 | .port_ops = &ahci_ops, | 134 | .port_ops = &ahci_ops, |
134 | }, | 135 | }, |
136 | [board_ahci_yes_fbs] = | ||
137 | { | ||
138 | AHCI_HFLAGS (AHCI_HFLAG_YES_FBS), | ||
139 | .flags = AHCI_FLAG_COMMON, | ||
140 | .pio_mask = ATA_PIO4, | ||
141 | .udma_mask = ATA_UDMA6, | ||
142 | .port_ops = &ahci_ops, | ||
143 | }, | ||
135 | /* by chipsets */ | 144 | /* by chipsets */ |
136 | [board_ahci_mcp65] = | 145 | [board_ahci_mcp65] = |
137 | { | 146 | { |
@@ -362,6 +371,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
362 | /* Marvell */ | 371 | /* Marvell */ |
363 | { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ | 372 | { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ |
364 | { PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv }, /* 6121 */ | 373 | { PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv }, /* 6121 */ |
374 | { PCI_DEVICE(0x1b4b, 0x9123), | ||
375 | .driver_data = board_ahci_yes_fbs }, /* 88se9128 */ | ||
365 | 376 | ||
366 | /* Promise */ | 377 | /* Promise */ |
367 | { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ | 378 | { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ |
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 7113c572447..474427b6f99 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h | |||
@@ -209,6 +209,7 @@ enum { | |||
209 | link offline */ | 209 | link offline */ |
210 | AHCI_HFLAG_NO_SNTF = (1 << 12), /* no sntf */ | 210 | AHCI_HFLAG_NO_SNTF = (1 << 12), /* no sntf */ |
211 | AHCI_HFLAG_NO_FPDMA_AA = (1 << 13), /* no FPDMA AA */ | 211 | AHCI_HFLAG_NO_FPDMA_AA = (1 << 13), /* no FPDMA AA */ |
212 | AHCI_HFLAG_YES_FBS = (1 << 14), /* force FBS cap on */ | ||
212 | 213 | ||
213 | /* ap->flags bits */ | 214 | /* ap->flags bits */ |
214 | 215 | ||
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 81e772a94d5..666850d31df 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
@@ -430,6 +430,12 @@ void ahci_save_initial_config(struct device *dev, | |||
430 | cap &= ~HOST_CAP_SNTF; | 430 | cap &= ~HOST_CAP_SNTF; |
431 | } | 431 | } |
432 | 432 | ||
433 | if (!(cap & HOST_CAP_FBS) && (hpriv->flags & AHCI_HFLAG_YES_FBS)) { | ||
434 | dev_printk(KERN_INFO, dev, | ||
435 | "controller can do FBS, turning on CAP_FBS\n"); | ||
436 | cap |= HOST_CAP_FBS; | ||
437 | } | ||
438 | |||
433 | if (force_port_map && port_map != force_port_map) { | 439 | if (force_port_map && port_map != force_port_map) { |
434 | dev_printk(KERN_INFO, dev, "forcing port_map 0x%x -> 0x%x\n", | 440 | dev_printk(KERN_INFO, dev, "forcing port_map 0x%x -> 0x%x\n", |
435 | port_map, force_port_map); | 441 | port_map, force_port_map); |
@@ -2036,9 +2042,15 @@ static int ahci_port_start(struct ata_port *ap) | |||
2036 | u32 cmd = readl(port_mmio + PORT_CMD); | 2042 | u32 cmd = readl(port_mmio + PORT_CMD); |
2037 | if (cmd & PORT_CMD_FBSCP) | 2043 | if (cmd & PORT_CMD_FBSCP) |
2038 | pp->fbs_supported = true; | 2044 | pp->fbs_supported = true; |
2039 | else | 2045 | else if (hpriv->flags & AHCI_HFLAG_YES_FBS) { |
2046 | dev_printk(KERN_INFO, dev, | ||
2047 | "port %d can do FBS, forcing FBSCP\n", | ||
2048 | ap->port_no); | ||
2049 | pp->fbs_supported = true; | ||
2050 | } else | ||
2040 | dev_printk(KERN_WARNING, dev, | 2051 | dev_printk(KERN_WARNING, dev, |
2041 | "The port is not capable of FBS\n"); | 2052 | "port %d is not capable of FBS\n", |
2053 | ap->port_no); | ||
2042 | } | 2054 | } |
2043 | 2055 | ||
2044 | if (pp->fbs_supported) { | 2056 | if (pp->fbs_supported) { |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 7ef7c4f216f..c035b3d041e 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -5111,15 +5111,18 @@ void ata_qc_issue(struct ata_queued_cmd *qc) | |||
5111 | qc->flags |= ATA_QCFLAG_ACTIVE; | 5111 | qc->flags |= ATA_QCFLAG_ACTIVE; |
5112 | ap->qc_active |= 1 << qc->tag; | 5112 | ap->qc_active |= 1 << qc->tag; |
5113 | 5113 | ||
5114 | /* We guarantee to LLDs that they will have at least one | 5114 | /* |
5115 | * We guarantee to LLDs that they will have at least one | ||
5115 | * non-zero sg if the command is a data command. | 5116 | * non-zero sg if the command is a data command. |
5116 | */ | 5117 | */ |
5117 | BUG_ON(ata_is_data(prot) && (!qc->sg || !qc->n_elem || !qc->nbytes)); | 5118 | if (WARN_ON_ONCE(ata_is_data(prot) && |
5119 | (!qc->sg || !qc->n_elem || !qc->nbytes))) | ||
5120 | goto sys_err; | ||
5118 | 5121 | ||
5119 | if (ata_is_dma(prot) || (ata_is_pio(prot) && | 5122 | if (ata_is_dma(prot) || (ata_is_pio(prot) && |
5120 | (ap->flags & ATA_FLAG_PIO_DMA))) | 5123 | (ap->flags & ATA_FLAG_PIO_DMA))) |
5121 | if (ata_sg_setup(qc)) | 5124 | if (ata_sg_setup(qc)) |
5122 | goto sg_err; | 5125 | goto sys_err; |
5123 | 5126 | ||
5124 | /* if device is sleeping, schedule reset and abort the link */ | 5127 | /* if device is sleeping, schedule reset and abort the link */ |
5125 | if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) { | 5128 | if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) { |
@@ -5136,7 +5139,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc) | |||
5136 | goto err; | 5139 | goto err; |
5137 | return; | 5140 | return; |
5138 | 5141 | ||
5139 | sg_err: | 5142 | sys_err: |
5140 | qc->err_mask |= AC_ERR_SYSTEM; | 5143 | qc->err_mask |= AC_ERR_SYSTEM; |
5141 | err: | 5144 | err: |
5142 | ata_qc_complete(qc); | 5145 | ata_qc_complete(qc); |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 674c1436491..3b82d8ef76f 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -2735,10 +2735,6 @@ unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc) | |||
2735 | { | 2735 | { |
2736 | struct ata_port *ap = qc->ap; | 2736 | struct ata_port *ap = qc->ap; |
2737 | 2737 | ||
2738 | /* see ata_dma_blacklisted() */ | ||
2739 | BUG_ON((ap->flags & ATA_FLAG_PIO_POLLING) && | ||
2740 | qc->tf.protocol == ATAPI_PROT_DMA); | ||
2741 | |||
2742 | /* defer PIO handling to sff_qc_issue */ | 2738 | /* defer PIO handling to sff_qc_issue */ |
2743 | if (!ata_is_dma(qc->tf.protocol)) | 2739 | if (!ata_is_dma(qc->tf.protocol)) |
2744 | return ata_sff_qc_issue(qc); | 2740 | return ata_sff_qc_issue(qc); |
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 9f5da1c7454..905ff76d3cb 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c | |||
@@ -121,14 +121,8 @@ static void cmd64x_set_timing(struct ata_port *ap, struct ata_device *adev, u8 m | |||
121 | 121 | ||
122 | if (pair) { | 122 | if (pair) { |
123 | struct ata_timing tp; | 123 | struct ata_timing tp; |
124 | |||
125 | ata_timing_compute(pair, pair->pio_mode, &tp, T, 0); | 124 | ata_timing_compute(pair, pair->pio_mode, &tp, T, 0); |
126 | ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP); | 125 | ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP); |
127 | if (pair->dma_mode) { | ||
128 | ata_timing_compute(pair, pair->dma_mode, | ||
129 | &tp, T, 0); | ||
130 | ata_timing_merge(&tp, &t, &t, ATA_TIMING_SETUP); | ||
131 | } | ||
132 | } | 126 | } |
133 | } | 127 | } |
134 | 128 | ||
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 9df1ff7e1ea..eaf194138f2 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c | |||
@@ -44,6 +44,9 @@ | |||
44 | * Specific support is included for the ht6560a/ht6560b/opti82c611a/ | 44 | * Specific support is included for the ht6560a/ht6560b/opti82c611a/ |
45 | * opti82c465mv/promise 20230c/20630/qdi65x0/winbond83759A | 45 | * opti82c465mv/promise 20230c/20630/qdi65x0/winbond83759A |
46 | * | 46 | * |
47 | * Support for the Winbond 83759A when operating in advanced mode. | ||
48 | * Multichip mode is not currently supported. | ||
49 | * | ||
47 | * Use the autospeed and pio_mask options with: | 50 | * Use the autospeed and pio_mask options with: |
48 | * Appian ADI/2 aka CLPD7220 or AIC25VL01. | 51 | * Appian ADI/2 aka CLPD7220 or AIC25VL01. |
49 | * Use the jumpers, autospeed and set pio_mask to the mode on the jumpers with | 52 | * Use the jumpers, autospeed and set pio_mask to the mode on the jumpers with |
@@ -135,12 +138,18 @@ static int ht6560b; /* HT 6560A on primary 1, second 2, both 3 */ | |||
135 | static int opti82c611a; /* Opti82c611A on primary 1, sec 2, both 3 */ | 138 | static int opti82c611a; /* Opti82c611A on primary 1, sec 2, both 3 */ |
136 | static int opti82c46x; /* Opti 82c465MV present(pri/sec autodetect) */ | 139 | static int opti82c46x; /* Opti 82c465MV present(pri/sec autodetect) */ |
137 | static int qdi; /* Set to probe QDI controllers */ | 140 | static int qdi; /* Set to probe QDI controllers */ |
138 | static int winbond; /* Set to probe Winbond controllers, | ||
139 | give I/O port if non standard */ | ||
140 | static int autospeed; /* Chip present which snoops speed changes */ | 141 | static int autospeed; /* Chip present which snoops speed changes */ |
141 | static int pio_mask = ATA_PIO4; /* PIO range for autospeed devices */ | 142 | static int pio_mask = ATA_PIO4; /* PIO range for autospeed devices */ |
142 | static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ | 143 | static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ |
143 | 144 | ||
145 | #ifdef PATA_WINBOND_VLB_MODULE | ||
146 | static int winbond = 1; /* Set to probe Winbond controllers, | ||
147 | give I/O port if non standard */ | ||
148 | #else | ||
149 | static int winbond; /* Set to probe Winbond controllers, | ||
150 | give I/O port if non standard */ | ||
151 | #endif | ||
152 | |||
144 | /** | 153 | /** |
145 | * legacy_probe_add - Add interface to probe list | 154 | * legacy_probe_add - Add interface to probe list |
146 | * @port: Controller port | 155 | * @port: Controller port |
@@ -1297,6 +1306,7 @@ MODULE_AUTHOR("Alan Cox"); | |||
1297 | MODULE_DESCRIPTION("low-level driver for legacy ATA"); | 1306 | MODULE_DESCRIPTION("low-level driver for legacy ATA"); |
1298 | MODULE_LICENSE("GPL"); | 1307 | MODULE_LICENSE("GPL"); |
1299 | MODULE_VERSION(DRV_VERSION); | 1308 | MODULE_VERSION(DRV_VERSION); |
1309 | MODULE_ALIAS("pata_winbond"); | ||
1300 | 1310 | ||
1301 | module_param(probe_all, int, 0); | 1311 | module_param(probe_all, int, 0); |
1302 | module_param(autospeed, int, 0); | 1312 | module_param(autospeed, int, 0); |
@@ -1305,6 +1315,7 @@ module_param(ht6560b, int, 0); | |||
1305 | module_param(opti82c611a, int, 0); | 1315 | module_param(opti82c611a, int, 0); |
1306 | module_param(opti82c46x, int, 0); | 1316 | module_param(opti82c46x, int, 0); |
1307 | module_param(qdi, int, 0); | 1317 | module_param(qdi, int, 0); |
1318 | module_param(winbond, int, 0); | ||
1308 | module_param(pio_mask, int, 0); | 1319 | module_param(pio_mask, int, 0); |
1309 | module_param(iordy_mask, int, 0); | 1320 | module_param(iordy_mask, int, 0); |
1310 | 1321 | ||
diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c deleted file mode 100644 index 6d8619b6f67..00000000000 --- a/drivers/ata/pata_winbond.c +++ /dev/null | |||
@@ -1,282 +0,0 @@ | |||
1 | /* | ||
2 | * pata_winbond.c - Winbond VLB ATA controllers | ||
3 | * (C) 2006 Red Hat | ||
4 | * | ||
5 | * Support for the Winbond 83759A when operating in advanced mode. | ||
6 | * Multichip mode is not currently supported. | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/blkdev.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <scsi/scsi_host.h> | ||
15 | #include <linux/libata.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #define DRV_NAME "pata_winbond" | ||
19 | #define DRV_VERSION "0.0.3" | ||
20 | |||
21 | #define NR_HOST 4 /* Two winbond controllers, two channels each */ | ||
22 | |||
23 | struct winbond_data { | ||
24 | unsigned long config; | ||
25 | struct platform_device *platform_dev; | ||
26 | }; | ||
27 | |||
28 | static struct ata_host *winbond_host[NR_HOST]; | ||
29 | static struct winbond_data winbond_data[NR_HOST]; | ||
30 | static int nr_winbond_host; | ||
31 | |||
32 | #ifdef MODULE | ||
33 | static int probe_winbond = 1; | ||
34 | #else | ||
35 | static int probe_winbond; | ||
36 | #endif | ||
37 | |||
38 | static DEFINE_SPINLOCK(winbond_lock); | ||
39 | |||
40 | static void winbond_writecfg(unsigned long port, u8 reg, u8 val) | ||
41 | { | ||
42 | unsigned long flags; | ||
43 | spin_lock_irqsave(&winbond_lock, flags); | ||
44 | outb(reg, port + 0x01); | ||
45 | outb(val, port + 0x02); | ||
46 | spin_unlock_irqrestore(&winbond_lock, flags); | ||
47 | } | ||
48 | |||
49 | static u8 winbond_readcfg(unsigned long port, u8 reg) | ||
50 | { | ||
51 | u8 val; | ||
52 | |||
53 | unsigned long flags; | ||
54 | spin_lock_irqsave(&winbond_lock, flags); | ||
55 | outb(reg, port + 0x01); | ||
56 | val = inb(port + 0x02); | ||
57 | spin_unlock_irqrestore(&winbond_lock, flags); | ||
58 | |||
59 | return val; | ||
60 | } | ||
61 | |||
62 | static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) | ||
63 | { | ||
64 | struct ata_timing t; | ||
65 | struct winbond_data *winbond = ap->host->private_data; | ||
66 | int active, recovery; | ||
67 | u8 reg; | ||
68 | int timing = 0x88 + (ap->port_no * 4) + (adev->devno * 2); | ||
69 | |||
70 | reg = winbond_readcfg(winbond->config, 0x81); | ||
71 | |||
72 | /* Get the timing data in cycles */ | ||
73 | if (reg & 0x40) /* Fast VLB bus, assume 50MHz */ | ||
74 | ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000); | ||
75 | else | ||
76 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); | ||
77 | |||
78 | active = (clamp_val(t.active, 3, 17) - 1) & 0x0F; | ||
79 | recovery = (clamp_val(t.recover, 1, 15) + 1) & 0x0F; | ||
80 | timing = (active << 4) | recovery; | ||
81 | winbond_writecfg(winbond->config, timing, reg); | ||
82 | |||
83 | /* Load the setup timing */ | ||
84 | |||
85 | reg = 0x35; | ||
86 | if (adev->class != ATA_DEV_ATA) | ||
87 | reg |= 0x08; /* FIFO off */ | ||
88 | if (!ata_pio_need_iordy(adev)) | ||
89 | reg |= 0x02; /* IORDY off */ | ||
90 | reg |= (clamp_val(t.setup, 0, 3) << 6); | ||
91 | winbond_writecfg(winbond->config, timing + 1, reg); | ||
92 | } | ||
93 | |||
94 | |||
95 | static unsigned int winbond_data_xfer(struct ata_device *dev, | ||
96 | unsigned char *buf, unsigned int buflen, int rw) | ||
97 | { | ||
98 | struct ata_port *ap = dev->link->ap; | ||
99 | int slop = buflen & 3; | ||
100 | |||
101 | if (ata_id_has_dword_io(dev->id)) { | ||
102 | if (rw == READ) | ||
103 | ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | ||
104 | else | ||
105 | iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | ||
106 | |||
107 | if (unlikely(slop)) { | ||
108 | __le32 pad; | ||
109 | if (rw == READ) { | ||
110 | pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); | ||
111 | memcpy(buf + buflen - slop, &pad, slop); | ||
112 | } else { | ||
113 | memcpy(&pad, buf + buflen - slop, slop); | ||
114 | iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); | ||
115 | } | ||
116 | buflen += 4 - slop; | ||
117 | } | ||
118 | } else | ||
119 | buflen = ata_sff_data_xfer(dev, buf, buflen, rw); | ||
120 | |||
121 | return buflen; | ||
122 | } | ||
123 | |||
124 | static struct scsi_host_template winbond_sht = { | ||
125 | ATA_PIO_SHT(DRV_NAME), | ||
126 | }; | ||
127 | |||
128 | static struct ata_port_operations winbond_port_ops = { | ||
129 | .inherits = &ata_sff_port_ops, | ||
130 | .sff_data_xfer = winbond_data_xfer, | ||
131 | .cable_detect = ata_cable_40wire, | ||
132 | .set_piomode = winbond_set_piomode, | ||
133 | }; | ||
134 | |||
135 | /** | ||
136 | * winbond_init_one - attach a winbond interface | ||
137 | * @type: Type to display | ||
138 | * @io: I/O port start | ||
139 | * @irq: interrupt line | ||
140 | * @fast: True if on a > 33Mhz VLB | ||
141 | * | ||
142 | * Register a VLB bus IDE interface. Such interfaces are PIO and we | ||
143 | * assume do not support IRQ sharing. | ||
144 | */ | ||
145 | |||
146 | static __init int winbond_init_one(unsigned long port) | ||
147 | { | ||
148 | struct platform_device *pdev; | ||
149 | u8 reg; | ||
150 | int i, rc; | ||
151 | |||
152 | reg = winbond_readcfg(port, 0x81); | ||
153 | reg |= 0x80; /* jumpered mode off */ | ||
154 | winbond_writecfg(port, 0x81, reg); | ||
155 | reg = winbond_readcfg(port, 0x83); | ||
156 | reg |= 0xF0; /* local control */ | ||
157 | winbond_writecfg(port, 0x83, reg); | ||
158 | reg = winbond_readcfg(port, 0x85); | ||
159 | reg |= 0xF0; /* programmable timing */ | ||
160 | winbond_writecfg(port, 0x85, reg); | ||
161 | |||
162 | reg = winbond_readcfg(port, 0x81); | ||
163 | |||
164 | if (!(reg & 0x03)) /* Disabled */ | ||
165 | return -ENODEV; | ||
166 | |||
167 | for (i = 0; i < 2 ; i ++) { | ||
168 | unsigned long cmd_port = 0x1F0 - (0x80 * i); | ||
169 | unsigned long ctl_port = cmd_port + 0x206; | ||
170 | struct ata_host *host; | ||
171 | struct ata_port *ap; | ||
172 | void __iomem *cmd_addr, *ctl_addr; | ||
173 | |||
174 | if (!(reg & (1 << i))) | ||
175 | continue; | ||
176 | |||
177 | pdev = platform_device_register_simple(DRV_NAME, nr_winbond_host, NULL, 0); | ||
178 | if (IS_ERR(pdev)) | ||
179 | return PTR_ERR(pdev); | ||
180 | |||
181 | rc = -ENOMEM; | ||
182 | host = ata_host_alloc(&pdev->dev, 1); | ||
183 | if (!host) | ||
184 | goto err_unregister; | ||
185 | ap = host->ports[0]; | ||
186 | |||
187 | rc = -ENOMEM; | ||
188 | cmd_addr = devm_ioport_map(&pdev->dev, cmd_port, 8); | ||
189 | ctl_addr = devm_ioport_map(&pdev->dev, ctl_port, 1); | ||
190 | if (!cmd_addr || !ctl_addr) | ||
191 | goto err_unregister; | ||
192 | |||
193 | ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", cmd_port, ctl_port); | ||
194 | |||
195 | ap->ops = &winbond_port_ops; | ||
196 | ap->pio_mask = ATA_PIO4; | ||
197 | ap->flags |= ATA_FLAG_SLAVE_POSS; | ||
198 | ap->ioaddr.cmd_addr = cmd_addr; | ||
199 | ap->ioaddr.altstatus_addr = ctl_addr; | ||
200 | ap->ioaddr.ctl_addr = ctl_addr; | ||
201 | ata_sff_std_ports(&ap->ioaddr); | ||
202 | |||
203 | /* hook in a private data structure per channel */ | ||
204 | host->private_data = &winbond_data[nr_winbond_host]; | ||
205 | winbond_data[nr_winbond_host].config = port; | ||
206 | winbond_data[nr_winbond_host].platform_dev = pdev; | ||
207 | |||
208 | /* activate */ | ||
209 | rc = ata_host_activate(host, 14 + i, ata_sff_interrupt, 0, | ||
210 | &winbond_sht); | ||
211 | if (rc) | ||
212 | goto err_unregister; | ||
213 | |||
214 | winbond_host[nr_winbond_host++] = dev_get_drvdata(&pdev->dev); | ||
215 | } | ||
216 | |||
217 | return 0; | ||
218 | |||
219 | err_unregister: | ||
220 | platform_device_unregister(pdev); | ||
221 | return rc; | ||
222 | } | ||
223 | |||
224 | /** | ||
225 | * winbond_init - attach winbond interfaces | ||
226 | * | ||
227 | * Attach winbond IDE interfaces by scanning the ports it may occupy. | ||
228 | */ | ||
229 | |||
230 | static __init int winbond_init(void) | ||
231 | { | ||
232 | static const unsigned long config[2] = { 0x130, 0x1B0 }; | ||
233 | |||
234 | int ct = 0; | ||
235 | int i; | ||
236 | |||
237 | if (probe_winbond == 0) | ||
238 | return -ENODEV; | ||
239 | |||
240 | /* | ||
241 | * Check both base addresses | ||
242 | */ | ||
243 | |||
244 | for (i = 0; i < 2; i++) { | ||
245 | if (probe_winbond & (1<<i)) { | ||
246 | int ret = 0; | ||
247 | unsigned long port = config[i]; | ||
248 | |||
249 | if (request_region(port, 2, "pata_winbond")) { | ||
250 | ret = winbond_init_one(port); | ||
251 | if (ret <= 0) | ||
252 | release_region(port, 2); | ||
253 | else ct+= ret; | ||
254 | } | ||
255 | } | ||
256 | } | ||
257 | if (ct != 0) | ||
258 | return 0; | ||
259 | return -ENODEV; | ||
260 | } | ||
261 | |||
262 | static __exit void winbond_exit(void) | ||
263 | { | ||
264 | int i; | ||
265 | |||
266 | for (i = 0; i < nr_winbond_host; i++) { | ||
267 | ata_host_detach(winbond_host[i]); | ||
268 | release_region(winbond_data[i].config, 2); | ||
269 | platform_device_unregister(winbond_data[i].platform_dev); | ||
270 | } | ||
271 | } | ||
272 | |||
273 | MODULE_AUTHOR("Alan Cox"); | ||
274 | MODULE_DESCRIPTION("low-level driver for Winbond VL ATA"); | ||
275 | MODULE_LICENSE("GPL"); | ||
276 | MODULE_VERSION(DRV_VERSION); | ||
277 | |||
278 | module_init(winbond_init); | ||
279 | module_exit(winbond_exit); | ||
280 | |||
281 | module_param(probe_winbond, int, 0); | ||
282 | |||
diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index ea24c1e51be..6cf57c5c2b5 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c | |||
@@ -1459,7 +1459,7 @@ static void sata_dwc_qc_prep_by_tag(struct ata_queued_cmd *qc, u8 tag) | |||
1459 | { | 1459 | { |
1460 | struct scatterlist *sg = qc->sg; | 1460 | struct scatterlist *sg = qc->sg; |
1461 | struct ata_port *ap = qc->ap; | 1461 | struct ata_port *ap = qc->ap; |
1462 | u32 dma_chan; | 1462 | int dma_chan; |
1463 | struct sata_dwc_device *hsdev = HSDEV_FROM_AP(ap); | 1463 | struct sata_dwc_device *hsdev = HSDEV_FROM_AP(ap); |
1464 | struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); | 1464 | struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); |
1465 | int err; | 1465 | int err; |
@@ -1588,7 +1588,7 @@ static const struct ata_port_info sata_dwc_port_info[] = { | |||
1588 | }, | 1588 | }, |
1589 | }; | 1589 | }; |
1590 | 1590 | ||
1591 | static int sata_dwc_probe(struct of_device *ofdev, | 1591 | static int sata_dwc_probe(struct platform_device *ofdev, |
1592 | const struct of_device_id *match) | 1592 | const struct of_device_id *match) |
1593 | { | 1593 | { |
1594 | struct sata_dwc_device *hsdev; | 1594 | struct sata_dwc_device *hsdev; |
@@ -1702,7 +1702,7 @@ error_out: | |||
1702 | return err; | 1702 | return err; |
1703 | } | 1703 | } |
1704 | 1704 | ||
1705 | static int sata_dwc_remove(struct of_device *ofdev) | 1705 | static int sata_dwc_remove(struct platform_device *ofdev) |
1706 | { | 1706 | { |
1707 | struct device *dev = &ofdev->dev; | 1707 | struct device *dev = &ofdev->dev; |
1708 | struct ata_host *host = dev_get_drvdata(dev); | 1708 | struct ata_host *host = dev_get_drvdata(dev); |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 9463c71dd38..81982594a01 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -1898,19 +1898,25 @@ static void mv_bmdma_start(struct ata_queued_cmd *qc) | |||
1898 | * LOCKING: | 1898 | * LOCKING: |
1899 | * Inherited from caller. | 1899 | * Inherited from caller. |
1900 | */ | 1900 | */ |
1901 | static void mv_bmdma_stop(struct ata_queued_cmd *qc) | 1901 | static void mv_bmdma_stop_ap(struct ata_port *ap) |
1902 | { | 1902 | { |
1903 | struct ata_port *ap = qc->ap; | ||
1904 | void __iomem *port_mmio = mv_ap_base(ap); | 1903 | void __iomem *port_mmio = mv_ap_base(ap); |
1905 | u32 cmd; | 1904 | u32 cmd; |
1906 | 1905 | ||
1907 | /* clear start/stop bit */ | 1906 | /* clear start/stop bit */ |
1908 | cmd = readl(port_mmio + BMDMA_CMD); | 1907 | cmd = readl(port_mmio + BMDMA_CMD); |
1909 | cmd &= ~ATA_DMA_START; | 1908 | if (cmd & ATA_DMA_START) { |
1910 | writelfl(cmd, port_mmio + BMDMA_CMD); | 1909 | cmd &= ~ATA_DMA_START; |
1910 | writelfl(cmd, port_mmio + BMDMA_CMD); | ||
1911 | |||
1912 | /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ | ||
1913 | ata_sff_dma_pause(ap); | ||
1914 | } | ||
1915 | } | ||
1911 | 1916 | ||
1912 | /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ | 1917 | static void mv_bmdma_stop(struct ata_queued_cmd *qc) |
1913 | ata_sff_dma_pause(ap); | 1918 | { |
1919 | mv_bmdma_stop_ap(qc->ap); | ||
1914 | } | 1920 | } |
1915 | 1921 | ||
1916 | /** | 1922 | /** |
@@ -1934,8 +1940,21 @@ static u8 mv_bmdma_status(struct ata_port *ap) | |||
1934 | reg = readl(port_mmio + BMDMA_STATUS); | 1940 | reg = readl(port_mmio + BMDMA_STATUS); |
1935 | if (reg & ATA_DMA_ACTIVE) | 1941 | if (reg & ATA_DMA_ACTIVE) |
1936 | status = ATA_DMA_ACTIVE; | 1942 | status = ATA_DMA_ACTIVE; |
1937 | else | 1943 | else if (reg & ATA_DMA_ERR) |
1938 | status = (reg & ATA_DMA_ERR) | ATA_DMA_INTR; | 1944 | status = (reg & ATA_DMA_ERR) | ATA_DMA_INTR; |
1945 | else { | ||
1946 | /* | ||
1947 | * Just because DMA_ACTIVE is 0 (DMA completed), | ||
1948 | * this does _not_ mean the device is "done". | ||
1949 | * So we should not yet be signalling ATA_DMA_INTR | ||
1950 | * in some cases. Eg. DSM/TRIM, and perhaps others. | ||
1951 | */ | ||
1952 | mv_bmdma_stop_ap(ap); | ||
1953 | if (ioread8(ap->ioaddr.altstatus_addr) & ATA_BUSY) | ||
1954 | status = 0; | ||
1955 | else | ||
1956 | status = ATA_DMA_INTR; | ||
1957 | } | ||
1939 | return status; | 1958 | return status; |
1940 | } | 1959 | } |
1941 | 1960 | ||
@@ -1995,6 +2014,9 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) | |||
1995 | 2014 | ||
1996 | switch (tf->protocol) { | 2015 | switch (tf->protocol) { |
1997 | case ATA_PROT_DMA: | 2016 | case ATA_PROT_DMA: |
2017 | if (tf->command == ATA_CMD_DSM) | ||
2018 | return; | ||
2019 | /* fall-thru */ | ||
1998 | case ATA_PROT_NCQ: | 2020 | case ATA_PROT_NCQ: |
1999 | break; /* continue below */ | 2021 | break; /* continue below */ |
2000 | case ATA_PROT_PIO: | 2022 | case ATA_PROT_PIO: |
@@ -2094,6 +2116,8 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc) | |||
2094 | if ((tf->protocol != ATA_PROT_DMA) && | 2116 | if ((tf->protocol != ATA_PROT_DMA) && |
2095 | (tf->protocol != ATA_PROT_NCQ)) | 2117 | (tf->protocol != ATA_PROT_NCQ)) |
2096 | return; | 2118 | return; |
2119 | if (tf->command == ATA_CMD_DSM) | ||
2120 | return; /* use bmdma for this */ | ||
2097 | 2121 | ||
2098 | /* Fill in Gen IIE command request block */ | 2122 | /* Fill in Gen IIE command request block */ |
2099 | if (!(tf->flags & ATA_TFLAG_WRITE)) | 2123 | if (!(tf->flags & ATA_TFLAG_WRITE)) |
@@ -2289,6 +2313,12 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) | |||
2289 | 2313 | ||
2290 | switch (qc->tf.protocol) { | 2314 | switch (qc->tf.protocol) { |
2291 | case ATA_PROT_DMA: | 2315 | case ATA_PROT_DMA: |
2316 | if (qc->tf.command == ATA_CMD_DSM) { | ||
2317 | if (!ap->ops->bmdma_setup) /* no bmdma on GEN_I */ | ||
2318 | return AC_ERR_OTHER; | ||
2319 | break; /* use bmdma for this */ | ||
2320 | } | ||
2321 | /* fall thru */ | ||
2292 | case ATA_PROT_NCQ: | 2322 | case ATA_PROT_NCQ: |
2293 | mv_start_edma(ap, port_mmio, pp, qc->tf.protocol); | 2323 | mv_start_edma(ap, port_mmio, pp, qc->tf.protocol); |
2294 | pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK; | 2324 | pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK; |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index c8a44f5e058..40af43ebd92 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -568,7 +568,7 @@ static int _request_firmware(const struct firmware **firmware_p, | |||
568 | out: | 568 | out: |
569 | if (retval) { | 569 | if (retval) { |
570 | release_firmware(firmware); | 570 | release_firmware(firmware); |
571 | firmware_p = NULL; | 571 | *firmware_p = NULL; |
572 | } | 572 | } |
573 | 573 | ||
574 | return retval; | 574 | return retval; |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index ac1b682edec..ab735a605cf 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -834,7 +834,7 @@ static int blkfront_probe(struct xenbus_device *dev, | |||
834 | char *type; | 834 | char *type; |
835 | int len; | 835 | int len; |
836 | /* no unplug has been done: do not hook devices != xen vbds */ | 836 | /* no unplug has been done: do not hook devices != xen vbds */ |
837 | if (xen_platform_pci_unplug & XEN_UNPLUG_IGNORE) { | 837 | if (xen_platform_pci_unplug & XEN_UNPLUG_UNNECESSARY) { |
838 | int major; | 838 | int major; |
839 | 839 | ||
840 | if (!VDEV_IS_EXTENDED(vdevice)) | 840 | if (!VDEV_IS_EXTENDED(vdevice)) |
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 2982b3ee946..057413bb16e 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c | |||
@@ -94,6 +94,7 @@ | |||
94 | #include <linux/hdreg.h> | 94 | #include <linux/hdreg.h> |
95 | #include <linux/platform_device.h> | 95 | #include <linux/platform_device.h> |
96 | #if defined(CONFIG_OF) | 96 | #if defined(CONFIG_OF) |
97 | #include <linux/of_address.h> | ||
97 | #include <linux/of_device.h> | 98 | #include <linux/of_device.h> |
98 | #include <linux/of_platform.h> | 99 | #include <linux/of_platform.h> |
99 | #endif | 100 | #endif |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index ddf5def1b0d..eab58db5f91 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <asm/smp.h> | 12 | #include <asm/smp.h> |
13 | #include "agp.h" | 13 | #include "agp.h" |
14 | #include "intel-agp.h" | 14 | #include "intel-agp.h" |
15 | #include <linux/intel-gtt.h> | ||
15 | 16 | ||
16 | #include "intel-gtt.c" | 17 | #include "intel-gtt.c" |
17 | 18 | ||
@@ -815,9 +816,19 @@ static const struct intel_driver_description { | |||
815 | "HD Graphics", NULL, &intel_i965_driver }, | 816 | "HD Graphics", NULL, &intel_i965_driver }, |
816 | { PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, | 817 | { PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, |
817 | "HD Graphics", NULL, &intel_i965_driver }, | 818 | "HD Graphics", NULL, &intel_i965_driver }, |
818 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG, | 819 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT1_IG, |
819 | "Sandybridge", NULL, &intel_gen6_driver }, | 820 | "Sandybridge", NULL, &intel_gen6_driver }, |
820 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG, | 821 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_IG, |
822 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
823 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_PLUS_IG, | ||
824 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
825 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT1_IG, | ||
826 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
827 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_IG, | ||
828 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
829 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_PLUS_IG, | ||
830 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
831 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG, | ||
821 | "Sandybridge", NULL, &intel_gen6_driver }, | 832 | "Sandybridge", NULL, &intel_gen6_driver }, |
822 | { 0, 0, NULL, NULL, NULL } | 833 | { 0, 0, NULL, NULL, NULL } |
823 | }; | 834 | }; |
@@ -825,7 +836,8 @@ static const struct intel_driver_description { | |||
825 | static int __devinit intel_gmch_probe(struct pci_dev *pdev, | 836 | static int __devinit intel_gmch_probe(struct pci_dev *pdev, |
826 | struct agp_bridge_data *bridge) | 837 | struct agp_bridge_data *bridge) |
827 | { | 838 | { |
828 | int i; | 839 | int i, mask; |
840 | |||
829 | bridge->driver = NULL; | 841 | bridge->driver = NULL; |
830 | 842 | ||
831 | for (i = 0; intel_agp_chipsets[i].name != NULL; i++) { | 843 | for (i = 0; intel_agp_chipsets[i].name != NULL; i++) { |
@@ -845,14 +857,19 @@ static int __devinit intel_gmch_probe(struct pci_dev *pdev, | |||
845 | 857 | ||
846 | dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name); | 858 | dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name); |
847 | 859 | ||
848 | if (bridge->driver->mask_memory == intel_i965_mask_memory) { | 860 | if (bridge->driver->mask_memory == intel_gen6_mask_memory) |
849 | if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36))) | 861 | mask = 40; |
850 | dev_err(&intel_private.pcidev->dev, | 862 | else if (bridge->driver->mask_memory == intel_i965_mask_memory) |
851 | "set gfx device dma mask 36bit failed!\n"); | 863 | mask = 36; |
852 | else | 864 | else |
853 | pci_set_consistent_dma_mask(intel_private.pcidev, | 865 | mask = 32; |
854 | DMA_BIT_MASK(36)); | 866 | |
855 | } | 867 | if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(mask))) |
868 | dev_err(&intel_private.pcidev->dev, | ||
869 | "set gfx device dma mask %d-bit failed!\n", mask); | ||
870 | else | ||
871 | pci_set_consistent_dma_mask(intel_private.pcidev, | ||
872 | DMA_BIT_MASK(mask)); | ||
856 | 873 | ||
857 | return 1; | 874 | return 1; |
858 | } | 875 | } |
@@ -1036,6 +1053,7 @@ static struct pci_device_id agp_intel_pci_table[] = { | |||
1036 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB), | 1053 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB), |
1037 | ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB), | 1054 | ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB), |
1038 | ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB), | 1055 | ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB), |
1056 | ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB), | ||
1039 | { } | 1057 | { } |
1040 | }; | 1058 | }; |
1041 | 1059 | ||
diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h index c05e3e51826..ee189c74d34 100644 --- a/drivers/char/agp/intel-agp.h +++ b/drivers/char/agp/intel-agp.h | |||
@@ -1,6 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Common Intel AGPGART and GTT definitions. | 2 | * Common Intel AGPGART and GTT definitions. |
3 | */ | 3 | */ |
4 | #ifndef _INTEL_AGP_H | ||
5 | #define _INTEL_AGP_H | ||
4 | 6 | ||
5 | /* Intel registers */ | 7 | /* Intel registers */ |
6 | #define INTEL_APSIZE 0xb4 | 8 | #define INTEL_APSIZE 0xb4 |
@@ -200,10 +202,16 @@ | |||
200 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB 0x0062 | 202 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB 0x0062 |
201 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB 0x006a | 203 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB 0x006a |
202 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG 0x0046 | 204 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG 0x0046 |
203 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB 0x0100 | 205 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB 0x0100 /* Desktop */ |
204 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG 0x0102 | 206 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT1_IG 0x0102 |
205 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB 0x0104 | 207 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_IG 0x0112 |
206 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG 0x0106 | 208 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_PLUS_IG 0x0122 |
209 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB 0x0104 /* Mobile */ | ||
210 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT1_IG 0x0106 | ||
211 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_IG 0x0116 | ||
212 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_PLUS_IG 0x0126 | ||
213 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB 0x0108 /* Server */ | ||
214 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG 0x010A | ||
207 | 215 | ||
208 | /* cover 915 and 945 variants */ | 216 | /* cover 915 and 945 variants */ |
209 | #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \ | 217 | #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \ |
@@ -230,7 +238,8 @@ | |||
230 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB) | 238 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB) |
231 | 239 | ||
232 | #define IS_SNB (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || \ | 240 | #define IS_SNB (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || \ |
233 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB) | 241 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB || \ |
242 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB) | ||
234 | 243 | ||
235 | #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_EAGLELAKE_HB || \ | 244 | #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_EAGLELAKE_HB || \ |
236 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \ | 245 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \ |
@@ -243,3 +252,5 @@ | |||
243 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB || \ | 252 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB || \ |
244 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB || \ | 253 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB || \ |
245 | IS_SNB) | 254 | IS_SNB) |
255 | |||
256 | #endif | ||
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index d22ffb811bf..75e0a349788 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
@@ -49,6 +49,26 @@ static struct gatt_mask intel_i810_masks[] = | |||
49 | .type = INTEL_AGP_CACHED_MEMORY} | 49 | .type = INTEL_AGP_CACHED_MEMORY} |
50 | }; | 50 | }; |
51 | 51 | ||
52 | #define INTEL_AGP_UNCACHED_MEMORY 0 | ||
53 | #define INTEL_AGP_CACHED_MEMORY_LLC 1 | ||
54 | #define INTEL_AGP_CACHED_MEMORY_LLC_GFDT 2 | ||
55 | #define INTEL_AGP_CACHED_MEMORY_LLC_MLC 3 | ||
56 | #define INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT 4 | ||
57 | |||
58 | static struct gatt_mask intel_gen6_masks[] = | ||
59 | { | ||
60 | {.mask = I810_PTE_VALID | GEN6_PTE_UNCACHED, | ||
61 | .type = INTEL_AGP_UNCACHED_MEMORY }, | ||
62 | {.mask = I810_PTE_VALID | GEN6_PTE_LLC, | ||
63 | .type = INTEL_AGP_CACHED_MEMORY_LLC }, | ||
64 | {.mask = I810_PTE_VALID | GEN6_PTE_LLC | GEN6_PTE_GFDT, | ||
65 | .type = INTEL_AGP_CACHED_MEMORY_LLC_GFDT }, | ||
66 | {.mask = I810_PTE_VALID | GEN6_PTE_LLC_MLC, | ||
67 | .type = INTEL_AGP_CACHED_MEMORY_LLC_MLC }, | ||
68 | {.mask = I810_PTE_VALID | GEN6_PTE_LLC_MLC | GEN6_PTE_GFDT, | ||
69 | .type = INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT }, | ||
70 | }; | ||
71 | |||
52 | static struct _intel_private { | 72 | static struct _intel_private { |
53 | struct pci_dev *pcidev; /* device one */ | 73 | struct pci_dev *pcidev; /* device one */ |
54 | u8 __iomem *registers; | 74 | u8 __iomem *registers; |
@@ -178,13 +198,6 @@ static void intel_agp_insert_sg_entries(struct agp_memory *mem, | |||
178 | off_t pg_start, int mask_type) | 198 | off_t pg_start, int mask_type) |
179 | { | 199 | { |
180 | int i, j; | 200 | int i, j; |
181 | u32 cache_bits = 0; | ||
182 | |||
183 | if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || | ||
184 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB) | ||
185 | { | ||
186 | cache_bits = GEN6_PTE_LLC_MLC; | ||
187 | } | ||
188 | 201 | ||
189 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 202 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
190 | writel(agp_bridge->driver->mask_memory(agp_bridge, | 203 | writel(agp_bridge->driver->mask_memory(agp_bridge, |
@@ -317,6 +330,23 @@ static int intel_i830_type_to_mask_type(struct agp_bridge_data *bridge, | |||
317 | return 0; | 330 | return 0; |
318 | } | 331 | } |
319 | 332 | ||
333 | static int intel_gen6_type_to_mask_type(struct agp_bridge_data *bridge, | ||
334 | int type) | ||
335 | { | ||
336 | unsigned int type_mask = type & ~AGP_USER_CACHED_MEMORY_GFDT; | ||
337 | unsigned int gfdt = type & AGP_USER_CACHED_MEMORY_GFDT; | ||
338 | |||
339 | if (type_mask == AGP_USER_UNCACHED_MEMORY) | ||
340 | return INTEL_AGP_UNCACHED_MEMORY; | ||
341 | else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC) | ||
342 | return gfdt ? INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT : | ||
343 | INTEL_AGP_CACHED_MEMORY_LLC_MLC; | ||
344 | else /* set 'normal'/'cached' to LLC by default */ | ||
345 | return gfdt ? INTEL_AGP_CACHED_MEMORY_LLC_GFDT : | ||
346 | INTEL_AGP_CACHED_MEMORY_LLC; | ||
347 | } | ||
348 | |||
349 | |||
320 | static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start, | 350 | static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start, |
321 | int type) | 351 | int type) |
322 | { | 352 | { |
@@ -588,8 +618,7 @@ static void intel_i830_init_gtt_entries(void) | |||
588 | gtt_entries = 0; | 618 | gtt_entries = 0; |
589 | break; | 619 | break; |
590 | } | 620 | } |
591 | } else if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || | 621 | } else if (IS_SNB) { |
592 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB) { | ||
593 | /* | 622 | /* |
594 | * SandyBridge has new memory control reg at 0x50.w | 623 | * SandyBridge has new memory control reg at 0x50.w |
595 | */ | 624 | */ |
@@ -1068,11 +1097,11 @@ static void intel_i9xx_setup_flush(void) | |||
1068 | intel_i915_setup_chipset_flush(); | 1097 | intel_i915_setup_chipset_flush(); |
1069 | } | 1098 | } |
1070 | 1099 | ||
1071 | if (intel_private.ifp_resource.start) { | 1100 | if (intel_private.ifp_resource.start) |
1072 | intel_private.i9xx_flush_page = ioremap_nocache(intel_private.ifp_resource.start, PAGE_SIZE); | 1101 | intel_private.i9xx_flush_page = ioremap_nocache(intel_private.ifp_resource.start, PAGE_SIZE); |
1073 | if (!intel_private.i9xx_flush_page) | 1102 | if (!intel_private.i9xx_flush_page) |
1074 | dev_info(&intel_private.pcidev->dev, "can't ioremap flush page - no chipset flushing"); | 1103 | dev_err(&intel_private.pcidev->dev, |
1075 | } | 1104 | "can't ioremap flush page - no chipset flushing\n"); |
1076 | } | 1105 | } |
1077 | 1106 | ||
1078 | static int intel_i9xx_configure(void) | 1107 | static int intel_i9xx_configure(void) |
@@ -1163,7 +1192,7 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start, | |||
1163 | 1192 | ||
1164 | mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type); | 1193 | mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type); |
1165 | 1194 | ||
1166 | if (mask_type != 0 && mask_type != AGP_PHYS_MEMORY && | 1195 | if (!IS_SNB && mask_type != 0 && mask_type != AGP_PHYS_MEMORY && |
1167 | mask_type != INTEL_AGP_CACHED_MEMORY) | 1196 | mask_type != INTEL_AGP_CACHED_MEMORY) |
1168 | goto out_err; | 1197 | goto out_err; |
1169 | 1198 | ||
@@ -1333,8 +1362,8 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge, | |||
1333 | static unsigned long intel_gen6_mask_memory(struct agp_bridge_data *bridge, | 1362 | static unsigned long intel_gen6_mask_memory(struct agp_bridge_data *bridge, |
1334 | dma_addr_t addr, int type) | 1363 | dma_addr_t addr, int type) |
1335 | { | 1364 | { |
1336 | /* Shift high bits down */ | 1365 | /* gen6 has bit11-4 for physical addr bit39-32 */ |
1337 | addr |= (addr >> 28) & 0xff; | 1366 | addr |= (addr >> 28) & 0xff0; |
1338 | 1367 | ||
1339 | /* Type checking must be done elsewhere */ | 1368 | /* Type checking must be done elsewhere */ |
1340 | return addr | bridge->driver->masks[type].mask; | 1369 | return addr | bridge->driver->masks[type].mask; |
@@ -1359,6 +1388,7 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) | |||
1359 | break; | 1388 | break; |
1360 | case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB: | 1389 | case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB: |
1361 | case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB: | 1390 | case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB: |
1391 | case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB: | ||
1362 | *gtt_offset = MB(2); | 1392 | *gtt_offset = MB(2); |
1363 | 1393 | ||
1364 | pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl); | 1394 | pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl); |
@@ -1563,7 +1593,7 @@ static const struct agp_bridge_driver intel_gen6_driver = { | |||
1563 | .fetch_size = intel_i9xx_fetch_size, | 1593 | .fetch_size = intel_i9xx_fetch_size, |
1564 | .cleanup = intel_i915_cleanup, | 1594 | .cleanup = intel_i915_cleanup, |
1565 | .mask_memory = intel_gen6_mask_memory, | 1595 | .mask_memory = intel_gen6_mask_memory, |
1566 | .masks = intel_i810_masks, | 1596 | .masks = intel_gen6_masks, |
1567 | .agp_enable = intel_i810_agp_enable, | 1597 | .agp_enable = intel_i810_agp_enable, |
1568 | .cache_flush = global_cache_flush, | 1598 | .cache_flush = global_cache_flush, |
1569 | .create_gatt_table = intel_i965_create_gatt_table, | 1599 | .create_gatt_table = intel_i965_create_gatt_table, |
@@ -1576,7 +1606,7 @@ static const struct agp_bridge_driver intel_gen6_driver = { | |||
1576 | .agp_alloc_pages = agp_generic_alloc_pages, | 1606 | .agp_alloc_pages = agp_generic_alloc_pages, |
1577 | .agp_destroy_page = agp_generic_destroy_page, | 1607 | .agp_destroy_page = agp_generic_destroy_page, |
1578 | .agp_destroy_pages = agp_generic_destroy_pages, | 1608 | .agp_destroy_pages = agp_generic_destroy_pages, |
1579 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 1609 | .agp_type_to_mask_type = intel_gen6_type_to_mask_type, |
1580 | .chipset_flush = intel_i915_chipset_flush, | 1610 | .chipset_flush = intel_i915_chipset_flush, |
1581 | #ifdef USE_PCI_DMA_API | 1611 | #ifdef USE_PCI_DMA_API |
1582 | .agp_map_page = intel_agp_map_page, | 1612 | .agp_map_page = intel_agp_map_page, |
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c index e0249722d25..f953c96efc8 100644 --- a/drivers/char/hangcheck-timer.c +++ b/drivers/char/hangcheck-timer.c | |||
@@ -159,7 +159,7 @@ static void hangcheck_fire(unsigned long data) | |||
159 | if (hangcheck_dump_tasks) { | 159 | if (hangcheck_dump_tasks) { |
160 | printk(KERN_CRIT "Hangcheck: Task state:\n"); | 160 | printk(KERN_CRIT "Hangcheck: Task state:\n"); |
161 | #ifdef CONFIG_MAGIC_SYSRQ | 161 | #ifdef CONFIG_MAGIC_SYSRQ |
162 | handle_sysrq('t', NULL); | 162 | handle_sysrq('t'); |
163 | #endif /* CONFIG_MAGIC_SYSRQ */ | 163 | #endif /* CONFIG_MAGIC_SYSRQ */ |
164 | } | 164 | } |
165 | if (hangcheck_reboot) { | 165 | if (hangcheck_reboot) { |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index fa27d1676ee..3afd62e856e 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -651,7 +651,7 @@ int hvc_poll(struct hvc_struct *hp) | |||
651 | if (sysrq_pressed) | 651 | if (sysrq_pressed) |
652 | continue; | 652 | continue; |
653 | } else if (sysrq_pressed) { | 653 | } else if (sysrq_pressed) { |
654 | handle_sysrq(buf[i], tty); | 654 | handle_sysrq(buf[i]); |
655 | sysrq_pressed = 0; | 655 | sysrq_pressed = 0; |
656 | continue; | 656 | continue; |
657 | } | 657 | } |
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c index 1f4b6de65a2..a2bc885ce60 100644 --- a/drivers/char/hvsi.c +++ b/drivers/char/hvsi.c | |||
@@ -403,7 +403,7 @@ static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len) | |||
403 | hp->sysrq = 1; | 403 | hp->sysrq = 1; |
404 | continue; | 404 | continue; |
405 | } else if (hp->sysrq) { | 405 | } else if (hp->sysrq) { |
406 | handle_sysrq(c, hp->tty); | 406 | handle_sysrq(c); |
407 | hp->sysrq = 0; | 407 | hp->sysrq = 0; |
408 | continue; | 408 | continue; |
409 | } | 409 | } |
diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index 1acdb250951..a3f5e381e74 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c | |||
@@ -387,7 +387,7 @@ static int n2rng_init_control(struct n2rng *np) | |||
387 | 387 | ||
388 | static int n2rng_data_read(struct hwrng *rng, u32 *data) | 388 | static int n2rng_data_read(struct hwrng *rng, u32 *data) |
389 | { | 389 | { |
390 | struct n2rng *np = rng->priv; | 390 | struct n2rng *np = (struct n2rng *) rng->priv; |
391 | unsigned long ra = __pa(&np->test_data); | 391 | unsigned long ra = __pa(&np->test_data); |
392 | int len; | 392 | int len; |
393 | 393 | ||
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 07f3ea38b58..d4b71e8d0d2 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -1650,7 +1650,7 @@ ip2_close( PTTY tty, struct file *pFile ) | |||
1650 | /* disable DSS reporting */ | 1650 | /* disable DSS reporting */ |
1651 | i2QueueCommands(PTYPE_INLINE, pCh, 100, 4, | 1651 | i2QueueCommands(PTYPE_INLINE, pCh, 100, 4, |
1652 | CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP); | 1652 | CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP); |
1653 | if ( !tty || (tty->termios->c_cflag & HUPCL) ) { | 1653 | if (tty->termios->c_cflag & HUPCL) { |
1654 | i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN); | 1654 | i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN); |
1655 | pCh->dataSetOut &= ~(I2_DTR | I2_RTS); | 1655 | pCh->dataSetOut &= ~(I2_DTR | I2_RTS); |
1656 | i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25)); | 1656 | i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25)); |
@@ -2930,6 +2930,8 @@ ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg ) | |||
2930 | if ( pCh ) | 2930 | if ( pCh ) |
2931 | { | 2931 | { |
2932 | rc = copy_to_user(argp, pCh, sizeof(i2ChanStr)); | 2932 | rc = copy_to_user(argp, pCh, sizeof(i2ChanStr)); |
2933 | if (rc) | ||
2934 | rc = -EFAULT; | ||
2933 | } else { | 2935 | } else { |
2934 | rc = -ENODEV; | 2936 | rc = -ENODEV; |
2935 | } | 2937 | } |
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index ad46eae1f9b..c350d01716b 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -675,8 +675,8 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
675 | } | 675 | } |
676 | 676 | ||
677 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ | 677 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ |
678 | filp->private_data = tty; | 678 | |
679 | file_move(filp, &tty->tty_files); | 679 | tty_add_file(tty, filp); |
680 | 680 | ||
681 | retval = devpts_pty_new(inode, tty->link); | 681 | retval = devpts_pty_new(inode, tty->link); |
682 | if (retval) | 682 | if (retval) |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 79c3bc69165..7c79d243acc 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -1244,6 +1244,7 @@ static int set_config(struct tty_struct *tty, struct r_port *info, | |||
1244 | } | 1244 | } |
1245 | info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK)); | 1245 | info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK)); |
1246 | configure_r_port(tty, info, NULL); | 1246 | configure_r_port(tty, info, NULL); |
1247 | mutex_unlock(&info->port.mutex); | ||
1247 | return 0; | 1248 | return 0; |
1248 | } | 1249 | } |
1249 | 1250 | ||
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index fef80cfcab5..e63b830c86c 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -691,8 +691,10 @@ static int open(struct tty_struct *tty, struct file *filp) | |||
691 | if (info->port.count == 1) { | 691 | if (info->port.count == 1) { |
692 | /* 1st open on this device, init hardware */ | 692 | /* 1st open on this device, init hardware */ |
693 | retval = startup(info); | 693 | retval = startup(info); |
694 | if (retval < 0) | 694 | if (retval < 0) { |
695 | mutex_unlock(&info->port.mutex); | ||
695 | goto cleanup; | 696 | goto cleanup; |
697 | } | ||
696 | } | 698 | } |
697 | mutex_unlock(&info->port.mutex); | 699 | mutex_unlock(&info->port.mutex); |
698 | retval = block_til_ready(tty, filp, info); | 700 | retval = block_til_ready(tty, filp, info); |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 878ac0c2cc6..ef31bb81e84 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
20 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
21 | #include <linux/tty.h> | ||
22 | #include <linux/mount.h> | 21 | #include <linux/mount.h> |
23 | #include <linux/kdev_t.h> | 22 | #include <linux/kdev_t.h> |
24 | #include <linux/major.h> | 23 | #include <linux/major.h> |
@@ -76,7 +75,7 @@ static int __init sysrq_always_enabled_setup(char *str) | |||
76 | __setup("sysrq_always_enabled", sysrq_always_enabled_setup); | 75 | __setup("sysrq_always_enabled", sysrq_always_enabled_setup); |
77 | 76 | ||
78 | 77 | ||
79 | static void sysrq_handle_loglevel(int key, struct tty_struct *tty) | 78 | static void sysrq_handle_loglevel(int key) |
80 | { | 79 | { |
81 | int i; | 80 | int i; |
82 | 81 | ||
@@ -93,7 +92,7 @@ static struct sysrq_key_op sysrq_loglevel_op = { | |||
93 | }; | 92 | }; |
94 | 93 | ||
95 | #ifdef CONFIG_VT | 94 | #ifdef CONFIG_VT |
96 | static void sysrq_handle_SAK(int key, struct tty_struct *tty) | 95 | static void sysrq_handle_SAK(int key) |
97 | { | 96 | { |
98 | struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work; | 97 | struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work; |
99 | schedule_work(SAK_work); | 98 | schedule_work(SAK_work); |
@@ -109,7 +108,7 @@ static struct sysrq_key_op sysrq_SAK_op = { | |||
109 | #endif | 108 | #endif |
110 | 109 | ||
111 | #ifdef CONFIG_VT | 110 | #ifdef CONFIG_VT |
112 | static void sysrq_handle_unraw(int key, struct tty_struct *tty) | 111 | static void sysrq_handle_unraw(int key) |
113 | { | 112 | { |
114 | struct kbd_struct *kbd = &kbd_table[fg_console]; | 113 | struct kbd_struct *kbd = &kbd_table[fg_console]; |
115 | 114 | ||
@@ -126,7 +125,7 @@ static struct sysrq_key_op sysrq_unraw_op = { | |||
126 | #define sysrq_unraw_op (*(struct sysrq_key_op *)NULL) | 125 | #define sysrq_unraw_op (*(struct sysrq_key_op *)NULL) |
127 | #endif /* CONFIG_VT */ | 126 | #endif /* CONFIG_VT */ |
128 | 127 | ||
129 | static void sysrq_handle_crash(int key, struct tty_struct *tty) | 128 | static void sysrq_handle_crash(int key) |
130 | { | 129 | { |
131 | char *killer = NULL; | 130 | char *killer = NULL; |
132 | 131 | ||
@@ -141,7 +140,7 @@ static struct sysrq_key_op sysrq_crash_op = { | |||
141 | .enable_mask = SYSRQ_ENABLE_DUMP, | 140 | .enable_mask = SYSRQ_ENABLE_DUMP, |
142 | }; | 141 | }; |
143 | 142 | ||
144 | static void sysrq_handle_reboot(int key, struct tty_struct *tty) | 143 | static void sysrq_handle_reboot(int key) |
145 | { | 144 | { |
146 | lockdep_off(); | 145 | lockdep_off(); |
147 | local_irq_enable(); | 146 | local_irq_enable(); |
@@ -154,7 +153,7 @@ static struct sysrq_key_op sysrq_reboot_op = { | |||
154 | .enable_mask = SYSRQ_ENABLE_BOOT, | 153 | .enable_mask = SYSRQ_ENABLE_BOOT, |
155 | }; | 154 | }; |
156 | 155 | ||
157 | static void sysrq_handle_sync(int key, struct tty_struct *tty) | 156 | static void sysrq_handle_sync(int key) |
158 | { | 157 | { |
159 | emergency_sync(); | 158 | emergency_sync(); |
160 | } | 159 | } |
@@ -165,7 +164,7 @@ static struct sysrq_key_op sysrq_sync_op = { | |||
165 | .enable_mask = SYSRQ_ENABLE_SYNC, | 164 | .enable_mask = SYSRQ_ENABLE_SYNC, |
166 | }; | 165 | }; |
167 | 166 | ||
168 | static void sysrq_handle_show_timers(int key, struct tty_struct *tty) | 167 | static void sysrq_handle_show_timers(int key) |
169 | { | 168 | { |
170 | sysrq_timer_list_show(); | 169 | sysrq_timer_list_show(); |
171 | } | 170 | } |
@@ -176,7 +175,7 @@ static struct sysrq_key_op sysrq_show_timers_op = { | |||
176 | .action_msg = "Show clockevent devices & pending hrtimers (no others)", | 175 | .action_msg = "Show clockevent devices & pending hrtimers (no others)", |
177 | }; | 176 | }; |
178 | 177 | ||
179 | static void sysrq_handle_mountro(int key, struct tty_struct *tty) | 178 | static void sysrq_handle_mountro(int key) |
180 | { | 179 | { |
181 | emergency_remount(); | 180 | emergency_remount(); |
182 | } | 181 | } |
@@ -188,7 +187,7 @@ static struct sysrq_key_op sysrq_mountro_op = { | |||
188 | }; | 187 | }; |
189 | 188 | ||
190 | #ifdef CONFIG_LOCKDEP | 189 | #ifdef CONFIG_LOCKDEP |
191 | static void sysrq_handle_showlocks(int key, struct tty_struct *tty) | 190 | static void sysrq_handle_showlocks(int key) |
192 | { | 191 | { |
193 | debug_show_all_locks(); | 192 | debug_show_all_locks(); |
194 | } | 193 | } |
@@ -226,7 +225,7 @@ static void sysrq_showregs_othercpus(struct work_struct *dummy) | |||
226 | 225 | ||
227 | static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus); | 226 | static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus); |
228 | 227 | ||
229 | static void sysrq_handle_showallcpus(int key, struct tty_struct *tty) | 228 | static void sysrq_handle_showallcpus(int key) |
230 | { | 229 | { |
231 | /* | 230 | /* |
232 | * Fall back to the workqueue based printing if the | 231 | * Fall back to the workqueue based printing if the |
@@ -252,7 +251,7 @@ static struct sysrq_key_op sysrq_showallcpus_op = { | |||
252 | }; | 251 | }; |
253 | #endif | 252 | #endif |
254 | 253 | ||
255 | static void sysrq_handle_showregs(int key, struct tty_struct *tty) | 254 | static void sysrq_handle_showregs(int key) |
256 | { | 255 | { |
257 | struct pt_regs *regs = get_irq_regs(); | 256 | struct pt_regs *regs = get_irq_regs(); |
258 | if (regs) | 257 | if (regs) |
@@ -266,7 +265,7 @@ static struct sysrq_key_op sysrq_showregs_op = { | |||
266 | .enable_mask = SYSRQ_ENABLE_DUMP, | 265 | .enable_mask = SYSRQ_ENABLE_DUMP, |
267 | }; | 266 | }; |
268 | 267 | ||
269 | static void sysrq_handle_showstate(int key, struct tty_struct *tty) | 268 | static void sysrq_handle_showstate(int key) |
270 | { | 269 | { |
271 | show_state(); | 270 | show_state(); |
272 | } | 271 | } |
@@ -277,7 +276,7 @@ static struct sysrq_key_op sysrq_showstate_op = { | |||
277 | .enable_mask = SYSRQ_ENABLE_DUMP, | 276 | .enable_mask = SYSRQ_ENABLE_DUMP, |
278 | }; | 277 | }; |
279 | 278 | ||
280 | static void sysrq_handle_showstate_blocked(int key, struct tty_struct *tty) | 279 | static void sysrq_handle_showstate_blocked(int key) |
281 | { | 280 | { |
282 | show_state_filter(TASK_UNINTERRUPTIBLE); | 281 | show_state_filter(TASK_UNINTERRUPTIBLE); |
283 | } | 282 | } |
@@ -291,7 +290,7 @@ static struct sysrq_key_op sysrq_showstate_blocked_op = { | |||
291 | #ifdef CONFIG_TRACING | 290 | #ifdef CONFIG_TRACING |
292 | #include <linux/ftrace.h> | 291 | #include <linux/ftrace.h> |
293 | 292 | ||
294 | static void sysrq_ftrace_dump(int key, struct tty_struct *tty) | 293 | static void sysrq_ftrace_dump(int key) |
295 | { | 294 | { |
296 | ftrace_dump(DUMP_ALL); | 295 | ftrace_dump(DUMP_ALL); |
297 | } | 296 | } |
@@ -305,7 +304,7 @@ static struct sysrq_key_op sysrq_ftrace_dump_op = { | |||
305 | #define sysrq_ftrace_dump_op (*(struct sysrq_key_op *)NULL) | 304 | #define sysrq_ftrace_dump_op (*(struct sysrq_key_op *)NULL) |
306 | #endif | 305 | #endif |
307 | 306 | ||
308 | static void sysrq_handle_showmem(int key, struct tty_struct *tty) | 307 | static void sysrq_handle_showmem(int key) |
309 | { | 308 | { |
310 | show_mem(); | 309 | show_mem(); |
311 | } | 310 | } |
@@ -330,7 +329,7 @@ static void send_sig_all(int sig) | |||
330 | } | 329 | } |
331 | } | 330 | } |
332 | 331 | ||
333 | static void sysrq_handle_term(int key, struct tty_struct *tty) | 332 | static void sysrq_handle_term(int key) |
334 | { | 333 | { |
335 | send_sig_all(SIGTERM); | 334 | send_sig_all(SIGTERM); |
336 | console_loglevel = 8; | 335 | console_loglevel = 8; |
@@ -349,7 +348,7 @@ static void moom_callback(struct work_struct *ignored) | |||
349 | 348 | ||
350 | static DECLARE_WORK(moom_work, moom_callback); | 349 | static DECLARE_WORK(moom_work, moom_callback); |
351 | 350 | ||
352 | static void sysrq_handle_moom(int key, struct tty_struct *tty) | 351 | static void sysrq_handle_moom(int key) |
353 | { | 352 | { |
354 | schedule_work(&moom_work); | 353 | schedule_work(&moom_work); |
355 | } | 354 | } |
@@ -361,7 +360,7 @@ static struct sysrq_key_op sysrq_moom_op = { | |||
361 | }; | 360 | }; |
362 | 361 | ||
363 | #ifdef CONFIG_BLOCK | 362 | #ifdef CONFIG_BLOCK |
364 | static void sysrq_handle_thaw(int key, struct tty_struct *tty) | 363 | static void sysrq_handle_thaw(int key) |
365 | { | 364 | { |
366 | emergency_thaw_all(); | 365 | emergency_thaw_all(); |
367 | } | 366 | } |
@@ -373,7 +372,7 @@ static struct sysrq_key_op sysrq_thaw_op = { | |||
373 | }; | 372 | }; |
374 | #endif | 373 | #endif |
375 | 374 | ||
376 | static void sysrq_handle_kill(int key, struct tty_struct *tty) | 375 | static void sysrq_handle_kill(int key) |
377 | { | 376 | { |
378 | send_sig_all(SIGKILL); | 377 | send_sig_all(SIGKILL); |
379 | console_loglevel = 8; | 378 | console_loglevel = 8; |
@@ -385,7 +384,7 @@ static struct sysrq_key_op sysrq_kill_op = { | |||
385 | .enable_mask = SYSRQ_ENABLE_SIGNAL, | 384 | .enable_mask = SYSRQ_ENABLE_SIGNAL, |
386 | }; | 385 | }; |
387 | 386 | ||
388 | static void sysrq_handle_unrt(int key, struct tty_struct *tty) | 387 | static void sysrq_handle_unrt(int key) |
389 | { | 388 | { |
390 | normalize_rt_tasks(); | 389 | normalize_rt_tasks(); |
391 | } | 390 | } |
@@ -493,7 +492,7 @@ static void __sysrq_put_key_op(int key, struct sysrq_key_op *op_p) | |||
493 | sysrq_key_table[i] = op_p; | 492 | sysrq_key_table[i] = op_p; |
494 | } | 493 | } |
495 | 494 | ||
496 | void __handle_sysrq(int key, struct tty_struct *tty, int check_mask) | 495 | void __handle_sysrq(int key, bool check_mask) |
497 | { | 496 | { |
498 | struct sysrq_key_op *op_p; | 497 | struct sysrq_key_op *op_p; |
499 | int orig_log_level; | 498 | int orig_log_level; |
@@ -520,7 +519,7 @@ void __handle_sysrq(int key, struct tty_struct *tty, int check_mask) | |||
520 | if (!check_mask || sysrq_on_mask(op_p->enable_mask)) { | 519 | if (!check_mask || sysrq_on_mask(op_p->enable_mask)) { |
521 | printk("%s\n", op_p->action_msg); | 520 | printk("%s\n", op_p->action_msg); |
522 | console_loglevel = orig_log_level; | 521 | console_loglevel = orig_log_level; |
523 | op_p->handler(key, tty); | 522 | op_p->handler(key); |
524 | } else { | 523 | } else { |
525 | printk("This sysrq operation is disabled.\n"); | 524 | printk("This sysrq operation is disabled.\n"); |
526 | } | 525 | } |
@@ -545,10 +544,10 @@ void __handle_sysrq(int key, struct tty_struct *tty, int check_mask) | |||
545 | spin_unlock_irqrestore(&sysrq_key_table_lock, flags); | 544 | spin_unlock_irqrestore(&sysrq_key_table_lock, flags); |
546 | } | 545 | } |
547 | 546 | ||
548 | void handle_sysrq(int key, struct tty_struct *tty) | 547 | void handle_sysrq(int key) |
549 | { | 548 | { |
550 | if (sysrq_on()) | 549 | if (sysrq_on()) |
551 | __handle_sysrq(key, tty, 1); | 550 | __handle_sysrq(key, true); |
552 | } | 551 | } |
553 | EXPORT_SYMBOL(handle_sysrq); | 552 | EXPORT_SYMBOL(handle_sysrq); |
554 | 553 | ||
@@ -597,7 +596,7 @@ static bool sysrq_filter(struct input_handle *handle, unsigned int type, | |||
597 | 596 | ||
598 | default: | 597 | default: |
599 | if (sysrq_down && value && value != 2) | 598 | if (sysrq_down && value && value != 2) |
600 | __handle_sysrq(sysrq_xlate[code], NULL, 1); | 599 | __handle_sysrq(sysrq_xlate[code], true); |
601 | break; | 600 | break; |
602 | } | 601 | } |
603 | 602 | ||
@@ -765,7 +764,7 @@ static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf, | |||
765 | 764 | ||
766 | if (get_user(c, buf)) | 765 | if (get_user(c, buf)) |
767 | return -EFAULT; | 766 | return -EFAULT; |
768 | __handle_sysrq(c, NULL, 0); | 767 | __handle_sysrq(c, false); |
769 | } | 768 | } |
770 | 769 | ||
771 | return count; | 770 | return count; |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 0350c42375a..613c852ee0f 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -136,6 +136,9 @@ LIST_HEAD(tty_drivers); /* linked list of tty drivers */ | |||
136 | DEFINE_MUTEX(tty_mutex); | 136 | DEFINE_MUTEX(tty_mutex); |
137 | EXPORT_SYMBOL(tty_mutex); | 137 | EXPORT_SYMBOL(tty_mutex); |
138 | 138 | ||
139 | /* Spinlock to protect the tty->tty_files list */ | ||
140 | DEFINE_SPINLOCK(tty_files_lock); | ||
141 | |||
139 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); | 142 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); |
140 | static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); | 143 | static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); |
141 | ssize_t redirected_tty_write(struct file *, const char __user *, | 144 | ssize_t redirected_tty_write(struct file *, const char __user *, |
@@ -185,6 +188,41 @@ void free_tty_struct(struct tty_struct *tty) | |||
185 | kfree(tty); | 188 | kfree(tty); |
186 | } | 189 | } |
187 | 190 | ||
191 | static inline struct tty_struct *file_tty(struct file *file) | ||
192 | { | ||
193 | return ((struct tty_file_private *)file->private_data)->tty; | ||
194 | } | ||
195 | |||
196 | /* Associate a new file with the tty structure */ | ||
197 | void tty_add_file(struct tty_struct *tty, struct file *file) | ||
198 | { | ||
199 | struct tty_file_private *priv; | ||
200 | |||
201 | /* XXX: must implement proper error handling in callers */ | ||
202 | priv = kmalloc(sizeof(*priv), GFP_KERNEL|__GFP_NOFAIL); | ||
203 | |||
204 | priv->tty = tty; | ||
205 | priv->file = file; | ||
206 | file->private_data = priv; | ||
207 | |||
208 | spin_lock(&tty_files_lock); | ||
209 | list_add(&priv->list, &tty->tty_files); | ||
210 | spin_unlock(&tty_files_lock); | ||
211 | } | ||
212 | |||
213 | /* Delete file from its tty */ | ||
214 | void tty_del_file(struct file *file) | ||
215 | { | ||
216 | struct tty_file_private *priv = file->private_data; | ||
217 | |||
218 | spin_lock(&tty_files_lock); | ||
219 | list_del(&priv->list); | ||
220 | spin_unlock(&tty_files_lock); | ||
221 | file->private_data = NULL; | ||
222 | kfree(priv); | ||
223 | } | ||
224 | |||
225 | |||
188 | #define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base) | 226 | #define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base) |
189 | 227 | ||
190 | /** | 228 | /** |
@@ -235,11 +273,11 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) | |||
235 | struct list_head *p; | 273 | struct list_head *p; |
236 | int count = 0; | 274 | int count = 0; |
237 | 275 | ||
238 | file_list_lock(); | 276 | spin_lock(&tty_files_lock); |
239 | list_for_each(p, &tty->tty_files) { | 277 | list_for_each(p, &tty->tty_files) { |
240 | count++; | 278 | count++; |
241 | } | 279 | } |
242 | file_list_unlock(); | 280 | spin_unlock(&tty_files_lock); |
243 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 281 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
244 | tty->driver->subtype == PTY_TYPE_SLAVE && | 282 | tty->driver->subtype == PTY_TYPE_SLAVE && |
245 | tty->link && tty->link->count) | 283 | tty->link && tty->link->count) |
@@ -317,7 +355,7 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line) | |||
317 | if (*stp == '\0') | 355 | if (*stp == '\0') |
318 | stp = NULL; | 356 | stp = NULL; |
319 | 357 | ||
320 | if (tty_line >= 0 && tty_line <= p->num && p->ops && | 358 | if (tty_line >= 0 && tty_line < p->num && p->ops && |
321 | p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) { | 359 | p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) { |
322 | res = tty_driver_kref_get(p); | 360 | res = tty_driver_kref_get(p); |
323 | *line = tty_line; | 361 | *line = tty_line; |
@@ -497,6 +535,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
497 | struct file *cons_filp = NULL; | 535 | struct file *cons_filp = NULL; |
498 | struct file *filp, *f = NULL; | 536 | struct file *filp, *f = NULL; |
499 | struct task_struct *p; | 537 | struct task_struct *p; |
538 | struct tty_file_private *priv; | ||
500 | int closecount = 0, n; | 539 | int closecount = 0, n; |
501 | unsigned long flags; | 540 | unsigned long flags; |
502 | int refs = 0; | 541 | int refs = 0; |
@@ -506,7 +545,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
506 | 545 | ||
507 | 546 | ||
508 | spin_lock(&redirect_lock); | 547 | spin_lock(&redirect_lock); |
509 | if (redirect && redirect->private_data == tty) { | 548 | if (redirect && file_tty(redirect) == tty) { |
510 | f = redirect; | 549 | f = redirect; |
511 | redirect = NULL; | 550 | redirect = NULL; |
512 | } | 551 | } |
@@ -519,9 +558,10 @@ void __tty_hangup(struct tty_struct *tty) | |||
519 | workqueue with the lock held */ | 558 | workqueue with the lock held */ |
520 | check_tty_count(tty, "tty_hangup"); | 559 | check_tty_count(tty, "tty_hangup"); |
521 | 560 | ||
522 | file_list_lock(); | 561 | spin_lock(&tty_files_lock); |
523 | /* This breaks for file handles being sent over AF_UNIX sockets ? */ | 562 | /* This breaks for file handles being sent over AF_UNIX sockets ? */ |
524 | list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) { | 563 | list_for_each_entry(priv, &tty->tty_files, list) { |
564 | filp = priv->file; | ||
525 | if (filp->f_op->write == redirected_tty_write) | 565 | if (filp->f_op->write == redirected_tty_write) |
526 | cons_filp = filp; | 566 | cons_filp = filp; |
527 | if (filp->f_op->write != tty_write) | 567 | if (filp->f_op->write != tty_write) |
@@ -530,7 +570,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
530 | __tty_fasync(-1, filp, 0); /* can't block */ | 570 | __tty_fasync(-1, filp, 0); /* can't block */ |
531 | filp->f_op = &hung_up_tty_fops; | 571 | filp->f_op = &hung_up_tty_fops; |
532 | } | 572 | } |
533 | file_list_unlock(); | 573 | spin_unlock(&tty_files_lock); |
534 | 574 | ||
535 | tty_ldisc_hangup(tty); | 575 | tty_ldisc_hangup(tty); |
536 | 576 | ||
@@ -889,12 +929,10 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, | |||
889 | loff_t *ppos) | 929 | loff_t *ppos) |
890 | { | 930 | { |
891 | int i; | 931 | int i; |
892 | struct tty_struct *tty; | 932 | struct inode *inode = file->f_path.dentry->d_inode; |
893 | struct inode *inode; | 933 | struct tty_struct *tty = file_tty(file); |
894 | struct tty_ldisc *ld; | 934 | struct tty_ldisc *ld; |
895 | 935 | ||
896 | tty = file->private_data; | ||
897 | inode = file->f_path.dentry->d_inode; | ||
898 | if (tty_paranoia_check(tty, inode, "tty_read")) | 936 | if (tty_paranoia_check(tty, inode, "tty_read")) |
899 | return -EIO; | 937 | return -EIO; |
900 | if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) | 938 | if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) |
@@ -1065,12 +1103,11 @@ void tty_write_message(struct tty_struct *tty, char *msg) | |||
1065 | static ssize_t tty_write(struct file *file, const char __user *buf, | 1103 | static ssize_t tty_write(struct file *file, const char __user *buf, |
1066 | size_t count, loff_t *ppos) | 1104 | size_t count, loff_t *ppos) |
1067 | { | 1105 | { |
1068 | struct tty_struct *tty; | ||
1069 | struct inode *inode = file->f_path.dentry->d_inode; | 1106 | struct inode *inode = file->f_path.dentry->d_inode; |
1107 | struct tty_struct *tty = file_tty(file); | ||
1108 | struct tty_ldisc *ld; | ||
1070 | ssize_t ret; | 1109 | ssize_t ret; |
1071 | struct tty_ldisc *ld; | ||
1072 | 1110 | ||
1073 | tty = file->private_data; | ||
1074 | if (tty_paranoia_check(tty, inode, "tty_write")) | 1111 | if (tty_paranoia_check(tty, inode, "tty_write")) |
1075 | return -EIO; | 1112 | return -EIO; |
1076 | if (!tty || !tty->ops->write || | 1113 | if (!tty || !tty->ops->write || |
@@ -1424,9 +1461,9 @@ static void release_one_tty(struct work_struct *work) | |||
1424 | tty_driver_kref_put(driver); | 1461 | tty_driver_kref_put(driver); |
1425 | module_put(driver->owner); | 1462 | module_put(driver->owner); |
1426 | 1463 | ||
1427 | file_list_lock(); | 1464 | spin_lock(&tty_files_lock); |
1428 | list_del_init(&tty->tty_files); | 1465 | list_del_init(&tty->tty_files); |
1429 | file_list_unlock(); | 1466 | spin_unlock(&tty_files_lock); |
1430 | 1467 | ||
1431 | put_pid(tty->pgrp); | 1468 | put_pid(tty->pgrp); |
1432 | put_pid(tty->session); | 1469 | put_pid(tty->session); |
@@ -1507,13 +1544,13 @@ static void release_tty(struct tty_struct *tty, int idx) | |||
1507 | 1544 | ||
1508 | int tty_release(struct inode *inode, struct file *filp) | 1545 | int tty_release(struct inode *inode, struct file *filp) |
1509 | { | 1546 | { |
1510 | struct tty_struct *tty, *o_tty; | 1547 | struct tty_struct *tty = file_tty(filp); |
1548 | struct tty_struct *o_tty; | ||
1511 | int pty_master, tty_closing, o_tty_closing, do_sleep; | 1549 | int pty_master, tty_closing, o_tty_closing, do_sleep; |
1512 | int devpts; | 1550 | int devpts; |
1513 | int idx; | 1551 | int idx; |
1514 | char buf[64]; | 1552 | char buf[64]; |
1515 | 1553 | ||
1516 | tty = filp->private_data; | ||
1517 | if (tty_paranoia_check(tty, inode, "tty_release_dev")) | 1554 | if (tty_paranoia_check(tty, inode, "tty_release_dev")) |
1518 | return 0; | 1555 | return 0; |
1519 | 1556 | ||
@@ -1671,8 +1708,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1671 | * - do_tty_hangup no longer sees this file descriptor as | 1708 | * - do_tty_hangup no longer sees this file descriptor as |
1672 | * something that needs to be handled for hangups. | 1709 | * something that needs to be handled for hangups. |
1673 | */ | 1710 | */ |
1674 | file_kill(filp); | 1711 | tty_del_file(filp); |
1675 | filp->private_data = NULL; | ||
1676 | 1712 | ||
1677 | /* | 1713 | /* |
1678 | * Perform some housekeeping before deciding whether to return. | 1714 | * Perform some housekeeping before deciding whether to return. |
@@ -1839,8 +1875,8 @@ got_driver: | |||
1839 | return PTR_ERR(tty); | 1875 | return PTR_ERR(tty); |
1840 | } | 1876 | } |
1841 | 1877 | ||
1842 | filp->private_data = tty; | 1878 | tty_add_file(tty, filp); |
1843 | file_move(filp, &tty->tty_files); | 1879 | |
1844 | check_tty_count(tty, "tty_open"); | 1880 | check_tty_count(tty, "tty_open"); |
1845 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1881 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
1846 | tty->driver->subtype == PTY_TYPE_MASTER) | 1882 | tty->driver->subtype == PTY_TYPE_MASTER) |
@@ -1916,11 +1952,10 @@ got_driver: | |||
1916 | 1952 | ||
1917 | static unsigned int tty_poll(struct file *filp, poll_table *wait) | 1953 | static unsigned int tty_poll(struct file *filp, poll_table *wait) |
1918 | { | 1954 | { |
1919 | struct tty_struct *tty; | 1955 | struct tty_struct *tty = file_tty(filp); |
1920 | struct tty_ldisc *ld; | 1956 | struct tty_ldisc *ld; |
1921 | int ret = 0; | 1957 | int ret = 0; |
1922 | 1958 | ||
1923 | tty = filp->private_data; | ||
1924 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll")) | 1959 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll")) |
1925 | return 0; | 1960 | return 0; |
1926 | 1961 | ||
@@ -1933,11 +1968,10 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait) | |||
1933 | 1968 | ||
1934 | static int __tty_fasync(int fd, struct file *filp, int on) | 1969 | static int __tty_fasync(int fd, struct file *filp, int on) |
1935 | { | 1970 | { |
1936 | struct tty_struct *tty; | 1971 | struct tty_struct *tty = file_tty(filp); |
1937 | unsigned long flags; | 1972 | unsigned long flags; |
1938 | int retval = 0; | 1973 | int retval = 0; |
1939 | 1974 | ||
1940 | tty = filp->private_data; | ||
1941 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) | 1975 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) |
1942 | goto out; | 1976 | goto out; |
1943 | 1977 | ||
@@ -2491,13 +2525,13 @@ EXPORT_SYMBOL(tty_pair_get_pty); | |||
2491 | */ | 2525 | */ |
2492 | long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 2526 | long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
2493 | { | 2527 | { |
2494 | struct tty_struct *tty, *real_tty; | 2528 | struct tty_struct *tty = file_tty(file); |
2529 | struct tty_struct *real_tty; | ||
2495 | void __user *p = (void __user *)arg; | 2530 | void __user *p = (void __user *)arg; |
2496 | int retval; | 2531 | int retval; |
2497 | struct tty_ldisc *ld; | 2532 | struct tty_ldisc *ld; |
2498 | struct inode *inode = file->f_dentry->d_inode; | 2533 | struct inode *inode = file->f_dentry->d_inode; |
2499 | 2534 | ||
2500 | tty = file->private_data; | ||
2501 | if (tty_paranoia_check(tty, inode, "tty_ioctl")) | 2535 | if (tty_paranoia_check(tty, inode, "tty_ioctl")) |
2502 | return -EINVAL; | 2536 | return -EINVAL; |
2503 | 2537 | ||
@@ -2619,7 +2653,7 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd, | |||
2619 | unsigned long arg) | 2653 | unsigned long arg) |
2620 | { | 2654 | { |
2621 | struct inode *inode = file->f_dentry->d_inode; | 2655 | struct inode *inode = file->f_dentry->d_inode; |
2622 | struct tty_struct *tty = file->private_data; | 2656 | struct tty_struct *tty = file_tty(file); |
2623 | struct tty_ldisc *ld; | 2657 | struct tty_ldisc *ld; |
2624 | int retval = -ENOIOCTLCMD; | 2658 | int retval = -ENOIOCTLCMD; |
2625 | 2659 | ||
@@ -2711,7 +2745,7 @@ void __do_SAK(struct tty_struct *tty) | |||
2711 | if (!filp) | 2745 | if (!filp) |
2712 | continue; | 2746 | continue; |
2713 | if (filp->f_op->read == tty_read && | 2747 | if (filp->f_op->read == tty_read && |
2714 | filp->private_data == tty) { | 2748 | file_tty(filp) == tty) { |
2715 | printk(KERN_NOTICE "SAK: killed process %d" | 2749 | printk(KERN_NOTICE "SAK: killed process %d" |
2716 | " (%s): fd#%d opened to the tty\n", | 2750 | " (%s): fd#%d opened to the tty\n", |
2717 | task_pid_nr(p), p->comm, i); | 2751 | task_pid_nr(p), p->comm, i); |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index c734f9b1263..281aada7b4a 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -194,10 +194,11 @@ static DECLARE_WORK(console_work, console_callback); | |||
194 | int fg_console; | 194 | int fg_console; |
195 | int last_console; | 195 | int last_console; |
196 | int want_console = -1; | 196 | int want_console = -1; |
197 | int saved_fg_console; | 197 | static int saved_fg_console; |
198 | int saved_last_console; | 198 | static int saved_last_console; |
199 | int saved_want_console; | 199 | static int saved_want_console; |
200 | int saved_vc_mode; | 200 | static int saved_vc_mode; |
201 | static int saved_console_blanked; | ||
201 | 202 | ||
202 | /* | 203 | /* |
203 | * For each existing display, we have a pointer to console currently visible | 204 | * For each existing display, we have a pointer to console currently visible |
@@ -905,22 +906,16 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, | |||
905 | * bottom of buffer | 906 | * bottom of buffer |
906 | */ | 907 | */ |
907 | old_origin += (old_rows - new_rows) * old_row_size; | 908 | old_origin += (old_rows - new_rows) * old_row_size; |
908 | end = vc->vc_scr_end; | ||
909 | } else { | 909 | } else { |
910 | /* | 910 | /* |
911 | * Cursor is in no man's land, copy 1/2 screenful | 911 | * Cursor is in no man's land, copy 1/2 screenful |
912 | * from the top and bottom of cursor position | 912 | * from the top and bottom of cursor position |
913 | */ | 913 | */ |
914 | old_origin += (vc->vc_y - new_rows/2) * old_row_size; | 914 | old_origin += (vc->vc_y - new_rows/2) * old_row_size; |
915 | end = old_origin + (old_row_size * new_rows); | ||
916 | } | 915 | } |
917 | } else | 916 | } |
918 | /* | 917 | |
919 | * Cursor near the top, copy contents from the top of buffer | 918 | end = old_origin + old_row_size * min(old_rows, new_rows); |
920 | */ | ||
921 | end = (old_rows > new_rows) ? old_origin + | ||
922 | (old_row_size * new_rows) : | ||
923 | vc->vc_scr_end; | ||
924 | 919 | ||
925 | update_attr(vc); | 920 | update_attr(vc); |
926 | 921 | ||
@@ -3074,8 +3069,7 @@ static int bind_con_driver(const struct consw *csw, int first, int last, | |||
3074 | 3069 | ||
3075 | old_was_color = vc->vc_can_do_color; | 3070 | old_was_color = vc->vc_can_do_color; |
3076 | vc->vc_sw->con_deinit(vc); | 3071 | vc->vc_sw->con_deinit(vc); |
3077 | if (!vc->vc_origin) | 3072 | vc->vc_origin = (unsigned long)vc->vc_screenbuf; |
3078 | vc->vc_origin = (unsigned long)vc->vc_screenbuf; | ||
3079 | visual_init(vc, i, 0); | 3073 | visual_init(vc, i, 0); |
3080 | set_origin(vc); | 3074 | set_origin(vc); |
3081 | update_attr(vc); | 3075 | update_attr(vc); |
@@ -3449,6 +3443,7 @@ int con_debug_enter(struct vc_data *vc) | |||
3449 | saved_last_console = last_console; | 3443 | saved_last_console = last_console; |
3450 | saved_want_console = want_console; | 3444 | saved_want_console = want_console; |
3451 | saved_vc_mode = vc->vc_mode; | 3445 | saved_vc_mode = vc->vc_mode; |
3446 | saved_console_blanked = console_blanked; | ||
3452 | vc->vc_mode = KD_TEXT; | 3447 | vc->vc_mode = KD_TEXT; |
3453 | console_blanked = 0; | 3448 | console_blanked = 0; |
3454 | if (vc->vc_sw->con_debug_enter) | 3449 | if (vc->vc_sw->con_debug_enter) |
@@ -3492,6 +3487,7 @@ int con_debug_leave(void) | |||
3492 | fg_console = saved_fg_console; | 3487 | fg_console = saved_fg_console; |
3493 | last_console = saved_last_console; | 3488 | last_console = saved_last_console; |
3494 | want_console = saved_want_console; | 3489 | want_console = saved_want_console; |
3490 | console_blanked = saved_console_blanked; | ||
3495 | vc_cons[fg_console].d->vc_mode = saved_vc_mode; | 3491 | vc_cons[fg_console].d->vc_mode = saved_vc_mode; |
3496 | 3492 | ||
3497 | vc = vc_cons[fg_console].d; | 3493 | vc = vc_cons[fg_console].d; |
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 0ed763cd2e7..b663d573aad 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c | |||
@@ -94,6 +94,7 @@ | |||
94 | 94 | ||
95 | #ifdef CONFIG_OF | 95 | #ifdef CONFIG_OF |
96 | /* For open firmware. */ | 96 | /* For open firmware. */ |
97 | #include <linux/of_address.h> | ||
97 | #include <linux/of_device.h> | 98 | #include <linux/of_device.h> |
98 | #include <linux/of_platform.h> | 99 | #include <linux/of_platform.h> |
99 | #endif | 100 | #endif |
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 670239ab751..e7d5d6b5dcf 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -2071,16 +2071,6 @@ static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci, | |||
2071 | amd64_handle_ce(mci, info); | 2071 | amd64_handle_ce(mci, info); |
2072 | else if (ecc_type == 1) | 2072 | else if (ecc_type == 1) |
2073 | amd64_handle_ue(mci, info); | 2073 | amd64_handle_ue(mci, info); |
2074 | |||
2075 | /* | ||
2076 | * If main error is CE then overflow must be CE. If main error is UE | ||
2077 | * then overflow is unknown. We'll call the overflow a CE - if | ||
2078 | * panic_on_ue is set then we're already panic'ed and won't arrive | ||
2079 | * here. Else, then apparently someone doesn't think that UE's are | ||
2080 | * catastrophic. | ||
2081 | */ | ||
2082 | if (info->nbsh & K8_NBSH_OVERFLOW) | ||
2083 | edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR " Error Overflow"); | ||
2084 | } | 2074 | } |
2085 | 2075 | ||
2086 | void amd64_decode_bus_error(int node_id, struct err_regs *regs) | 2076 | void amd64_decode_bus_error(int node_id, struct err_regs *regs) |
diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c index bae9351e947..9014df6f605 100644 --- a/drivers/edac/edac_mce_amd.c +++ b/drivers/edac/edac_mce_amd.c | |||
@@ -365,11 +365,10 @@ static int amd_decode_mce(struct notifier_block *nb, unsigned long val, | |||
365 | 365 | ||
366 | pr_emerg("MC%d_STATUS: ", m->bank); | 366 | pr_emerg("MC%d_STATUS: ", m->bank); |
367 | 367 | ||
368 | pr_cont("%sorrected error, report: %s, MiscV: %svalid, " | 368 | pr_cont("%sorrected error, other errors lost: %s, " |
369 | "CPU context corrupt: %s", | 369 | "CPU context corrupt: %s", |
370 | ((m->status & MCI_STATUS_UC) ? "Unc" : "C"), | 370 | ((m->status & MCI_STATUS_UC) ? "Unc" : "C"), |
371 | ((m->status & MCI_STATUS_EN) ? "yes" : "no"), | 371 | ((m->status & MCI_STATUS_OVER) ? "yes" : "no"), |
372 | ((m->status & MCI_STATUS_MISCV) ? "" : "in"), | ||
373 | ((m->status & MCI_STATUS_PCC) ? "yes" : "no")); | 372 | ((m->status & MCI_STATUS_PCC) ? "yes" : "no")); |
374 | 373 | ||
375 | /* do the two bits[14:13] together */ | 374 | /* do the two bits[14:13] together */ |
@@ -426,11 +425,15 @@ static struct notifier_block amd_mce_dec_nb = { | |||
426 | static int __init mce_amd_init(void) | 425 | static int __init mce_amd_init(void) |
427 | { | 426 | { |
428 | /* | 427 | /* |
429 | * We can decode MCEs for Opteron and later CPUs: | 428 | * We can decode MCEs for K8, F10h and F11h CPUs: |
430 | */ | 429 | */ |
431 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && | 430 | if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) |
432 | (boot_cpu_data.x86 >= 0xf)) | 431 | return 0; |
433 | atomic_notifier_chain_register(&x86_mce_decoder_chain, &amd_mce_dec_nb); | 432 | |
433 | if (boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x11) | ||
434 | return 0; | ||
435 | |||
436 | atomic_notifier_chain_register(&x86_mce_decoder_chain, &amd_mce_dec_nb); | ||
434 | 437 | ||
435 | return 0; | 438 | return 0; |
436 | } | 439 | } |
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index ca7ca56661e..b42a0bde849 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c | |||
@@ -81,6 +81,10 @@ static int close_transaction(struct fw_transaction *transaction, | |||
81 | spin_lock_irqsave(&card->lock, flags); | 81 | spin_lock_irqsave(&card->lock, flags); |
82 | list_for_each_entry(t, &card->transaction_list, link) { | 82 | list_for_each_entry(t, &card->transaction_list, link) { |
83 | if (t == transaction) { | 83 | if (t == transaction) { |
84 | if (!del_timer(&t->split_timeout_timer)) { | ||
85 | spin_unlock_irqrestore(&card->lock, flags); | ||
86 | goto timed_out; | ||
87 | } | ||
84 | list_del_init(&t->link); | 88 | list_del_init(&t->link); |
85 | card->tlabel_mask &= ~(1ULL << t->tlabel); | 89 | card->tlabel_mask &= ~(1ULL << t->tlabel); |
86 | break; | 90 | break; |
@@ -89,11 +93,11 @@ static int close_transaction(struct fw_transaction *transaction, | |||
89 | spin_unlock_irqrestore(&card->lock, flags); | 93 | spin_unlock_irqrestore(&card->lock, flags); |
90 | 94 | ||
91 | if (&t->link != &card->transaction_list) { | 95 | if (&t->link != &card->transaction_list) { |
92 | del_timer_sync(&t->split_timeout_timer); | ||
93 | t->callback(card, rcode, NULL, 0, t->callback_data); | 96 | t->callback(card, rcode, NULL, 0, t->callback_data); |
94 | return 0; | 97 | return 0; |
95 | } | 98 | } |
96 | 99 | ||
100 | timed_out: | ||
97 | return -ENOENT; | 101 | return -ENOENT; |
98 | } | 102 | } |
99 | 103 | ||
@@ -921,6 +925,10 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) | |||
921 | spin_lock_irqsave(&card->lock, flags); | 925 | spin_lock_irqsave(&card->lock, flags); |
922 | list_for_each_entry(t, &card->transaction_list, link) { | 926 | list_for_each_entry(t, &card->transaction_list, link) { |
923 | if (t->node_id == source && t->tlabel == tlabel) { | 927 | if (t->node_id == source && t->tlabel == tlabel) { |
928 | if (!del_timer(&t->split_timeout_timer)) { | ||
929 | spin_unlock_irqrestore(&card->lock, flags); | ||
930 | goto timed_out; | ||
931 | } | ||
924 | list_del_init(&t->link); | 932 | list_del_init(&t->link); |
925 | card->tlabel_mask &= ~(1ULL << t->tlabel); | 933 | card->tlabel_mask &= ~(1ULL << t->tlabel); |
926 | break; | 934 | break; |
@@ -929,6 +937,7 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) | |||
929 | spin_unlock_irqrestore(&card->lock, flags); | 937 | spin_unlock_irqrestore(&card->lock, flags); |
930 | 938 | ||
931 | if (&t->link == &card->transaction_list) { | 939 | if (&t->link == &card->transaction_list) { |
940 | timed_out: | ||
932 | fw_notify("Unsolicited response (source %x, tlabel %x)\n", | 941 | fw_notify("Unsolicited response (source %x, tlabel %x)\n", |
933 | source, tlabel); | 942 | source, tlabel); |
934 | return; | 943 | return; |
@@ -963,8 +972,6 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) | |||
963 | break; | 972 | break; |
964 | } | 973 | } |
965 | 974 | ||
966 | del_timer_sync(&t->split_timeout_timer); | ||
967 | |||
968 | /* | 975 | /* |
969 | * The response handler may be executed while the request handler | 976 | * The response handler may be executed while the request handler |
970 | * is still pending. Cancel the request handler. | 977 | * is still pending. Cancel the request handler. |
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 51e8a35ebd7..18fdd9703b4 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c | |||
@@ -578,7 +578,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
578 | if (!peer) { | 578 | if (!peer) { |
579 | fw_notify("No peer for ARP packet from %016llx\n", | 579 | fw_notify("No peer for ARP packet from %016llx\n", |
580 | (unsigned long long)peer_guid); | 580 | (unsigned long long)peer_guid); |
581 | goto failed_proto; | 581 | goto no_peer; |
582 | } | 582 | } |
583 | 583 | ||
584 | /* | 584 | /* |
@@ -655,7 +655,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
655 | 655 | ||
656 | return 0; | 656 | return 0; |
657 | 657 | ||
658 | failed_proto: | 658 | no_peer: |
659 | net->stats.rx_errors++; | 659 | net->stats.rx_errors++; |
660 | net->stats.rx_dropped++; | 660 | net->stats.rx_dropped++; |
661 | 661 | ||
@@ -663,7 +663,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
663 | if (netif_queue_stopped(net)) | 663 | if (netif_queue_stopped(net)) |
664 | netif_wake_queue(net); | 664 | netif_wake_queue(net); |
665 | 665 | ||
666 | return 0; | 666 | return -ENOENT; |
667 | } | 667 | } |
668 | 668 | ||
669 | static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | 669 | static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, |
@@ -700,7 +700,7 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
700 | fw_error("out of memory\n"); | 700 | fw_error("out of memory\n"); |
701 | net->stats.rx_dropped++; | 701 | net->stats.rx_dropped++; |
702 | 702 | ||
703 | return -1; | 703 | return -ENOMEM; |
704 | } | 704 | } |
705 | skb_reserve(skb, (net->hard_header_len + 15) & ~15); | 705 | skb_reserve(skb, (net->hard_header_len + 15) & ~15); |
706 | memcpy(skb_put(skb, len), buf, len); | 706 | memcpy(skb_put(skb, len), buf, len); |
@@ -725,8 +725,10 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
725 | spin_lock_irqsave(&dev->lock, flags); | 725 | spin_lock_irqsave(&dev->lock, flags); |
726 | 726 | ||
727 | peer = fwnet_peer_find_by_node_id(dev, source_node_id, generation); | 727 | peer = fwnet_peer_find_by_node_id(dev, source_node_id, generation); |
728 | if (!peer) | 728 | if (!peer) { |
729 | goto bad_proto; | 729 | retval = -ENOENT; |
730 | goto fail; | ||
731 | } | ||
730 | 732 | ||
731 | pd = fwnet_pd_find(peer, datagram_label); | 733 | pd = fwnet_pd_find(peer, datagram_label); |
732 | if (pd == NULL) { | 734 | if (pd == NULL) { |
@@ -740,7 +742,7 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
740 | dg_size, buf, fg_off, len); | 742 | dg_size, buf, fg_off, len); |
741 | if (pd == NULL) { | 743 | if (pd == NULL) { |
742 | retval = -ENOMEM; | 744 | retval = -ENOMEM; |
743 | goto bad_proto; | 745 | goto fail; |
744 | } | 746 | } |
745 | peer->pdg_size++; | 747 | peer->pdg_size++; |
746 | } else { | 748 | } else { |
@@ -754,9 +756,9 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
754 | pd = fwnet_pd_new(net, peer, datagram_label, | 756 | pd = fwnet_pd_new(net, peer, datagram_label, |
755 | dg_size, buf, fg_off, len); | 757 | dg_size, buf, fg_off, len); |
756 | if (pd == NULL) { | 758 | if (pd == NULL) { |
757 | retval = -ENOMEM; | ||
758 | peer->pdg_size--; | 759 | peer->pdg_size--; |
759 | goto bad_proto; | 760 | retval = -ENOMEM; |
761 | goto fail; | ||
760 | } | 762 | } |
761 | } else { | 763 | } else { |
762 | if (!fwnet_pd_update(peer, pd, buf, fg_off, len)) { | 764 | if (!fwnet_pd_update(peer, pd, buf, fg_off, len)) { |
@@ -767,7 +769,8 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
767 | */ | 769 | */ |
768 | fwnet_pd_delete(pd); | 770 | fwnet_pd_delete(pd); |
769 | peer->pdg_size--; | 771 | peer->pdg_size--; |
770 | goto bad_proto; | 772 | retval = -ENOMEM; |
773 | goto fail; | ||
771 | } | 774 | } |
772 | } | 775 | } |
773 | } /* new datagram or add to existing one */ | 776 | } /* new datagram or add to existing one */ |
@@ -793,14 +796,13 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
793 | spin_unlock_irqrestore(&dev->lock, flags); | 796 | spin_unlock_irqrestore(&dev->lock, flags); |
794 | 797 | ||
795 | return 0; | 798 | return 0; |
796 | 799 | fail: | |
797 | bad_proto: | ||
798 | spin_unlock_irqrestore(&dev->lock, flags); | 800 | spin_unlock_irqrestore(&dev->lock, flags); |
799 | 801 | ||
800 | if (netif_queue_stopped(net)) | 802 | if (netif_queue_stopped(net)) |
801 | netif_wake_queue(net); | 803 | netif_wake_queue(net); |
802 | 804 | ||
803 | return 0; | 805 | return retval; |
804 | } | 806 | } |
805 | 807 | ||
806 | static void fwnet_receive_packet(struct fw_card *card, struct fw_request *r, | 808 | static void fwnet_receive_packet(struct fw_card *card, struct fw_request *r, |
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 7f03540cabe..be29b0bb247 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -694,7 +694,15 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) | |||
694 | log_ar_at_event('R', p.speed, p.header, evt); | 694 | log_ar_at_event('R', p.speed, p.header, evt); |
695 | 695 | ||
696 | /* | 696 | /* |
697 | * The OHCI bus reset handler synthesizes a phy packet with | 697 | * Several controllers, notably from NEC and VIA, forget to |
698 | * write ack_complete status at PHY packet reception. | ||
699 | */ | ||
700 | if (evt == OHCI1394_evt_no_status && | ||
701 | (p.header[0] & 0xff) == (OHCI1394_phy_tcode << 4)) | ||
702 | p.ack = ACK_COMPLETE; | ||
703 | |||
704 | /* | ||
705 | * The OHCI bus reset handler synthesizes a PHY packet with | ||
698 | * the new generation number when a bus reset happens (see | 706 | * the new generation number when a bus reset happens (see |
699 | * section 8.4.2.3). This helps us determine when a request | 707 | * section 8.4.2.3). This helps us determine when a request |
700 | * was received and make sure we send the response in the same | 708 | * was received and make sure we send the response in the same |
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 9f76171717e..bfae4b30979 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c | |||
@@ -450,7 +450,7 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request, | |||
450 | 450 | ||
451 | if (&orb->link != &lu->orb_list) { | 451 | if (&orb->link != &lu->orb_list) { |
452 | orb->callback(orb, &status); | 452 | orb->callback(orb, &status); |
453 | kref_put(&orb->kref, free_orb); | 453 | kref_put(&orb->kref, free_orb); /* orb callback reference */ |
454 | } else { | 454 | } else { |
455 | fw_error("status write for unknown orb\n"); | 455 | fw_error("status write for unknown orb\n"); |
456 | } | 456 | } |
@@ -472,20 +472,28 @@ static void complete_transaction(struct fw_card *card, int rcode, | |||
472 | * So this callback only sets the rcode if it hasn't already | 472 | * So this callback only sets the rcode if it hasn't already |
473 | * been set and only does the cleanup if the transaction | 473 | * been set and only does the cleanup if the transaction |
474 | * failed and we didn't already get a status write. | 474 | * failed and we didn't already get a status write. |
475 | * | ||
476 | * Here we treat RCODE_CANCELLED like RCODE_COMPLETE because some | ||
477 | * OXUF936QSE firmwares occasionally respond after Split_Timeout and | ||
478 | * complete the ORB just fine. Note, we also get RCODE_CANCELLED | ||
479 | * from sbp2_cancel_orbs() if fw_cancel_transaction() == 0. | ||
475 | */ | 480 | */ |
476 | spin_lock_irqsave(&card->lock, flags); | 481 | spin_lock_irqsave(&card->lock, flags); |
477 | 482 | ||
478 | if (orb->rcode == -1) | 483 | if (orb->rcode == -1) |
479 | orb->rcode = rcode; | 484 | orb->rcode = rcode; |
480 | if (orb->rcode != RCODE_COMPLETE) { | 485 | |
486 | if (orb->rcode != RCODE_COMPLETE && orb->rcode != RCODE_CANCELLED) { | ||
481 | list_del(&orb->link); | 487 | list_del(&orb->link); |
482 | spin_unlock_irqrestore(&card->lock, flags); | 488 | spin_unlock_irqrestore(&card->lock, flags); |
489 | |||
483 | orb->callback(orb, NULL); | 490 | orb->callback(orb, NULL); |
491 | kref_put(&orb->kref, free_orb); /* orb callback reference */ | ||
484 | } else { | 492 | } else { |
485 | spin_unlock_irqrestore(&card->lock, flags); | 493 | spin_unlock_irqrestore(&card->lock, flags); |
486 | } | 494 | } |
487 | 495 | ||
488 | kref_put(&orb->kref, free_orb); | 496 | kref_put(&orb->kref, free_orb); /* transaction callback reference */ |
489 | } | 497 | } |
490 | 498 | ||
491 | static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, | 499 | static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, |
@@ -501,9 +509,8 @@ static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, | |||
501 | list_add_tail(&orb->link, &lu->orb_list); | 509 | list_add_tail(&orb->link, &lu->orb_list); |
502 | spin_unlock_irqrestore(&device->card->lock, flags); | 510 | spin_unlock_irqrestore(&device->card->lock, flags); |
503 | 511 | ||
504 | /* Take a ref for the orb list and for the transaction callback. */ | 512 | kref_get(&orb->kref); /* transaction callback reference */ |
505 | kref_get(&orb->kref); | 513 | kref_get(&orb->kref); /* orb callback reference */ |
506 | kref_get(&orb->kref); | ||
507 | 514 | ||
508 | fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, | 515 | fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, |
509 | node_id, generation, device->max_speed, offset, | 516 | node_id, generation, device->max_speed, offset, |
@@ -525,11 +532,11 @@ static int sbp2_cancel_orbs(struct sbp2_logical_unit *lu) | |||
525 | 532 | ||
526 | list_for_each_entry_safe(orb, next, &list, link) { | 533 | list_for_each_entry_safe(orb, next, &list, link) { |
527 | retval = 0; | 534 | retval = 0; |
528 | if (fw_cancel_transaction(device->card, &orb->t) == 0) | 535 | fw_cancel_transaction(device->card, &orb->t); |
529 | continue; | ||
530 | 536 | ||
531 | orb->rcode = RCODE_CANCELLED; | 537 | orb->rcode = RCODE_CANCELLED; |
532 | orb->callback(orb, NULL); | 538 | orb->callback(orb, NULL); |
539 | kref_put(&orb->kref, free_orb); /* orb callback reference */ | ||
533 | } | 540 | } |
534 | 541 | ||
535 | return retval; | 542 | return retval; |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 7e31d434834..d2ab01e90a9 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -34,6 +34,9 @@ | |||
34 | #include "drm_crtc_helper.h" | 34 | #include "drm_crtc_helper.h" |
35 | #include "drm_fb_helper.h" | 35 | #include "drm_fb_helper.h" |
36 | 36 | ||
37 | static bool drm_kms_helper_poll = true; | ||
38 | module_param_named(poll, drm_kms_helper_poll, bool, 0600); | ||
39 | |||
37 | static void drm_mode_validate_flag(struct drm_connector *connector, | 40 | static void drm_mode_validate_flag(struct drm_connector *connector, |
38 | int flags) | 41 | int flags) |
39 | { | 42 | { |
@@ -99,8 +102,10 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, | |||
99 | connector->status = connector_status_disconnected; | 102 | connector->status = connector_status_disconnected; |
100 | if (connector->funcs->force) | 103 | if (connector->funcs->force) |
101 | connector->funcs->force(connector); | 104 | connector->funcs->force(connector); |
102 | } else | 105 | } else { |
103 | connector->status = connector->funcs->detect(connector); | 106 | connector->status = connector->funcs->detect(connector); |
107 | drm_helper_hpd_irq_event(dev); | ||
108 | } | ||
104 | 109 | ||
105 | if (connector->status == connector_status_disconnected) { | 110 | if (connector->status == connector_status_disconnected) { |
106 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n", | 111 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n", |
@@ -110,11 +115,10 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, | |||
110 | } | 115 | } |
111 | 116 | ||
112 | count = (*connector_funcs->get_modes)(connector); | 117 | count = (*connector_funcs->get_modes)(connector); |
113 | if (!count) { | 118 | if (count == 0 && connector->status == connector_status_connected) |
114 | count = drm_add_modes_noedid(connector, 1024, 768); | 119 | count = drm_add_modes_noedid(connector, 1024, 768); |
115 | if (!count) | 120 | if (count == 0) |
116 | return 0; | 121 | goto prune; |
117 | } | ||
118 | 122 | ||
119 | drm_mode_connector_list_update(connector); | 123 | drm_mode_connector_list_update(connector); |
120 | 124 | ||
@@ -840,6 +844,9 @@ static void output_poll_execute(struct work_struct *work) | |||
840 | enum drm_connector_status old_status, status; | 844 | enum drm_connector_status old_status, status; |
841 | bool repoll = false, changed = false; | 845 | bool repoll = false, changed = false; |
842 | 846 | ||
847 | if (!drm_kms_helper_poll) | ||
848 | return; | ||
849 | |||
843 | mutex_lock(&dev->mode_config.mutex); | 850 | mutex_lock(&dev->mode_config.mutex); |
844 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 851 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
845 | 852 | ||
@@ -890,6 +897,9 @@ void drm_kms_helper_poll_enable(struct drm_device *dev) | |||
890 | bool poll = false; | 897 | bool poll = false; |
891 | struct drm_connector *connector; | 898 | struct drm_connector *connector; |
892 | 899 | ||
900 | if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll) | ||
901 | return; | ||
902 | |||
893 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 903 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
894 | if (connector->polled) | 904 | if (connector->polled) |
895 | poll = true; | 905 | poll = true; |
@@ -919,8 +929,10 @@ void drm_helper_hpd_irq_event(struct drm_device *dev) | |||
919 | { | 929 | { |
920 | if (!dev->mode_config.poll_enabled) | 930 | if (!dev->mode_config.poll_enabled) |
921 | return; | 931 | return; |
932 | |||
922 | /* kill timer and schedule immediate execution, this doesn't block */ | 933 | /* kill timer and schedule immediate execution, this doesn't block */ |
923 | cancel_delayed_work(&dev->mode_config.output_poll_work); | 934 | cancel_delayed_work(&dev->mode_config.output_poll_work); |
924 | queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0); | 935 | if (drm_kms_helper_poll) |
936 | queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0); | ||
925 | } | 937 | } |
926 | EXPORT_SYMBOL(drm_helper_hpd_irq_event); | 938 | EXPORT_SYMBOL(drm_helper_hpd_irq_event); |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 90288ec7c28..84da748555b 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -55,6 +55,9 @@ | |||
55 | static int drm_version(struct drm_device *dev, void *data, | 55 | static int drm_version(struct drm_device *dev, void *data, |
56 | struct drm_file *file_priv); | 56 | struct drm_file *file_priv); |
57 | 57 | ||
58 | #define DRM_IOCTL_DEF(ioctl, _func, _flags) \ | ||
59 | [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0} | ||
60 | |||
58 | /** Ioctl table */ | 61 | /** Ioctl table */ |
59 | static struct drm_ioctl_desc drm_ioctls[] = { | 62 | static struct drm_ioctl_desc drm_ioctls[] = { |
60 | DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0), | 63 | DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0), |
@@ -421,6 +424,7 @@ long drm_ioctl(struct file *filp, | |||
421 | int retcode = -EINVAL; | 424 | int retcode = -EINVAL; |
422 | char stack_kdata[128]; | 425 | char stack_kdata[128]; |
423 | char *kdata = NULL; | 426 | char *kdata = NULL; |
427 | unsigned int usize, asize; | ||
424 | 428 | ||
425 | dev = file_priv->minor->dev; | 429 | dev = file_priv->minor->dev; |
426 | atomic_inc(&dev->ioctl_count); | 430 | atomic_inc(&dev->ioctl_count); |
@@ -436,11 +440,18 @@ long drm_ioctl(struct file *filp, | |||
436 | ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END))) | 440 | ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END))) |
437 | goto err_i1; | 441 | goto err_i1; |
438 | if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) && | 442 | if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) && |
439 | (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) | 443 | (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) { |
444 | u32 drv_size; | ||
440 | ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; | 445 | ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; |
446 | drv_size = _IOC_SIZE(ioctl->cmd_drv); | ||
447 | usize = asize = _IOC_SIZE(cmd); | ||
448 | if (drv_size > asize) | ||
449 | asize = drv_size; | ||
450 | } | ||
441 | else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { | 451 | else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { |
442 | ioctl = &drm_ioctls[nr]; | 452 | ioctl = &drm_ioctls[nr]; |
443 | cmd = ioctl->cmd; | 453 | cmd = ioctl->cmd; |
454 | usize = asize = _IOC_SIZE(cmd); | ||
444 | } else | 455 | } else |
445 | goto err_i1; | 456 | goto err_i1; |
446 | 457 | ||
@@ -460,10 +471,10 @@ long drm_ioctl(struct file *filp, | |||
460 | retcode = -EACCES; | 471 | retcode = -EACCES; |
461 | } else { | 472 | } else { |
462 | if (cmd & (IOC_IN | IOC_OUT)) { | 473 | if (cmd & (IOC_IN | IOC_OUT)) { |
463 | if (_IOC_SIZE(cmd) <= sizeof(stack_kdata)) { | 474 | if (asize <= sizeof(stack_kdata)) { |
464 | kdata = stack_kdata; | 475 | kdata = stack_kdata; |
465 | } else { | 476 | } else { |
466 | kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); | 477 | kdata = kmalloc(asize, GFP_KERNEL); |
467 | if (!kdata) { | 478 | if (!kdata) { |
468 | retcode = -ENOMEM; | 479 | retcode = -ENOMEM; |
469 | goto err_i1; | 480 | goto err_i1; |
@@ -473,11 +484,13 @@ long drm_ioctl(struct file *filp, | |||
473 | 484 | ||
474 | if (cmd & IOC_IN) { | 485 | if (cmd & IOC_IN) { |
475 | if (copy_from_user(kdata, (void __user *)arg, | 486 | if (copy_from_user(kdata, (void __user *)arg, |
476 | _IOC_SIZE(cmd)) != 0) { | 487 | usize) != 0) { |
477 | retcode = -EFAULT; | 488 | retcode = -EFAULT; |
478 | goto err_i1; | 489 | goto err_i1; |
479 | } | 490 | } |
480 | } | 491 | } else |
492 | memset(kdata, 0, usize); | ||
493 | |||
481 | if (ioctl->flags & DRM_UNLOCKED) | 494 | if (ioctl->flags & DRM_UNLOCKED) |
482 | retcode = func(dev, kdata, file_priv); | 495 | retcode = func(dev, kdata, file_priv); |
483 | else { | 496 | else { |
@@ -488,7 +501,7 @@ long drm_ioctl(struct file *filp, | |||
488 | 501 | ||
489 | if (cmd & IOC_OUT) { | 502 | if (cmd & IOC_OUT) { |
490 | if (copy_to_user((void __user *)arg, kdata, | 503 | if (copy_to_user((void __user *)arg, kdata, |
491 | _IOC_SIZE(cmd)) != 0) | 504 | usize) != 0) |
492 | retcode = -EFAULT; | 505 | retcode = -EFAULT; |
493 | } | 506 | } |
494 | } | 507 | } |
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index de82e201d68..6a5e403f9aa 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -94,10 +94,11 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_fb_helper_conn | |||
94 | int i; | 94 | int i; |
95 | enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; | 95 | enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; |
96 | struct drm_fb_helper_cmdline_mode *cmdline_mode; | 96 | struct drm_fb_helper_cmdline_mode *cmdline_mode; |
97 | struct drm_connector *connector = fb_helper_conn->connector; | 97 | struct drm_connector *connector; |
98 | 98 | ||
99 | if (!fb_helper_conn) | 99 | if (!fb_helper_conn) |
100 | return false; | 100 | return false; |
101 | connector = fb_helper_conn->connector; | ||
101 | 102 | ||
102 | cmdline_mode = &fb_helper_conn->cmdline_mode; | 103 | cmdline_mode = &fb_helper_conn->cmdline_mode; |
103 | if (!mode_option) | 104 | if (!mode_option) |
@@ -369,7 +370,7 @@ static void drm_fb_helper_restore_work_fn(struct work_struct *ignored) | |||
369 | } | 370 | } |
370 | static DECLARE_WORK(drm_fb_helper_restore_work, drm_fb_helper_restore_work_fn); | 371 | static DECLARE_WORK(drm_fb_helper_restore_work, drm_fb_helper_restore_work_fn); |
371 | 372 | ||
372 | static void drm_fb_helper_sysrq(int dummy1, struct tty_struct *dummy3) | 373 | static void drm_fb_helper_sysrq(int dummy1) |
373 | { | 374 | { |
374 | schedule_work(&drm_fb_helper_restore_work); | 375 | schedule_work(&drm_fb_helper_restore_work); |
375 | } | 376 | } |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 3a652a65546..b744dad5c23 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
@@ -41,6 +41,7 @@ | |||
41 | 41 | ||
42 | /* from BKL pushdown: note that nothing else serializes idr_find() */ | 42 | /* from BKL pushdown: note that nothing else serializes idr_find() */ |
43 | DEFINE_MUTEX(drm_global_mutex); | 43 | DEFINE_MUTEX(drm_global_mutex); |
44 | EXPORT_SYMBOL(drm_global_mutex); | ||
44 | 45 | ||
45 | static int drm_open_helper(struct inode *inode, struct file *filp, | 46 | static int drm_open_helper(struct inode *inode, struct file *filp, |
46 | struct drm_device * dev); | 47 | struct drm_device * dev); |
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c index e2f70a516c3..9bf93bc9a32 100644 --- a/drivers/gpu/drm/drm_lock.c +++ b/drivers/gpu/drm/drm_lock.c | |||
@@ -92,7 +92,9 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
92 | } | 92 | } |
93 | 93 | ||
94 | /* Contention */ | 94 | /* Contention */ |
95 | mutex_unlock(&drm_global_mutex); | ||
95 | schedule(); | 96 | schedule(); |
97 | mutex_lock(&drm_global_mutex); | ||
96 | if (signal_pending(current)) { | 98 | if (signal_pending(current)) { |
97 | ret = -EINTR; | 99 | ret = -EINTR; |
98 | break; | 100 | break; |
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index da99edc5088..a6bfc302ed9 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
@@ -285,21 +285,21 @@ void drm_mm_put_block(struct drm_mm_node *cur) | |||
285 | 285 | ||
286 | EXPORT_SYMBOL(drm_mm_put_block); | 286 | EXPORT_SYMBOL(drm_mm_put_block); |
287 | 287 | ||
288 | static int check_free_mm_node(struct drm_mm_node *entry, unsigned long size, | 288 | static int check_free_hole(unsigned long start, unsigned long end, |
289 | unsigned alignment) | 289 | unsigned long size, unsigned alignment) |
290 | { | 290 | { |
291 | unsigned wasted = 0; | 291 | unsigned wasted = 0; |
292 | 292 | ||
293 | if (entry->size < size) | 293 | if (end - start < size) |
294 | return 0; | 294 | return 0; |
295 | 295 | ||
296 | if (alignment) { | 296 | if (alignment) { |
297 | register unsigned tmp = entry->start % alignment; | 297 | unsigned tmp = start % alignment; |
298 | if (tmp) | 298 | if (tmp) |
299 | wasted = alignment - tmp; | 299 | wasted = alignment - tmp; |
300 | } | 300 | } |
301 | 301 | ||
302 | if (entry->size >= size + wasted) { | 302 | if (end >= start + size + wasted) { |
303 | return 1; | 303 | return 1; |
304 | } | 304 | } |
305 | 305 | ||
@@ -320,7 +320,8 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, | |||
320 | best_size = ~0UL; | 320 | best_size = ~0UL; |
321 | 321 | ||
322 | list_for_each_entry(entry, &mm->free_stack, free_stack) { | 322 | list_for_each_entry(entry, &mm->free_stack, free_stack) { |
323 | if (!check_free_mm_node(entry, size, alignment)) | 323 | if (!check_free_hole(entry->start, entry->start + entry->size, |
324 | size, alignment)) | ||
324 | continue; | 325 | continue; |
325 | 326 | ||
326 | if (!best_match) | 327 | if (!best_match) |
@@ -353,10 +354,12 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, | |||
353 | best_size = ~0UL; | 354 | best_size = ~0UL; |
354 | 355 | ||
355 | list_for_each_entry(entry, &mm->free_stack, free_stack) { | 356 | list_for_each_entry(entry, &mm->free_stack, free_stack) { |
356 | if (entry->start > end || (entry->start+entry->size) < start) | 357 | unsigned long adj_start = entry->start < start ? |
357 | continue; | 358 | start : entry->start; |
359 | unsigned long adj_end = entry->start + entry->size > end ? | ||
360 | end : entry->start + entry->size; | ||
358 | 361 | ||
359 | if (!check_free_mm_node(entry, size, alignment)) | 362 | if (!check_free_hole(adj_start, adj_end, size, alignment)) |
360 | continue; | 363 | continue; |
361 | 364 | ||
362 | if (!best_match) | 365 | if (!best_match) |
@@ -449,7 +452,8 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) | |||
449 | node->free_stack.prev = prev_free; | 452 | node->free_stack.prev = prev_free; |
450 | node->free_stack.next = next_free; | 453 | node->free_stack.next = next_free; |
451 | 454 | ||
452 | if (check_free_mm_node(node, mm->scan_size, mm->scan_alignment)) { | 455 | if (check_free_hole(node->start, node->start + node->size, |
456 | mm->scan_size, mm->scan_alignment)) { | ||
453 | mm->scan_hit_start = node->start; | 457 | mm->scan_hit_start = node->start; |
454 | mm->scan_hit_size = node->size; | 458 | mm->scan_hit_size = node->size; |
455 | 459 | ||
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index f1f473ea97d..949326d2a8e 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
@@ -251,7 +251,10 @@ struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay, | |||
251 | drm_mode->htotal = drm_mode->hdisplay + CVT_RB_H_BLANK; | 251 | drm_mode->htotal = drm_mode->hdisplay + CVT_RB_H_BLANK; |
252 | /* Fill in HSync values */ | 252 | /* Fill in HSync values */ |
253 | drm_mode->hsync_end = drm_mode->hdisplay + CVT_RB_H_BLANK / 2; | 253 | drm_mode->hsync_end = drm_mode->hdisplay + CVT_RB_H_BLANK / 2; |
254 | drm_mode->hsync_start = drm_mode->hsync_end = CVT_RB_H_SYNC; | 254 | drm_mode->hsync_start = drm_mode->hsync_end - CVT_RB_H_SYNC; |
255 | /* Fill in VSync values */ | ||
256 | drm_mode->vsync_start = drm_mode->vdisplay + CVT_RB_VFPORCH; | ||
257 | drm_mode->vsync_end = drm_mode->vsync_start + vsync; | ||
255 | } | 258 | } |
256 | /* 15/13. Find pixel clock frequency (kHz for xf86) */ | 259 | /* 15/13. Find pixel clock frequency (kHz for xf86) */ |
257 | drm_mode->clock = drm_mode->htotal * HV_FACTOR * 1000 / hperiod; | 260 | drm_mode->clock = drm_mode->htotal * HV_FACTOR * 1000 / hperiod; |
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index 3778360ecee..fda67468e60 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c | |||
@@ -138,7 +138,7 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
138 | break; | 138 | break; |
139 | } | 139 | } |
140 | 140 | ||
141 | if (!agpmem) | 141 | if (&agpmem->head == &dev->agp->memory) |
142 | goto vm_fault_error; | 142 | goto vm_fault_error; |
143 | 143 | ||
144 | /* | 144 | /* |
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 0e6c131313d..61b4caf220f 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c | |||
@@ -1255,21 +1255,21 @@ long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1255 | } | 1255 | } |
1256 | 1256 | ||
1257 | struct drm_ioctl_desc i810_ioctls[] = { | 1257 | struct drm_ioctl_desc i810_ioctls[] = { |
1258 | DRM_IOCTL_DEF(DRM_I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 1258 | DRM_IOCTL_DEF_DRV(I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
1259 | DRM_IOCTL_DEF(DRM_I810_VERTEX, i810_dma_vertex, DRM_AUTH|DRM_UNLOCKED), | 1259 | DRM_IOCTL_DEF_DRV(I810_VERTEX, i810_dma_vertex, DRM_AUTH|DRM_UNLOCKED), |
1260 | DRM_IOCTL_DEF(DRM_I810_CLEAR, i810_clear_bufs, DRM_AUTH|DRM_UNLOCKED), | 1260 | DRM_IOCTL_DEF_DRV(I810_CLEAR, i810_clear_bufs, DRM_AUTH|DRM_UNLOCKED), |
1261 | DRM_IOCTL_DEF(DRM_I810_FLUSH, i810_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), | 1261 | DRM_IOCTL_DEF_DRV(I810_FLUSH, i810_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), |
1262 | DRM_IOCTL_DEF(DRM_I810_GETAGE, i810_getage, DRM_AUTH|DRM_UNLOCKED), | 1262 | DRM_IOCTL_DEF_DRV(I810_GETAGE, i810_getage, DRM_AUTH|DRM_UNLOCKED), |
1263 | DRM_IOCTL_DEF(DRM_I810_GETBUF, i810_getbuf, DRM_AUTH|DRM_UNLOCKED), | 1263 | DRM_IOCTL_DEF_DRV(I810_GETBUF, i810_getbuf, DRM_AUTH|DRM_UNLOCKED), |
1264 | DRM_IOCTL_DEF(DRM_I810_SWAP, i810_swap_bufs, DRM_AUTH|DRM_UNLOCKED), | 1264 | DRM_IOCTL_DEF_DRV(I810_SWAP, i810_swap_bufs, DRM_AUTH|DRM_UNLOCKED), |
1265 | DRM_IOCTL_DEF(DRM_I810_COPY, i810_copybuf, DRM_AUTH|DRM_UNLOCKED), | 1265 | DRM_IOCTL_DEF_DRV(I810_COPY, i810_copybuf, DRM_AUTH|DRM_UNLOCKED), |
1266 | DRM_IOCTL_DEF(DRM_I810_DOCOPY, i810_docopy, DRM_AUTH|DRM_UNLOCKED), | 1266 | DRM_IOCTL_DEF_DRV(I810_DOCOPY, i810_docopy, DRM_AUTH|DRM_UNLOCKED), |
1267 | DRM_IOCTL_DEF(DRM_I810_OV0INFO, i810_ov0_info, DRM_AUTH|DRM_UNLOCKED), | 1267 | DRM_IOCTL_DEF_DRV(I810_OV0INFO, i810_ov0_info, DRM_AUTH|DRM_UNLOCKED), |
1268 | DRM_IOCTL_DEF(DRM_I810_FSTATUS, i810_fstatus, DRM_AUTH|DRM_UNLOCKED), | 1268 | DRM_IOCTL_DEF_DRV(I810_FSTATUS, i810_fstatus, DRM_AUTH|DRM_UNLOCKED), |
1269 | DRM_IOCTL_DEF(DRM_I810_OV0FLIP, i810_ov0_flip, DRM_AUTH|DRM_UNLOCKED), | 1269 | DRM_IOCTL_DEF_DRV(I810_OV0FLIP, i810_ov0_flip, DRM_AUTH|DRM_UNLOCKED), |
1270 | DRM_IOCTL_DEF(DRM_I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 1270 | DRM_IOCTL_DEF_DRV(I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
1271 | DRM_IOCTL_DEF(DRM_I810_RSTATUS, i810_rstatus, DRM_AUTH|DRM_UNLOCKED), | 1271 | DRM_IOCTL_DEF_DRV(I810_RSTATUS, i810_rstatus, DRM_AUTH|DRM_UNLOCKED), |
1272 | DRM_IOCTL_DEF(DRM_I810_FLIP, i810_flip_bufs, DRM_AUTH|DRM_UNLOCKED), | 1272 | DRM_IOCTL_DEF_DRV(I810_FLIP, i810_flip_bufs, DRM_AUTH|DRM_UNLOCKED), |
1273 | }; | 1273 | }; |
1274 | 1274 | ||
1275 | int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); | 1275 | int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); |
diff --git a/drivers/gpu/drm/i830/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c index 5168862c922..671aa18415a 100644 --- a/drivers/gpu/drm/i830/i830_dma.c +++ b/drivers/gpu/drm/i830/i830_dma.c | |||
@@ -1524,20 +1524,20 @@ long i830_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1524 | } | 1524 | } |
1525 | 1525 | ||
1526 | struct drm_ioctl_desc i830_ioctls[] = { | 1526 | struct drm_ioctl_desc i830_ioctls[] = { |
1527 | DRM_IOCTL_DEF(DRM_I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 1527 | DRM_IOCTL_DEF_DRV(I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
1528 | DRM_IOCTL_DEF(DRM_I830_VERTEX, i830_dma_vertex, DRM_AUTH|DRM_UNLOCKED), | 1528 | DRM_IOCTL_DEF_DRV(I830_VERTEX, i830_dma_vertex, DRM_AUTH|DRM_UNLOCKED), |
1529 | DRM_IOCTL_DEF(DRM_I830_CLEAR, i830_clear_bufs, DRM_AUTH|DRM_UNLOCKED), | 1529 | DRM_IOCTL_DEF_DRV(I830_CLEAR, i830_clear_bufs, DRM_AUTH|DRM_UNLOCKED), |
1530 | DRM_IOCTL_DEF(DRM_I830_FLUSH, i830_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), | 1530 | DRM_IOCTL_DEF_DRV(I830_FLUSH, i830_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), |
1531 | DRM_IOCTL_DEF(DRM_I830_GETAGE, i830_getage, DRM_AUTH|DRM_UNLOCKED), | 1531 | DRM_IOCTL_DEF_DRV(I830_GETAGE, i830_getage, DRM_AUTH|DRM_UNLOCKED), |
1532 | DRM_IOCTL_DEF(DRM_I830_GETBUF, i830_getbuf, DRM_AUTH|DRM_UNLOCKED), | 1532 | DRM_IOCTL_DEF_DRV(I830_GETBUF, i830_getbuf, DRM_AUTH|DRM_UNLOCKED), |
1533 | DRM_IOCTL_DEF(DRM_I830_SWAP, i830_swap_bufs, DRM_AUTH|DRM_UNLOCKED), | 1533 | DRM_IOCTL_DEF_DRV(I830_SWAP, i830_swap_bufs, DRM_AUTH|DRM_UNLOCKED), |
1534 | DRM_IOCTL_DEF(DRM_I830_COPY, i830_copybuf, DRM_AUTH|DRM_UNLOCKED), | 1534 | DRM_IOCTL_DEF_DRV(I830_COPY, i830_copybuf, DRM_AUTH|DRM_UNLOCKED), |
1535 | DRM_IOCTL_DEF(DRM_I830_DOCOPY, i830_docopy, DRM_AUTH|DRM_UNLOCKED), | 1535 | DRM_IOCTL_DEF_DRV(I830_DOCOPY, i830_docopy, DRM_AUTH|DRM_UNLOCKED), |
1536 | DRM_IOCTL_DEF(DRM_I830_FLIP, i830_flip_bufs, DRM_AUTH|DRM_UNLOCKED), | 1536 | DRM_IOCTL_DEF_DRV(I830_FLIP, i830_flip_bufs, DRM_AUTH|DRM_UNLOCKED), |
1537 | DRM_IOCTL_DEF(DRM_I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH|DRM_UNLOCKED), | 1537 | DRM_IOCTL_DEF_DRV(I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH|DRM_UNLOCKED), |
1538 | DRM_IOCTL_DEF(DRM_I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH|DRM_UNLOCKED), | 1538 | DRM_IOCTL_DEF_DRV(I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH|DRM_UNLOCKED), |
1539 | DRM_IOCTL_DEF(DRM_I830_GETPARAM, i830_getparam, DRM_AUTH|DRM_UNLOCKED), | 1539 | DRM_IOCTL_DEF_DRV(I830_GETPARAM, i830_getparam, DRM_AUTH|DRM_UNLOCKED), |
1540 | DRM_IOCTL_DEF(DRM_I830_SETPARAM, i830_setparam, DRM_AUTH|DRM_UNLOCKED), | 1540 | DRM_IOCTL_DEF_DRV(I830_SETPARAM, i830_setparam, DRM_AUTH|DRM_UNLOCKED), |
1541 | }; | 1541 | }; |
1542 | 1542 | ||
1543 | int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); | 1543 | int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); |
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index da78f2c0d90..5c8e53458ed 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -8,6 +8,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ | |||
8 | i915_suspend.o \ | 8 | i915_suspend.o \ |
9 | i915_gem.o \ | 9 | i915_gem.o \ |
10 | i915_gem_debug.o \ | 10 | i915_gem_debug.o \ |
11 | i915_gem_evict.o \ | ||
11 | i915_gem_tiling.o \ | 12 | i915_gem_tiling.o \ |
12 | i915_trace_points.o \ | 13 | i915_trace_points.o \ |
13 | intel_display.o \ | 14 | intel_display.o \ |
@@ -18,6 +19,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ | |||
18 | intel_hdmi.o \ | 19 | intel_hdmi.o \ |
19 | intel_sdvo.o \ | 20 | intel_sdvo.o \ |
20 | intel_modes.o \ | 21 | intel_modes.o \ |
22 | intel_panel.o \ | ||
21 | intel_i2c.o \ | 23 | intel_i2c.o \ |
22 | intel_fb.o \ | 24 | intel_fb.o \ |
23 | intel_tv.o \ | 25 | intel_tv.o \ |
diff --git a/drivers/gpu/drm/i915/dvo.h b/drivers/gpu/drm/i915/dvo.h index 0d6ff640e1c..8c2ad014c47 100644 --- a/drivers/gpu/drm/i915/dvo.h +++ b/drivers/gpu/drm/i915/dvo.h | |||
@@ -30,20 +30,17 @@ | |||
30 | #include "intel_drv.h" | 30 | #include "intel_drv.h" |
31 | 31 | ||
32 | struct intel_dvo_device { | 32 | struct intel_dvo_device { |
33 | char *name; | 33 | const char *name; |
34 | int type; | 34 | int type; |
35 | /* DVOA/B/C output register */ | 35 | /* DVOA/B/C output register */ |
36 | u32 dvo_reg; | 36 | u32 dvo_reg; |
37 | /* GPIO register used for i2c bus to control this device */ | 37 | /* GPIO register used for i2c bus to control this device */ |
38 | u32 gpio; | 38 | u32 gpio; |
39 | int slave_addr; | 39 | int slave_addr; |
40 | struct i2c_adapter *i2c_bus; | ||
41 | 40 | ||
42 | const struct intel_dvo_dev_ops *dev_ops; | 41 | const struct intel_dvo_dev_ops *dev_ops; |
43 | void *dev_priv; | 42 | void *dev_priv; |
44 | 43 | struct i2c_adapter *i2c_bus; | |
45 | struct drm_display_mode *panel_fixed_mode; | ||
46 | bool panel_wants_dither; | ||
47 | }; | 44 | }; |
48 | 45 | ||
49 | struct intel_dvo_dev_ops { | 46 | struct intel_dvo_dev_ops { |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9214119c015..5e43d707678 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include "drmP.h" | 32 | #include "drmP.h" |
33 | #include "drm.h" | 33 | #include "drm.h" |
34 | #include "intel_drv.h" | ||
34 | #include "i915_drm.h" | 35 | #include "i915_drm.h" |
35 | #include "i915_drv.h" | 36 | #include "i915_drv.h" |
36 | 37 | ||
@@ -121,6 +122,54 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
121 | return 0; | 122 | return 0; |
122 | } | 123 | } |
123 | 124 | ||
125 | static int i915_gem_pageflip_info(struct seq_file *m, void *data) | ||
126 | { | ||
127 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
128 | struct drm_device *dev = node->minor->dev; | ||
129 | unsigned long flags; | ||
130 | struct intel_crtc *crtc; | ||
131 | |||
132 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) { | ||
133 | const char *pipe = crtc->pipe ? "B" : "A"; | ||
134 | const char *plane = crtc->plane ? "B" : "A"; | ||
135 | struct intel_unpin_work *work; | ||
136 | |||
137 | spin_lock_irqsave(&dev->event_lock, flags); | ||
138 | work = crtc->unpin_work; | ||
139 | if (work == NULL) { | ||
140 | seq_printf(m, "No flip due on pipe %s (plane %s)\n", | ||
141 | pipe, plane); | ||
142 | } else { | ||
143 | if (!work->pending) { | ||
144 | seq_printf(m, "Flip queued on pipe %s (plane %s)\n", | ||
145 | pipe, plane); | ||
146 | } else { | ||
147 | seq_printf(m, "Flip pending (waiting for vsync) on pipe %s (plane %s)\n", | ||
148 | pipe, plane); | ||
149 | } | ||
150 | if (work->enable_stall_check) | ||
151 | seq_printf(m, "Stall check enabled, "); | ||
152 | else | ||
153 | seq_printf(m, "Stall check waiting for page flip ioctl, "); | ||
154 | seq_printf(m, "%d prepares\n", work->pending); | ||
155 | |||
156 | if (work->old_fb_obj) { | ||
157 | struct drm_i915_gem_object *obj_priv = to_intel_bo(work->old_fb_obj); | ||
158 | if(obj_priv) | ||
159 | seq_printf(m, "Old framebuffer gtt_offset 0x%08x\n", obj_priv->gtt_offset ); | ||
160 | } | ||
161 | if (work->pending_flip_obj) { | ||
162 | struct drm_i915_gem_object *obj_priv = to_intel_bo(work->pending_flip_obj); | ||
163 | if(obj_priv) | ||
164 | seq_printf(m, "New framebuffer gtt_offset 0x%08x\n", obj_priv->gtt_offset ); | ||
165 | } | ||
166 | } | ||
167 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
168 | } | ||
169 | |||
170 | return 0; | ||
171 | } | ||
172 | |||
124 | static int i915_gem_request_info(struct seq_file *m, void *data) | 173 | static int i915_gem_request_info(struct seq_file *m, void *data) |
125 | { | 174 | { |
126 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 175 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
@@ -467,6 +516,9 @@ static int i915_error_state(struct seq_file *m, void *unused) | |||
467 | } | 516 | } |
468 | } | 517 | } |
469 | 518 | ||
519 | if (error->overlay) | ||
520 | intel_overlay_print_error_state(m, error->overlay); | ||
521 | |||
470 | out: | 522 | out: |
471 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); | 523 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); |
472 | 524 | ||
@@ -774,6 +826,7 @@ static struct drm_info_list i915_debugfs_list[] = { | |||
774 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, | 826 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, |
775 | {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, | 827 | {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, |
776 | {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, | 828 | {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, |
829 | {"i915_gem_pageflip", i915_gem_pageflip_info, 0}, | ||
777 | {"i915_gem_request", i915_gem_request_info, 0}, | 830 | {"i915_gem_request", i915_gem_request_info, 0}, |
778 | {"i915_gem_seqno", i915_gem_seqno_info, 0}, | 831 | {"i915_gem_seqno", i915_gem_seqno_info, 0}, |
779 | {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, | 832 | {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index f19ffe87af3..9d67b485303 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -499,6 +499,13 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, | |||
499 | } | 499 | } |
500 | } | 500 | } |
501 | 501 | ||
502 | |||
503 | if (IS_G4X(dev) || IS_IRONLAKE(dev)) { | ||
504 | BEGIN_LP_RING(2); | ||
505 | OUT_RING(MI_FLUSH | MI_NO_WRITE_FLUSH | MI_INVALIDATE_ISP); | ||
506 | OUT_RING(MI_NOOP); | ||
507 | ADVANCE_LP_RING(); | ||
508 | } | ||
502 | i915_emit_breadcrumb(dev); | 509 | i915_emit_breadcrumb(dev); |
503 | 510 | ||
504 | return 0; | 511 | return 0; |
@@ -613,8 +620,10 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, | |||
613 | ret = copy_from_user(cliprects, batch->cliprects, | 620 | ret = copy_from_user(cliprects, batch->cliprects, |
614 | batch->num_cliprects * | 621 | batch->num_cliprects * |
615 | sizeof(struct drm_clip_rect)); | 622 | sizeof(struct drm_clip_rect)); |
616 | if (ret != 0) | 623 | if (ret != 0) { |
624 | ret = -EFAULT; | ||
617 | goto fail_free; | 625 | goto fail_free; |
626 | } | ||
618 | } | 627 | } |
619 | 628 | ||
620 | mutex_lock(&dev->struct_mutex); | 629 | mutex_lock(&dev->struct_mutex); |
@@ -655,8 +664,10 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
655 | return -ENOMEM; | 664 | return -ENOMEM; |
656 | 665 | ||
657 | ret = copy_from_user(batch_data, cmdbuf->buf, cmdbuf->sz); | 666 | ret = copy_from_user(batch_data, cmdbuf->buf, cmdbuf->sz); |
658 | if (ret != 0) | 667 | if (ret != 0) { |
668 | ret = -EFAULT; | ||
659 | goto fail_batch_free; | 669 | goto fail_batch_free; |
670 | } | ||
660 | 671 | ||
661 | if (cmdbuf->num_cliprects) { | 672 | if (cmdbuf->num_cliprects) { |
662 | cliprects = kcalloc(cmdbuf->num_cliprects, | 673 | cliprects = kcalloc(cmdbuf->num_cliprects, |
@@ -669,8 +680,10 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
669 | ret = copy_from_user(cliprects, cmdbuf->cliprects, | 680 | ret = copy_from_user(cliprects, cmdbuf->cliprects, |
670 | cmdbuf->num_cliprects * | 681 | cmdbuf->num_cliprects * |
671 | sizeof(struct drm_clip_rect)); | 682 | sizeof(struct drm_clip_rect)); |
672 | if (ret != 0) | 683 | if (ret != 0) { |
684 | ret = -EFAULT; | ||
673 | goto fail_clip_free; | 685 | goto fail_clip_free; |
686 | } | ||
674 | } | 687 | } |
675 | 688 | ||
676 | mutex_lock(&dev->struct_mutex); | 689 | mutex_lock(&dev->struct_mutex); |
@@ -878,7 +891,7 @@ intel_alloc_mchbar_resource(struct drm_device *dev) | |||
878 | int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; | 891 | int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; |
879 | u32 temp_lo, temp_hi = 0; | 892 | u32 temp_lo, temp_hi = 0; |
880 | u64 mchbar_addr; | 893 | u64 mchbar_addr; |
881 | int ret = 0; | 894 | int ret; |
882 | 895 | ||
883 | if (IS_I965G(dev)) | 896 | if (IS_I965G(dev)) |
884 | pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi); | 897 | pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi); |
@@ -888,22 +901,23 @@ intel_alloc_mchbar_resource(struct drm_device *dev) | |||
888 | /* If ACPI doesn't have it, assume we need to allocate it ourselves */ | 901 | /* If ACPI doesn't have it, assume we need to allocate it ourselves */ |
889 | #ifdef CONFIG_PNP | 902 | #ifdef CONFIG_PNP |
890 | if (mchbar_addr && | 903 | if (mchbar_addr && |
891 | pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) { | 904 | pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) |
892 | ret = 0; | 905 | return 0; |
893 | goto out; | ||
894 | } | ||
895 | #endif | 906 | #endif |
896 | 907 | ||
897 | /* Get some space for it */ | 908 | /* Get some space for it */ |
898 | ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, &dev_priv->mch_res, | 909 | dev_priv->mch_res.name = "i915 MCHBAR"; |
910 | dev_priv->mch_res.flags = IORESOURCE_MEM; | ||
911 | ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, | ||
912 | &dev_priv->mch_res, | ||
899 | MCHBAR_SIZE, MCHBAR_SIZE, | 913 | MCHBAR_SIZE, MCHBAR_SIZE, |
900 | PCIBIOS_MIN_MEM, | 914 | PCIBIOS_MIN_MEM, |
901 | 0, pcibios_align_resource, | 915 | 0, pcibios_align_resource, |
902 | dev_priv->bridge_dev); | 916 | dev_priv->bridge_dev); |
903 | if (ret) { | 917 | if (ret) { |
904 | DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret); | 918 | DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret); |
905 | dev_priv->mch_res.start = 0; | 919 | dev_priv->mch_res.start = 0; |
906 | goto out; | 920 | return ret; |
907 | } | 921 | } |
908 | 922 | ||
909 | if (IS_I965G(dev)) | 923 | if (IS_I965G(dev)) |
@@ -912,8 +926,7 @@ intel_alloc_mchbar_resource(struct drm_device *dev) | |||
912 | 926 | ||
913 | pci_write_config_dword(dev_priv->bridge_dev, reg, | 927 | pci_write_config_dword(dev_priv->bridge_dev, reg, |
914 | lower_32_bits(dev_priv->mch_res.start)); | 928 | lower_32_bits(dev_priv->mch_res.start)); |
915 | out: | 929 | return 0; |
916 | return ret; | ||
917 | } | 930 | } |
918 | 931 | ||
919 | /* Setup MCHBAR if possible, return true if we should disable it again */ | 932 | /* Setup MCHBAR if possible, return true if we should disable it again */ |
@@ -2075,6 +2088,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2075 | goto free_priv; | 2088 | goto free_priv; |
2076 | } | 2089 | } |
2077 | 2090 | ||
2091 | /* overlay on gen2 is broken and can't address above 1G */ | ||
2092 | if (IS_GEN2(dev)) | ||
2093 | dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); | ||
2094 | |||
2078 | dev_priv->regs = ioremap(base, size); | 2095 | dev_priv->regs = ioremap(base, size); |
2079 | if (!dev_priv->regs) { | 2096 | if (!dev_priv->regs) { |
2080 | DRM_ERROR("failed to map registers\n"); | 2097 | DRM_ERROR("failed to map registers\n"); |
@@ -2360,46 +2377,46 @@ void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) | |||
2360 | } | 2377 | } |
2361 | 2378 | ||
2362 | struct drm_ioctl_desc i915_ioctls[] = { | 2379 | struct drm_ioctl_desc i915_ioctls[] = { |
2363 | DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2380 | DRM_IOCTL_DEF_DRV(I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2364 | DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH), | 2381 | DRM_IOCTL_DEF_DRV(I915_FLUSH, i915_flush_ioctl, DRM_AUTH), |
2365 | DRM_IOCTL_DEF(DRM_I915_FLIP, i915_flip_bufs, DRM_AUTH), | 2382 | DRM_IOCTL_DEF_DRV(I915_FLIP, i915_flip_bufs, DRM_AUTH), |
2366 | DRM_IOCTL_DEF(DRM_I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH), | 2383 | DRM_IOCTL_DEF_DRV(I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH), |
2367 | DRM_IOCTL_DEF(DRM_I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH), | 2384 | DRM_IOCTL_DEF_DRV(I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH), |
2368 | DRM_IOCTL_DEF(DRM_I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), | 2385 | DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), |
2369 | DRM_IOCTL_DEF(DRM_I915_GETPARAM, i915_getparam, DRM_AUTH), | 2386 | DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH), |
2370 | DRM_IOCTL_DEF(DRM_I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2387 | DRM_IOCTL_DEF_DRV(I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2371 | DRM_IOCTL_DEF(DRM_I915_ALLOC, i915_mem_alloc, DRM_AUTH), | 2388 | DRM_IOCTL_DEF_DRV(I915_ALLOC, i915_mem_alloc, DRM_AUTH), |
2372 | DRM_IOCTL_DEF(DRM_I915_FREE, i915_mem_free, DRM_AUTH), | 2389 | DRM_IOCTL_DEF_DRV(I915_FREE, i915_mem_free, DRM_AUTH), |
2373 | DRM_IOCTL_DEF(DRM_I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2390 | DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2374 | DRM_IOCTL_DEF(DRM_I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), | 2391 | DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), |
2375 | DRM_IOCTL_DEF(DRM_I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), | 2392 | DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2376 | DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), | 2393 | DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2377 | DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ), | 2394 | DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH), |
2378 | DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), | 2395 | DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), |
2379 | DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2396 | DRM_IOCTL_DEF_DRV(I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2380 | DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2397 | DRM_IOCTL_DEF_DRV(I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
2381 | DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED), | 2398 | DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED), |
2382 | DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED), | 2399 | DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED), |
2383 | DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2400 | DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), |
2384 | DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2401 | DRM_IOCTL_DEF_DRV(I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), |
2385 | DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), | 2402 | DRM_IOCTL_DEF_DRV(I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), |
2386 | DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED), | 2403 | DRM_IOCTL_DEF_DRV(I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED), |
2387 | DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2404 | DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
2388 | DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2405 | DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
2389 | DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED), | 2406 | DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED), |
2390 | DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED), | 2407 | DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED), |
2391 | DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED), | 2408 | DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED), |
2392 | DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_UNLOCKED), | 2409 | DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_UNLOCKED), |
2393 | DRM_IOCTL_DEF(DRM_I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED), | 2410 | DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED), |
2394 | DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED), | 2411 | DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED), |
2395 | DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED), | 2412 | DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED), |
2396 | DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED), | 2413 | DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED), |
2397 | DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED), | 2414 | DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED), |
2398 | DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED), | 2415 | DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED), |
2399 | DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED), | 2416 | DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED), |
2400 | DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED), | 2417 | DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED), |
2401 | DRM_IOCTL_DEF(DRM_I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 2418 | DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
2402 | DRM_IOCTL_DEF(DRM_I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 2419 | DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
2403 | }; | 2420 | }; |
2404 | 2421 | ||
2405 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); | 2422 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 5044f653e8e..216deb57978 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -61,91 +61,86 @@ extern int intel_agp_enabled; | |||
61 | .driver_data = (unsigned long) info } | 61 | .driver_data = (unsigned long) info } |
62 | 62 | ||
63 | static const struct intel_device_info intel_i830_info = { | 63 | static const struct intel_device_info intel_i830_info = { |
64 | .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, | 64 | .gen = 2, .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, |
65 | }; | 65 | }; |
66 | 66 | ||
67 | static const struct intel_device_info intel_845g_info = { | 67 | static const struct intel_device_info intel_845g_info = { |
68 | .is_i8xx = 1, | 68 | .gen = 2, .is_i8xx = 1, |
69 | }; | 69 | }; |
70 | 70 | ||
71 | static const struct intel_device_info intel_i85x_info = { | 71 | static const struct intel_device_info intel_i85x_info = { |
72 | .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1, | 72 | .gen = 2, .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1, |
73 | .cursor_needs_physical = 1, | 73 | .cursor_needs_physical = 1, |
74 | }; | 74 | }; |
75 | 75 | ||
76 | static const struct intel_device_info intel_i865g_info = { | 76 | static const struct intel_device_info intel_i865g_info = { |
77 | .is_i8xx = 1, | 77 | .gen = 2, .is_i8xx = 1, |
78 | }; | 78 | }; |
79 | 79 | ||
80 | static const struct intel_device_info intel_i915g_info = { | 80 | static const struct intel_device_info intel_i915g_info = { |
81 | .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, | 81 | .gen = 3, .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, |
82 | }; | 82 | }; |
83 | static const struct intel_device_info intel_i915gm_info = { | 83 | static const struct intel_device_info intel_i915gm_info = { |
84 | .is_i9xx = 1, .is_mobile = 1, | 84 | .gen = 3, .is_i9xx = 1, .is_mobile = 1, |
85 | .cursor_needs_physical = 1, | 85 | .cursor_needs_physical = 1, |
86 | }; | 86 | }; |
87 | static const struct intel_device_info intel_i945g_info = { | 87 | static const struct intel_device_info intel_i945g_info = { |
88 | .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, | 88 | .gen = 3, .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, |
89 | }; | 89 | }; |
90 | static const struct intel_device_info intel_i945gm_info = { | 90 | static const struct intel_device_info intel_i945gm_info = { |
91 | .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, | 91 | .gen = 3, .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, |
92 | .has_hotplug = 1, .cursor_needs_physical = 1, | 92 | .has_hotplug = 1, .cursor_needs_physical = 1, |
93 | }; | 93 | }; |
94 | 94 | ||
95 | static const struct intel_device_info intel_i965g_info = { | 95 | static const struct intel_device_info intel_i965g_info = { |
96 | .is_broadwater = 1, .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1, | 96 | .gen = 4, .is_broadwater = 1, .is_i965g = 1, .is_i9xx = 1, |
97 | .has_hotplug = 1, | ||
97 | }; | 98 | }; |
98 | 99 | ||
99 | static const struct intel_device_info intel_i965gm_info = { | 100 | static const struct intel_device_info intel_i965gm_info = { |
100 | .is_crestline = 1, .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1, | 101 | .gen = 4, .is_crestline = 1, .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1, |
101 | .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, | 102 | .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1, |
102 | .has_hotplug = 1, | ||
103 | }; | 103 | }; |
104 | 104 | ||
105 | static const struct intel_device_info intel_g33_info = { | 105 | static const struct intel_device_info intel_g33_info = { |
106 | .is_g33 = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 106 | .gen = 3, .is_g33 = 1, .is_i9xx = 1, |
107 | .has_hotplug = 1, | 107 | .need_gfx_hws = 1, .has_hotplug = 1, |
108 | }; | 108 | }; |
109 | 109 | ||
110 | static const struct intel_device_info intel_g45_info = { | 110 | static const struct intel_device_info intel_g45_info = { |
111 | .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 111 | .gen = 4, .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1, |
112 | .has_pipe_cxsr = 1, | 112 | .has_pipe_cxsr = 1, .has_hotplug = 1, |
113 | .has_hotplug = 1, | ||
114 | }; | 113 | }; |
115 | 114 | ||
116 | static const struct intel_device_info intel_gm45_info = { | 115 | static const struct intel_device_info intel_gm45_info = { |
117 | .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, | 116 | .gen = 4, .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, |
118 | .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, | 117 | .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, |
119 | .has_pipe_cxsr = 1, | 118 | .has_pipe_cxsr = 1, .has_hotplug = 1, |
120 | .has_hotplug = 1, | ||
121 | }; | 119 | }; |
122 | 120 | ||
123 | static const struct intel_device_info intel_pineview_info = { | 121 | static const struct intel_device_info intel_pineview_info = { |
124 | .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1, | 122 | .gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1, |
125 | .need_gfx_hws = 1, | 123 | .need_gfx_hws = 1, .has_hotplug = 1, |
126 | .has_hotplug = 1, | ||
127 | }; | 124 | }; |
128 | 125 | ||
129 | static const struct intel_device_info intel_ironlake_d_info = { | 126 | static const struct intel_device_info intel_ironlake_d_info = { |
130 | .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 127 | .gen = 5, .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, |
131 | .has_pipe_cxsr = 1, | 128 | .need_gfx_hws = 1, .has_pipe_cxsr = 1, .has_hotplug = 1, |
132 | .has_hotplug = 1, | ||
133 | }; | 129 | }; |
134 | 130 | ||
135 | static const struct intel_device_info intel_ironlake_m_info = { | 131 | static const struct intel_device_info intel_ironlake_m_info = { |
136 | .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1, | 132 | .gen = 5, .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1, |
137 | .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, | 133 | .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1, |
138 | .has_hotplug = 1, | ||
139 | }; | 134 | }; |
140 | 135 | ||
141 | static const struct intel_device_info intel_sandybridge_d_info = { | 136 | static const struct intel_device_info intel_sandybridge_d_info = { |
142 | .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 137 | .gen = 6, .is_i965g = 1, .is_i9xx = 1, |
143 | .has_hotplug = 1, .is_gen6 = 1, | 138 | .need_gfx_hws = 1, .has_hotplug = 1, |
144 | }; | 139 | }; |
145 | 140 | ||
146 | static const struct intel_device_info intel_sandybridge_m_info = { | 141 | static const struct intel_device_info intel_sandybridge_m_info = { |
147 | .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 142 | .gen = 6, .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, |
148 | .has_hotplug = 1, .is_gen6 = 1, | 143 | .need_gfx_hws = 1, .has_hotplug = 1, |
149 | }; | 144 | }; |
150 | 145 | ||
151 | static const struct pci_device_id pciidlist[] = { /* aka */ | 146 | static const struct pci_device_id pciidlist[] = { /* aka */ |
@@ -180,7 +175,12 @@ static const struct pci_device_id pciidlist[] = { /* aka */ | |||
180 | INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info), | 175 | INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info), |
181 | INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info), | 176 | INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info), |
182 | INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info), | 177 | INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info), |
178 | INTEL_VGA_DEVICE(0x0112, &intel_sandybridge_d_info), | ||
179 | INTEL_VGA_DEVICE(0x0122, &intel_sandybridge_d_info), | ||
183 | INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info), | 180 | INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info), |
181 | INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info), | ||
182 | INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info), | ||
183 | INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info), | ||
184 | {0, 0, 0} | 184 | {0, 0, 0} |
185 | }; | 185 | }; |
186 | 186 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 906663b9929..af4a263cf25 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -113,6 +113,9 @@ struct intel_opregion { | |||
113 | int enabled; | 113 | int enabled; |
114 | }; | 114 | }; |
115 | 115 | ||
116 | struct intel_overlay; | ||
117 | struct intel_overlay_error_state; | ||
118 | |||
116 | struct drm_i915_master_private { | 119 | struct drm_i915_master_private { |
117 | drm_local_map_t *sarea; | 120 | drm_local_map_t *sarea; |
118 | struct _drm_i915_sarea *sarea_priv; | 121 | struct _drm_i915_sarea *sarea_priv; |
@@ -166,6 +169,7 @@ struct drm_i915_error_state { | |||
166 | u32 purgeable:1; | 169 | u32 purgeable:1; |
167 | } *active_bo; | 170 | } *active_bo; |
168 | u32 active_bo_count; | 171 | u32 active_bo_count; |
172 | struct intel_overlay_error_state *overlay; | ||
169 | }; | 173 | }; |
170 | 174 | ||
171 | struct drm_i915_display_funcs { | 175 | struct drm_i915_display_funcs { |
@@ -186,9 +190,8 @@ struct drm_i915_display_funcs { | |||
186 | /* clock gating init */ | 190 | /* clock gating init */ |
187 | }; | 191 | }; |
188 | 192 | ||
189 | struct intel_overlay; | ||
190 | |||
191 | struct intel_device_info { | 193 | struct intel_device_info { |
194 | u8 gen; | ||
192 | u8 is_mobile : 1; | 195 | u8 is_mobile : 1; |
193 | u8 is_i8xx : 1; | 196 | u8 is_i8xx : 1; |
194 | u8 is_i85x : 1; | 197 | u8 is_i85x : 1; |
@@ -204,7 +207,6 @@ struct intel_device_info { | |||
204 | u8 is_broadwater : 1; | 207 | u8 is_broadwater : 1; |
205 | u8 is_crestline : 1; | 208 | u8 is_crestline : 1; |
206 | u8 is_ironlake : 1; | 209 | u8 is_ironlake : 1; |
207 | u8 is_gen6 : 1; | ||
208 | u8 has_fbc : 1; | 210 | u8 has_fbc : 1; |
209 | u8 has_rc6 : 1; | 211 | u8 has_rc6 : 1; |
210 | u8 has_pipe_cxsr : 1; | 212 | u8 has_pipe_cxsr : 1; |
@@ -242,6 +244,7 @@ typedef struct drm_i915_private { | |||
242 | struct pci_dev *bridge_dev; | 244 | struct pci_dev *bridge_dev; |
243 | struct intel_ring_buffer render_ring; | 245 | struct intel_ring_buffer render_ring; |
244 | struct intel_ring_buffer bsd_ring; | 246 | struct intel_ring_buffer bsd_ring; |
247 | uint32_t next_seqno; | ||
245 | 248 | ||
246 | drm_dma_handle_t *status_page_dmah; | 249 | drm_dma_handle_t *status_page_dmah; |
247 | void *seqno_page; | 250 | void *seqno_page; |
@@ -251,6 +254,7 @@ typedef struct drm_i915_private { | |||
251 | drm_local_map_t hws_map; | 254 | drm_local_map_t hws_map; |
252 | struct drm_gem_object *seqno_obj; | 255 | struct drm_gem_object *seqno_obj; |
253 | struct drm_gem_object *pwrctx; | 256 | struct drm_gem_object *pwrctx; |
257 | struct drm_gem_object *renderctx; | ||
254 | 258 | ||
255 | struct resource mch_res; | 259 | struct resource mch_res; |
256 | 260 | ||
@@ -285,6 +289,9 @@ typedef struct drm_i915_private { | |||
285 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; | 289 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; |
286 | int vblank_pipe; | 290 | int vblank_pipe; |
287 | int num_pipe; | 291 | int num_pipe; |
292 | u32 flush_rings; | ||
293 | #define FLUSH_RENDER_RING 0x1 | ||
294 | #define FLUSH_BSD_RING 0x2 | ||
288 | 295 | ||
289 | /* For hangcheck timer */ | 296 | /* For hangcheck timer */ |
290 | #define DRM_I915_HANGCHECK_PERIOD 75 /* in jiffies */ | 297 | #define DRM_I915_HANGCHECK_PERIOD 75 /* in jiffies */ |
@@ -568,8 +575,6 @@ typedef struct drm_i915_private { | |||
568 | */ | 575 | */ |
569 | struct delayed_work retire_work; | 576 | struct delayed_work retire_work; |
570 | 577 | ||
571 | uint32_t next_gem_seqno; | ||
572 | |||
573 | /** | 578 | /** |
574 | * Waiting sequence number, if any | 579 | * Waiting sequence number, if any |
575 | */ | 580 | */ |
@@ -610,6 +615,8 @@ typedef struct drm_i915_private { | |||
610 | struct sdvo_device_mapping sdvo_mappings[2]; | 615 | struct sdvo_device_mapping sdvo_mappings[2]; |
611 | /* indicate whether the LVDS_BORDER should be enabled or not */ | 616 | /* indicate whether the LVDS_BORDER should be enabled or not */ |
612 | unsigned int lvds_border_bits; | 617 | unsigned int lvds_border_bits; |
618 | /* Panel fitter placement and size for Ironlake+ */ | ||
619 | u32 pch_pf_pos, pch_pf_size; | ||
613 | 620 | ||
614 | struct drm_crtc *plane_to_crtc_mapping[2]; | 621 | struct drm_crtc *plane_to_crtc_mapping[2]; |
615 | struct drm_crtc *pipe_to_crtc_mapping[2]; | 622 | struct drm_crtc *pipe_to_crtc_mapping[2]; |
@@ -669,6 +676,8 @@ struct drm_i915_gem_object { | |||
669 | struct list_head list; | 676 | struct list_head list; |
670 | /** This object's place on GPU write list */ | 677 | /** This object's place on GPU write list */ |
671 | struct list_head gpu_write_list; | 678 | struct list_head gpu_write_list; |
679 | /** This object's place on eviction list */ | ||
680 | struct list_head evict_list; | ||
672 | 681 | ||
673 | /** | 682 | /** |
674 | * This is set if the object is on the active or flushing lists | 683 | * This is set if the object is on the active or flushing lists |
@@ -978,6 +987,7 @@ int i915_gem_init_ringbuffer(struct drm_device *dev); | |||
978 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); | 987 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); |
979 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, | 988 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, |
980 | unsigned long end); | 989 | unsigned long end); |
990 | int i915_gpu_idle(struct drm_device *dev); | ||
981 | int i915_gem_idle(struct drm_device *dev); | 991 | int i915_gem_idle(struct drm_device *dev); |
982 | uint32_t i915_add_request(struct drm_device *dev, | 992 | uint32_t i915_add_request(struct drm_device *dev, |
983 | struct drm_file *file_priv, | 993 | struct drm_file *file_priv, |
@@ -991,7 +1001,9 @@ int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, | |||
991 | int write); | 1001 | int write); |
992 | int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj); | 1002 | int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj); |
993 | int i915_gem_attach_phys_object(struct drm_device *dev, | 1003 | int i915_gem_attach_phys_object(struct drm_device *dev, |
994 | struct drm_gem_object *obj, int id); | 1004 | struct drm_gem_object *obj, |
1005 | int id, | ||
1006 | int align); | ||
995 | void i915_gem_detach_phys_object(struct drm_device *dev, | 1007 | void i915_gem_detach_phys_object(struct drm_device *dev, |
996 | struct drm_gem_object *obj); | 1008 | struct drm_gem_object *obj); |
997 | void i915_gem_free_all_phys_object(struct drm_device *dev); | 1009 | void i915_gem_free_all_phys_object(struct drm_device *dev); |
@@ -1003,6 +1015,11 @@ int i915_gem_object_flush_write_domain(struct drm_gem_object *obj); | |||
1003 | void i915_gem_shrinker_init(void); | 1015 | void i915_gem_shrinker_init(void); |
1004 | void i915_gem_shrinker_exit(void); | 1016 | void i915_gem_shrinker_exit(void); |
1005 | 1017 | ||
1018 | /* i915_gem_evict.c */ | ||
1019 | int i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment); | ||
1020 | int i915_gem_evict_everything(struct drm_device *dev); | ||
1021 | int i915_gem_evict_inactive(struct drm_device *dev); | ||
1022 | |||
1006 | /* i915_gem_tiling.c */ | 1023 | /* i915_gem_tiling.c */ |
1007 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); | 1024 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); |
1008 | void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj); | 1025 | void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj); |
@@ -1066,6 +1083,10 @@ extern bool ironlake_set_drps(struct drm_device *dev, u8 val); | |||
1066 | extern void intel_detect_pch (struct drm_device *dev); | 1083 | extern void intel_detect_pch (struct drm_device *dev); |
1067 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | 1084 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); |
1068 | 1085 | ||
1086 | /* overlay */ | ||
1087 | extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); | ||
1088 | extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error); | ||
1089 | |||
1069 | /** | 1090 | /** |
1070 | * Lock test for when it's just for synchronization of ring access. | 1091 | * Lock test for when it's just for synchronization of ring access. |
1071 | * | 1092 | * |
@@ -1092,26 +1113,26 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | |||
1092 | #define I915_VERBOSE 0 | 1113 | #define I915_VERBOSE 0 |
1093 | 1114 | ||
1094 | #define BEGIN_LP_RING(n) do { \ | 1115 | #define BEGIN_LP_RING(n) do { \ |
1095 | drm_i915_private_t *dev_priv = dev->dev_private; \ | 1116 | drm_i915_private_t *dev_priv__ = dev->dev_private; \ |
1096 | if (I915_VERBOSE) \ | 1117 | if (I915_VERBOSE) \ |
1097 | DRM_DEBUG(" BEGIN_LP_RING %x\n", (int)(n)); \ | 1118 | DRM_DEBUG(" BEGIN_LP_RING %x\n", (int)(n)); \ |
1098 | intel_ring_begin(dev, &dev_priv->render_ring, (n)); \ | 1119 | intel_ring_begin(dev, &dev_priv__->render_ring, (n)); \ |
1099 | } while (0) | 1120 | } while (0) |
1100 | 1121 | ||
1101 | 1122 | ||
1102 | #define OUT_RING(x) do { \ | 1123 | #define OUT_RING(x) do { \ |
1103 | drm_i915_private_t *dev_priv = dev->dev_private; \ | 1124 | drm_i915_private_t *dev_priv__ = dev->dev_private; \ |
1104 | if (I915_VERBOSE) \ | 1125 | if (I915_VERBOSE) \ |
1105 | DRM_DEBUG(" OUT_RING %x\n", (int)(x)); \ | 1126 | DRM_DEBUG(" OUT_RING %x\n", (int)(x)); \ |
1106 | intel_ring_emit(dev, &dev_priv->render_ring, x); \ | 1127 | intel_ring_emit(dev, &dev_priv__->render_ring, x); \ |
1107 | } while (0) | 1128 | } while (0) |
1108 | 1129 | ||
1109 | #define ADVANCE_LP_RING() do { \ | 1130 | #define ADVANCE_LP_RING() do { \ |
1110 | drm_i915_private_t *dev_priv = dev->dev_private; \ | 1131 | drm_i915_private_t *dev_priv__ = dev->dev_private; \ |
1111 | if (I915_VERBOSE) \ | 1132 | if (I915_VERBOSE) \ |
1112 | DRM_DEBUG("ADVANCE_LP_RING %x\n", \ | 1133 | DRM_DEBUG("ADVANCE_LP_RING %x\n", \ |
1113 | dev_priv->render_ring.tail); \ | 1134 | dev_priv__->render_ring.tail); \ |
1114 | intel_ring_advance(dev, &dev_priv->render_ring); \ | 1135 | intel_ring_advance(dev, &dev_priv__->render_ring); \ |
1115 | } while(0) | 1136 | } while(0) |
1116 | 1137 | ||
1117 | /** | 1138 | /** |
@@ -1141,7 +1162,6 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | |||
1141 | #define IS_845G(dev) ((dev)->pci_device == 0x2562) | 1162 | #define IS_845G(dev) ((dev)->pci_device == 0x2562) |
1142 | #define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x) | 1163 | #define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x) |
1143 | #define IS_I865G(dev) ((dev)->pci_device == 0x2572) | 1164 | #define IS_I865G(dev) ((dev)->pci_device == 0x2572) |
1144 | #define IS_GEN2(dev) (INTEL_INFO(dev)->is_i8xx) | ||
1145 | #define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) | 1165 | #define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) |
1146 | #define IS_I915GM(dev) ((dev)->pci_device == 0x2592) | 1166 | #define IS_I915GM(dev) ((dev)->pci_device == 0x2592) |
1147 | #define IS_I945G(dev) ((dev)->pci_device == 0x2772) | 1167 | #define IS_I945G(dev) ((dev)->pci_device == 0x2772) |
@@ -1160,27 +1180,13 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | |||
1160 | #define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046) | 1180 | #define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046) |
1161 | #define IS_IRONLAKE(dev) (INTEL_INFO(dev)->is_ironlake) | 1181 | #define IS_IRONLAKE(dev) (INTEL_INFO(dev)->is_ironlake) |
1162 | #define IS_I9XX(dev) (INTEL_INFO(dev)->is_i9xx) | 1182 | #define IS_I9XX(dev) (INTEL_INFO(dev)->is_i9xx) |
1163 | #define IS_GEN6(dev) (INTEL_INFO(dev)->is_gen6) | ||
1164 | #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) | 1183 | #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) |
1165 | 1184 | ||
1166 | #define IS_GEN3(dev) (IS_I915G(dev) || \ | 1185 | #define IS_GEN2(dev) (INTEL_INFO(dev)->gen == 2) |
1167 | IS_I915GM(dev) || \ | 1186 | #define IS_GEN3(dev) (INTEL_INFO(dev)->gen == 3) |
1168 | IS_I945G(dev) || \ | 1187 | #define IS_GEN4(dev) (INTEL_INFO(dev)->gen == 4) |
1169 | IS_I945GM(dev) || \ | 1188 | #define IS_GEN5(dev) (INTEL_INFO(dev)->gen == 5) |
1170 | IS_G33(dev) || \ | 1189 | #define IS_GEN6(dev) (INTEL_INFO(dev)->gen == 6) |
1171 | IS_PINEVIEW(dev)) | ||
1172 | #define IS_GEN4(dev) ((dev)->pci_device == 0x2972 || \ | ||
1173 | (dev)->pci_device == 0x2982 || \ | ||
1174 | (dev)->pci_device == 0x2992 || \ | ||
1175 | (dev)->pci_device == 0x29A2 || \ | ||
1176 | (dev)->pci_device == 0x2A02 || \ | ||
1177 | (dev)->pci_device == 0x2A12 || \ | ||
1178 | (dev)->pci_device == 0x2E02 || \ | ||
1179 | (dev)->pci_device == 0x2E12 || \ | ||
1180 | (dev)->pci_device == 0x2E22 || \ | ||
1181 | (dev)->pci_device == 0x2E32 || \ | ||
1182 | (dev)->pci_device == 0x2A42 || \ | ||
1183 | (dev)->pci_device == 0x2E42) | ||
1184 | 1190 | ||
1185 | #define HAS_BSD(dev) (IS_IRONLAKE(dev) || IS_G4X(dev)) | 1191 | #define HAS_BSD(dev) (IS_IRONLAKE(dev) || IS_G4X(dev)) |
1186 | #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) | 1192 | #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0758c7802e6..16fca1d1799 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -34,7 +34,9 @@ | |||
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/swap.h> | 35 | #include <linux/swap.h> |
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | #include <linux/intel-gtt.h> | ||
37 | 38 | ||
39 | static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj); | ||
38 | static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); | 40 | static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); |
39 | static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); | 41 | static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); |
40 | static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); | 42 | static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); |
@@ -48,8 +50,6 @@ static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); | |||
48 | static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, | 50 | static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, |
49 | unsigned alignment); | 51 | unsigned alignment); |
50 | static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); | 52 | static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); |
51 | static int i915_gem_evict_something(struct drm_device *dev, int min_size); | ||
52 | static int i915_gem_evict_from_inactive_list(struct drm_device *dev); | ||
53 | static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | 53 | static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, |
54 | struct drm_i915_gem_pwrite *args, | 54 | struct drm_i915_gem_pwrite *args, |
55 | struct drm_file *file_priv); | 55 | struct drm_file *file_priv); |
@@ -58,6 +58,14 @@ static void i915_gem_free_object_tail(struct drm_gem_object *obj); | |||
58 | static LIST_HEAD(shrink_list); | 58 | static LIST_HEAD(shrink_list); |
59 | static DEFINE_SPINLOCK(shrink_list_lock); | 59 | static DEFINE_SPINLOCK(shrink_list_lock); |
60 | 60 | ||
61 | static inline bool | ||
62 | i915_gem_object_is_inactive(struct drm_i915_gem_object *obj_priv) | ||
63 | { | ||
64 | return obj_priv->gtt_space && | ||
65 | !obj_priv->active && | ||
66 | obj_priv->pin_count == 0; | ||
67 | } | ||
68 | |||
61 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, | 69 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, |
62 | unsigned long end) | 70 | unsigned long end) |
63 | { | 71 | { |
@@ -128,12 +136,15 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, | |||
128 | return -ENOMEM; | 136 | return -ENOMEM; |
129 | 137 | ||
130 | ret = drm_gem_handle_create(file_priv, obj, &handle); | 138 | ret = drm_gem_handle_create(file_priv, obj, &handle); |
131 | drm_gem_object_unreference_unlocked(obj); | 139 | if (ret) { |
132 | if (ret) | 140 | drm_gem_object_unreference_unlocked(obj); |
133 | return ret; | 141 | return ret; |
142 | } | ||
134 | 143 | ||
135 | args->handle = handle; | 144 | /* Sink the floating reference from kref_init(handlecount) */ |
145 | drm_gem_object_handle_unreference_unlocked(obj); | ||
136 | 146 | ||
147 | args->handle = handle; | ||
137 | return 0; | 148 | return 0; |
138 | } | 149 | } |
139 | 150 | ||
@@ -313,7 +324,8 @@ i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj) | |||
313 | if (ret == -ENOMEM) { | 324 | if (ret == -ENOMEM) { |
314 | struct drm_device *dev = obj->dev; | 325 | struct drm_device *dev = obj->dev; |
315 | 326 | ||
316 | ret = i915_gem_evict_something(dev, obj->size); | 327 | ret = i915_gem_evict_something(dev, obj->size, |
328 | i915_gem_get_gtt_alignment(obj)); | ||
317 | if (ret) | 329 | if (ret) |
318 | return ret; | 330 | return ret; |
319 | 331 | ||
@@ -1036,6 +1048,11 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
1036 | ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); | 1048 | ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); |
1037 | } | 1049 | } |
1038 | 1050 | ||
1051 | |||
1052 | /* Maintain LRU order of "inactive" objects */ | ||
1053 | if (ret == 0 && i915_gem_object_is_inactive(obj_priv)) | ||
1054 | list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
1055 | |||
1039 | drm_gem_object_unreference(obj); | 1056 | drm_gem_object_unreference(obj); |
1040 | mutex_unlock(&dev->struct_mutex); | 1057 | mutex_unlock(&dev->struct_mutex); |
1041 | return ret; | 1058 | return ret; |
@@ -1137,7 +1154,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1137 | { | 1154 | { |
1138 | struct drm_gem_object *obj = vma->vm_private_data; | 1155 | struct drm_gem_object *obj = vma->vm_private_data; |
1139 | struct drm_device *dev = obj->dev; | 1156 | struct drm_device *dev = obj->dev; |
1140 | struct drm_i915_private *dev_priv = dev->dev_private; | 1157 | drm_i915_private_t *dev_priv = dev->dev_private; |
1141 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 1158 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1142 | pgoff_t page_offset; | 1159 | pgoff_t page_offset; |
1143 | unsigned long pfn; | 1160 | unsigned long pfn; |
@@ -1155,8 +1172,6 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1155 | if (ret) | 1172 | if (ret) |
1156 | goto unlock; | 1173 | goto unlock; |
1157 | 1174 | ||
1158 | list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
1159 | |||
1160 | ret = i915_gem_object_set_to_gtt_domain(obj, write); | 1175 | ret = i915_gem_object_set_to_gtt_domain(obj, write); |
1161 | if (ret) | 1176 | if (ret) |
1162 | goto unlock; | 1177 | goto unlock; |
@@ -1169,6 +1184,9 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1169 | goto unlock; | 1184 | goto unlock; |
1170 | } | 1185 | } |
1171 | 1186 | ||
1187 | if (i915_gem_object_is_inactive(obj_priv)) | ||
1188 | list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
1189 | |||
1172 | pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) + | 1190 | pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) + |
1173 | page_offset; | 1191 | page_offset; |
1174 | 1192 | ||
@@ -1363,7 +1381,6 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | |||
1363 | struct drm_file *file_priv) | 1381 | struct drm_file *file_priv) |
1364 | { | 1382 | { |
1365 | struct drm_i915_gem_mmap_gtt *args = data; | 1383 | struct drm_i915_gem_mmap_gtt *args = data; |
1366 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1367 | struct drm_gem_object *obj; | 1384 | struct drm_gem_object *obj; |
1368 | struct drm_i915_gem_object *obj_priv; | 1385 | struct drm_i915_gem_object *obj_priv; |
1369 | int ret; | 1386 | int ret; |
@@ -1409,7 +1426,6 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | |||
1409 | mutex_unlock(&dev->struct_mutex); | 1426 | mutex_unlock(&dev->struct_mutex); |
1410 | return ret; | 1427 | return ret; |
1411 | } | 1428 | } |
1412 | list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
1413 | } | 1429 | } |
1414 | 1430 | ||
1415 | drm_gem_object_unreference(obj); | 1431 | drm_gem_object_unreference(obj); |
@@ -1493,9 +1509,16 @@ i915_gem_object_truncate(struct drm_gem_object *obj) | |||
1493 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 1509 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1494 | struct inode *inode; | 1510 | struct inode *inode; |
1495 | 1511 | ||
1512 | /* Our goal here is to return as much of the memory as | ||
1513 | * is possible back to the system as we are called from OOM. | ||
1514 | * To do this we must instruct the shmfs to drop all of its | ||
1515 | * backing pages, *now*. Here we mirror the actions taken | ||
1516 | * when by shmem_delete_inode() to release the backing store. | ||
1517 | */ | ||
1496 | inode = obj->filp->f_path.dentry->d_inode; | 1518 | inode = obj->filp->f_path.dentry->d_inode; |
1497 | if (inode->i_op->truncate) | 1519 | truncate_inode_pages(inode->i_mapping, 0); |
1498 | inode->i_op->truncate (inode); | 1520 | if (inode->i_op->truncate_range) |
1521 | inode->i_op->truncate_range(inode, 0, (loff_t)-1); | ||
1499 | 1522 | ||
1500 | obj_priv->madv = __I915_MADV_PURGED; | 1523 | obj_priv->madv = __I915_MADV_PURGED; |
1501 | } | 1524 | } |
@@ -1887,19 +1910,6 @@ i915_gem_flush(struct drm_device *dev, | |||
1887 | flush_domains); | 1910 | flush_domains); |
1888 | } | 1911 | } |
1889 | 1912 | ||
1890 | static void | ||
1891 | i915_gem_flush_ring(struct drm_device *dev, | ||
1892 | uint32_t invalidate_domains, | ||
1893 | uint32_t flush_domains, | ||
1894 | struct intel_ring_buffer *ring) | ||
1895 | { | ||
1896 | if (flush_domains & I915_GEM_DOMAIN_CPU) | ||
1897 | drm_agp_chipset_flush(dev); | ||
1898 | ring->flush(dev, ring, | ||
1899 | invalidate_domains, | ||
1900 | flush_domains); | ||
1901 | } | ||
1902 | |||
1903 | /** | 1913 | /** |
1904 | * Ensures that all rendering to the object has completed and the object is | 1914 | * Ensures that all rendering to the object has completed and the object is |
1905 | * safe to unbind from the GTT or access from the CPU. | 1915 | * safe to unbind from the GTT or access from the CPU. |
@@ -1973,8 +1983,6 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
1973 | * cause memory corruption through use-after-free. | 1983 | * cause memory corruption through use-after-free. |
1974 | */ | 1984 | */ |
1975 | 1985 | ||
1976 | BUG_ON(obj_priv->active); | ||
1977 | |||
1978 | /* release the fence reg _after_ flushing */ | 1986 | /* release the fence reg _after_ flushing */ |
1979 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | 1987 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) |
1980 | i915_gem_clear_fence_reg(obj); | 1988 | i915_gem_clear_fence_reg(obj); |
@@ -2010,34 +2018,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
2010 | return ret; | 2018 | return ret; |
2011 | } | 2019 | } |
2012 | 2020 | ||
2013 | static struct drm_gem_object * | 2021 | int |
2014 | i915_gem_find_inactive_object(struct drm_device *dev, int min_size) | ||
2015 | { | ||
2016 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
2017 | struct drm_i915_gem_object *obj_priv; | ||
2018 | struct drm_gem_object *best = NULL; | ||
2019 | struct drm_gem_object *first = NULL; | ||
2020 | |||
2021 | /* Try to find the smallest clean object */ | ||
2022 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { | ||
2023 | struct drm_gem_object *obj = &obj_priv->base; | ||
2024 | if (obj->size >= min_size) { | ||
2025 | if ((!obj_priv->dirty || | ||
2026 | i915_gem_object_is_purgeable(obj_priv)) && | ||
2027 | (!best || obj->size < best->size)) { | ||
2028 | best = obj; | ||
2029 | if (best->size == min_size) | ||
2030 | return best; | ||
2031 | } | ||
2032 | if (!first) | ||
2033 | first = obj; | ||
2034 | } | ||
2035 | } | ||
2036 | |||
2037 | return best ? best : first; | ||
2038 | } | ||
2039 | |||
2040 | static int | ||
2041 | i915_gpu_idle(struct drm_device *dev) | 2022 | i915_gpu_idle(struct drm_device *dev) |
2042 | { | 2023 | { |
2043 | drm_i915_private_t *dev_priv = dev->dev_private; | 2024 | drm_i915_private_t *dev_priv = dev->dev_private; |
@@ -2078,155 +2059,6 @@ i915_gpu_idle(struct drm_device *dev) | |||
2078 | return ret; | 2059 | return ret; |
2079 | } | 2060 | } |
2080 | 2061 | ||
2081 | static int | ||
2082 | i915_gem_evict_everything(struct drm_device *dev) | ||
2083 | { | ||
2084 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
2085 | int ret; | ||
2086 | bool lists_empty; | ||
2087 | |||
2088 | spin_lock(&dev_priv->mm.active_list_lock); | ||
2089 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | ||
2090 | list_empty(&dev_priv->mm.flushing_list) && | ||
2091 | list_empty(&dev_priv->render_ring.active_list) && | ||
2092 | (!HAS_BSD(dev) | ||
2093 | || list_empty(&dev_priv->bsd_ring.active_list))); | ||
2094 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
2095 | |||
2096 | if (lists_empty) | ||
2097 | return -ENOSPC; | ||
2098 | |||
2099 | /* Flush everything (on to the inactive lists) and evict */ | ||
2100 | ret = i915_gpu_idle(dev); | ||
2101 | if (ret) | ||
2102 | return ret; | ||
2103 | |||
2104 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | ||
2105 | |||
2106 | ret = i915_gem_evict_from_inactive_list(dev); | ||
2107 | if (ret) | ||
2108 | return ret; | ||
2109 | |||
2110 | spin_lock(&dev_priv->mm.active_list_lock); | ||
2111 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | ||
2112 | list_empty(&dev_priv->mm.flushing_list) && | ||
2113 | list_empty(&dev_priv->render_ring.active_list) && | ||
2114 | (!HAS_BSD(dev) | ||
2115 | || list_empty(&dev_priv->bsd_ring.active_list))); | ||
2116 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
2117 | BUG_ON(!lists_empty); | ||
2118 | |||
2119 | return 0; | ||
2120 | } | ||
2121 | |||
2122 | static int | ||
2123 | i915_gem_evict_something(struct drm_device *dev, int min_size) | ||
2124 | { | ||
2125 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
2126 | struct drm_gem_object *obj; | ||
2127 | int ret; | ||
2128 | |||
2129 | struct intel_ring_buffer *render_ring = &dev_priv->render_ring; | ||
2130 | struct intel_ring_buffer *bsd_ring = &dev_priv->bsd_ring; | ||
2131 | for (;;) { | ||
2132 | i915_gem_retire_requests(dev); | ||
2133 | |||
2134 | /* If there's an inactive buffer available now, grab it | ||
2135 | * and be done. | ||
2136 | */ | ||
2137 | obj = i915_gem_find_inactive_object(dev, min_size); | ||
2138 | if (obj) { | ||
2139 | struct drm_i915_gem_object *obj_priv; | ||
2140 | |||
2141 | #if WATCH_LRU | ||
2142 | DRM_INFO("%s: evicting %p\n", __func__, obj); | ||
2143 | #endif | ||
2144 | obj_priv = to_intel_bo(obj); | ||
2145 | BUG_ON(obj_priv->pin_count != 0); | ||
2146 | BUG_ON(obj_priv->active); | ||
2147 | |||
2148 | /* Wait on the rendering and unbind the buffer. */ | ||
2149 | return i915_gem_object_unbind(obj); | ||
2150 | } | ||
2151 | |||
2152 | /* If we didn't get anything, but the ring is still processing | ||
2153 | * things, wait for the next to finish and hopefully leave us | ||
2154 | * a buffer to evict. | ||
2155 | */ | ||
2156 | if (!list_empty(&render_ring->request_list)) { | ||
2157 | struct drm_i915_gem_request *request; | ||
2158 | |||
2159 | request = list_first_entry(&render_ring->request_list, | ||
2160 | struct drm_i915_gem_request, | ||
2161 | list); | ||
2162 | |||
2163 | ret = i915_wait_request(dev, | ||
2164 | request->seqno, request->ring); | ||
2165 | if (ret) | ||
2166 | return ret; | ||
2167 | |||
2168 | continue; | ||
2169 | } | ||
2170 | |||
2171 | if (HAS_BSD(dev) && !list_empty(&bsd_ring->request_list)) { | ||
2172 | struct drm_i915_gem_request *request; | ||
2173 | |||
2174 | request = list_first_entry(&bsd_ring->request_list, | ||
2175 | struct drm_i915_gem_request, | ||
2176 | list); | ||
2177 | |||
2178 | ret = i915_wait_request(dev, | ||
2179 | request->seqno, request->ring); | ||
2180 | if (ret) | ||
2181 | return ret; | ||
2182 | |||
2183 | continue; | ||
2184 | } | ||
2185 | |||
2186 | /* If we didn't have anything on the request list but there | ||
2187 | * are buffers awaiting a flush, emit one and try again. | ||
2188 | * When we wait on it, those buffers waiting for that flush | ||
2189 | * will get moved to inactive. | ||
2190 | */ | ||
2191 | if (!list_empty(&dev_priv->mm.flushing_list)) { | ||
2192 | struct drm_i915_gem_object *obj_priv; | ||
2193 | |||
2194 | /* Find an object that we can immediately reuse */ | ||
2195 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) { | ||
2196 | obj = &obj_priv->base; | ||
2197 | if (obj->size >= min_size) | ||
2198 | break; | ||
2199 | |||
2200 | obj = NULL; | ||
2201 | } | ||
2202 | |||
2203 | if (obj != NULL) { | ||
2204 | uint32_t seqno; | ||
2205 | |||
2206 | i915_gem_flush_ring(dev, | ||
2207 | obj->write_domain, | ||
2208 | obj->write_domain, | ||
2209 | obj_priv->ring); | ||
2210 | seqno = i915_add_request(dev, NULL, | ||
2211 | obj->write_domain, | ||
2212 | obj_priv->ring); | ||
2213 | if (seqno == 0) | ||
2214 | return -ENOMEM; | ||
2215 | continue; | ||
2216 | } | ||
2217 | } | ||
2218 | |||
2219 | /* If we didn't do any of the above, there's no single buffer | ||
2220 | * large enough to swap out for the new one, so just evict | ||
2221 | * everything and start again. (This should be rare.) | ||
2222 | */ | ||
2223 | if (!list_empty (&dev_priv->mm.inactive_list)) | ||
2224 | return i915_gem_evict_from_inactive_list(dev); | ||
2225 | else | ||
2226 | return i915_gem_evict_everything(dev); | ||
2227 | } | ||
2228 | } | ||
2229 | |||
2230 | int | 2062 | int |
2231 | i915_gem_object_get_pages(struct drm_gem_object *obj, | 2063 | i915_gem_object_get_pages(struct drm_gem_object *obj, |
2232 | gfp_t gfpmask) | 2064 | gfp_t gfpmask) |
@@ -2666,7 +2498,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2666 | #if WATCH_LRU | 2498 | #if WATCH_LRU |
2667 | DRM_INFO("%s: GTT full, evicting something\n", __func__); | 2499 | DRM_INFO("%s: GTT full, evicting something\n", __func__); |
2668 | #endif | 2500 | #endif |
2669 | ret = i915_gem_evict_something(dev, obj->size); | 2501 | ret = i915_gem_evict_something(dev, obj->size, alignment); |
2670 | if (ret) | 2502 | if (ret) |
2671 | return ret; | 2503 | return ret; |
2672 | 2504 | ||
@@ -2684,7 +2516,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2684 | 2516 | ||
2685 | if (ret == -ENOMEM) { | 2517 | if (ret == -ENOMEM) { |
2686 | /* first try to clear up some space from the GTT */ | 2518 | /* first try to clear up some space from the GTT */ |
2687 | ret = i915_gem_evict_something(dev, obj->size); | 2519 | ret = i915_gem_evict_something(dev, obj->size, |
2520 | alignment); | ||
2688 | if (ret) { | 2521 | if (ret) { |
2689 | /* now try to shrink everyone else */ | 2522 | /* now try to shrink everyone else */ |
2690 | if (gfpmask) { | 2523 | if (gfpmask) { |
@@ -2714,7 +2547,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2714 | drm_mm_put_block(obj_priv->gtt_space); | 2547 | drm_mm_put_block(obj_priv->gtt_space); |
2715 | obj_priv->gtt_space = NULL; | 2548 | obj_priv->gtt_space = NULL; |
2716 | 2549 | ||
2717 | ret = i915_gem_evict_something(dev, obj->size); | 2550 | ret = i915_gem_evict_something(dev, obj->size, alignment); |
2718 | if (ret) | 2551 | if (ret) |
2719 | return ret; | 2552 | return ret; |
2720 | 2553 | ||
@@ -2723,6 +2556,9 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2723 | atomic_inc(&dev->gtt_count); | 2556 | atomic_inc(&dev->gtt_count); |
2724 | atomic_add(obj->size, &dev->gtt_memory); | 2557 | atomic_add(obj->size, &dev->gtt_memory); |
2725 | 2558 | ||
2559 | /* keep track of bounds object by adding it to the inactive list */ | ||
2560 | list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
2561 | |||
2726 | /* Assert that the object is not currently in any GPU domain. As it | 2562 | /* Assert that the object is not currently in any GPU domain. As it |
2727 | * wasn't in the GTT, there shouldn't be any way it could have been in | 2563 | * wasn't in the GTT, there shouldn't be any way it could have been in |
2728 | * a GPU cache | 2564 | * a GPU cache |
@@ -3117,6 +2953,7 @@ static void | |||
3117 | i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) | 2953 | i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) |
3118 | { | 2954 | { |
3119 | struct drm_device *dev = obj->dev; | 2955 | struct drm_device *dev = obj->dev; |
2956 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3120 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2957 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
3121 | uint32_t invalidate_domains = 0; | 2958 | uint32_t invalidate_domains = 0; |
3122 | uint32_t flush_domains = 0; | 2959 | uint32_t flush_domains = 0; |
@@ -3179,6 +3016,13 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) | |||
3179 | obj->pending_write_domain = obj->write_domain; | 3016 | obj->pending_write_domain = obj->write_domain; |
3180 | obj->read_domains = obj->pending_read_domains; | 3017 | obj->read_domains = obj->pending_read_domains; |
3181 | 3018 | ||
3019 | if (flush_domains & I915_GEM_GPU_DOMAINS) { | ||
3020 | if (obj_priv->ring == &dev_priv->render_ring) | ||
3021 | dev_priv->flush_rings |= FLUSH_RENDER_RING; | ||
3022 | else if (obj_priv->ring == &dev_priv->bsd_ring) | ||
3023 | dev_priv->flush_rings |= FLUSH_BSD_RING; | ||
3024 | } | ||
3025 | |||
3182 | dev->invalidate_domains |= invalidate_domains; | 3026 | dev->invalidate_domains |= invalidate_domains; |
3183 | dev->flush_domains |= flush_domains; | 3027 | dev->flush_domains |= flush_domains; |
3184 | #if WATCH_BUF | 3028 | #if WATCH_BUF |
@@ -3718,7 +3562,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3718 | ring = &dev_priv->render_ring; | 3562 | ring = &dev_priv->render_ring; |
3719 | } | 3563 | } |
3720 | 3564 | ||
3721 | |||
3722 | if (args->buffer_count < 1) { | 3565 | if (args->buffer_count < 1) { |
3723 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); | 3566 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); |
3724 | return -EINVAL; | 3567 | return -EINVAL; |
@@ -3746,6 +3589,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3746 | if (ret != 0) { | 3589 | if (ret != 0) { |
3747 | DRM_ERROR("copy %d cliprects failed: %d\n", | 3590 | DRM_ERROR("copy %d cliprects failed: %d\n", |
3748 | args->num_cliprects, ret); | 3591 | args->num_cliprects, ret); |
3592 | ret = -EFAULT; | ||
3749 | goto pre_mutex_err; | 3593 | goto pre_mutex_err; |
3750 | } | 3594 | } |
3751 | } | 3595 | } |
@@ -3892,6 +3736,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3892 | */ | 3736 | */ |
3893 | dev->invalidate_domains = 0; | 3737 | dev->invalidate_domains = 0; |
3894 | dev->flush_domains = 0; | 3738 | dev->flush_domains = 0; |
3739 | dev_priv->flush_rings = 0; | ||
3895 | 3740 | ||
3896 | for (i = 0; i < args->buffer_count; i++) { | 3741 | for (i = 0; i < args->buffer_count; i++) { |
3897 | struct drm_gem_object *obj = object_list[i]; | 3742 | struct drm_gem_object *obj = object_list[i]; |
@@ -3912,16 +3757,14 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3912 | i915_gem_flush(dev, | 3757 | i915_gem_flush(dev, |
3913 | dev->invalidate_domains, | 3758 | dev->invalidate_domains, |
3914 | dev->flush_domains); | 3759 | dev->flush_domains); |
3915 | if (dev->flush_domains & I915_GEM_GPU_DOMAINS) { | 3760 | if (dev_priv->flush_rings & FLUSH_RENDER_RING) |
3916 | (void)i915_add_request(dev, file_priv, | 3761 | (void)i915_add_request(dev, file_priv, |
3917 | dev->flush_domains, | 3762 | dev->flush_domains, |
3918 | &dev_priv->render_ring); | 3763 | &dev_priv->render_ring); |
3919 | 3764 | if (dev_priv->flush_rings & FLUSH_BSD_RING) | |
3920 | if (HAS_BSD(dev)) | 3765 | (void)i915_add_request(dev, file_priv, |
3921 | (void)i915_add_request(dev, file_priv, | 3766 | dev->flush_domains, |
3922 | dev->flush_domains, | 3767 | &dev_priv->bsd_ring); |
3923 | &dev_priv->bsd_ring); | ||
3924 | } | ||
3925 | } | 3768 | } |
3926 | 3769 | ||
3927 | for (i = 0; i < args->buffer_count; i++) { | 3770 | for (i = 0; i < args->buffer_count; i++) { |
@@ -4192,6 +4035,10 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | |||
4192 | if (alignment == 0) | 4035 | if (alignment == 0) |
4193 | alignment = i915_gem_get_gtt_alignment(obj); | 4036 | alignment = i915_gem_get_gtt_alignment(obj); |
4194 | if (obj_priv->gtt_offset & (alignment - 1)) { | 4037 | if (obj_priv->gtt_offset & (alignment - 1)) { |
4038 | WARN(obj_priv->pin_count, | ||
4039 | "bo is already pinned with incorrect alignment:" | ||
4040 | " offset=%x, req.alignment=%x\n", | ||
4041 | obj_priv->gtt_offset, alignment); | ||
4195 | ret = i915_gem_object_unbind(obj); | 4042 | ret = i915_gem_object_unbind(obj); |
4196 | if (ret) | 4043 | if (ret) |
4197 | return ret; | 4044 | return ret; |
@@ -4213,8 +4060,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | |||
4213 | atomic_inc(&dev->pin_count); | 4060 | atomic_inc(&dev->pin_count); |
4214 | atomic_add(obj->size, &dev->pin_memory); | 4061 | atomic_add(obj->size, &dev->pin_memory); |
4215 | if (!obj_priv->active && | 4062 | if (!obj_priv->active && |
4216 | (obj->write_domain & I915_GEM_GPU_DOMAINS) == 0 && | 4063 | (obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) |
4217 | !list_empty(&obj_priv->list)) | ||
4218 | list_del_init(&obj_priv->list); | 4064 | list_del_init(&obj_priv->list); |
4219 | } | 4065 | } |
4220 | i915_verify_inactive(dev, __FILE__, __LINE__); | 4066 | i915_verify_inactive(dev, __FILE__, __LINE__); |
@@ -4359,22 +4205,34 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
4359 | } | 4205 | } |
4360 | 4206 | ||
4361 | mutex_lock(&dev->struct_mutex); | 4207 | mutex_lock(&dev->struct_mutex); |
4362 | /* Update the active list for the hardware's current position. | ||
4363 | * Otherwise this only updates on a delayed timer or when irqs are | ||
4364 | * actually unmasked, and our working set ends up being larger than | ||
4365 | * required. | ||
4366 | */ | ||
4367 | i915_gem_retire_requests(dev); | ||
4368 | 4208 | ||
4369 | obj_priv = to_intel_bo(obj); | 4209 | /* Count all active objects as busy, even if they are currently not used |
4370 | /* Don't count being on the flushing list against the object being | 4210 | * by the gpu. Users of this interface expect objects to eventually |
4371 | * done. Otherwise, a buffer left on the flushing list but not getting | 4211 | * become non-busy without any further actions, therefore emit any |
4372 | * flushed (because nobody's flushing that domain) won't ever return | 4212 | * necessary flushes here. |
4373 | * unbusy and get reused by libdrm's bo cache. The other expected | ||
4374 | * consumer of this interface, OpenGL's occlusion queries, also specs | ||
4375 | * that the objects get unbusy "eventually" without any interference. | ||
4376 | */ | 4213 | */ |
4377 | args->busy = obj_priv->active && obj_priv->last_rendering_seqno != 0; | 4214 | obj_priv = to_intel_bo(obj); |
4215 | args->busy = obj_priv->active; | ||
4216 | if (args->busy) { | ||
4217 | /* Unconditionally flush objects, even when the gpu still uses this | ||
4218 | * object. Userspace calling this function indicates that it wants to | ||
4219 | * use this buffer rather sooner than later, so issuing the required | ||
4220 | * flush earlier is beneficial. | ||
4221 | */ | ||
4222 | if (obj->write_domain) { | ||
4223 | i915_gem_flush(dev, 0, obj->write_domain); | ||
4224 | (void)i915_add_request(dev, file_priv, obj->write_domain, obj_priv->ring); | ||
4225 | } | ||
4226 | |||
4227 | /* Update the active list for the hardware's current position. | ||
4228 | * Otherwise this only updates on a delayed timer or when irqs | ||
4229 | * are actually unmasked, and our working set ends up being | ||
4230 | * larger than required. | ||
4231 | */ | ||
4232 | i915_gem_retire_requests_ring(dev, obj_priv->ring); | ||
4233 | |||
4234 | args->busy = obj_priv->active; | ||
4235 | } | ||
4378 | 4236 | ||
4379 | drm_gem_object_unreference(obj); | 4237 | drm_gem_object_unreference(obj); |
4380 | mutex_unlock(&dev->struct_mutex); | 4238 | mutex_unlock(&dev->struct_mutex); |
@@ -4514,30 +4372,6 @@ void i915_gem_free_object(struct drm_gem_object *obj) | |||
4514 | i915_gem_free_object_tail(obj); | 4372 | i915_gem_free_object_tail(obj); |
4515 | } | 4373 | } |
4516 | 4374 | ||
4517 | /** Unbinds all inactive objects. */ | ||
4518 | static int | ||
4519 | i915_gem_evict_from_inactive_list(struct drm_device *dev) | ||
4520 | { | ||
4521 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
4522 | |||
4523 | while (!list_empty(&dev_priv->mm.inactive_list)) { | ||
4524 | struct drm_gem_object *obj; | ||
4525 | int ret; | ||
4526 | |||
4527 | obj = &list_first_entry(&dev_priv->mm.inactive_list, | ||
4528 | struct drm_i915_gem_object, | ||
4529 | list)->base; | ||
4530 | |||
4531 | ret = i915_gem_object_unbind(obj); | ||
4532 | if (ret != 0) { | ||
4533 | DRM_ERROR("Error unbinding object: %d\n", ret); | ||
4534 | return ret; | ||
4535 | } | ||
4536 | } | ||
4537 | |||
4538 | return 0; | ||
4539 | } | ||
4540 | |||
4541 | int | 4375 | int |
4542 | i915_gem_idle(struct drm_device *dev) | 4376 | i915_gem_idle(struct drm_device *dev) |
4543 | { | 4377 | { |
@@ -4562,7 +4396,7 @@ i915_gem_idle(struct drm_device *dev) | |||
4562 | 4396 | ||
4563 | /* Under UMS, be paranoid and evict. */ | 4397 | /* Under UMS, be paranoid and evict. */ |
4564 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) { | 4398 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) { |
4565 | ret = i915_gem_evict_from_inactive_list(dev); | 4399 | ret = i915_gem_evict_inactive(dev); |
4566 | if (ret) { | 4400 | if (ret) { |
4567 | mutex_unlock(&dev->struct_mutex); | 4401 | mutex_unlock(&dev->struct_mutex); |
4568 | return ret; | 4402 | return ret; |
@@ -4680,6 +4514,8 @@ i915_gem_init_ringbuffer(struct drm_device *dev) | |||
4680 | goto cleanup_render_ring; | 4514 | goto cleanup_render_ring; |
4681 | } | 4515 | } |
4682 | 4516 | ||
4517 | dev_priv->next_seqno = 1; | ||
4518 | |||
4683 | return 0; | 4519 | return 0; |
4684 | 4520 | ||
4685 | cleanup_render_ring: | 4521 | cleanup_render_ring: |
@@ -4841,7 +4677,7 @@ i915_gem_load(struct drm_device *dev) | |||
4841 | * e.g. for cursor + overlay regs | 4677 | * e.g. for cursor + overlay regs |
4842 | */ | 4678 | */ |
4843 | int i915_gem_init_phys_object(struct drm_device *dev, | 4679 | int i915_gem_init_phys_object(struct drm_device *dev, |
4844 | int id, int size) | 4680 | int id, int size, int align) |
4845 | { | 4681 | { |
4846 | drm_i915_private_t *dev_priv = dev->dev_private; | 4682 | drm_i915_private_t *dev_priv = dev->dev_private; |
4847 | struct drm_i915_gem_phys_object *phys_obj; | 4683 | struct drm_i915_gem_phys_object *phys_obj; |
@@ -4856,7 +4692,7 @@ int i915_gem_init_phys_object(struct drm_device *dev, | |||
4856 | 4692 | ||
4857 | phys_obj->id = id; | 4693 | phys_obj->id = id; |
4858 | 4694 | ||
4859 | phys_obj->handle = drm_pci_alloc(dev, size, 0); | 4695 | phys_obj->handle = drm_pci_alloc(dev, size, align); |
4860 | if (!phys_obj->handle) { | 4696 | if (!phys_obj->handle) { |
4861 | ret = -ENOMEM; | 4697 | ret = -ENOMEM; |
4862 | goto kfree_obj; | 4698 | goto kfree_obj; |
@@ -4938,7 +4774,9 @@ out: | |||
4938 | 4774 | ||
4939 | int | 4775 | int |
4940 | i915_gem_attach_phys_object(struct drm_device *dev, | 4776 | i915_gem_attach_phys_object(struct drm_device *dev, |
4941 | struct drm_gem_object *obj, int id) | 4777 | struct drm_gem_object *obj, |
4778 | int id, | ||
4779 | int align) | ||
4942 | { | 4780 | { |
4943 | drm_i915_private_t *dev_priv = dev->dev_private; | 4781 | drm_i915_private_t *dev_priv = dev->dev_private; |
4944 | struct drm_i915_gem_object *obj_priv; | 4782 | struct drm_i915_gem_object *obj_priv; |
@@ -4957,11 +4795,10 @@ i915_gem_attach_phys_object(struct drm_device *dev, | |||
4957 | i915_gem_detach_phys_object(dev, obj); | 4795 | i915_gem_detach_phys_object(dev, obj); |
4958 | } | 4796 | } |
4959 | 4797 | ||
4960 | |||
4961 | /* create a new object */ | 4798 | /* create a new object */ |
4962 | if (!dev_priv->mm.phys_objs[id - 1]) { | 4799 | if (!dev_priv->mm.phys_objs[id - 1]) { |
4963 | ret = i915_gem_init_phys_object(dev, id, | 4800 | ret = i915_gem_init_phys_object(dev, id, |
4964 | obj->size); | 4801 | obj->size, align); |
4965 | if (ret) { | 4802 | if (ret) { |
4966 | DRM_ERROR("failed to init phys object %d size: %zu\n", id, obj->size); | 4803 | DRM_ERROR("failed to init phys object %d size: %zu\n", id, obj->size); |
4967 | goto out; | 4804 | goto out; |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c new file mode 100644 index 00000000000..72cae3cccad --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
@@ -0,0 +1,271 @@ | |||
1 | /* | ||
2 | * Copyright © 2008-2010 Intel Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: | ||
24 | * Eric Anholt <eric@anholt.net> | ||
25 | * Chris Wilson <chris@chris-wilson.co.uuk> | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #include "drmP.h" | ||
30 | #include "drm.h" | ||
31 | #include "i915_drv.h" | ||
32 | #include "i915_drm.h" | ||
33 | |||
34 | static struct drm_i915_gem_object * | ||
35 | i915_gem_next_active_object(struct drm_device *dev, | ||
36 | struct list_head **render_iter, | ||
37 | struct list_head **bsd_iter) | ||
38 | { | ||
39 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
40 | struct drm_i915_gem_object *render_obj = NULL, *bsd_obj = NULL; | ||
41 | |||
42 | if (*render_iter != &dev_priv->render_ring.active_list) | ||
43 | render_obj = list_entry(*render_iter, | ||
44 | struct drm_i915_gem_object, | ||
45 | list); | ||
46 | |||
47 | if (HAS_BSD(dev)) { | ||
48 | if (*bsd_iter != &dev_priv->bsd_ring.active_list) | ||
49 | bsd_obj = list_entry(*bsd_iter, | ||
50 | struct drm_i915_gem_object, | ||
51 | list); | ||
52 | |||
53 | if (render_obj == NULL) { | ||
54 | *bsd_iter = (*bsd_iter)->next; | ||
55 | return bsd_obj; | ||
56 | } | ||
57 | |||
58 | if (bsd_obj == NULL) { | ||
59 | *render_iter = (*render_iter)->next; | ||
60 | return render_obj; | ||
61 | } | ||
62 | |||
63 | /* XXX can we handle seqno wrapping? */ | ||
64 | if (render_obj->last_rendering_seqno < bsd_obj->last_rendering_seqno) { | ||
65 | *render_iter = (*render_iter)->next; | ||
66 | return render_obj; | ||
67 | } else { | ||
68 | *bsd_iter = (*bsd_iter)->next; | ||
69 | return bsd_obj; | ||
70 | } | ||
71 | } else { | ||
72 | *render_iter = (*render_iter)->next; | ||
73 | return render_obj; | ||
74 | } | ||
75 | } | ||
76 | |||
77 | static bool | ||
78 | mark_free(struct drm_i915_gem_object *obj_priv, | ||
79 | struct list_head *unwind) | ||
80 | { | ||
81 | list_add(&obj_priv->evict_list, unwind); | ||
82 | return drm_mm_scan_add_block(obj_priv->gtt_space); | ||
83 | } | ||
84 | |||
85 | #define i915_for_each_active_object(OBJ, R, B) \ | ||
86 | *(R) = dev_priv->render_ring.active_list.next; \ | ||
87 | *(B) = dev_priv->bsd_ring.active_list.next; \ | ||
88 | while (((OBJ) = i915_gem_next_active_object(dev, (R), (B))) != NULL) | ||
89 | |||
90 | int | ||
91 | i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment) | ||
92 | { | ||
93 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
94 | struct list_head eviction_list, unwind_list; | ||
95 | struct drm_i915_gem_object *obj_priv, *tmp_obj_priv; | ||
96 | struct list_head *render_iter, *bsd_iter; | ||
97 | int ret = 0; | ||
98 | |||
99 | i915_gem_retire_requests(dev); | ||
100 | |||
101 | /* Re-check for free space after retiring requests */ | ||
102 | if (drm_mm_search_free(&dev_priv->mm.gtt_space, | ||
103 | min_size, alignment, 0)) | ||
104 | return 0; | ||
105 | |||
106 | /* | ||
107 | * The goal is to evict objects and amalgamate space in LRU order. | ||
108 | * The oldest idle objects reside on the inactive list, which is in | ||
109 | * retirement order. The next objects to retire are those on the (per | ||
110 | * ring) active list that do not have an outstanding flush. Once the | ||
111 | * hardware reports completion (the seqno is updated after the | ||
112 | * batchbuffer has been finished) the clean buffer objects would | ||
113 | * be retired to the inactive list. Any dirty objects would be added | ||
114 | * to the tail of the flushing list. So after processing the clean | ||
115 | * active objects we need to emit a MI_FLUSH to retire the flushing | ||
116 | * list, hence the retirement order of the flushing list is in | ||
117 | * advance of the dirty objects on the active lists. | ||
118 | * | ||
119 | * The retirement sequence is thus: | ||
120 | * 1. Inactive objects (already retired) | ||
121 | * 2. Clean active objects | ||
122 | * 3. Flushing list | ||
123 | * 4. Dirty active objects. | ||
124 | * | ||
125 | * On each list, the oldest objects lie at the HEAD with the freshest | ||
126 | * object on the TAIL. | ||
127 | */ | ||
128 | |||
129 | INIT_LIST_HEAD(&unwind_list); | ||
130 | drm_mm_init_scan(&dev_priv->mm.gtt_space, min_size, alignment); | ||
131 | |||
132 | /* First see if there is a large enough contiguous idle region... */ | ||
133 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { | ||
134 | if (mark_free(obj_priv, &unwind_list)) | ||
135 | goto found; | ||
136 | } | ||
137 | |||
138 | /* Now merge in the soon-to-be-expired objects... */ | ||
139 | i915_for_each_active_object(obj_priv, &render_iter, &bsd_iter) { | ||
140 | /* Does the object require an outstanding flush? */ | ||
141 | if (obj_priv->base.write_domain || obj_priv->pin_count) | ||
142 | continue; | ||
143 | |||
144 | if (mark_free(obj_priv, &unwind_list)) | ||
145 | goto found; | ||
146 | } | ||
147 | |||
148 | /* Finally add anything with a pending flush (in order of retirement) */ | ||
149 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) { | ||
150 | if (obj_priv->pin_count) | ||
151 | continue; | ||
152 | |||
153 | if (mark_free(obj_priv, &unwind_list)) | ||
154 | goto found; | ||
155 | } | ||
156 | i915_for_each_active_object(obj_priv, &render_iter, &bsd_iter) { | ||
157 | if (! obj_priv->base.write_domain || obj_priv->pin_count) | ||
158 | continue; | ||
159 | |||
160 | if (mark_free(obj_priv, &unwind_list)) | ||
161 | goto found; | ||
162 | } | ||
163 | |||
164 | /* Nothing found, clean up and bail out! */ | ||
165 | list_for_each_entry(obj_priv, &unwind_list, evict_list) { | ||
166 | ret = drm_mm_scan_remove_block(obj_priv->gtt_space); | ||
167 | BUG_ON(ret); | ||
168 | } | ||
169 | |||
170 | /* We expect the caller to unpin, evict all and try again, or give up. | ||
171 | * So calling i915_gem_evict_everything() is unnecessary. | ||
172 | */ | ||
173 | return -ENOSPC; | ||
174 | |||
175 | found: | ||
176 | INIT_LIST_HEAD(&eviction_list); | ||
177 | list_for_each_entry_safe(obj_priv, tmp_obj_priv, | ||
178 | &unwind_list, evict_list) { | ||
179 | if (drm_mm_scan_remove_block(obj_priv->gtt_space)) { | ||
180 | /* drm_mm doesn't allow any other other operations while | ||
181 | * scanning, therefore store to be evicted objects on a | ||
182 | * temporary list. */ | ||
183 | list_move(&obj_priv->evict_list, &eviction_list); | ||
184 | } | ||
185 | } | ||
186 | |||
187 | /* Unbinding will emit any required flushes */ | ||
188 | list_for_each_entry_safe(obj_priv, tmp_obj_priv, | ||
189 | &eviction_list, evict_list) { | ||
190 | #if WATCH_LRU | ||
191 | DRM_INFO("%s: evicting %p\n", __func__, obj); | ||
192 | #endif | ||
193 | ret = i915_gem_object_unbind(&obj_priv->base); | ||
194 | if (ret) | ||
195 | return ret; | ||
196 | } | ||
197 | |||
198 | /* The just created free hole should be on the top of the free stack | ||
199 | * maintained by drm_mm, so this BUG_ON actually executes in O(1). | ||
200 | * Furthermore all accessed data has just recently been used, so it | ||
201 | * should be really fast, too. */ | ||
202 | BUG_ON(!drm_mm_search_free(&dev_priv->mm.gtt_space, min_size, | ||
203 | alignment, 0)); | ||
204 | |||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | int | ||
209 | i915_gem_evict_everything(struct drm_device *dev) | ||
210 | { | ||
211 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
212 | int ret; | ||
213 | bool lists_empty; | ||
214 | |||
215 | spin_lock(&dev_priv->mm.active_list_lock); | ||
216 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | ||
217 | list_empty(&dev_priv->mm.flushing_list) && | ||
218 | list_empty(&dev_priv->render_ring.active_list) && | ||
219 | (!HAS_BSD(dev) | ||
220 | || list_empty(&dev_priv->bsd_ring.active_list))); | ||
221 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
222 | |||
223 | if (lists_empty) | ||
224 | return -ENOSPC; | ||
225 | |||
226 | /* Flush everything (on to the inactive lists) and evict */ | ||
227 | ret = i915_gpu_idle(dev); | ||
228 | if (ret) | ||
229 | return ret; | ||
230 | |||
231 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | ||
232 | |||
233 | ret = i915_gem_evict_inactive(dev); | ||
234 | if (ret) | ||
235 | return ret; | ||
236 | |||
237 | spin_lock(&dev_priv->mm.active_list_lock); | ||
238 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | ||
239 | list_empty(&dev_priv->mm.flushing_list) && | ||
240 | list_empty(&dev_priv->render_ring.active_list) && | ||
241 | (!HAS_BSD(dev) | ||
242 | || list_empty(&dev_priv->bsd_ring.active_list))); | ||
243 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
244 | BUG_ON(!lists_empty); | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | /** Unbinds all inactive objects. */ | ||
250 | int | ||
251 | i915_gem_evict_inactive(struct drm_device *dev) | ||
252 | { | ||
253 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
254 | |||
255 | while (!list_empty(&dev_priv->mm.inactive_list)) { | ||
256 | struct drm_gem_object *obj; | ||
257 | int ret; | ||
258 | |||
259 | obj = &list_first_entry(&dev_priv->mm.inactive_list, | ||
260 | struct drm_i915_gem_object, | ||
261 | list)->base; | ||
262 | |||
263 | ret = i915_gem_object_unbind(obj); | ||
264 | if (ret != 0) { | ||
265 | DRM_ERROR("Error unbinding object: %d\n", ret); | ||
266 | return ret; | ||
267 | } | ||
268 | } | ||
269 | |||
270 | return 0; | ||
271 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 85785a8844e..59457e83b01 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -425,9 +425,11 @@ static struct drm_i915_error_object * | |||
425 | i915_error_object_create(struct drm_device *dev, | 425 | i915_error_object_create(struct drm_device *dev, |
426 | struct drm_gem_object *src) | 426 | struct drm_gem_object *src) |
427 | { | 427 | { |
428 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
428 | struct drm_i915_error_object *dst; | 429 | struct drm_i915_error_object *dst; |
429 | struct drm_i915_gem_object *src_priv; | 430 | struct drm_i915_gem_object *src_priv; |
430 | int page, page_count; | 431 | int page, page_count; |
432 | u32 reloc_offset; | ||
431 | 433 | ||
432 | if (src == NULL) | 434 | if (src == NULL) |
433 | return NULL; | 435 | return NULL; |
@@ -442,18 +444,27 @@ i915_error_object_create(struct drm_device *dev, | |||
442 | if (dst == NULL) | 444 | if (dst == NULL) |
443 | return NULL; | 445 | return NULL; |
444 | 446 | ||
447 | reloc_offset = src_priv->gtt_offset; | ||
445 | for (page = 0; page < page_count; page++) { | 448 | for (page = 0; page < page_count; page++) { |
446 | void *s, *d = kmalloc(PAGE_SIZE, GFP_ATOMIC); | ||
447 | unsigned long flags; | 449 | unsigned long flags; |
450 | void __iomem *s; | ||
451 | void *d; | ||
448 | 452 | ||
453 | d = kmalloc(PAGE_SIZE, GFP_ATOMIC); | ||
449 | if (d == NULL) | 454 | if (d == NULL) |
450 | goto unwind; | 455 | goto unwind; |
456 | |||
451 | local_irq_save(flags); | 457 | local_irq_save(flags); |
452 | s = kmap_atomic(src_priv->pages[page], KM_IRQ0); | 458 | s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, |
453 | memcpy(d, s, PAGE_SIZE); | 459 | reloc_offset, |
454 | kunmap_atomic(s, KM_IRQ0); | 460 | KM_IRQ0); |
461 | memcpy_fromio(d, s, PAGE_SIZE); | ||
462 | io_mapping_unmap_atomic(s, KM_IRQ0); | ||
455 | local_irq_restore(flags); | 463 | local_irq_restore(flags); |
464 | |||
456 | dst->pages[page] = d; | 465 | dst->pages[page] = d; |
466 | |||
467 | reloc_offset += PAGE_SIZE; | ||
457 | } | 468 | } |
458 | dst->page_count = page_count; | 469 | dst->page_count = page_count; |
459 | dst->gtt_offset = src_priv->gtt_offset; | 470 | dst->gtt_offset = src_priv->gtt_offset; |
@@ -489,6 +500,7 @@ i915_error_state_free(struct drm_device *dev, | |||
489 | i915_error_object_free(error->batchbuffer[1]); | 500 | i915_error_object_free(error->batchbuffer[1]); |
490 | i915_error_object_free(error->ringbuffer); | 501 | i915_error_object_free(error->ringbuffer); |
491 | kfree(error->active_bo); | 502 | kfree(error->active_bo); |
503 | kfree(error->overlay); | ||
492 | kfree(error); | 504 | kfree(error); |
493 | } | 505 | } |
494 | 506 | ||
@@ -612,18 +624,57 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
612 | 624 | ||
613 | if (batchbuffer[1] == NULL && | 625 | if (batchbuffer[1] == NULL && |
614 | error->acthd >= obj_priv->gtt_offset && | 626 | error->acthd >= obj_priv->gtt_offset && |
615 | error->acthd < obj_priv->gtt_offset + obj->size && | 627 | error->acthd < obj_priv->gtt_offset + obj->size) |
616 | batchbuffer[0] != obj) | ||
617 | batchbuffer[1] = obj; | 628 | batchbuffer[1] = obj; |
618 | 629 | ||
619 | count++; | 630 | count++; |
620 | } | 631 | } |
632 | /* Scan the other lists for completeness for those bizarre errors. */ | ||
633 | if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { | ||
634 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) { | ||
635 | struct drm_gem_object *obj = &obj_priv->base; | ||
636 | |||
637 | if (batchbuffer[0] == NULL && | ||
638 | bbaddr >= obj_priv->gtt_offset && | ||
639 | bbaddr < obj_priv->gtt_offset + obj->size) | ||
640 | batchbuffer[0] = obj; | ||
641 | |||
642 | if (batchbuffer[1] == NULL && | ||
643 | error->acthd >= obj_priv->gtt_offset && | ||
644 | error->acthd < obj_priv->gtt_offset + obj->size) | ||
645 | batchbuffer[1] = obj; | ||
646 | |||
647 | if (batchbuffer[0] && batchbuffer[1]) | ||
648 | break; | ||
649 | } | ||
650 | } | ||
651 | if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { | ||
652 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { | ||
653 | struct drm_gem_object *obj = &obj_priv->base; | ||
654 | |||
655 | if (batchbuffer[0] == NULL && | ||
656 | bbaddr >= obj_priv->gtt_offset && | ||
657 | bbaddr < obj_priv->gtt_offset + obj->size) | ||
658 | batchbuffer[0] = obj; | ||
659 | |||
660 | if (batchbuffer[1] == NULL && | ||
661 | error->acthd >= obj_priv->gtt_offset && | ||
662 | error->acthd < obj_priv->gtt_offset + obj->size) | ||
663 | batchbuffer[1] = obj; | ||
664 | |||
665 | if (batchbuffer[0] && batchbuffer[1]) | ||
666 | break; | ||
667 | } | ||
668 | } | ||
621 | 669 | ||
622 | /* We need to copy these to an anonymous buffer as the simplest | 670 | /* We need to copy these to an anonymous buffer as the simplest |
623 | * method to avoid being overwritten by userpace. | 671 | * method to avoid being overwritten by userpace. |
624 | */ | 672 | */ |
625 | error->batchbuffer[0] = i915_error_object_create(dev, batchbuffer[0]); | 673 | error->batchbuffer[0] = i915_error_object_create(dev, batchbuffer[0]); |
626 | error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); | 674 | if (batchbuffer[1] != batchbuffer[0]) |
675 | error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); | ||
676 | else | ||
677 | error->batchbuffer[1] = NULL; | ||
627 | 678 | ||
628 | /* Record the ringbuffer */ | 679 | /* Record the ringbuffer */ |
629 | error->ringbuffer = i915_error_object_create(dev, | 680 | error->ringbuffer = i915_error_object_create(dev, |
@@ -667,6 +718,8 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
667 | 718 | ||
668 | do_gettimeofday(&error->time); | 719 | do_gettimeofday(&error->time); |
669 | 720 | ||
721 | error->overlay = intel_overlay_capture_error_state(dev); | ||
722 | |||
670 | spin_lock_irqsave(&dev_priv->error_lock, flags); | 723 | spin_lock_irqsave(&dev_priv->error_lock, flags); |
671 | if (dev_priv->first_error == NULL) { | 724 | if (dev_priv->first_error == NULL) { |
672 | dev_priv->first_error = error; | 725 | dev_priv->first_error = error; |
@@ -834,6 +887,49 @@ static void i915_handle_error(struct drm_device *dev, bool wedged) | |||
834 | queue_work(dev_priv->wq, &dev_priv->error_work); | 887 | queue_work(dev_priv->wq, &dev_priv->error_work); |
835 | } | 888 | } |
836 | 889 | ||
890 | static void i915_pageflip_stall_check(struct drm_device *dev, int pipe) | ||
891 | { | ||
892 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
893 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | ||
894 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
895 | struct drm_i915_gem_object *obj_priv; | ||
896 | struct intel_unpin_work *work; | ||
897 | unsigned long flags; | ||
898 | bool stall_detected; | ||
899 | |||
900 | /* Ignore early vblank irqs */ | ||
901 | if (intel_crtc == NULL) | ||
902 | return; | ||
903 | |||
904 | spin_lock_irqsave(&dev->event_lock, flags); | ||
905 | work = intel_crtc->unpin_work; | ||
906 | |||
907 | if (work == NULL || work->pending || !work->enable_stall_check) { | ||
908 | /* Either the pending flip IRQ arrived, or we're too early. Don't check */ | ||
909 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
910 | return; | ||
911 | } | ||
912 | |||
913 | /* Potential stall - if we see that the flip has happened, assume a missed interrupt */ | ||
914 | obj_priv = to_intel_bo(work->pending_flip_obj); | ||
915 | if(IS_I965G(dev)) { | ||
916 | int dspsurf = intel_crtc->plane == 0 ? DSPASURF : DSPBSURF; | ||
917 | stall_detected = I915_READ(dspsurf) == obj_priv->gtt_offset; | ||
918 | } else { | ||
919 | int dspaddr = intel_crtc->plane == 0 ? DSPAADDR : DSPBADDR; | ||
920 | stall_detected = I915_READ(dspaddr) == (obj_priv->gtt_offset + | ||
921 | crtc->y * crtc->fb->pitch + | ||
922 | crtc->x * crtc->fb->bits_per_pixel/8); | ||
923 | } | ||
924 | |||
925 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
926 | |||
927 | if (stall_detected) { | ||
928 | DRM_DEBUG_DRIVER("Pageflip stall detected\n"); | ||
929 | intel_prepare_page_flip(dev, intel_crtc->plane); | ||
930 | } | ||
931 | } | ||
932 | |||
837 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | 933 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) |
838 | { | 934 | { |
839 | struct drm_device *dev = (struct drm_device *) arg; | 935 | struct drm_device *dev = (struct drm_device *) arg; |
@@ -951,15 +1047,19 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
951 | if (pipea_stats & vblank_status) { | 1047 | if (pipea_stats & vblank_status) { |
952 | vblank++; | 1048 | vblank++; |
953 | drm_handle_vblank(dev, 0); | 1049 | drm_handle_vblank(dev, 0); |
954 | if (!dev_priv->flip_pending_is_done) | 1050 | if (!dev_priv->flip_pending_is_done) { |
1051 | i915_pageflip_stall_check(dev, 0); | ||
955 | intel_finish_page_flip(dev, 0); | 1052 | intel_finish_page_flip(dev, 0); |
1053 | } | ||
956 | } | 1054 | } |
957 | 1055 | ||
958 | if (pipeb_stats & vblank_status) { | 1056 | if (pipeb_stats & vblank_status) { |
959 | vblank++; | 1057 | vblank++; |
960 | drm_handle_vblank(dev, 1); | 1058 | drm_handle_vblank(dev, 1); |
961 | if (!dev_priv->flip_pending_is_done) | 1059 | if (!dev_priv->flip_pending_is_done) { |
1060 | i915_pageflip_stall_check(dev, 1); | ||
962 | intel_finish_page_flip(dev, 1); | 1061 | intel_finish_page_flip(dev, 1); |
1062 | } | ||
963 | } | 1063 | } |
964 | 1064 | ||
965 | if ((pipea_stats & PIPE_LEGACY_BLC_EVENT_STATUS) || | 1065 | if ((pipea_stats & PIPE_LEGACY_BLC_EVENT_STATUS) || |
@@ -1251,6 +1351,16 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1251 | &dev_priv->render_ring), | 1351 | &dev_priv->render_ring), |
1252 | i915_get_tail_request(dev)->seqno)) { | 1352 | i915_get_tail_request(dev)->seqno)) { |
1253 | dev_priv->hangcheck_count = 0; | 1353 | dev_priv->hangcheck_count = 0; |
1354 | |||
1355 | /* Issue a wake-up to catch stuck h/w. */ | ||
1356 | if (dev_priv->render_ring.waiting_gem_seqno | | ||
1357 | dev_priv->bsd_ring.waiting_gem_seqno) { | ||
1358 | DRM_ERROR("Hangcheck timer elapsed... GPU idle, missed IRQ.\n"); | ||
1359 | if (dev_priv->render_ring.waiting_gem_seqno) | ||
1360 | DRM_WAKEUP(&dev_priv->render_ring.irq_queue); | ||
1361 | if (dev_priv->bsd_ring.waiting_gem_seqno) | ||
1362 | DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); | ||
1363 | } | ||
1254 | return; | 1364 | return; |
1255 | } | 1365 | } |
1256 | 1366 | ||
@@ -1318,12 +1428,17 @@ static int ironlake_irq_postinstall(struct drm_device *dev) | |||
1318 | I915_WRITE(DEIER, dev_priv->de_irq_enable_reg); | 1428 | I915_WRITE(DEIER, dev_priv->de_irq_enable_reg); |
1319 | (void) I915_READ(DEIER); | 1429 | (void) I915_READ(DEIER); |
1320 | 1430 | ||
1321 | /* user interrupt should be enabled, but masked initial */ | 1431 | /* Gen6 only needs render pipe_control now */ |
1432 | if (IS_GEN6(dev)) | ||
1433 | render_mask = GT_PIPE_NOTIFY; | ||
1434 | |||
1322 | dev_priv->gt_irq_mask_reg = ~render_mask; | 1435 | dev_priv->gt_irq_mask_reg = ~render_mask; |
1323 | dev_priv->gt_irq_enable_reg = render_mask; | 1436 | dev_priv->gt_irq_enable_reg = render_mask; |
1324 | 1437 | ||
1325 | I915_WRITE(GTIIR, I915_READ(GTIIR)); | 1438 | I915_WRITE(GTIIR, I915_READ(GTIIR)); |
1326 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); | 1439 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); |
1440 | if (IS_GEN6(dev)) | ||
1441 | I915_WRITE(GEN6_RENDER_IMR, ~GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT); | ||
1327 | I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); | 1442 | I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); |
1328 | (void) I915_READ(GTIER); | 1443 | (void) I915_READ(GTIER); |
1329 | 1444 | ||
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c index d1bf92b9978..ea5d3fea4b6 100644 --- a/drivers/gpu/drm/i915/i915_opregion.c +++ b/drivers/gpu/drm/i915/i915_opregion.c | |||
@@ -114,10 +114,6 @@ struct opregion_asle { | |||
114 | #define ASLE_REQ_MSK 0xf | 114 | #define ASLE_REQ_MSK 0xf |
115 | 115 | ||
116 | /* response bits of ASLE irq request */ | 116 | /* response bits of ASLE irq request */ |
117 | #define ASLE_ALS_ILLUM_FAIL (2<<10) | ||
118 | #define ASLE_BACKLIGHT_FAIL (2<<12) | ||
119 | #define ASLE_PFIT_FAIL (2<<14) | ||
120 | #define ASLE_PWM_FREQ_FAIL (2<<16) | ||
121 | #define ASLE_ALS_ILLUM_FAILED (1<<10) | 117 | #define ASLE_ALS_ILLUM_FAILED (1<<10) |
122 | #define ASLE_BACKLIGHT_FAILED (1<<12) | 118 | #define ASLE_BACKLIGHT_FAILED (1<<12) |
123 | #define ASLE_PFIT_FAILED (1<<14) | 119 | #define ASLE_PFIT_FAILED (1<<14) |
@@ -155,11 +151,11 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) | |||
155 | u32 max_backlight, level, shift; | 151 | u32 max_backlight, level, shift; |
156 | 152 | ||
157 | if (!(bclp & ASLE_BCLP_VALID)) | 153 | if (!(bclp & ASLE_BCLP_VALID)) |
158 | return ASLE_BACKLIGHT_FAIL; | 154 | return ASLE_BACKLIGHT_FAILED; |
159 | 155 | ||
160 | bclp &= ASLE_BCLP_MSK; | 156 | bclp &= ASLE_BCLP_MSK; |
161 | if (bclp < 0 || bclp > 255) | 157 | if (bclp < 0 || bclp > 255) |
162 | return ASLE_BACKLIGHT_FAIL; | 158 | return ASLE_BACKLIGHT_FAILED; |
163 | 159 | ||
164 | blc_pwm_ctl = I915_READ(BLC_PWM_CTL); | 160 | blc_pwm_ctl = I915_READ(BLC_PWM_CTL); |
165 | blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2); | 161 | blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2); |
@@ -211,7 +207,7 @@ static u32 asle_set_pfit(struct drm_device *dev, u32 pfit) | |||
211 | /* Panel fitting is currently controlled by the X code, so this is a | 207 | /* Panel fitting is currently controlled by the X code, so this is a |
212 | noop until modesetting support works fully */ | 208 | noop until modesetting support works fully */ |
213 | if (!(pfit & ASLE_PFIT_VALID)) | 209 | if (!(pfit & ASLE_PFIT_VALID)) |
214 | return ASLE_PFIT_FAIL; | 210 | return ASLE_PFIT_FAILED; |
215 | return 0; | 211 | return 0; |
216 | } | 212 | } |
217 | 213 | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 281db6e5403..d094e912922 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -170,6 +170,7 @@ | |||
170 | #define MI_NO_WRITE_FLUSH (1 << 2) | 170 | #define MI_NO_WRITE_FLUSH (1 << 2) |
171 | #define MI_SCENE_COUNT (1 << 3) /* just increment scene count */ | 171 | #define MI_SCENE_COUNT (1 << 3) /* just increment scene count */ |
172 | #define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ | 172 | #define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ |
173 | #define MI_INVALIDATE_ISP (1 << 5) /* invalidate indirect state pointers */ | ||
173 | #define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0) | 174 | #define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0) |
174 | #define MI_REPORT_HEAD MI_INSTR(0x07, 0) | 175 | #define MI_REPORT_HEAD MI_INSTR(0x07, 0) |
175 | #define MI_OVERLAY_FLIP MI_INSTR(0x11,0) | 176 | #define MI_OVERLAY_FLIP MI_INSTR(0x11,0) |
@@ -180,6 +181,12 @@ | |||
180 | #define MI_DISPLAY_FLIP MI_INSTR(0x14, 2) | 181 | #define MI_DISPLAY_FLIP MI_INSTR(0x14, 2) |
181 | #define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1) | 182 | #define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1) |
182 | #define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20) | 183 | #define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20) |
184 | #define MI_SET_CONTEXT MI_INSTR(0x18, 0) | ||
185 | #define MI_MM_SPACE_GTT (1<<8) | ||
186 | #define MI_MM_SPACE_PHYSICAL (0<<8) | ||
187 | #define MI_SAVE_EXT_STATE_EN (1<<3) | ||
188 | #define MI_RESTORE_EXT_STATE_EN (1<<2) | ||
189 | #define MI_RESTORE_INHIBIT (1<<0) | ||
183 | #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) | 190 | #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) |
184 | #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ | 191 | #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ |
185 | #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) | 192 | #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) |
@@ -312,6 +319,7 @@ | |||
312 | 319 | ||
313 | #define MI_MODE 0x0209c | 320 | #define MI_MODE 0x0209c |
314 | # define VS_TIMER_DISPATCH (1 << 6) | 321 | # define VS_TIMER_DISPATCH (1 << 6) |
322 | # define MI_FLUSH_ENABLE (1 << 11) | ||
315 | 323 | ||
316 | #define SCPD0 0x0209c /* 915+ only */ | 324 | #define SCPD0 0x0209c /* 915+ only */ |
317 | #define IER 0x020a0 | 325 | #define IER 0x020a0 |
@@ -1100,6 +1108,11 @@ | |||
1100 | #define PEG_BAND_GAP_DATA 0x14d68 | 1108 | #define PEG_BAND_GAP_DATA 0x14d68 |
1101 | 1109 | ||
1102 | /* | 1110 | /* |
1111 | * Logical Context regs | ||
1112 | */ | ||
1113 | #define CCID 0x2180 | ||
1114 | #define CCID_EN (1<<0) | ||
1115 | /* | ||
1103 | * Overlay regs | 1116 | * Overlay regs |
1104 | */ | 1117 | */ |
1105 | 1118 | ||
@@ -2069,6 +2082,7 @@ | |||
2069 | #define PIPE_DITHER_TYPE_ST01 (1 << 2) | 2082 | #define PIPE_DITHER_TYPE_ST01 (1 << 2) |
2070 | /* Pipe A */ | 2083 | /* Pipe A */ |
2071 | #define PIPEADSL 0x70000 | 2084 | #define PIPEADSL 0x70000 |
2085 | #define DSL_LINEMASK 0x00000fff | ||
2072 | #define PIPEACONF 0x70008 | 2086 | #define PIPEACONF 0x70008 |
2073 | #define PIPEACONF_ENABLE (1<<31) | 2087 | #define PIPEACONF_ENABLE (1<<31) |
2074 | #define PIPEACONF_DISABLE 0 | 2088 | #define PIPEACONF_DISABLE 0 |
@@ -2928,6 +2942,7 @@ | |||
2928 | #define TRANS_DP_VSYNC_ACTIVE_LOW 0 | 2942 | #define TRANS_DP_VSYNC_ACTIVE_LOW 0 |
2929 | #define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3) | 2943 | #define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3) |
2930 | #define TRANS_DP_HSYNC_ACTIVE_LOW 0 | 2944 | #define TRANS_DP_HSYNC_ACTIVE_LOW 0 |
2945 | #define TRANS_DP_SYNC_MASK (3<<3) | ||
2931 | 2946 | ||
2932 | /* SNB eDP training params */ | 2947 | /* SNB eDP training params */ |
2933 | /* SNB A-stepping */ | 2948 | /* SNB A-stepping */ |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 6e2025274db..2c6b98f2440 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -34,7 +34,7 @@ static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) | |||
34 | struct drm_i915_private *dev_priv = dev->dev_private; | 34 | struct drm_i915_private *dev_priv = dev->dev_private; |
35 | u32 dpll_reg; | 35 | u32 dpll_reg; |
36 | 36 | ||
37 | if (IS_IRONLAKE(dev)) { | 37 | if (HAS_PCH_SPLIT(dev)) { |
38 | dpll_reg = (pipe == PIPE_A) ? PCH_DPLL_A: PCH_DPLL_B; | 38 | dpll_reg = (pipe == PIPE_A) ? PCH_DPLL_A: PCH_DPLL_B; |
39 | } else { | 39 | } else { |
40 | dpll_reg = (pipe == PIPE_A) ? DPLL_A: DPLL_B; | 40 | dpll_reg = (pipe == PIPE_A) ? DPLL_A: DPLL_B; |
@@ -53,7 +53,7 @@ static void i915_save_palette(struct drm_device *dev, enum pipe pipe) | |||
53 | if (!i915_pipe_enabled(dev, pipe)) | 53 | if (!i915_pipe_enabled(dev, pipe)) |
54 | return; | 54 | return; |
55 | 55 | ||
56 | if (IS_IRONLAKE(dev)) | 56 | if (HAS_PCH_SPLIT(dev)) |
57 | reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; | 57 | reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; |
58 | 58 | ||
59 | if (pipe == PIPE_A) | 59 | if (pipe == PIPE_A) |
@@ -75,7 +75,7 @@ static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) | |||
75 | if (!i915_pipe_enabled(dev, pipe)) | 75 | if (!i915_pipe_enabled(dev, pipe)) |
76 | return; | 76 | return; |
77 | 77 | ||
78 | if (IS_IRONLAKE(dev)) | 78 | if (HAS_PCH_SPLIT(dev)) |
79 | reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; | 79 | reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; |
80 | 80 | ||
81 | if (pipe == PIPE_A) | 81 | if (pipe == PIPE_A) |
@@ -239,7 +239,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
239 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 239 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
240 | return; | 240 | return; |
241 | 241 | ||
242 | if (IS_IRONLAKE(dev)) { | 242 | if (HAS_PCH_SPLIT(dev)) { |
243 | dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); | 243 | dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); |
244 | dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); | 244 | dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); |
245 | } | 245 | } |
@@ -247,7 +247,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
247 | /* Pipe & plane A info */ | 247 | /* Pipe & plane A info */ |
248 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); | 248 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); |
249 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); | 249 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); |
250 | if (IS_IRONLAKE(dev)) { | 250 | if (HAS_PCH_SPLIT(dev)) { |
251 | dev_priv->saveFPA0 = I915_READ(PCH_FPA0); | 251 | dev_priv->saveFPA0 = I915_READ(PCH_FPA0); |
252 | dev_priv->saveFPA1 = I915_READ(PCH_FPA1); | 252 | dev_priv->saveFPA1 = I915_READ(PCH_FPA1); |
253 | dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A); | 253 | dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A); |
@@ -256,7 +256,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
256 | dev_priv->saveFPA1 = I915_READ(FPA1); | 256 | dev_priv->saveFPA1 = I915_READ(FPA1); |
257 | dev_priv->saveDPLL_A = I915_READ(DPLL_A); | 257 | dev_priv->saveDPLL_A = I915_READ(DPLL_A); |
258 | } | 258 | } |
259 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 259 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) |
260 | dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); | 260 | dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); |
261 | dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); | 261 | dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); |
262 | dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); | 262 | dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); |
@@ -264,10 +264,10 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
264 | dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); | 264 | dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); |
265 | dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); | 265 | dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); |
266 | dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); | 266 | dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); |
267 | if (!IS_IRONLAKE(dev)) | 267 | if (!HAS_PCH_SPLIT(dev)) |
268 | dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); | 268 | dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); |
269 | 269 | ||
270 | if (IS_IRONLAKE(dev)) { | 270 | if (HAS_PCH_SPLIT(dev)) { |
271 | dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1); | 271 | dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1); |
272 | dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1); | 272 | dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1); |
273 | dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1); | 273 | dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1); |
@@ -304,7 +304,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
304 | /* Pipe & plane B info */ | 304 | /* Pipe & plane B info */ |
305 | dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); | 305 | dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); |
306 | dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); | 306 | dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); |
307 | if (IS_IRONLAKE(dev)) { | 307 | if (HAS_PCH_SPLIT(dev)) { |
308 | dev_priv->saveFPB0 = I915_READ(PCH_FPB0); | 308 | dev_priv->saveFPB0 = I915_READ(PCH_FPB0); |
309 | dev_priv->saveFPB1 = I915_READ(PCH_FPB1); | 309 | dev_priv->saveFPB1 = I915_READ(PCH_FPB1); |
310 | dev_priv->saveDPLL_B = I915_READ(PCH_DPLL_B); | 310 | dev_priv->saveDPLL_B = I915_READ(PCH_DPLL_B); |
@@ -313,7 +313,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
313 | dev_priv->saveFPB1 = I915_READ(FPB1); | 313 | dev_priv->saveFPB1 = I915_READ(FPB1); |
314 | dev_priv->saveDPLL_B = I915_READ(DPLL_B); | 314 | dev_priv->saveDPLL_B = I915_READ(DPLL_B); |
315 | } | 315 | } |
316 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 316 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) |
317 | dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); | 317 | dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); |
318 | dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); | 318 | dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); |
319 | dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); | 319 | dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); |
@@ -321,10 +321,10 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
321 | dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); | 321 | dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); |
322 | dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); | 322 | dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); |
323 | dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); | 323 | dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); |
324 | if (!IS_IRONLAKE(dev)) | 324 | if (!HAS_PCH_SPLIT(dev)) |
325 | dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B); | 325 | dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B); |
326 | 326 | ||
327 | if (IS_IRONLAKE(dev)) { | 327 | if (HAS_PCH_SPLIT(dev)) { |
328 | dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1); | 328 | dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1); |
329 | dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1); | 329 | dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1); |
330 | dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1); | 330 | dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1); |
@@ -369,7 +369,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
369 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 369 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
370 | return; | 370 | return; |
371 | 371 | ||
372 | if (IS_IRONLAKE(dev)) { | 372 | if (HAS_PCH_SPLIT(dev)) { |
373 | dpll_a_reg = PCH_DPLL_A; | 373 | dpll_a_reg = PCH_DPLL_A; |
374 | dpll_b_reg = PCH_DPLL_B; | 374 | dpll_b_reg = PCH_DPLL_B; |
375 | fpa0_reg = PCH_FPA0; | 375 | fpa0_reg = PCH_FPA0; |
@@ -385,7 +385,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
385 | fpb1_reg = FPB1; | 385 | fpb1_reg = FPB1; |
386 | } | 386 | } |
387 | 387 | ||
388 | if (IS_IRONLAKE(dev)) { | 388 | if (HAS_PCH_SPLIT(dev)) { |
389 | I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL); | 389 | I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL); |
390 | I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL); | 390 | I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL); |
391 | } | 391 | } |
@@ -395,16 +395,20 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
395 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | 395 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { |
396 | I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A & | 396 | I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A & |
397 | ~DPLL_VCO_ENABLE); | 397 | ~DPLL_VCO_ENABLE); |
398 | DRM_UDELAY(150); | 398 | POSTING_READ(dpll_a_reg); |
399 | udelay(150); | ||
399 | } | 400 | } |
400 | I915_WRITE(fpa0_reg, dev_priv->saveFPA0); | 401 | I915_WRITE(fpa0_reg, dev_priv->saveFPA0); |
401 | I915_WRITE(fpa1_reg, dev_priv->saveFPA1); | 402 | I915_WRITE(fpa1_reg, dev_priv->saveFPA1); |
402 | /* Actually enable it */ | 403 | /* Actually enable it */ |
403 | I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A); | 404 | I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A); |
404 | DRM_UDELAY(150); | 405 | POSTING_READ(dpll_a_reg); |
405 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 406 | udelay(150); |
407 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) { | ||
406 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); | 408 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); |
407 | DRM_UDELAY(150); | 409 | POSTING_READ(DPLL_A_MD); |
410 | } | ||
411 | udelay(150); | ||
408 | 412 | ||
409 | /* Restore mode */ | 413 | /* Restore mode */ |
410 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); | 414 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); |
@@ -413,10 +417,10 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
413 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); | 417 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); |
414 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); | 418 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); |
415 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); | 419 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); |
416 | if (!IS_IRONLAKE(dev)) | 420 | if (!HAS_PCH_SPLIT(dev)) |
417 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | 421 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); |
418 | 422 | ||
419 | if (IS_IRONLAKE(dev)) { | 423 | if (HAS_PCH_SPLIT(dev)) { |
420 | I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1); | 424 | I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1); |
421 | I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1); | 425 | I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1); |
422 | I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1); | 426 | I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1); |
@@ -460,16 +464,20 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
460 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { | 464 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { |
461 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B & | 465 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B & |
462 | ~DPLL_VCO_ENABLE); | 466 | ~DPLL_VCO_ENABLE); |
463 | DRM_UDELAY(150); | 467 | POSTING_READ(dpll_b_reg); |
468 | udelay(150); | ||
464 | } | 469 | } |
465 | I915_WRITE(fpb0_reg, dev_priv->saveFPB0); | 470 | I915_WRITE(fpb0_reg, dev_priv->saveFPB0); |
466 | I915_WRITE(fpb1_reg, dev_priv->saveFPB1); | 471 | I915_WRITE(fpb1_reg, dev_priv->saveFPB1); |
467 | /* Actually enable it */ | 472 | /* Actually enable it */ |
468 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B); | 473 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B); |
469 | DRM_UDELAY(150); | 474 | POSTING_READ(dpll_b_reg); |
470 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 475 | udelay(150); |
476 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) { | ||
471 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | 477 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); |
472 | DRM_UDELAY(150); | 478 | POSTING_READ(DPLL_B_MD); |
479 | } | ||
480 | udelay(150); | ||
473 | 481 | ||
474 | /* Restore mode */ | 482 | /* Restore mode */ |
475 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); | 483 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); |
@@ -478,10 +486,10 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
478 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); | 486 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); |
479 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); | 487 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); |
480 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); | 488 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); |
481 | if (!IS_IRONLAKE(dev)) | 489 | if (!HAS_PCH_SPLIT(dev)) |
482 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | 490 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); |
483 | 491 | ||
484 | if (IS_IRONLAKE(dev)) { | 492 | if (HAS_PCH_SPLIT(dev)) { |
485 | I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1); | 493 | I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1); |
486 | I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1); | 494 | I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1); |
487 | I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1); | 495 | I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1); |
@@ -546,14 +554,14 @@ void i915_save_display(struct drm_device *dev) | |||
546 | dev_priv->saveCURSIZE = I915_READ(CURSIZE); | 554 | dev_priv->saveCURSIZE = I915_READ(CURSIZE); |
547 | 555 | ||
548 | /* CRT state */ | 556 | /* CRT state */ |
549 | if (IS_IRONLAKE(dev)) { | 557 | if (HAS_PCH_SPLIT(dev)) { |
550 | dev_priv->saveADPA = I915_READ(PCH_ADPA); | 558 | dev_priv->saveADPA = I915_READ(PCH_ADPA); |
551 | } else { | 559 | } else { |
552 | dev_priv->saveADPA = I915_READ(ADPA); | 560 | dev_priv->saveADPA = I915_READ(ADPA); |
553 | } | 561 | } |
554 | 562 | ||
555 | /* LVDS state */ | 563 | /* LVDS state */ |
556 | if (IS_IRONLAKE(dev)) { | 564 | if (HAS_PCH_SPLIT(dev)) { |
557 | dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL); | 565 | dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL); |
558 | dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1); | 566 | dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1); |
559 | dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2); | 567 | dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2); |
@@ -571,10 +579,10 @@ void i915_save_display(struct drm_device *dev) | |||
571 | dev_priv->saveLVDS = I915_READ(LVDS); | 579 | dev_priv->saveLVDS = I915_READ(LVDS); |
572 | } | 580 | } |
573 | 581 | ||
574 | if (!IS_I830(dev) && !IS_845G(dev) && !IS_IRONLAKE(dev)) | 582 | if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev)) |
575 | dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); | 583 | dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); |
576 | 584 | ||
577 | if (IS_IRONLAKE(dev)) { | 585 | if (HAS_PCH_SPLIT(dev)) { |
578 | dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS); | 586 | dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS); |
579 | dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS); | 587 | dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS); |
580 | dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR); | 588 | dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR); |
@@ -602,7 +610,7 @@ void i915_save_display(struct drm_device *dev) | |||
602 | 610 | ||
603 | /* Only save FBC state on the platform that supports FBC */ | 611 | /* Only save FBC state on the platform that supports FBC */ |
604 | if (I915_HAS_FBC(dev)) { | 612 | if (I915_HAS_FBC(dev)) { |
605 | if (IS_IRONLAKE_M(dev)) { | 613 | if (HAS_PCH_SPLIT(dev)) { |
606 | dev_priv->saveDPFC_CB_BASE = I915_READ(ILK_DPFC_CB_BASE); | 614 | dev_priv->saveDPFC_CB_BASE = I915_READ(ILK_DPFC_CB_BASE); |
607 | } else if (IS_GM45(dev)) { | 615 | } else if (IS_GM45(dev)) { |
608 | dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE); | 616 | dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE); |
@@ -618,7 +626,7 @@ void i915_save_display(struct drm_device *dev) | |||
618 | dev_priv->saveVGA0 = I915_READ(VGA0); | 626 | dev_priv->saveVGA0 = I915_READ(VGA0); |
619 | dev_priv->saveVGA1 = I915_READ(VGA1); | 627 | dev_priv->saveVGA1 = I915_READ(VGA1); |
620 | dev_priv->saveVGA_PD = I915_READ(VGA_PD); | 628 | dev_priv->saveVGA_PD = I915_READ(VGA_PD); |
621 | if (IS_IRONLAKE(dev)) | 629 | if (HAS_PCH_SPLIT(dev)) |
622 | dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL); | 630 | dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL); |
623 | else | 631 | else |
624 | dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); | 632 | dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); |
@@ -660,24 +668,24 @@ void i915_restore_display(struct drm_device *dev) | |||
660 | I915_WRITE(CURSIZE, dev_priv->saveCURSIZE); | 668 | I915_WRITE(CURSIZE, dev_priv->saveCURSIZE); |
661 | 669 | ||
662 | /* CRT state */ | 670 | /* CRT state */ |
663 | if (IS_IRONLAKE(dev)) | 671 | if (HAS_PCH_SPLIT(dev)) |
664 | I915_WRITE(PCH_ADPA, dev_priv->saveADPA); | 672 | I915_WRITE(PCH_ADPA, dev_priv->saveADPA); |
665 | else | 673 | else |
666 | I915_WRITE(ADPA, dev_priv->saveADPA); | 674 | I915_WRITE(ADPA, dev_priv->saveADPA); |
667 | 675 | ||
668 | /* LVDS state */ | 676 | /* LVDS state */ |
669 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 677 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) |
670 | I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); | 678 | I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); |
671 | 679 | ||
672 | if (IS_IRONLAKE(dev)) { | 680 | if (HAS_PCH_SPLIT(dev)) { |
673 | I915_WRITE(PCH_LVDS, dev_priv->saveLVDS); | 681 | I915_WRITE(PCH_LVDS, dev_priv->saveLVDS); |
674 | } else if (IS_MOBILE(dev) && !IS_I830(dev)) | 682 | } else if (IS_MOBILE(dev) && !IS_I830(dev)) |
675 | I915_WRITE(LVDS, dev_priv->saveLVDS); | 683 | I915_WRITE(LVDS, dev_priv->saveLVDS); |
676 | 684 | ||
677 | if (!IS_I830(dev) && !IS_845G(dev) && !IS_IRONLAKE(dev)) | 685 | if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev)) |
678 | I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); | 686 | I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); |
679 | 687 | ||
680 | if (IS_IRONLAKE(dev)) { | 688 | if (HAS_PCH_SPLIT(dev)) { |
681 | I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL); | 689 | I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL); |
682 | I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2); | 690 | I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2); |
683 | I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); | 691 | I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); |
@@ -708,7 +716,7 @@ void i915_restore_display(struct drm_device *dev) | |||
708 | 716 | ||
709 | /* only restore FBC info on the platform that supports FBC*/ | 717 | /* only restore FBC info on the platform that supports FBC*/ |
710 | if (I915_HAS_FBC(dev)) { | 718 | if (I915_HAS_FBC(dev)) { |
711 | if (IS_IRONLAKE_M(dev)) { | 719 | if (HAS_PCH_SPLIT(dev)) { |
712 | ironlake_disable_fbc(dev); | 720 | ironlake_disable_fbc(dev); |
713 | I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); | 721 | I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); |
714 | } else if (IS_GM45(dev)) { | 722 | } else if (IS_GM45(dev)) { |
@@ -723,14 +731,15 @@ void i915_restore_display(struct drm_device *dev) | |||
723 | } | 731 | } |
724 | } | 732 | } |
725 | /* VGA state */ | 733 | /* VGA state */ |
726 | if (IS_IRONLAKE(dev)) | 734 | if (HAS_PCH_SPLIT(dev)) |
727 | I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL); | 735 | I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL); |
728 | else | 736 | else |
729 | I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); | 737 | I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); |
730 | I915_WRITE(VGA0, dev_priv->saveVGA0); | 738 | I915_WRITE(VGA0, dev_priv->saveVGA0); |
731 | I915_WRITE(VGA1, dev_priv->saveVGA1); | 739 | I915_WRITE(VGA1, dev_priv->saveVGA1); |
732 | I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); | 740 | I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); |
733 | DRM_UDELAY(150); | 741 | POSTING_READ(VGA_PD); |
742 | udelay(150); | ||
734 | 743 | ||
735 | i915_restore_vga(dev); | 744 | i915_restore_vga(dev); |
736 | } | 745 | } |
@@ -748,7 +757,7 @@ int i915_save_state(struct drm_device *dev) | |||
748 | i915_save_display(dev); | 757 | i915_save_display(dev); |
749 | 758 | ||
750 | /* Interrupt state */ | 759 | /* Interrupt state */ |
751 | if (IS_IRONLAKE(dev)) { | 760 | if (HAS_PCH_SPLIT(dev)) { |
752 | dev_priv->saveDEIER = I915_READ(DEIER); | 761 | dev_priv->saveDEIER = I915_READ(DEIER); |
753 | dev_priv->saveDEIMR = I915_READ(DEIMR); | 762 | dev_priv->saveDEIMR = I915_READ(DEIMR); |
754 | dev_priv->saveGTIER = I915_READ(GTIER); | 763 | dev_priv->saveGTIER = I915_READ(GTIER); |
@@ -762,7 +771,7 @@ int i915_save_state(struct drm_device *dev) | |||
762 | dev_priv->saveIMR = I915_READ(IMR); | 771 | dev_priv->saveIMR = I915_READ(IMR); |
763 | } | 772 | } |
764 | 773 | ||
765 | if (IS_IRONLAKE_M(dev)) | 774 | if (HAS_PCH_SPLIT(dev)) |
766 | ironlake_disable_drps(dev); | 775 | ironlake_disable_drps(dev); |
767 | 776 | ||
768 | /* Cache mode state */ | 777 | /* Cache mode state */ |
@@ -820,7 +829,7 @@ int i915_restore_state(struct drm_device *dev) | |||
820 | i915_restore_display(dev); | 829 | i915_restore_display(dev); |
821 | 830 | ||
822 | /* Interrupt state */ | 831 | /* Interrupt state */ |
823 | if (IS_IRONLAKE(dev)) { | 832 | if (HAS_PCH_SPLIT(dev)) { |
824 | I915_WRITE(DEIER, dev_priv->saveDEIER); | 833 | I915_WRITE(DEIER, dev_priv->saveDEIER); |
825 | I915_WRITE(DEIMR, dev_priv->saveDEIMR); | 834 | I915_WRITE(DEIMR, dev_priv->saveDEIMR); |
826 | I915_WRITE(GTIER, dev_priv->saveGTIER); | 835 | I915_WRITE(GTIER, dev_priv->saveGTIER); |
@@ -835,7 +844,7 @@ int i915_restore_state(struct drm_device *dev) | |||
835 | /* Clock gating state */ | 844 | /* Clock gating state */ |
836 | intel_init_clock_gating(dev); | 845 | intel_init_clock_gating(dev); |
837 | 846 | ||
838 | if (IS_IRONLAKE_M(dev)) | 847 | if (HAS_PCH_SPLIT(dev)) |
839 | ironlake_enable_drps(dev); | 848 | ironlake_enable_drps(dev); |
840 | 849 | ||
841 | /* Cache mode state */ | 850 | /* Cache mode state */ |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index ee0732b222a..4b7735196cd 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -160,19 +160,20 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) | |||
160 | struct drm_i915_private *dev_priv = dev->dev_private; | 160 | struct drm_i915_private *dev_priv = dev->dev_private; |
161 | u32 adpa, temp; | 161 | u32 adpa, temp; |
162 | bool ret; | 162 | bool ret; |
163 | bool turn_off_dac = false; | ||
163 | 164 | ||
164 | temp = adpa = I915_READ(PCH_ADPA); | 165 | temp = adpa = I915_READ(PCH_ADPA); |
165 | 166 | ||
166 | if (HAS_PCH_CPT(dev)) { | 167 | if (HAS_PCH_SPLIT(dev)) |
167 | /* Disable DAC before force detect */ | 168 | turn_off_dac = true; |
168 | I915_WRITE(PCH_ADPA, adpa & ~ADPA_DAC_ENABLE); | 169 | |
169 | (void)I915_READ(PCH_ADPA); | 170 | adpa &= ~ADPA_CRT_HOTPLUG_MASK; |
170 | } else { | 171 | if (turn_off_dac) |
171 | adpa &= ~ADPA_CRT_HOTPLUG_MASK; | 172 | adpa &= ~ADPA_DAC_ENABLE; |
172 | /* disable HPD first */ | 173 | |
173 | I915_WRITE(PCH_ADPA, adpa); | 174 | /* disable HPD first */ |
174 | (void)I915_READ(PCH_ADPA); | 175 | I915_WRITE(PCH_ADPA, adpa); |
175 | } | 176 | (void)I915_READ(PCH_ADPA); |
176 | 177 | ||
177 | adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | | 178 | adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | |
178 | ADPA_CRT_HOTPLUG_WARMUP_10MS | | 179 | ADPA_CRT_HOTPLUG_WARMUP_10MS | |
@@ -185,10 +186,11 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) | |||
185 | DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa); | 186 | DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa); |
186 | I915_WRITE(PCH_ADPA, adpa); | 187 | I915_WRITE(PCH_ADPA, adpa); |
187 | 188 | ||
188 | while ((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) != 0) | 189 | if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, |
189 | ; | 190 | 1000, 1)) |
191 | DRM_ERROR("timed out waiting for FORCE_TRIGGER"); | ||
190 | 192 | ||
191 | if (HAS_PCH_CPT(dev)) { | 193 | if (turn_off_dac) { |
192 | I915_WRITE(PCH_ADPA, temp); | 194 | I915_WRITE(PCH_ADPA, temp); |
193 | (void)I915_READ(PCH_ADPA); | 195 | (void)I915_READ(PCH_ADPA); |
194 | } | 196 | } |
@@ -237,17 +239,13 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
237 | hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; | 239 | hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; |
238 | 240 | ||
239 | for (i = 0; i < tries ; i++) { | 241 | for (i = 0; i < tries ; i++) { |
240 | unsigned long timeout; | ||
241 | /* turn on the FORCE_DETECT */ | 242 | /* turn on the FORCE_DETECT */ |
242 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); | 243 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); |
243 | timeout = jiffies + msecs_to_jiffies(1000); | ||
244 | /* wait for FORCE_DETECT to go off */ | 244 | /* wait for FORCE_DETECT to go off */ |
245 | do { | 245 | if (wait_for((I915_READ(PORT_HOTPLUG_EN) & |
246 | if (!(I915_READ(PORT_HOTPLUG_EN) & | 246 | CRT_HOTPLUG_FORCE_DETECT) == 0, |
247 | CRT_HOTPLUG_FORCE_DETECT)) | 247 | 1000, 1)) |
248 | break; | 248 | DRM_ERROR("timed out waiting for FORCE_DETECT to go off"); |
249 | msleep(1); | ||
250 | } while (time_after(timeout, jiffies)); | ||
251 | } | 249 | } |
252 | 250 | ||
253 | stat = I915_READ(PORT_HOTPLUG_STAT); | 251 | stat = I915_READ(PORT_HOTPLUG_STAT); |
@@ -331,7 +329,7 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
331 | I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER); | 329 | I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER); |
332 | /* Wait for next Vblank to substitue | 330 | /* Wait for next Vblank to substitue |
333 | * border color for Color info */ | 331 | * border color for Color info */ |
334 | intel_wait_for_vblank(dev); | 332 | intel_wait_for_vblank(dev, pipe); |
335 | st00 = I915_READ8(VGA_MSR_WRITE); | 333 | st00 = I915_READ8(VGA_MSR_WRITE); |
336 | status = ((st00 & (1 << 4)) != 0) ? | 334 | status = ((st00 & (1 << 4)) != 0) ? |
337 | connector_status_connected : | 335 | connector_status_connected : |
@@ -508,17 +506,8 @@ static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs | |||
508 | .best_encoder = intel_attached_encoder, | 506 | .best_encoder = intel_attached_encoder, |
509 | }; | 507 | }; |
510 | 508 | ||
511 | static void intel_crt_enc_destroy(struct drm_encoder *encoder) | ||
512 | { | ||
513 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
514 | |||
515 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
516 | drm_encoder_cleanup(encoder); | ||
517 | kfree(intel_encoder); | ||
518 | } | ||
519 | |||
520 | static const struct drm_encoder_funcs intel_crt_enc_funcs = { | 509 | static const struct drm_encoder_funcs intel_crt_enc_funcs = { |
521 | .destroy = intel_crt_enc_destroy, | 510 | .destroy = intel_encoder_destroy, |
522 | }; | 511 | }; |
523 | 512 | ||
524 | void intel_crt_init(struct drm_device *dev) | 513 | void intel_crt_init(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5ec10e02341..40cc5da264a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/vgaarb.h> | ||
32 | #include "drmP.h" | 33 | #include "drmP.h" |
33 | #include "intel_drv.h" | 34 | #include "intel_drv.h" |
34 | #include "i915_drm.h" | 35 | #include "i915_drm.h" |
@@ -976,14 +977,70 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
976 | return true; | 977 | return true; |
977 | } | 978 | } |
978 | 979 | ||
979 | void | 980 | /** |
980 | intel_wait_for_vblank(struct drm_device *dev) | 981 | * intel_wait_for_vblank - wait for vblank on a given pipe |
982 | * @dev: drm device | ||
983 | * @pipe: pipe to wait for | ||
984 | * | ||
985 | * Wait for vblank to occur on a given pipe. Needed for various bits of | ||
986 | * mode setting code. | ||
987 | */ | ||
988 | void intel_wait_for_vblank(struct drm_device *dev, int pipe) | ||
981 | { | 989 | { |
982 | /* Wait for 20ms, i.e. one cycle at 50hz. */ | 990 | struct drm_i915_private *dev_priv = dev->dev_private; |
983 | if (in_dbg_master()) | 991 | int pipestat_reg = (pipe == 0 ? PIPEASTAT : PIPEBSTAT); |
984 | mdelay(20); /* The kernel debugger cannot call msleep() */ | 992 | |
985 | else | 993 | /* Clear existing vblank status. Note this will clear any other |
986 | msleep(20); | 994 | * sticky status fields as well. |
995 | * | ||
996 | * This races with i915_driver_irq_handler() with the result | ||
997 | * that either function could miss a vblank event. Here it is not | ||
998 | * fatal, as we will either wait upon the next vblank interrupt or | ||
999 | * timeout. Generally speaking intel_wait_for_vblank() is only | ||
1000 | * called during modeset at which time the GPU should be idle and | ||
1001 | * should *not* be performing page flips and thus not waiting on | ||
1002 | * vblanks... | ||
1003 | * Currently, the result of us stealing a vblank from the irq | ||
1004 | * handler is that a single frame will be skipped during swapbuffers. | ||
1005 | */ | ||
1006 | I915_WRITE(pipestat_reg, | ||
1007 | I915_READ(pipestat_reg) | PIPE_VBLANK_INTERRUPT_STATUS); | ||
1008 | |||
1009 | /* Wait for vblank interrupt bit to set */ | ||
1010 | if (wait_for((I915_READ(pipestat_reg) & | ||
1011 | PIPE_VBLANK_INTERRUPT_STATUS), | ||
1012 | 50, 0)) | ||
1013 | DRM_DEBUG_KMS("vblank wait timed out\n"); | ||
1014 | } | ||
1015 | |||
1016 | /** | ||
1017 | * intel_wait_for_vblank_off - wait for vblank after disabling a pipe | ||
1018 | * @dev: drm device | ||
1019 | * @pipe: pipe to wait for | ||
1020 | * | ||
1021 | * After disabling a pipe, we can't wait for vblank in the usual way, | ||
1022 | * spinning on the vblank interrupt status bit, since we won't actually | ||
1023 | * see an interrupt when the pipe is disabled. | ||
1024 | * | ||
1025 | * So this function waits for the display line value to settle (it | ||
1026 | * usually ends up stopping at the start of the next frame). | ||
1027 | */ | ||
1028 | void intel_wait_for_vblank_off(struct drm_device *dev, int pipe) | ||
1029 | { | ||
1030 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1031 | int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL); | ||
1032 | unsigned long timeout = jiffies + msecs_to_jiffies(100); | ||
1033 | u32 last_line; | ||
1034 | |||
1035 | /* Wait for the display line to settle */ | ||
1036 | do { | ||
1037 | last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK; | ||
1038 | mdelay(5); | ||
1039 | } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) && | ||
1040 | time_after(timeout, jiffies)); | ||
1041 | |||
1042 | if (time_after(jiffies, timeout)) | ||
1043 | DRM_DEBUG_KMS("vblank wait timed out\n"); | ||
987 | } | 1044 | } |
988 | 1045 | ||
989 | /* Parameters have changed, update FBC info */ | 1046 | /* Parameters have changed, update FBC info */ |
@@ -1037,7 +1094,6 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1037 | void i8xx_disable_fbc(struct drm_device *dev) | 1094 | void i8xx_disable_fbc(struct drm_device *dev) |
1038 | { | 1095 | { |
1039 | struct drm_i915_private *dev_priv = dev->dev_private; | 1096 | struct drm_i915_private *dev_priv = dev->dev_private; |
1040 | unsigned long timeout = jiffies + msecs_to_jiffies(1); | ||
1041 | u32 fbc_ctl; | 1097 | u32 fbc_ctl; |
1042 | 1098 | ||
1043 | if (!I915_HAS_FBC(dev)) | 1099 | if (!I915_HAS_FBC(dev)) |
@@ -1052,16 +1108,11 @@ void i8xx_disable_fbc(struct drm_device *dev) | |||
1052 | I915_WRITE(FBC_CONTROL, fbc_ctl); | 1108 | I915_WRITE(FBC_CONTROL, fbc_ctl); |
1053 | 1109 | ||
1054 | /* Wait for compressing bit to clear */ | 1110 | /* Wait for compressing bit to clear */ |
1055 | while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) { | 1111 | if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10, 0)) { |
1056 | if (time_after(jiffies, timeout)) { | 1112 | DRM_DEBUG_KMS("FBC idle timed out\n"); |
1057 | DRM_DEBUG_DRIVER("FBC idle timed out\n"); | 1113 | return; |
1058 | break; | ||
1059 | } | ||
1060 | ; /* do nothing */ | ||
1061 | } | 1114 | } |
1062 | 1115 | ||
1063 | intel_wait_for_vblank(dev); | ||
1064 | |||
1065 | DRM_DEBUG_KMS("disabled FBC\n"); | 1116 | DRM_DEBUG_KMS("disabled FBC\n"); |
1066 | } | 1117 | } |
1067 | 1118 | ||
@@ -1118,7 +1169,6 @@ void g4x_disable_fbc(struct drm_device *dev) | |||
1118 | dpfc_ctl = I915_READ(DPFC_CONTROL); | 1169 | dpfc_ctl = I915_READ(DPFC_CONTROL); |
1119 | dpfc_ctl &= ~DPFC_CTL_EN; | 1170 | dpfc_ctl &= ~DPFC_CTL_EN; |
1120 | I915_WRITE(DPFC_CONTROL, dpfc_ctl); | 1171 | I915_WRITE(DPFC_CONTROL, dpfc_ctl); |
1121 | intel_wait_for_vblank(dev); | ||
1122 | 1172 | ||
1123 | DRM_DEBUG_KMS("disabled FBC\n"); | 1173 | DRM_DEBUG_KMS("disabled FBC\n"); |
1124 | } | 1174 | } |
@@ -1179,7 +1229,6 @@ void ironlake_disable_fbc(struct drm_device *dev) | |||
1179 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); | 1229 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); |
1180 | dpfc_ctl &= ~DPFC_CTL_EN; | 1230 | dpfc_ctl &= ~DPFC_CTL_EN; |
1181 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); | 1231 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); |
1182 | intel_wait_for_vblank(dev); | ||
1183 | 1232 | ||
1184 | DRM_DEBUG_KMS("disabled FBC\n"); | 1233 | DRM_DEBUG_KMS("disabled FBC\n"); |
1185 | } | 1234 | } |
@@ -1453,7 +1502,7 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
1453 | dspcntr &= ~DISPPLANE_TILED; | 1502 | dspcntr &= ~DISPPLANE_TILED; |
1454 | } | 1503 | } |
1455 | 1504 | ||
1456 | if (IS_IRONLAKE(dev)) | 1505 | if (HAS_PCH_SPLIT(dev)) |
1457 | /* must disable */ | 1506 | /* must disable */ |
1458 | dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; | 1507 | dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; |
1459 | 1508 | ||
@@ -1462,23 +1511,22 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
1462 | Start = obj_priv->gtt_offset; | 1511 | Start = obj_priv->gtt_offset; |
1463 | Offset = y * fb->pitch + x * (fb->bits_per_pixel / 8); | 1512 | Offset = y * fb->pitch + x * (fb->bits_per_pixel / 8); |
1464 | 1513 | ||
1465 | DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y); | 1514 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", |
1515 | Start, Offset, x, y, fb->pitch); | ||
1466 | I915_WRITE(dspstride, fb->pitch); | 1516 | I915_WRITE(dspstride, fb->pitch); |
1467 | if (IS_I965G(dev)) { | 1517 | if (IS_I965G(dev)) { |
1468 | I915_WRITE(dspbase, Offset); | ||
1469 | I915_READ(dspbase); | ||
1470 | I915_WRITE(dspsurf, Start); | 1518 | I915_WRITE(dspsurf, Start); |
1471 | I915_READ(dspsurf); | ||
1472 | I915_WRITE(dsptileoff, (y << 16) | x); | 1519 | I915_WRITE(dsptileoff, (y << 16) | x); |
1520 | I915_WRITE(dspbase, Offset); | ||
1473 | } else { | 1521 | } else { |
1474 | I915_WRITE(dspbase, Start + Offset); | 1522 | I915_WRITE(dspbase, Start + Offset); |
1475 | I915_READ(dspbase); | ||
1476 | } | 1523 | } |
1524 | POSTING_READ(dspbase); | ||
1477 | 1525 | ||
1478 | if ((IS_I965G(dev) || plane == 0)) | 1526 | if (IS_I965G(dev) || plane == 0) |
1479 | intel_update_fbc(crtc, &crtc->mode); | 1527 | intel_update_fbc(crtc, &crtc->mode); |
1480 | 1528 | ||
1481 | intel_wait_for_vblank(dev); | 1529 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1482 | intel_increase_pllclock(crtc, true); | 1530 | intel_increase_pllclock(crtc, true); |
1483 | 1531 | ||
1484 | return 0; | 1532 | return 0; |
@@ -1489,7 +1537,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1489 | struct drm_framebuffer *old_fb) | 1537 | struct drm_framebuffer *old_fb) |
1490 | { | 1538 | { |
1491 | struct drm_device *dev = crtc->dev; | 1539 | struct drm_device *dev = crtc->dev; |
1492 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1493 | struct drm_i915_master_private *master_priv; | 1540 | struct drm_i915_master_private *master_priv; |
1494 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1541 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1495 | struct intel_framebuffer *intel_fb; | 1542 | struct intel_framebuffer *intel_fb; |
@@ -1497,13 +1544,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1497 | struct drm_gem_object *obj; | 1544 | struct drm_gem_object *obj; |
1498 | int pipe = intel_crtc->pipe; | 1545 | int pipe = intel_crtc->pipe; |
1499 | int plane = intel_crtc->plane; | 1546 | int plane = intel_crtc->plane; |
1500 | unsigned long Start, Offset; | ||
1501 | int dspbase = (plane == 0 ? DSPAADDR : DSPBADDR); | ||
1502 | int dspsurf = (plane == 0 ? DSPASURF : DSPBSURF); | ||
1503 | int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE; | ||
1504 | int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF); | ||
1505 | int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; | ||
1506 | u32 dspcntr; | ||
1507 | int ret; | 1547 | int ret; |
1508 | 1548 | ||
1509 | /* no fb bound */ | 1549 | /* no fb bound */ |
@@ -1539,73 +1579,18 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1539 | return ret; | 1579 | return ret; |
1540 | } | 1580 | } |
1541 | 1581 | ||
1542 | dspcntr = I915_READ(dspcntr_reg); | 1582 | ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y); |
1543 | /* Mask out pixel format bits in case we change it */ | 1583 | if (ret) { |
1544 | dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; | ||
1545 | switch (crtc->fb->bits_per_pixel) { | ||
1546 | case 8: | ||
1547 | dspcntr |= DISPPLANE_8BPP; | ||
1548 | break; | ||
1549 | case 16: | ||
1550 | if (crtc->fb->depth == 15) | ||
1551 | dspcntr |= DISPPLANE_15_16BPP; | ||
1552 | else | ||
1553 | dspcntr |= DISPPLANE_16BPP; | ||
1554 | break; | ||
1555 | case 24: | ||
1556 | case 32: | ||
1557 | if (crtc->fb->depth == 30) | ||
1558 | dspcntr |= DISPPLANE_32BPP_30BIT_NO_ALPHA; | ||
1559 | else | ||
1560 | dspcntr |= DISPPLANE_32BPP_NO_ALPHA; | ||
1561 | break; | ||
1562 | default: | ||
1563 | DRM_ERROR("Unknown color depth\n"); | ||
1564 | i915_gem_object_unpin(obj); | 1584 | i915_gem_object_unpin(obj); |
1565 | mutex_unlock(&dev->struct_mutex); | 1585 | mutex_unlock(&dev->struct_mutex); |
1566 | return -EINVAL; | 1586 | return ret; |
1567 | } | ||
1568 | if (IS_I965G(dev)) { | ||
1569 | if (obj_priv->tiling_mode != I915_TILING_NONE) | ||
1570 | dspcntr |= DISPPLANE_TILED; | ||
1571 | else | ||
1572 | dspcntr &= ~DISPPLANE_TILED; | ||
1573 | } | ||
1574 | |||
1575 | if (HAS_PCH_SPLIT(dev)) | ||
1576 | /* must disable */ | ||
1577 | dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; | ||
1578 | |||
1579 | I915_WRITE(dspcntr_reg, dspcntr); | ||
1580 | |||
1581 | Start = obj_priv->gtt_offset; | ||
1582 | Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); | ||
1583 | |||
1584 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", | ||
1585 | Start, Offset, x, y, crtc->fb->pitch); | ||
1586 | I915_WRITE(dspstride, crtc->fb->pitch); | ||
1587 | if (IS_I965G(dev)) { | ||
1588 | I915_WRITE(dspbase, Offset); | ||
1589 | I915_READ(dspbase); | ||
1590 | I915_WRITE(dspsurf, Start); | ||
1591 | I915_READ(dspsurf); | ||
1592 | I915_WRITE(dsptileoff, (y << 16) | x); | ||
1593 | } else { | ||
1594 | I915_WRITE(dspbase, Start + Offset); | ||
1595 | I915_READ(dspbase); | ||
1596 | } | 1587 | } |
1597 | 1588 | ||
1598 | if ((IS_I965G(dev) || plane == 0)) | ||
1599 | intel_update_fbc(crtc, &crtc->mode); | ||
1600 | |||
1601 | intel_wait_for_vblank(dev); | ||
1602 | |||
1603 | if (old_fb) { | 1589 | if (old_fb) { |
1604 | intel_fb = to_intel_framebuffer(old_fb); | 1590 | intel_fb = to_intel_framebuffer(old_fb); |
1605 | obj_priv = to_intel_bo(intel_fb->obj); | 1591 | obj_priv = to_intel_bo(intel_fb->obj); |
1606 | i915_gem_object_unpin(intel_fb->obj); | 1592 | i915_gem_object_unpin(intel_fb->obj); |
1607 | } | 1593 | } |
1608 | intel_increase_pllclock(crtc, true); | ||
1609 | 1594 | ||
1610 | mutex_unlock(&dev->struct_mutex); | 1595 | mutex_unlock(&dev->struct_mutex); |
1611 | 1596 | ||
@@ -1627,54 +1612,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1627 | return 0; | 1612 | return 0; |
1628 | } | 1613 | } |
1629 | 1614 | ||
1630 | /* Disable the VGA plane that we never use */ | ||
1631 | static void i915_disable_vga (struct drm_device *dev) | ||
1632 | { | ||
1633 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1634 | u8 sr1; | ||
1635 | u32 vga_reg; | ||
1636 | |||
1637 | if (HAS_PCH_SPLIT(dev)) | ||
1638 | vga_reg = CPU_VGACNTRL; | ||
1639 | else | ||
1640 | vga_reg = VGACNTRL; | ||
1641 | |||
1642 | if (I915_READ(vga_reg) & VGA_DISP_DISABLE) | ||
1643 | return; | ||
1644 | |||
1645 | I915_WRITE8(VGA_SR_INDEX, 1); | ||
1646 | sr1 = I915_READ8(VGA_SR_DATA); | ||
1647 | I915_WRITE8(VGA_SR_DATA, sr1 | (1 << 5)); | ||
1648 | udelay(100); | ||
1649 | |||
1650 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); | ||
1651 | } | ||
1652 | |||
1653 | static void ironlake_disable_pll_edp (struct drm_crtc *crtc) | ||
1654 | { | ||
1655 | struct drm_device *dev = crtc->dev; | ||
1656 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1657 | u32 dpa_ctl; | ||
1658 | |||
1659 | DRM_DEBUG_KMS("\n"); | ||
1660 | dpa_ctl = I915_READ(DP_A); | ||
1661 | dpa_ctl &= ~DP_PLL_ENABLE; | ||
1662 | I915_WRITE(DP_A, dpa_ctl); | ||
1663 | } | ||
1664 | |||
1665 | static void ironlake_enable_pll_edp (struct drm_crtc *crtc) | ||
1666 | { | ||
1667 | struct drm_device *dev = crtc->dev; | ||
1668 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1669 | u32 dpa_ctl; | ||
1670 | |||
1671 | dpa_ctl = I915_READ(DP_A); | ||
1672 | dpa_ctl |= DP_PLL_ENABLE; | ||
1673 | I915_WRITE(DP_A, dpa_ctl); | ||
1674 | udelay(200); | ||
1675 | } | ||
1676 | |||
1677 | |||
1678 | static void ironlake_set_pll_edp (struct drm_crtc *crtc, int clock) | 1615 | static void ironlake_set_pll_edp (struct drm_crtc *crtc, int clock) |
1679 | { | 1616 | { |
1680 | struct drm_device *dev = crtc->dev; | 1617 | struct drm_device *dev = crtc->dev; |
@@ -1928,9 +1865,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1928 | int fdi_tx_reg = (pipe == 0) ? FDI_TXA_CTL : FDI_TXB_CTL; | 1865 | int fdi_tx_reg = (pipe == 0) ? FDI_TXA_CTL : FDI_TXB_CTL; |
1929 | int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL; | 1866 | int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL; |
1930 | int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF; | 1867 | int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF; |
1931 | int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1; | ||
1932 | int pf_win_size = (pipe == 0) ? PFA_WIN_SZ : PFB_WIN_SZ; | ||
1933 | int pf_win_pos = (pipe == 0) ? PFA_WIN_POS : PFB_WIN_POS; | ||
1934 | int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; | 1868 | int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; |
1935 | int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; | 1869 | int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; |
1936 | int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; | 1870 | int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; |
@@ -1945,7 +1879,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1945 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; | 1879 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; |
1946 | int trans_dpll_sel = (pipe == 0) ? 0 : 1; | 1880 | int trans_dpll_sel = (pipe == 0) ? 0 : 1; |
1947 | u32 temp; | 1881 | u32 temp; |
1948 | int n; | ||
1949 | u32 pipe_bpc; | 1882 | u32 pipe_bpc; |
1950 | 1883 | ||
1951 | temp = I915_READ(pipeconf_reg); | 1884 | temp = I915_READ(pipeconf_reg); |
@@ -1958,7 +1891,7 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1958 | case DRM_MODE_DPMS_ON: | 1891 | case DRM_MODE_DPMS_ON: |
1959 | case DRM_MODE_DPMS_STANDBY: | 1892 | case DRM_MODE_DPMS_STANDBY: |
1960 | case DRM_MODE_DPMS_SUSPEND: | 1893 | case DRM_MODE_DPMS_SUSPEND: |
1961 | DRM_DEBUG_KMS("crtc %d dpms on\n", pipe); | 1894 | DRM_DEBUG_KMS("crtc %d/%d dpms on\n", pipe, plane); |
1962 | 1895 | ||
1963 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | 1896 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
1964 | temp = I915_READ(PCH_LVDS); | 1897 | temp = I915_READ(PCH_LVDS); |
@@ -1968,10 +1901,7 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1968 | } | 1901 | } |
1969 | } | 1902 | } |
1970 | 1903 | ||
1971 | if (HAS_eDP) { | 1904 | if (!HAS_eDP) { |
1972 | /* enable eDP PLL */ | ||
1973 | ironlake_enable_pll_edp(crtc); | ||
1974 | } else { | ||
1975 | 1905 | ||
1976 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ | 1906 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ |
1977 | temp = I915_READ(fdi_rx_reg); | 1907 | temp = I915_READ(fdi_rx_reg); |
@@ -2003,17 +1933,19 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2003 | } | 1933 | } |
2004 | 1934 | ||
2005 | /* Enable panel fitting for LVDS */ | 1935 | /* Enable panel fitting for LVDS */ |
2006 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) | 1936 | if (dev_priv->pch_pf_size && |
2007 | || HAS_eDP || intel_pch_has_edp(crtc)) { | 1937 | (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) |
2008 | temp = I915_READ(pf_ctl_reg); | 1938 | || HAS_eDP || intel_pch_has_edp(crtc))) { |
2009 | I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); | 1939 | /* Force use of hard-coded filter coefficients |
2010 | 1940 | * as some pre-programmed values are broken, | |
2011 | /* currently full aspect */ | 1941 | * e.g. x201. |
2012 | I915_WRITE(pf_win_pos, 0); | 1942 | */ |
2013 | 1943 | I915_WRITE(pipe ? PFB_CTL_1 : PFA_CTL_1, | |
2014 | I915_WRITE(pf_win_size, | 1944 | PF_ENABLE | PF_FILTER_MED_3x3); |
2015 | (dev_priv->panel_fixed_mode->hdisplay << 16) | | 1945 | I915_WRITE(pipe ? PFB_WIN_POS : PFA_WIN_POS, |
2016 | (dev_priv->panel_fixed_mode->vdisplay)); | 1946 | dev_priv->pch_pf_pos); |
1947 | I915_WRITE(pipe ? PFB_WIN_SZ : PFA_WIN_SZ, | ||
1948 | dev_priv->pch_pf_size); | ||
2017 | } | 1949 | } |
2018 | 1950 | ||
2019 | /* Enable CPU pipe */ | 1951 | /* Enable CPU pipe */ |
@@ -2097,9 +2029,10 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2097 | int reg; | 2029 | int reg; |
2098 | 2030 | ||
2099 | reg = I915_READ(trans_dp_ctl); | 2031 | reg = I915_READ(trans_dp_ctl); |
2100 | reg &= ~TRANS_DP_PORT_SEL_MASK; | 2032 | reg &= ~(TRANS_DP_PORT_SEL_MASK | |
2101 | reg = TRANS_DP_OUTPUT_ENABLE | | 2033 | TRANS_DP_SYNC_MASK); |
2102 | TRANS_DP_ENH_FRAMING; | 2034 | reg |= (TRANS_DP_OUTPUT_ENABLE | |
2035 | TRANS_DP_ENH_FRAMING); | ||
2103 | 2036 | ||
2104 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) | 2037 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) |
2105 | reg |= TRANS_DP_HSYNC_ACTIVE_HIGH; | 2038 | reg |= TRANS_DP_HSYNC_ACTIVE_HIGH; |
@@ -2137,18 +2070,17 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2137 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); | 2070 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); |
2138 | I915_READ(transconf_reg); | 2071 | I915_READ(transconf_reg); |
2139 | 2072 | ||
2140 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0) | 2073 | if (wait_for(I915_READ(transconf_reg) & TRANS_STATE_ENABLE, 100, 1)) |
2141 | ; | 2074 | DRM_ERROR("failed to enable transcoder\n"); |
2142 | |||
2143 | } | 2075 | } |
2144 | 2076 | ||
2145 | intel_crtc_load_lut(crtc); | 2077 | intel_crtc_load_lut(crtc); |
2146 | 2078 | ||
2147 | intel_update_fbc(crtc, &crtc->mode); | 2079 | intel_update_fbc(crtc, &crtc->mode); |
2080 | break; | ||
2148 | 2081 | ||
2149 | break; | ||
2150 | case DRM_MODE_DPMS_OFF: | 2082 | case DRM_MODE_DPMS_OFF: |
2151 | DRM_DEBUG_KMS("crtc %d dpms off\n", pipe); | 2083 | DRM_DEBUG_KMS("crtc %d/%d dpms off\n", pipe, plane); |
2152 | 2084 | ||
2153 | drm_vblank_off(dev, pipe); | 2085 | drm_vblank_off(dev, pipe); |
2154 | /* Disable display plane */ | 2086 | /* Disable display plane */ |
@@ -2164,40 +2096,22 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2164 | dev_priv->display.disable_fbc) | 2096 | dev_priv->display.disable_fbc) |
2165 | dev_priv->display.disable_fbc(dev); | 2097 | dev_priv->display.disable_fbc(dev); |
2166 | 2098 | ||
2167 | i915_disable_vga(dev); | ||
2168 | |||
2169 | /* disable cpu pipe, disable after all planes disabled */ | 2099 | /* disable cpu pipe, disable after all planes disabled */ |
2170 | temp = I915_READ(pipeconf_reg); | 2100 | temp = I915_READ(pipeconf_reg); |
2171 | if ((temp & PIPEACONF_ENABLE) != 0) { | 2101 | if ((temp & PIPEACONF_ENABLE) != 0) { |
2172 | I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); | 2102 | I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); |
2173 | I915_READ(pipeconf_reg); | 2103 | |
2174 | n = 0; | ||
2175 | /* wait for cpu pipe off, pipe state */ | 2104 | /* wait for cpu pipe off, pipe state */ |
2176 | while ((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) != 0) { | 2105 | if (wait_for((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) == 0, 50, 1)) |
2177 | n++; | 2106 | DRM_ERROR("failed to turn off cpu pipe\n"); |
2178 | if (n < 60) { | ||
2179 | udelay(500); | ||
2180 | continue; | ||
2181 | } else { | ||
2182 | DRM_DEBUG_KMS("pipe %d off delay\n", | ||
2183 | pipe); | ||
2184 | break; | ||
2185 | } | ||
2186 | } | ||
2187 | } else | 2107 | } else |
2188 | DRM_DEBUG_KMS("crtc %d is disabled\n", pipe); | 2108 | DRM_DEBUG_KMS("crtc %d is disabled\n", pipe); |
2189 | 2109 | ||
2190 | udelay(100); | 2110 | udelay(100); |
2191 | 2111 | ||
2192 | /* Disable PF */ | 2112 | /* Disable PF */ |
2193 | temp = I915_READ(pf_ctl_reg); | 2113 | I915_WRITE(pipe ? PFB_CTL_1 : PFA_CTL_1, 0); |
2194 | if ((temp & PF_ENABLE) != 0) { | 2114 | I915_WRITE(pipe ? PFB_WIN_SZ : PFA_WIN_SZ, 0); |
2195 | I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); | ||
2196 | I915_READ(pf_ctl_reg); | ||
2197 | } | ||
2198 | I915_WRITE(pf_win_size, 0); | ||
2199 | POSTING_READ(pf_win_size); | ||
2200 | |||
2201 | 2115 | ||
2202 | /* disable CPU FDI tx and PCH FDI rx */ | 2116 | /* disable CPU FDI tx and PCH FDI rx */ |
2203 | temp = I915_READ(fdi_tx_reg); | 2117 | temp = I915_READ(fdi_tx_reg); |
@@ -2244,20 +2158,10 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2244 | temp = I915_READ(transconf_reg); | 2158 | temp = I915_READ(transconf_reg); |
2245 | if ((temp & TRANS_ENABLE) != 0) { | 2159 | if ((temp & TRANS_ENABLE) != 0) { |
2246 | I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE); | 2160 | I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE); |
2247 | I915_READ(transconf_reg); | 2161 | |
2248 | n = 0; | ||
2249 | /* wait for PCH transcoder off, transcoder state */ | 2162 | /* wait for PCH transcoder off, transcoder state */ |
2250 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) != 0) { | 2163 | if (wait_for((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0, 50, 1)) |
2251 | n++; | 2164 | DRM_ERROR("failed to disable transcoder\n"); |
2252 | if (n < 60) { | ||
2253 | udelay(500); | ||
2254 | continue; | ||
2255 | } else { | ||
2256 | DRM_DEBUG_KMS("transcoder %d off " | ||
2257 | "delay\n", pipe); | ||
2258 | break; | ||
2259 | } | ||
2260 | } | ||
2261 | } | 2165 | } |
2262 | 2166 | ||
2263 | temp = I915_READ(transconf_reg); | 2167 | temp = I915_READ(transconf_reg); |
@@ -2294,10 +2198,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2294 | I915_WRITE(pch_dpll_reg, temp & ~DPLL_VCO_ENABLE); | 2198 | I915_WRITE(pch_dpll_reg, temp & ~DPLL_VCO_ENABLE); |
2295 | I915_READ(pch_dpll_reg); | 2199 | I915_READ(pch_dpll_reg); |
2296 | 2200 | ||
2297 | if (HAS_eDP) { | ||
2298 | ironlake_disable_pll_edp(crtc); | ||
2299 | } | ||
2300 | |||
2301 | /* Switch from PCDclk to Rawclk */ | 2201 | /* Switch from PCDclk to Rawclk */ |
2302 | temp = I915_READ(fdi_rx_reg); | 2202 | temp = I915_READ(fdi_rx_reg); |
2303 | temp &= ~FDI_SEL_PCDCLK; | 2203 | temp &= ~FDI_SEL_PCDCLK; |
@@ -2372,8 +2272,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2372 | case DRM_MODE_DPMS_ON: | 2272 | case DRM_MODE_DPMS_ON: |
2373 | case DRM_MODE_DPMS_STANDBY: | 2273 | case DRM_MODE_DPMS_STANDBY: |
2374 | case DRM_MODE_DPMS_SUSPEND: | 2274 | case DRM_MODE_DPMS_SUSPEND: |
2375 | intel_update_watermarks(dev); | ||
2376 | |||
2377 | /* Enable the DPLL */ | 2275 | /* Enable the DPLL */ |
2378 | temp = I915_READ(dpll_reg); | 2276 | temp = I915_READ(dpll_reg); |
2379 | if ((temp & DPLL_VCO_ENABLE) == 0) { | 2277 | if ((temp & DPLL_VCO_ENABLE) == 0) { |
@@ -2413,8 +2311,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2413 | intel_crtc_dpms_overlay(intel_crtc, true); | 2311 | intel_crtc_dpms_overlay(intel_crtc, true); |
2414 | break; | 2312 | break; |
2415 | case DRM_MODE_DPMS_OFF: | 2313 | case DRM_MODE_DPMS_OFF: |
2416 | intel_update_watermarks(dev); | ||
2417 | |||
2418 | /* Give the overlay scaler a chance to disable if it's on this pipe */ | 2314 | /* Give the overlay scaler a chance to disable if it's on this pipe */ |
2419 | intel_crtc_dpms_overlay(intel_crtc, false); | 2315 | intel_crtc_dpms_overlay(intel_crtc, false); |
2420 | drm_vblank_off(dev, pipe); | 2316 | drm_vblank_off(dev, pipe); |
@@ -2423,9 +2319,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2423 | dev_priv->display.disable_fbc) | 2319 | dev_priv->display.disable_fbc) |
2424 | dev_priv->display.disable_fbc(dev); | 2320 | dev_priv->display.disable_fbc(dev); |
2425 | 2321 | ||
2426 | /* Disable the VGA plane that we never use */ | ||
2427 | i915_disable_vga(dev); | ||
2428 | |||
2429 | /* Disable display plane */ | 2322 | /* Disable display plane */ |
2430 | temp = I915_READ(dspcntr_reg); | 2323 | temp = I915_READ(dspcntr_reg); |
2431 | if ((temp & DISPLAY_PLANE_ENABLE) != 0) { | 2324 | if ((temp & DISPLAY_PLANE_ENABLE) != 0) { |
@@ -2435,10 +2328,8 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2435 | I915_READ(dspbase_reg); | 2328 | I915_READ(dspbase_reg); |
2436 | } | 2329 | } |
2437 | 2330 | ||
2438 | if (!IS_I9XX(dev)) { | 2331 | /* Wait for vblank for the disable to take effect */ |
2439 | /* Wait for vblank for the disable to take effect */ | 2332 | intel_wait_for_vblank_off(dev, pipe); |
2440 | intel_wait_for_vblank(dev); | ||
2441 | } | ||
2442 | 2333 | ||
2443 | /* Don't disable pipe A or pipe A PLLs if needed */ | 2334 | /* Don't disable pipe A or pipe A PLLs if needed */ |
2444 | if (pipeconf_reg == PIPEACONF && | 2335 | if (pipeconf_reg == PIPEACONF && |
@@ -2453,7 +2344,7 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2453 | } | 2344 | } |
2454 | 2345 | ||
2455 | /* Wait for vblank for the disable to take effect. */ | 2346 | /* Wait for vblank for the disable to take effect. */ |
2456 | intel_wait_for_vblank(dev); | 2347 | intel_wait_for_vblank_off(dev, pipe); |
2457 | 2348 | ||
2458 | temp = I915_READ(dpll_reg); | 2349 | temp = I915_READ(dpll_reg); |
2459 | if ((temp & DPLL_VCO_ENABLE) != 0) { | 2350 | if ((temp & DPLL_VCO_ENABLE) != 0) { |
@@ -2469,9 +2360,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2469 | 2360 | ||
2470 | /** | 2361 | /** |
2471 | * Sets the power management mode of the pipe and plane. | 2362 | * Sets the power management mode of the pipe and plane. |
2472 | * | ||
2473 | * This code should probably grow support for turning the cursor off and back | ||
2474 | * on appropriately at the same time as we're turning the pipe off/on. | ||
2475 | */ | 2363 | */ |
2476 | static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) | 2364 | static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) |
2477 | { | 2365 | { |
@@ -2482,9 +2370,29 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2482 | int pipe = intel_crtc->pipe; | 2370 | int pipe = intel_crtc->pipe; |
2483 | bool enabled; | 2371 | bool enabled; |
2484 | 2372 | ||
2485 | dev_priv->display.dpms(crtc, mode); | 2373 | if (intel_crtc->dpms_mode == mode) |
2374 | return; | ||
2486 | 2375 | ||
2487 | intel_crtc->dpms_mode = mode; | 2376 | intel_crtc->dpms_mode = mode; |
2377 | intel_crtc->cursor_on = mode == DRM_MODE_DPMS_ON; | ||
2378 | |||
2379 | /* When switching on the display, ensure that SR is disabled | ||
2380 | * with multiple pipes prior to enabling to new pipe. | ||
2381 | * | ||
2382 | * When switching off the display, make sure the cursor is | ||
2383 | * properly hidden prior to disabling the pipe. | ||
2384 | */ | ||
2385 | if (mode == DRM_MODE_DPMS_ON) | ||
2386 | intel_update_watermarks(dev); | ||
2387 | else | ||
2388 | intel_crtc_update_cursor(crtc); | ||
2389 | |||
2390 | dev_priv->display.dpms(crtc, mode); | ||
2391 | |||
2392 | if (mode == DRM_MODE_DPMS_ON) | ||
2393 | intel_crtc_update_cursor(crtc); | ||
2394 | else | ||
2395 | intel_update_watermarks(dev); | ||
2488 | 2396 | ||
2489 | if (!dev->primary->master) | 2397 | if (!dev->primary->master) |
2490 | return; | 2398 | return; |
@@ -2536,6 +2444,20 @@ void intel_encoder_commit (struct drm_encoder *encoder) | |||
2536 | encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); | 2444 | encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); |
2537 | } | 2445 | } |
2538 | 2446 | ||
2447 | void intel_encoder_destroy(struct drm_encoder *encoder) | ||
2448 | { | ||
2449 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
2450 | |||
2451 | if (intel_encoder->ddc_bus) | ||
2452 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
2453 | |||
2454 | if (intel_encoder->i2c_bus) | ||
2455 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
2456 | |||
2457 | drm_encoder_cleanup(encoder); | ||
2458 | kfree(intel_encoder); | ||
2459 | } | ||
2460 | |||
2539 | static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, | 2461 | static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, |
2540 | struct drm_display_mode *mode, | 2462 | struct drm_display_mode *mode, |
2541 | struct drm_display_mode *adjusted_mode) | 2463 | struct drm_display_mode *adjusted_mode) |
@@ -2867,7 +2789,7 @@ struct cxsr_latency { | |||
2867 | unsigned long cursor_hpll_disable; | 2789 | unsigned long cursor_hpll_disable; |
2868 | }; | 2790 | }; |
2869 | 2791 | ||
2870 | static struct cxsr_latency cxsr_latency_table[] = { | 2792 | static const struct cxsr_latency cxsr_latency_table[] = { |
2871 | {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ | 2793 | {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ |
2872 | {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ | 2794 | {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ |
2873 | {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ | 2795 | {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ |
@@ -2905,11 +2827,13 @@ static struct cxsr_latency cxsr_latency_table[] = { | |||
2905 | {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ | 2827 | {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ |
2906 | }; | 2828 | }; |
2907 | 2829 | ||
2908 | static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3, | 2830 | static const struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, |
2909 | int fsb, int mem) | 2831 | int is_ddr3, |
2832 | int fsb, | ||
2833 | int mem) | ||
2910 | { | 2834 | { |
2835 | const struct cxsr_latency *latency; | ||
2911 | int i; | 2836 | int i; |
2912 | struct cxsr_latency *latency; | ||
2913 | 2837 | ||
2914 | if (fsb == 0 || mem == 0) | 2838 | if (fsb == 0 || mem == 0) |
2915 | return NULL; | 2839 | return NULL; |
@@ -2930,13 +2854,9 @@ static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3, | |||
2930 | static void pineview_disable_cxsr(struct drm_device *dev) | 2854 | static void pineview_disable_cxsr(struct drm_device *dev) |
2931 | { | 2855 | { |
2932 | struct drm_i915_private *dev_priv = dev->dev_private; | 2856 | struct drm_i915_private *dev_priv = dev->dev_private; |
2933 | u32 reg; | ||
2934 | 2857 | ||
2935 | /* deactivate cxsr */ | 2858 | /* deactivate cxsr */ |
2936 | reg = I915_READ(DSPFW3); | 2859 | I915_WRITE(DSPFW3, I915_READ(DSPFW3) & ~PINEVIEW_SELF_REFRESH_EN); |
2937 | reg &= ~(PINEVIEW_SELF_REFRESH_EN); | ||
2938 | I915_WRITE(DSPFW3, reg); | ||
2939 | DRM_INFO("Big FIFO is disabled\n"); | ||
2940 | } | 2860 | } |
2941 | 2861 | ||
2942 | /* | 2862 | /* |
@@ -3024,12 +2944,12 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, | |||
3024 | int pixel_size) | 2944 | int pixel_size) |
3025 | { | 2945 | { |
3026 | struct drm_i915_private *dev_priv = dev->dev_private; | 2946 | struct drm_i915_private *dev_priv = dev->dev_private; |
2947 | const struct cxsr_latency *latency; | ||
3027 | u32 reg; | 2948 | u32 reg; |
3028 | unsigned long wm; | 2949 | unsigned long wm; |
3029 | struct cxsr_latency *latency; | ||
3030 | int sr_clock; | 2950 | int sr_clock; |
3031 | 2951 | ||
3032 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, | 2952 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, |
3033 | dev_priv->fsb_freq, dev_priv->mem_freq); | 2953 | dev_priv->fsb_freq, dev_priv->mem_freq); |
3034 | if (!latency) { | 2954 | if (!latency) { |
3035 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); | 2955 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); |
@@ -3075,9 +2995,8 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, | |||
3075 | DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg); | 2995 | DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg); |
3076 | 2996 | ||
3077 | /* activate cxsr */ | 2997 | /* activate cxsr */ |
3078 | reg = I915_READ(DSPFW3); | 2998 | I915_WRITE(DSPFW3, |
3079 | reg |= PINEVIEW_SELF_REFRESH_EN; | 2999 | I915_READ(DSPFW3) | PINEVIEW_SELF_REFRESH_EN); |
3080 | I915_WRITE(DSPFW3, reg); | ||
3081 | DRM_DEBUG_KMS("Self-refresh is enabled\n"); | 3000 | DRM_DEBUG_KMS("Self-refresh is enabled\n"); |
3082 | } else { | 3001 | } else { |
3083 | pineview_disable_cxsr(dev); | 3002 | pineview_disable_cxsr(dev); |
@@ -3354,12 +3273,11 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, | |||
3354 | int line_count; | 3273 | int line_count; |
3355 | int planea_htotal = 0, planeb_htotal = 0; | 3274 | int planea_htotal = 0, planeb_htotal = 0; |
3356 | struct drm_crtc *crtc; | 3275 | struct drm_crtc *crtc; |
3357 | struct intel_crtc *intel_crtc; | ||
3358 | 3276 | ||
3359 | /* Need htotal for all active display plane */ | 3277 | /* Need htotal for all active display plane */ |
3360 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 3278 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
3361 | intel_crtc = to_intel_crtc(crtc); | 3279 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3362 | if (crtc->enabled) { | 3280 | if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) { |
3363 | if (intel_crtc->plane == 0) | 3281 | if (intel_crtc->plane == 0) |
3364 | planea_htotal = crtc->mode.htotal; | 3282 | planea_htotal = crtc->mode.htotal; |
3365 | else | 3283 | else |
@@ -3519,7 +3437,6 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
3519 | { | 3437 | { |
3520 | struct drm_i915_private *dev_priv = dev->dev_private; | 3438 | struct drm_i915_private *dev_priv = dev->dev_private; |
3521 | struct drm_crtc *crtc; | 3439 | struct drm_crtc *crtc; |
3522 | struct intel_crtc *intel_crtc; | ||
3523 | int sr_hdisplay = 0; | 3440 | int sr_hdisplay = 0; |
3524 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; | 3441 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; |
3525 | int enabled = 0, pixel_size = 0; | 3442 | int enabled = 0, pixel_size = 0; |
@@ -3530,8 +3447,8 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
3530 | 3447 | ||
3531 | /* Get the clock config from both planes */ | 3448 | /* Get the clock config from both planes */ |
3532 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 3449 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
3533 | intel_crtc = to_intel_crtc(crtc); | 3450 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3534 | if (crtc->enabled) { | 3451 | if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) { |
3535 | enabled++; | 3452 | enabled++; |
3536 | if (intel_crtc->plane == 0) { | 3453 | if (intel_crtc->plane == 0) { |
3537 | DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n", | 3454 | DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n", |
@@ -3589,10 +3506,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3589 | u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf; | 3506 | u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf; |
3590 | bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; | 3507 | bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; |
3591 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; | 3508 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; |
3592 | bool is_edp = false; | 3509 | struct intel_encoder *has_edp_encoder = NULL; |
3593 | struct drm_mode_config *mode_config = &dev->mode_config; | 3510 | struct drm_mode_config *mode_config = &dev->mode_config; |
3594 | struct drm_encoder *encoder; | 3511 | struct drm_encoder *encoder; |
3595 | struct intel_encoder *intel_encoder = NULL; | ||
3596 | const intel_limit_t *limit; | 3512 | const intel_limit_t *limit; |
3597 | int ret; | 3513 | int ret; |
3598 | struct fdi_m_n m_n = {0}; | 3514 | struct fdi_m_n m_n = {0}; |
@@ -3613,12 +3529,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3613 | drm_vblank_pre_modeset(dev, pipe); | 3529 | drm_vblank_pre_modeset(dev, pipe); |
3614 | 3530 | ||
3615 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | 3531 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
3532 | struct intel_encoder *intel_encoder; | ||
3616 | 3533 | ||
3617 | if (!encoder || encoder->crtc != crtc) | 3534 | if (encoder->crtc != crtc) |
3618 | continue; | 3535 | continue; |
3619 | 3536 | ||
3620 | intel_encoder = enc_to_intel_encoder(encoder); | 3537 | intel_encoder = enc_to_intel_encoder(encoder); |
3621 | |||
3622 | switch (intel_encoder->type) { | 3538 | switch (intel_encoder->type) { |
3623 | case INTEL_OUTPUT_LVDS: | 3539 | case INTEL_OUTPUT_LVDS: |
3624 | is_lvds = true; | 3540 | is_lvds = true; |
@@ -3642,7 +3558,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3642 | is_dp = true; | 3558 | is_dp = true; |
3643 | break; | 3559 | break; |
3644 | case INTEL_OUTPUT_EDP: | 3560 | case INTEL_OUTPUT_EDP: |
3645 | is_edp = true; | 3561 | has_edp_encoder = intel_encoder; |
3646 | break; | 3562 | break; |
3647 | } | 3563 | } |
3648 | 3564 | ||
@@ -3720,10 +3636,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3720 | int lane = 0, link_bw, bpp; | 3636 | int lane = 0, link_bw, bpp; |
3721 | /* eDP doesn't require FDI link, so just set DP M/N | 3637 | /* eDP doesn't require FDI link, so just set DP M/N |
3722 | according to current link config */ | 3638 | according to current link config */ |
3723 | if (is_edp) { | 3639 | if (has_edp_encoder) { |
3724 | target_clock = mode->clock; | 3640 | target_clock = mode->clock; |
3725 | intel_edp_link_config(intel_encoder, | 3641 | intel_edp_link_config(has_edp_encoder, |
3726 | &lane, &link_bw); | 3642 | &lane, &link_bw); |
3727 | } else { | 3643 | } else { |
3728 | /* DP over FDI requires target mode clock | 3644 | /* DP over FDI requires target mode clock |
3729 | instead of link clock */ | 3645 | instead of link clock */ |
@@ -3744,7 +3660,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3744 | temp |= PIPE_8BPC; | 3660 | temp |= PIPE_8BPC; |
3745 | else | 3661 | else |
3746 | temp |= PIPE_6BPC; | 3662 | temp |= PIPE_6BPC; |
3747 | } else if (is_edp || (is_dp && intel_pch_has_edp(crtc))) { | 3663 | } else if (has_edp_encoder || (is_dp && intel_pch_has_edp(crtc))) { |
3748 | switch (dev_priv->edp_bpp/3) { | 3664 | switch (dev_priv->edp_bpp/3) { |
3749 | case 8: | 3665 | case 8: |
3750 | temp |= PIPE_8BPC; | 3666 | temp |= PIPE_8BPC; |
@@ -3817,7 +3733,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3817 | 3733 | ||
3818 | udelay(200); | 3734 | udelay(200); |
3819 | 3735 | ||
3820 | if (is_edp) { | 3736 | if (has_edp_encoder) { |
3821 | if (dev_priv->lvds_use_ssc) { | 3737 | if (dev_priv->lvds_use_ssc) { |
3822 | temp |= DREF_SSC1_ENABLE; | 3738 | temp |= DREF_SSC1_ENABLE; |
3823 | I915_WRITE(PCH_DREF_CONTROL, temp); | 3739 | I915_WRITE(PCH_DREF_CONTROL, temp); |
@@ -3966,9 +3882,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3966 | dpll_reg = pch_dpll_reg; | 3882 | dpll_reg = pch_dpll_reg; |
3967 | } | 3883 | } |
3968 | 3884 | ||
3969 | if (is_edp) { | 3885 | if (!has_edp_encoder) { |
3970 | ironlake_disable_pll_edp(crtc); | ||
3971 | } else if ((dpll & DPLL_VCO_ENABLE)) { | ||
3972 | I915_WRITE(fp_reg, fp); | 3886 | I915_WRITE(fp_reg, fp); |
3973 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); | 3887 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); |
3974 | I915_READ(dpll_reg); | 3888 | I915_READ(dpll_reg); |
@@ -4063,7 +3977,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
4063 | } | 3977 | } |
4064 | } | 3978 | } |
4065 | 3979 | ||
4066 | if (!is_edp) { | 3980 | if (!has_edp_encoder) { |
4067 | I915_WRITE(fp_reg, fp); | 3981 | I915_WRITE(fp_reg, fp); |
4068 | I915_WRITE(dpll_reg, dpll); | 3982 | I915_WRITE(dpll_reg, dpll); |
4069 | I915_READ(dpll_reg); | 3983 | I915_READ(dpll_reg); |
@@ -4142,7 +4056,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
4142 | I915_WRITE(link_m1_reg, m_n.link_m); | 4056 | I915_WRITE(link_m1_reg, m_n.link_m); |
4143 | I915_WRITE(link_n1_reg, m_n.link_n); | 4057 | I915_WRITE(link_n1_reg, m_n.link_n); |
4144 | 4058 | ||
4145 | if (is_edp) { | 4059 | if (has_edp_encoder) { |
4146 | ironlake_set_pll_edp(crtc, adjusted_mode->clock); | 4060 | ironlake_set_pll_edp(crtc, adjusted_mode->clock); |
4147 | } else { | 4061 | } else { |
4148 | /* enable FDI RX PLL too */ | 4062 | /* enable FDI RX PLL too */ |
@@ -4167,7 +4081,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
4167 | I915_WRITE(pipeconf_reg, pipeconf); | 4081 | I915_WRITE(pipeconf_reg, pipeconf); |
4168 | I915_READ(pipeconf_reg); | 4082 | I915_READ(pipeconf_reg); |
4169 | 4083 | ||
4170 | intel_wait_for_vblank(dev); | 4084 | intel_wait_for_vblank(dev, pipe); |
4171 | 4085 | ||
4172 | if (IS_IRONLAKE(dev)) { | 4086 | if (IS_IRONLAKE(dev)) { |
4173 | /* enable address swizzle for tiling buffer */ | 4087 | /* enable address swizzle for tiling buffer */ |
@@ -4180,9 +4094,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
4180 | /* Flush the plane changes */ | 4094 | /* Flush the plane changes */ |
4181 | ret = intel_pipe_set_base(crtc, x, y, old_fb); | 4095 | ret = intel_pipe_set_base(crtc, x, y, old_fb); |
4182 | 4096 | ||
4183 | if ((IS_I965G(dev) || plane == 0)) | ||
4184 | intel_update_fbc(crtc, &crtc->mode); | ||
4185 | |||
4186 | intel_update_watermarks(dev); | 4097 | intel_update_watermarks(dev); |
4187 | 4098 | ||
4188 | drm_vblank_post_modeset(dev, pipe); | 4099 | drm_vblank_post_modeset(dev, pipe); |
@@ -4216,6 +4127,62 @@ void intel_crtc_load_lut(struct drm_crtc *crtc) | |||
4216 | } | 4127 | } |
4217 | } | 4128 | } |
4218 | 4129 | ||
4130 | static void i845_update_cursor(struct drm_crtc *crtc, u32 base) | ||
4131 | { | ||
4132 | struct drm_device *dev = crtc->dev; | ||
4133 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4134 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
4135 | bool visible = base != 0; | ||
4136 | u32 cntl; | ||
4137 | |||
4138 | if (intel_crtc->cursor_visible == visible) | ||
4139 | return; | ||
4140 | |||
4141 | cntl = I915_READ(CURACNTR); | ||
4142 | if (visible) { | ||
4143 | /* On these chipsets we can only modify the base whilst | ||
4144 | * the cursor is disabled. | ||
4145 | */ | ||
4146 | I915_WRITE(CURABASE, base); | ||
4147 | |||
4148 | cntl &= ~(CURSOR_FORMAT_MASK); | ||
4149 | /* XXX width must be 64, stride 256 => 0x00 << 28 */ | ||
4150 | cntl |= CURSOR_ENABLE | | ||
4151 | CURSOR_GAMMA_ENABLE | | ||
4152 | CURSOR_FORMAT_ARGB; | ||
4153 | } else | ||
4154 | cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); | ||
4155 | I915_WRITE(CURACNTR, cntl); | ||
4156 | |||
4157 | intel_crtc->cursor_visible = visible; | ||
4158 | } | ||
4159 | |||
4160 | static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) | ||
4161 | { | ||
4162 | struct drm_device *dev = crtc->dev; | ||
4163 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4164 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
4165 | int pipe = intel_crtc->pipe; | ||
4166 | bool visible = base != 0; | ||
4167 | |||
4168 | if (intel_crtc->cursor_visible != visible) { | ||
4169 | uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR); | ||
4170 | if (base) { | ||
4171 | cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); | ||
4172 | cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; | ||
4173 | cntl |= pipe << 28; /* Connect to correct pipe */ | ||
4174 | } else { | ||
4175 | cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); | ||
4176 | cntl |= CURSOR_MODE_DISABLE; | ||
4177 | } | ||
4178 | I915_WRITE(pipe == 0 ? CURACNTR : CURBCNTR, cntl); | ||
4179 | |||
4180 | intel_crtc->cursor_visible = visible; | ||
4181 | } | ||
4182 | /* and commit changes on next vblank */ | ||
4183 | I915_WRITE(pipe == 0 ? CURABASE : CURBBASE, base); | ||
4184 | } | ||
4185 | |||
4219 | /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ | 4186 | /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ |
4220 | static void intel_crtc_update_cursor(struct drm_crtc *crtc) | 4187 | static void intel_crtc_update_cursor(struct drm_crtc *crtc) |
4221 | { | 4188 | { |
@@ -4225,12 +4192,12 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc) | |||
4225 | int pipe = intel_crtc->pipe; | 4192 | int pipe = intel_crtc->pipe; |
4226 | int x = intel_crtc->cursor_x; | 4193 | int x = intel_crtc->cursor_x; |
4227 | int y = intel_crtc->cursor_y; | 4194 | int y = intel_crtc->cursor_y; |
4228 | uint32_t base, pos; | 4195 | u32 base, pos; |
4229 | bool visible; | 4196 | bool visible; |
4230 | 4197 | ||
4231 | pos = 0; | 4198 | pos = 0; |
4232 | 4199 | ||
4233 | if (crtc->fb) { | 4200 | if (intel_crtc->cursor_on && crtc->fb) { |
4234 | base = intel_crtc->cursor_addr; | 4201 | base = intel_crtc->cursor_addr; |
4235 | if (x > (int) crtc->fb->width) | 4202 | if (x > (int) crtc->fb->width) |
4236 | base = 0; | 4203 | base = 0; |
@@ -4259,37 +4226,14 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc) | |||
4259 | pos |= y << CURSOR_Y_SHIFT; | 4226 | pos |= y << CURSOR_Y_SHIFT; |
4260 | 4227 | ||
4261 | visible = base != 0; | 4228 | visible = base != 0; |
4262 | if (!visible && !intel_crtc->cursor_visble) | 4229 | if (!visible && !intel_crtc->cursor_visible) |
4263 | return; | 4230 | return; |
4264 | 4231 | ||
4265 | I915_WRITE(pipe == 0 ? CURAPOS : CURBPOS, pos); | 4232 | I915_WRITE(pipe == 0 ? CURAPOS : CURBPOS, pos); |
4266 | if (intel_crtc->cursor_visble != visible) { | 4233 | if (IS_845G(dev) || IS_I865G(dev)) |
4267 | uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR); | 4234 | i845_update_cursor(crtc, base); |
4268 | if (base) { | 4235 | else |
4269 | /* Hooray for CUR*CNTR differences */ | 4236 | i9xx_update_cursor(crtc, base); |
4270 | if (IS_MOBILE(dev) || IS_I9XX(dev)) { | ||
4271 | cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); | ||
4272 | cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; | ||
4273 | cntl |= pipe << 28; /* Connect to correct pipe */ | ||
4274 | } else { | ||
4275 | cntl &= ~(CURSOR_FORMAT_MASK); | ||
4276 | cntl |= CURSOR_ENABLE; | ||
4277 | cntl |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE; | ||
4278 | } | ||
4279 | } else { | ||
4280 | if (IS_MOBILE(dev) || IS_I9XX(dev)) { | ||
4281 | cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); | ||
4282 | cntl |= CURSOR_MODE_DISABLE; | ||
4283 | } else { | ||
4284 | cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); | ||
4285 | } | ||
4286 | } | ||
4287 | I915_WRITE(pipe == 0 ? CURACNTR : CURBCNTR, cntl); | ||
4288 | |||
4289 | intel_crtc->cursor_visble = visible; | ||
4290 | } | ||
4291 | /* and commit changes on next vblank */ | ||
4292 | I915_WRITE(pipe == 0 ? CURABASE : CURBBASE, base); | ||
4293 | 4237 | ||
4294 | if (visible) | 4238 | if (visible) |
4295 | intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj); | 4239 | intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj); |
@@ -4354,8 +4298,10 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
4354 | 4298 | ||
4355 | addr = obj_priv->gtt_offset; | 4299 | addr = obj_priv->gtt_offset; |
4356 | } else { | 4300 | } else { |
4301 | int align = IS_I830(dev) ? 16 * 1024 : 256; | ||
4357 | ret = i915_gem_attach_phys_object(dev, bo, | 4302 | ret = i915_gem_attach_phys_object(dev, bo, |
4358 | (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); | 4303 | (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1, |
4304 | align); | ||
4359 | if (ret) { | 4305 | if (ret) { |
4360 | DRM_ERROR("failed to attach phys object\n"); | 4306 | DRM_ERROR("failed to attach phys object\n"); |
4361 | goto fail_locked; | 4307 | goto fail_locked; |
@@ -4544,7 +4490,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, | |||
4544 | encoder_funcs->commit(encoder); | 4490 | encoder_funcs->commit(encoder); |
4545 | } | 4491 | } |
4546 | /* let the connector get through one full cycle before testing */ | 4492 | /* let the connector get through one full cycle before testing */ |
4547 | intel_wait_for_vblank(dev); | 4493 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
4548 | 4494 | ||
4549 | return crtc; | 4495 | return crtc; |
4550 | } | 4496 | } |
@@ -4749,7 +4695,7 @@ static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule) | |||
4749 | dpll &= ~DISPLAY_RATE_SELECT_FPA1; | 4695 | dpll &= ~DISPLAY_RATE_SELECT_FPA1; |
4750 | I915_WRITE(dpll_reg, dpll); | 4696 | I915_WRITE(dpll_reg, dpll); |
4751 | dpll = I915_READ(dpll_reg); | 4697 | dpll = I915_READ(dpll_reg); |
4752 | intel_wait_for_vblank(dev); | 4698 | intel_wait_for_vblank(dev, pipe); |
4753 | dpll = I915_READ(dpll_reg); | 4699 | dpll = I915_READ(dpll_reg); |
4754 | if (dpll & DISPLAY_RATE_SELECT_FPA1) | 4700 | if (dpll & DISPLAY_RATE_SELECT_FPA1) |
4755 | DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); | 4701 | DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); |
@@ -4793,7 +4739,7 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc) | |||
4793 | dpll |= DISPLAY_RATE_SELECT_FPA1; | 4739 | dpll |= DISPLAY_RATE_SELECT_FPA1; |
4794 | I915_WRITE(dpll_reg, dpll); | 4740 | I915_WRITE(dpll_reg, dpll); |
4795 | dpll = I915_READ(dpll_reg); | 4741 | dpll = I915_READ(dpll_reg); |
4796 | intel_wait_for_vblank(dev); | 4742 | intel_wait_for_vblank(dev, pipe); |
4797 | dpll = I915_READ(dpll_reg); | 4743 | dpll = I915_READ(dpll_reg); |
4798 | if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) | 4744 | if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) |
4799 | DRM_DEBUG_DRIVER("failed to downclock LVDS!\n"); | 4745 | DRM_DEBUG_DRIVER("failed to downclock LVDS!\n"); |
@@ -4916,15 +4862,6 @@ static void intel_crtc_destroy(struct drm_crtc *crtc) | |||
4916 | kfree(intel_crtc); | 4862 | kfree(intel_crtc); |
4917 | } | 4863 | } |
4918 | 4864 | ||
4919 | struct intel_unpin_work { | ||
4920 | struct work_struct work; | ||
4921 | struct drm_device *dev; | ||
4922 | struct drm_gem_object *old_fb_obj; | ||
4923 | struct drm_gem_object *pending_flip_obj; | ||
4924 | struct drm_pending_vblank_event *event; | ||
4925 | int pending; | ||
4926 | }; | ||
4927 | |||
4928 | static void intel_unpin_work_fn(struct work_struct *__work) | 4865 | static void intel_unpin_work_fn(struct work_struct *__work) |
4929 | { | 4866 | { |
4930 | struct intel_unpin_work *work = | 4867 | struct intel_unpin_work *work = |
@@ -5012,7 +4949,8 @@ void intel_prepare_page_flip(struct drm_device *dev, int plane) | |||
5012 | 4949 | ||
5013 | spin_lock_irqsave(&dev->event_lock, flags); | 4950 | spin_lock_irqsave(&dev->event_lock, flags); |
5014 | if (intel_crtc->unpin_work) { | 4951 | if (intel_crtc->unpin_work) { |
5015 | intel_crtc->unpin_work->pending = 1; | 4952 | if ((++intel_crtc->unpin_work->pending) > 1) |
4953 | DRM_ERROR("Prepared flip multiple times\n"); | ||
5016 | } else { | 4954 | } else { |
5017 | DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n"); | 4955 | DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n"); |
5018 | } | 4956 | } |
@@ -5031,9 +4969,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5031 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 4969 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
5032 | struct intel_unpin_work *work; | 4970 | struct intel_unpin_work *work; |
5033 | unsigned long flags, offset; | 4971 | unsigned long flags, offset; |
5034 | int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC; | 4972 | int pipe = intel_crtc->pipe; |
5035 | int ret, pipesrc; | 4973 | u32 pf, pipesrc; |
5036 | u32 flip_mask; | 4974 | int ret; |
5037 | 4975 | ||
5038 | work = kzalloc(sizeof *work, GFP_KERNEL); | 4976 | work = kzalloc(sizeof *work, GFP_KERNEL); |
5039 | if (work == NULL) | 4977 | if (work == NULL) |
@@ -5082,34 +5020,73 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5082 | atomic_inc(&obj_priv->pending_flip); | 5020 | atomic_inc(&obj_priv->pending_flip); |
5083 | work->pending_flip_obj = obj; | 5021 | work->pending_flip_obj = obj; |
5084 | 5022 | ||
5085 | if (intel_crtc->plane) | 5023 | if (IS_GEN3(dev) || IS_GEN2(dev)) { |
5086 | flip_mask = I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; | 5024 | u32 flip_mask; |
5087 | else | ||
5088 | flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT; | ||
5089 | 5025 | ||
5090 | /* Wait for any previous flip to finish */ | 5026 | if (intel_crtc->plane) |
5091 | if (IS_GEN3(dev)) | 5027 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; |
5092 | while (I915_READ(ISR) & flip_mask) | 5028 | else |
5093 | ; | 5029 | flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; |
5030 | |||
5031 | BEGIN_LP_RING(2); | ||
5032 | OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); | ||
5033 | OUT_RING(0); | ||
5034 | ADVANCE_LP_RING(); | ||
5035 | } | ||
5036 | |||
5037 | work->enable_stall_check = true; | ||
5094 | 5038 | ||
5095 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ | 5039 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ |
5096 | offset = obj_priv->gtt_offset; | 5040 | offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8; |
5097 | offset += (crtc->y * fb->pitch) + (crtc->x * (fb->bits_per_pixel) / 8); | ||
5098 | 5041 | ||
5099 | BEGIN_LP_RING(4); | 5042 | BEGIN_LP_RING(4); |
5100 | if (IS_I965G(dev)) { | 5043 | switch(INTEL_INFO(dev)->gen) { |
5044 | case 2: | ||
5101 | OUT_RING(MI_DISPLAY_FLIP | | 5045 | OUT_RING(MI_DISPLAY_FLIP | |
5102 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 5046 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
5103 | OUT_RING(fb->pitch); | 5047 | OUT_RING(fb->pitch); |
5104 | OUT_RING(offset | obj_priv->tiling_mode); | 5048 | OUT_RING(obj_priv->gtt_offset + offset); |
5105 | pipesrc = I915_READ(pipesrc_reg); | 5049 | OUT_RING(MI_NOOP); |
5106 | OUT_RING(pipesrc & 0x0fff0fff); | 5050 | break; |
5107 | } else { | 5051 | |
5052 | case 3: | ||
5108 | OUT_RING(MI_DISPLAY_FLIP_I915 | | 5053 | OUT_RING(MI_DISPLAY_FLIP_I915 | |
5109 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 5054 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
5110 | OUT_RING(fb->pitch); | 5055 | OUT_RING(fb->pitch); |
5111 | OUT_RING(offset); | 5056 | OUT_RING(obj_priv->gtt_offset + offset); |
5112 | OUT_RING(MI_NOOP); | 5057 | OUT_RING(MI_NOOP); |
5058 | break; | ||
5059 | |||
5060 | case 4: | ||
5061 | case 5: | ||
5062 | /* i965+ uses the linear or tiled offsets from the | ||
5063 | * Display Registers (which do not change across a page-flip) | ||
5064 | * so we need only reprogram the base address. | ||
5065 | */ | ||
5066 | OUT_RING(MI_DISPLAY_FLIP | | ||
5067 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | ||
5068 | OUT_RING(fb->pitch); | ||
5069 | OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode); | ||
5070 | |||
5071 | /* XXX Enabling the panel-fitter across page-flip is so far | ||
5072 | * untested on non-native modes, so ignore it for now. | ||
5073 | * pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE; | ||
5074 | */ | ||
5075 | pf = 0; | ||
5076 | pipesrc = I915_READ(pipe == 0 ? PIPEASRC : PIPEBSRC) & 0x0fff0fff; | ||
5077 | OUT_RING(pf | pipesrc); | ||
5078 | break; | ||
5079 | |||
5080 | case 6: | ||
5081 | OUT_RING(MI_DISPLAY_FLIP | | ||
5082 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | ||
5083 | OUT_RING(fb->pitch | obj_priv->tiling_mode); | ||
5084 | OUT_RING(obj_priv->gtt_offset); | ||
5085 | |||
5086 | pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE; | ||
5087 | pipesrc = I915_READ(pipe == 0 ? PIPEASRC : PIPEBSRC) & 0x0fff0fff; | ||
5088 | OUT_RING(pf | pipesrc); | ||
5089 | break; | ||
5113 | } | 5090 | } |
5114 | ADVANCE_LP_RING(); | 5091 | ADVANCE_LP_RING(); |
5115 | 5092 | ||
@@ -5190,7 +5167,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
5190 | dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; | 5167 | dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; |
5191 | 5168 | ||
5192 | intel_crtc->cursor_addr = 0; | 5169 | intel_crtc->cursor_addr = 0; |
5193 | intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF; | 5170 | intel_crtc->dpms_mode = -1; |
5194 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); | 5171 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); |
5195 | 5172 | ||
5196 | intel_crtc->busy = false; | 5173 | intel_crtc->busy = false; |
@@ -5432,37 +5409,37 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { | |||
5432 | }; | 5409 | }; |
5433 | 5410 | ||
5434 | static struct drm_gem_object * | 5411 | static struct drm_gem_object * |
5435 | intel_alloc_power_context(struct drm_device *dev) | 5412 | intel_alloc_context_page(struct drm_device *dev) |
5436 | { | 5413 | { |
5437 | struct drm_gem_object *pwrctx; | 5414 | struct drm_gem_object *ctx; |
5438 | int ret; | 5415 | int ret; |
5439 | 5416 | ||
5440 | pwrctx = i915_gem_alloc_object(dev, 4096); | 5417 | ctx = i915_gem_alloc_object(dev, 4096); |
5441 | if (!pwrctx) { | 5418 | if (!ctx) { |
5442 | DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); | 5419 | DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); |
5443 | return NULL; | 5420 | return NULL; |
5444 | } | 5421 | } |
5445 | 5422 | ||
5446 | mutex_lock(&dev->struct_mutex); | 5423 | mutex_lock(&dev->struct_mutex); |
5447 | ret = i915_gem_object_pin(pwrctx, 4096); | 5424 | ret = i915_gem_object_pin(ctx, 4096); |
5448 | if (ret) { | 5425 | if (ret) { |
5449 | DRM_ERROR("failed to pin power context: %d\n", ret); | 5426 | DRM_ERROR("failed to pin power context: %d\n", ret); |
5450 | goto err_unref; | 5427 | goto err_unref; |
5451 | } | 5428 | } |
5452 | 5429 | ||
5453 | ret = i915_gem_object_set_to_gtt_domain(pwrctx, 1); | 5430 | ret = i915_gem_object_set_to_gtt_domain(ctx, 1); |
5454 | if (ret) { | 5431 | if (ret) { |
5455 | DRM_ERROR("failed to set-domain on power context: %d\n", ret); | 5432 | DRM_ERROR("failed to set-domain on power context: %d\n", ret); |
5456 | goto err_unpin; | 5433 | goto err_unpin; |
5457 | } | 5434 | } |
5458 | mutex_unlock(&dev->struct_mutex); | 5435 | mutex_unlock(&dev->struct_mutex); |
5459 | 5436 | ||
5460 | return pwrctx; | 5437 | return ctx; |
5461 | 5438 | ||
5462 | err_unpin: | 5439 | err_unpin: |
5463 | i915_gem_object_unpin(pwrctx); | 5440 | i915_gem_object_unpin(ctx); |
5464 | err_unref: | 5441 | err_unref: |
5465 | drm_gem_object_unreference(pwrctx); | 5442 | drm_gem_object_unreference(ctx); |
5466 | mutex_unlock(&dev->struct_mutex); | 5443 | mutex_unlock(&dev->struct_mutex); |
5467 | return NULL; | 5444 | return NULL; |
5468 | } | 5445 | } |
@@ -5494,7 +5471,6 @@ void ironlake_enable_drps(struct drm_device *dev) | |||
5494 | struct drm_i915_private *dev_priv = dev->dev_private; | 5471 | struct drm_i915_private *dev_priv = dev->dev_private; |
5495 | u32 rgvmodectl = I915_READ(MEMMODECTL); | 5472 | u32 rgvmodectl = I915_READ(MEMMODECTL); |
5496 | u8 fmax, fmin, fstart, vstart; | 5473 | u8 fmax, fmin, fstart, vstart; |
5497 | int i = 0; | ||
5498 | 5474 | ||
5499 | /* 100ms RC evaluation intervals */ | 5475 | /* 100ms RC evaluation intervals */ |
5500 | I915_WRITE(RCUPEI, 100000); | 5476 | I915_WRITE(RCUPEI, 100000); |
@@ -5538,13 +5514,8 @@ void ironlake_enable_drps(struct drm_device *dev) | |||
5538 | rgvmodectl |= MEMMODE_SWMODE_EN; | 5514 | rgvmodectl |= MEMMODE_SWMODE_EN; |
5539 | I915_WRITE(MEMMODECTL, rgvmodectl); | 5515 | I915_WRITE(MEMMODECTL, rgvmodectl); |
5540 | 5516 | ||
5541 | while (I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) { | 5517 | if (wait_for((I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) == 0, 1, 0)) |
5542 | if (i++ > 100) { | 5518 | DRM_ERROR("stuck trying to change perf mode\n"); |
5543 | DRM_ERROR("stuck trying to change perf mode\n"); | ||
5544 | break; | ||
5545 | } | ||
5546 | msleep(1); | ||
5547 | } | ||
5548 | msleep(1); | 5519 | msleep(1); |
5549 | 5520 | ||
5550 | ironlake_set_drps(dev, fstart); | 5521 | ironlake_set_drps(dev, fstart); |
@@ -5725,7 +5696,8 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
5725 | ILK_DPFC_DIS2 | | 5696 | ILK_DPFC_DIS2 | |
5726 | ILK_CLK_FBC); | 5697 | ILK_CLK_FBC); |
5727 | } | 5698 | } |
5728 | return; | 5699 | if (IS_GEN6(dev)) |
5700 | return; | ||
5729 | } else if (IS_G4X(dev)) { | 5701 | } else if (IS_G4X(dev)) { |
5730 | uint32_t dspclk_gate; | 5702 | uint32_t dspclk_gate; |
5731 | I915_WRITE(RENCLK_GATE_D1, 0); | 5703 | I915_WRITE(RENCLK_GATE_D1, 0); |
@@ -5768,6 +5740,31 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
5768 | * GPU can automatically power down the render unit if given a page | 5740 | * GPU can automatically power down the render unit if given a page |
5769 | * to save state. | 5741 | * to save state. |
5770 | */ | 5742 | */ |
5743 | if (IS_IRONLAKE_M(dev)) { | ||
5744 | if (dev_priv->renderctx == NULL) | ||
5745 | dev_priv->renderctx = intel_alloc_context_page(dev); | ||
5746 | if (dev_priv->renderctx) { | ||
5747 | struct drm_i915_gem_object *obj_priv; | ||
5748 | obj_priv = to_intel_bo(dev_priv->renderctx); | ||
5749 | if (obj_priv) { | ||
5750 | BEGIN_LP_RING(4); | ||
5751 | OUT_RING(MI_SET_CONTEXT); | ||
5752 | OUT_RING(obj_priv->gtt_offset | | ||
5753 | MI_MM_SPACE_GTT | | ||
5754 | MI_SAVE_EXT_STATE_EN | | ||
5755 | MI_RESTORE_EXT_STATE_EN | | ||
5756 | MI_RESTORE_INHIBIT); | ||
5757 | OUT_RING(MI_NOOP); | ||
5758 | OUT_RING(MI_FLUSH); | ||
5759 | ADVANCE_LP_RING(); | ||
5760 | } | ||
5761 | } else { | ||
5762 | DRM_DEBUG_KMS("Failed to allocate render context." | ||
5763 | "Disable RC6\n"); | ||
5764 | return; | ||
5765 | } | ||
5766 | } | ||
5767 | |||
5771 | if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) { | 5768 | if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) { |
5772 | struct drm_i915_gem_object *obj_priv = NULL; | 5769 | struct drm_i915_gem_object *obj_priv = NULL; |
5773 | 5770 | ||
@@ -5776,7 +5773,7 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
5776 | } else { | 5773 | } else { |
5777 | struct drm_gem_object *pwrctx; | 5774 | struct drm_gem_object *pwrctx; |
5778 | 5775 | ||
5779 | pwrctx = intel_alloc_power_context(dev); | 5776 | pwrctx = intel_alloc_context_page(dev); |
5780 | if (pwrctx) { | 5777 | if (pwrctx) { |
5781 | dev_priv->pwrctx = pwrctx; | 5778 | dev_priv->pwrctx = pwrctx; |
5782 | obj_priv = to_intel_bo(pwrctx); | 5779 | obj_priv = to_intel_bo(pwrctx); |
@@ -5948,6 +5945,29 @@ static void intel_init_quirks(struct drm_device *dev) | |||
5948 | } | 5945 | } |
5949 | } | 5946 | } |
5950 | 5947 | ||
5948 | /* Disable the VGA plane that we never use */ | ||
5949 | static void i915_disable_vga(struct drm_device *dev) | ||
5950 | { | ||
5951 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5952 | u8 sr1; | ||
5953 | u32 vga_reg; | ||
5954 | |||
5955 | if (HAS_PCH_SPLIT(dev)) | ||
5956 | vga_reg = CPU_VGACNTRL; | ||
5957 | else | ||
5958 | vga_reg = VGACNTRL; | ||
5959 | |||
5960 | vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); | ||
5961 | outb(1, VGA_SR_INDEX); | ||
5962 | sr1 = inb(VGA_SR_DATA); | ||
5963 | outb(sr1 | 1<<5, VGA_SR_DATA); | ||
5964 | vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); | ||
5965 | udelay(300); | ||
5966 | |||
5967 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); | ||
5968 | POSTING_READ(vga_reg); | ||
5969 | } | ||
5970 | |||
5951 | void intel_modeset_init(struct drm_device *dev) | 5971 | void intel_modeset_init(struct drm_device *dev) |
5952 | { | 5972 | { |
5953 | struct drm_i915_private *dev_priv = dev->dev_private; | 5973 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -5996,6 +6016,9 @@ void intel_modeset_init(struct drm_device *dev) | |||
5996 | 6016 | ||
5997 | intel_init_clock_gating(dev); | 6017 | intel_init_clock_gating(dev); |
5998 | 6018 | ||
6019 | /* Just disable it once at startup */ | ||
6020 | i915_disable_vga(dev); | ||
6021 | |||
5999 | if (IS_IRONLAKE_M(dev)) { | 6022 | if (IS_IRONLAKE_M(dev)) { |
6000 | ironlake_enable_drps(dev); | 6023 | ironlake_enable_drps(dev); |
6001 | intel_init_emon(dev); | 6024 | intel_init_emon(dev); |
@@ -6034,6 +6057,16 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
6034 | if (dev_priv->display.disable_fbc) | 6057 | if (dev_priv->display.disable_fbc) |
6035 | dev_priv->display.disable_fbc(dev); | 6058 | dev_priv->display.disable_fbc(dev); |
6036 | 6059 | ||
6060 | if (dev_priv->renderctx) { | ||
6061 | struct drm_i915_gem_object *obj_priv; | ||
6062 | |||
6063 | obj_priv = to_intel_bo(dev_priv->renderctx); | ||
6064 | I915_WRITE(CCID, obj_priv->gtt_offset &~ CCID_EN); | ||
6065 | I915_READ(CCID); | ||
6066 | i915_gem_object_unpin(dev_priv->renderctx); | ||
6067 | drm_gem_object_unreference(dev_priv->renderctx); | ||
6068 | } | ||
6069 | |||
6037 | if (dev_priv->pwrctx) { | 6070 | if (dev_priv->pwrctx) { |
6038 | struct drm_i915_gem_object *obj_priv; | 6071 | struct drm_i915_gem_object *obj_priv; |
6039 | 6072 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 40be1fa65be..51d142939a2 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -42,10 +42,11 @@ | |||
42 | 42 | ||
43 | #define DP_LINK_CONFIGURATION_SIZE 9 | 43 | #define DP_LINK_CONFIGURATION_SIZE 9 |
44 | 44 | ||
45 | #define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP) | 45 | #define IS_eDP(i) ((i)->base.type == INTEL_OUTPUT_EDP) |
46 | #define IS_PCH_eDP(dp_priv) ((dp_priv)->is_pch_edp) | 46 | #define IS_PCH_eDP(i) ((i)->is_pch_edp) |
47 | 47 | ||
48 | struct intel_dp_priv { | 48 | struct intel_dp { |
49 | struct intel_encoder base; | ||
49 | uint32_t output_reg; | 50 | uint32_t output_reg; |
50 | uint32_t DP; | 51 | uint32_t DP; |
51 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; | 52 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; |
@@ -54,40 +55,39 @@ struct intel_dp_priv { | |||
54 | uint8_t link_bw; | 55 | uint8_t link_bw; |
55 | uint8_t lane_count; | 56 | uint8_t lane_count; |
56 | uint8_t dpcd[4]; | 57 | uint8_t dpcd[4]; |
57 | struct intel_encoder *intel_encoder; | ||
58 | struct i2c_adapter adapter; | 58 | struct i2c_adapter adapter; |
59 | struct i2c_algo_dp_aux_data algo; | 59 | struct i2c_algo_dp_aux_data algo; |
60 | bool is_pch_edp; | 60 | bool is_pch_edp; |
61 | }; | 61 | }; |
62 | 62 | ||
63 | static void | 63 | static struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder) |
64 | intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | 64 | { |
65 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]); | 65 | return container_of(enc_to_intel_encoder(encoder), struct intel_dp, base); |
66 | } | ||
66 | 67 | ||
67 | static void | 68 | static void intel_dp_link_train(struct intel_dp *intel_dp); |
68 | intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP); | 69 | static void intel_dp_link_down(struct intel_dp *intel_dp); |
69 | 70 | ||
70 | void | 71 | void |
71 | intel_edp_link_config (struct intel_encoder *intel_encoder, | 72 | intel_edp_link_config (struct intel_encoder *intel_encoder, |
72 | int *lane_num, int *link_bw) | 73 | int *lane_num, int *link_bw) |
73 | { | 74 | { |
74 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 75 | struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); |
75 | 76 | ||
76 | *lane_num = dp_priv->lane_count; | 77 | *lane_num = intel_dp->lane_count; |
77 | if (dp_priv->link_bw == DP_LINK_BW_1_62) | 78 | if (intel_dp->link_bw == DP_LINK_BW_1_62) |
78 | *link_bw = 162000; | 79 | *link_bw = 162000; |
79 | else if (dp_priv->link_bw == DP_LINK_BW_2_7) | 80 | else if (intel_dp->link_bw == DP_LINK_BW_2_7) |
80 | *link_bw = 270000; | 81 | *link_bw = 270000; |
81 | } | 82 | } |
82 | 83 | ||
83 | static int | 84 | static int |
84 | intel_dp_max_lane_count(struct intel_encoder *intel_encoder) | 85 | intel_dp_max_lane_count(struct intel_dp *intel_dp) |
85 | { | 86 | { |
86 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
87 | int max_lane_count = 4; | 87 | int max_lane_count = 4; |
88 | 88 | ||
89 | if (dp_priv->dpcd[0] >= 0x11) { | 89 | if (intel_dp->dpcd[0] >= 0x11) { |
90 | max_lane_count = dp_priv->dpcd[2] & 0x1f; | 90 | max_lane_count = intel_dp->dpcd[2] & 0x1f; |
91 | switch (max_lane_count) { | 91 | switch (max_lane_count) { |
92 | case 1: case 2: case 4: | 92 | case 1: case 2: case 4: |
93 | break; | 93 | break; |
@@ -99,10 +99,9 @@ intel_dp_max_lane_count(struct intel_encoder *intel_encoder) | |||
99 | } | 99 | } |
100 | 100 | ||
101 | static int | 101 | static int |
102 | intel_dp_max_link_bw(struct intel_encoder *intel_encoder) | 102 | intel_dp_max_link_bw(struct intel_dp *intel_dp) |
103 | { | 103 | { |
104 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 104 | int max_link_bw = intel_dp->dpcd[1]; |
105 | int max_link_bw = dp_priv->dpcd[1]; | ||
106 | 105 | ||
107 | switch (max_link_bw) { | 106 | switch (max_link_bw) { |
108 | case DP_LINK_BW_1_62: | 107 | case DP_LINK_BW_1_62: |
@@ -126,13 +125,11 @@ intel_dp_link_clock(uint8_t link_bw) | |||
126 | 125 | ||
127 | /* I think this is a fiction */ | 126 | /* I think this is a fiction */ |
128 | static int | 127 | static int |
129 | intel_dp_link_required(struct drm_device *dev, | 128 | intel_dp_link_required(struct drm_device *dev, struct intel_dp *intel_dp, int pixel_clock) |
130 | struct intel_encoder *intel_encoder, int pixel_clock) | ||
131 | { | 129 | { |
132 | struct drm_i915_private *dev_priv = dev->dev_private; | 130 | struct drm_i915_private *dev_priv = dev->dev_private; |
133 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
134 | 131 | ||
135 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) | 132 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) |
136 | return (pixel_clock * dev_priv->edp_bpp) / 8; | 133 | return (pixel_clock * dev_priv->edp_bpp) / 8; |
137 | else | 134 | else |
138 | return pixel_clock * 3; | 135 | return pixel_clock * 3; |
@@ -149,14 +146,13 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
149 | struct drm_display_mode *mode) | 146 | struct drm_display_mode *mode) |
150 | { | 147 | { |
151 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 148 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
152 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 149 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
153 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
154 | struct drm_device *dev = connector->dev; | 150 | struct drm_device *dev = connector->dev; |
155 | struct drm_i915_private *dev_priv = dev->dev_private; | 151 | struct drm_i915_private *dev_priv = dev->dev_private; |
156 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder)); | 152 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); |
157 | int max_lanes = intel_dp_max_lane_count(intel_encoder); | 153 | int max_lanes = intel_dp_max_lane_count(intel_dp); |
158 | 154 | ||
159 | if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) && | 155 | if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) && |
160 | dev_priv->panel_fixed_mode) { | 156 | dev_priv->panel_fixed_mode) { |
161 | if (mode->hdisplay > dev_priv->panel_fixed_mode->hdisplay) | 157 | if (mode->hdisplay > dev_priv->panel_fixed_mode->hdisplay) |
162 | return MODE_PANEL; | 158 | return MODE_PANEL; |
@@ -167,8 +163,8 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
167 | 163 | ||
168 | /* only refuse the mode on non eDP since we have seen some wierd eDP panels | 164 | /* only refuse the mode on non eDP since we have seen some wierd eDP panels |
169 | which are outside spec tolerances but somehow work by magic */ | 165 | which are outside spec tolerances but somehow work by magic */ |
170 | if (!IS_eDP(intel_encoder) && | 166 | if (!IS_eDP(intel_dp) && |
171 | (intel_dp_link_required(connector->dev, intel_encoder, mode->clock) | 167 | (intel_dp_link_required(connector->dev, intel_dp, mode->clock) |
172 | > intel_dp_max_data_rate(max_link_clock, max_lanes))) | 168 | > intel_dp_max_data_rate(max_link_clock, max_lanes))) |
173 | return MODE_CLOCK_HIGH; | 169 | return MODE_CLOCK_HIGH; |
174 | 170 | ||
@@ -232,19 +228,17 @@ intel_hrawclk(struct drm_device *dev) | |||
232 | } | 228 | } |
233 | 229 | ||
234 | static int | 230 | static int |
235 | intel_dp_aux_ch(struct intel_encoder *intel_encoder, | 231 | intel_dp_aux_ch(struct intel_dp *intel_dp, |
236 | uint8_t *send, int send_bytes, | 232 | uint8_t *send, int send_bytes, |
237 | uint8_t *recv, int recv_size) | 233 | uint8_t *recv, int recv_size) |
238 | { | 234 | { |
239 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 235 | uint32_t output_reg = intel_dp->output_reg; |
240 | uint32_t output_reg = dp_priv->output_reg; | 236 | struct drm_device *dev = intel_dp->base.enc.dev; |
241 | struct drm_device *dev = intel_encoder->enc.dev; | ||
242 | struct drm_i915_private *dev_priv = dev->dev_private; | 237 | struct drm_i915_private *dev_priv = dev->dev_private; |
243 | uint32_t ch_ctl = output_reg + 0x10; | 238 | uint32_t ch_ctl = output_reg + 0x10; |
244 | uint32_t ch_data = ch_ctl + 4; | 239 | uint32_t ch_data = ch_ctl + 4; |
245 | int i; | 240 | int i; |
246 | int recv_bytes; | 241 | int recv_bytes; |
247 | uint32_t ctl; | ||
248 | uint32_t status; | 242 | uint32_t status; |
249 | uint32_t aux_clock_divider; | 243 | uint32_t aux_clock_divider; |
250 | int try, precharge; | 244 | int try, precharge; |
@@ -253,7 +247,7 @@ intel_dp_aux_ch(struct intel_encoder *intel_encoder, | |||
253 | * and would like to run at 2MHz. So, take the | 247 | * and would like to run at 2MHz. So, take the |
254 | * hrawclk value and divide by 2 and use that | 248 | * hrawclk value and divide by 2 and use that |
255 | */ | 249 | */ |
256 | if (IS_eDP(intel_encoder)) { | 250 | if (IS_eDP(intel_dp)) { |
257 | if (IS_GEN6(dev)) | 251 | if (IS_GEN6(dev)) |
258 | aux_clock_divider = 200; /* SNB eDP input clock at 400Mhz */ | 252 | aux_clock_divider = 200; /* SNB eDP input clock at 400Mhz */ |
259 | else | 253 | else |
@@ -268,41 +262,43 @@ intel_dp_aux_ch(struct intel_encoder *intel_encoder, | |||
268 | else | 262 | else |
269 | precharge = 5; | 263 | precharge = 5; |
270 | 264 | ||
265 | if (I915_READ(ch_ctl) & DP_AUX_CH_CTL_SEND_BUSY) { | ||
266 | DRM_ERROR("dp_aux_ch not started status 0x%08x\n", | ||
267 | I915_READ(ch_ctl)); | ||
268 | return -EBUSY; | ||
269 | } | ||
270 | |||
271 | /* Must try at least 3 times according to DP spec */ | 271 | /* Must try at least 3 times according to DP spec */ |
272 | for (try = 0; try < 5; try++) { | 272 | for (try = 0; try < 5; try++) { |
273 | /* Load the send data into the aux channel data registers */ | 273 | /* Load the send data into the aux channel data registers */ |
274 | for (i = 0; i < send_bytes; i += 4) { | 274 | for (i = 0; i < send_bytes; i += 4) |
275 | uint32_t d = pack_aux(send + i, send_bytes - i); | 275 | I915_WRITE(ch_data + i, |
276 | 276 | pack_aux(send + i, send_bytes - i)); | |
277 | I915_WRITE(ch_data + i, d); | ||
278 | } | ||
279 | |||
280 | ctl = (DP_AUX_CH_CTL_SEND_BUSY | | ||
281 | DP_AUX_CH_CTL_TIME_OUT_400us | | ||
282 | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | | ||
283 | (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | | ||
284 | (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | | ||
285 | DP_AUX_CH_CTL_DONE | | ||
286 | DP_AUX_CH_CTL_TIME_OUT_ERROR | | ||
287 | DP_AUX_CH_CTL_RECEIVE_ERROR); | ||
288 | 277 | ||
289 | /* Send the command and wait for it to complete */ | 278 | /* Send the command and wait for it to complete */ |
290 | I915_WRITE(ch_ctl, ctl); | 279 | I915_WRITE(ch_ctl, |
291 | (void) I915_READ(ch_ctl); | 280 | DP_AUX_CH_CTL_SEND_BUSY | |
281 | DP_AUX_CH_CTL_TIME_OUT_400us | | ||
282 | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | | ||
283 | (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | | ||
284 | (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | | ||
285 | DP_AUX_CH_CTL_DONE | | ||
286 | DP_AUX_CH_CTL_TIME_OUT_ERROR | | ||
287 | DP_AUX_CH_CTL_RECEIVE_ERROR); | ||
292 | for (;;) { | 288 | for (;;) { |
293 | udelay(100); | ||
294 | status = I915_READ(ch_ctl); | 289 | status = I915_READ(ch_ctl); |
295 | if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) | 290 | if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) |
296 | break; | 291 | break; |
292 | udelay(100); | ||
297 | } | 293 | } |
298 | 294 | ||
299 | /* Clear done status and any errors */ | 295 | /* Clear done status and any errors */ |
300 | I915_WRITE(ch_ctl, (status | | 296 | I915_WRITE(ch_ctl, |
301 | DP_AUX_CH_CTL_DONE | | 297 | status | |
302 | DP_AUX_CH_CTL_TIME_OUT_ERROR | | 298 | DP_AUX_CH_CTL_DONE | |
303 | DP_AUX_CH_CTL_RECEIVE_ERROR)); | 299 | DP_AUX_CH_CTL_TIME_OUT_ERROR | |
304 | (void) I915_READ(ch_ctl); | 300 | DP_AUX_CH_CTL_RECEIVE_ERROR); |
305 | if ((status & DP_AUX_CH_CTL_TIME_OUT_ERROR) == 0) | 301 | if (status & DP_AUX_CH_CTL_DONE) |
306 | break; | 302 | break; |
307 | } | 303 | } |
308 | 304 | ||
@@ -329,22 +325,19 @@ intel_dp_aux_ch(struct intel_encoder *intel_encoder, | |||
329 | /* Unload any bytes sent back from the other side */ | 325 | /* Unload any bytes sent back from the other side */ |
330 | recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >> | 326 | recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >> |
331 | DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT); | 327 | DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT); |
332 | |||
333 | if (recv_bytes > recv_size) | 328 | if (recv_bytes > recv_size) |
334 | recv_bytes = recv_size; | 329 | recv_bytes = recv_size; |
335 | 330 | ||
336 | for (i = 0; i < recv_bytes; i += 4) { | 331 | for (i = 0; i < recv_bytes; i += 4) |
337 | uint32_t d = I915_READ(ch_data + i); | 332 | unpack_aux(I915_READ(ch_data + i), |
338 | 333 | recv + i, recv_bytes - i); | |
339 | unpack_aux(d, recv + i, recv_bytes - i); | ||
340 | } | ||
341 | 334 | ||
342 | return recv_bytes; | 335 | return recv_bytes; |
343 | } | 336 | } |
344 | 337 | ||
345 | /* Write data to the aux channel in native mode */ | 338 | /* Write data to the aux channel in native mode */ |
346 | static int | 339 | static int |
347 | intel_dp_aux_native_write(struct intel_encoder *intel_encoder, | 340 | intel_dp_aux_native_write(struct intel_dp *intel_dp, |
348 | uint16_t address, uint8_t *send, int send_bytes) | 341 | uint16_t address, uint8_t *send, int send_bytes) |
349 | { | 342 | { |
350 | int ret; | 343 | int ret; |
@@ -361,7 +354,7 @@ intel_dp_aux_native_write(struct intel_encoder *intel_encoder, | |||
361 | memcpy(&msg[4], send, send_bytes); | 354 | memcpy(&msg[4], send, send_bytes); |
362 | msg_bytes = send_bytes + 4; | 355 | msg_bytes = send_bytes + 4; |
363 | for (;;) { | 356 | for (;;) { |
364 | ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, &ack, 1); | 357 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, &ack, 1); |
365 | if (ret < 0) | 358 | if (ret < 0) |
366 | return ret; | 359 | return ret; |
367 | if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) | 360 | if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) |
@@ -376,15 +369,15 @@ intel_dp_aux_native_write(struct intel_encoder *intel_encoder, | |||
376 | 369 | ||
377 | /* Write a single byte to the aux channel in native mode */ | 370 | /* Write a single byte to the aux channel in native mode */ |
378 | static int | 371 | static int |
379 | intel_dp_aux_native_write_1(struct intel_encoder *intel_encoder, | 372 | intel_dp_aux_native_write_1(struct intel_dp *intel_dp, |
380 | uint16_t address, uint8_t byte) | 373 | uint16_t address, uint8_t byte) |
381 | { | 374 | { |
382 | return intel_dp_aux_native_write(intel_encoder, address, &byte, 1); | 375 | return intel_dp_aux_native_write(intel_dp, address, &byte, 1); |
383 | } | 376 | } |
384 | 377 | ||
385 | /* read bytes from a native aux channel */ | 378 | /* read bytes from a native aux channel */ |
386 | static int | 379 | static int |
387 | intel_dp_aux_native_read(struct intel_encoder *intel_encoder, | 380 | intel_dp_aux_native_read(struct intel_dp *intel_dp, |
388 | uint16_t address, uint8_t *recv, int recv_bytes) | 381 | uint16_t address, uint8_t *recv, int recv_bytes) |
389 | { | 382 | { |
390 | uint8_t msg[4]; | 383 | uint8_t msg[4]; |
@@ -403,7 +396,7 @@ intel_dp_aux_native_read(struct intel_encoder *intel_encoder, | |||
403 | reply_bytes = recv_bytes + 1; | 396 | reply_bytes = recv_bytes + 1; |
404 | 397 | ||
405 | for (;;) { | 398 | for (;;) { |
406 | ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, | 399 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, |
407 | reply, reply_bytes); | 400 | reply, reply_bytes); |
408 | if (ret == 0) | 401 | if (ret == 0) |
409 | return -EPROTO; | 402 | return -EPROTO; |
@@ -426,10 +419,9 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
426 | uint8_t write_byte, uint8_t *read_byte) | 419 | uint8_t write_byte, uint8_t *read_byte) |
427 | { | 420 | { |
428 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; | 421 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; |
429 | struct intel_dp_priv *dp_priv = container_of(adapter, | 422 | struct intel_dp *intel_dp = container_of(adapter, |
430 | struct intel_dp_priv, | 423 | struct intel_dp, |
431 | adapter); | 424 | adapter); |
432 | struct intel_encoder *intel_encoder = dp_priv->intel_encoder; | ||
433 | uint16_t address = algo_data->address; | 425 | uint16_t address = algo_data->address; |
434 | uint8_t msg[5]; | 426 | uint8_t msg[5]; |
435 | uint8_t reply[2]; | 427 | uint8_t reply[2]; |
@@ -468,7 +460,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
468 | } | 460 | } |
469 | 461 | ||
470 | for (;;) { | 462 | for (;;) { |
471 | ret = intel_dp_aux_ch(intel_encoder, | 463 | ret = intel_dp_aux_ch(intel_dp, |
472 | msg, msg_bytes, | 464 | msg, msg_bytes, |
473 | reply, reply_bytes); | 465 | reply, reply_bytes); |
474 | if (ret < 0) { | 466 | if (ret < 0) { |
@@ -496,57 +488,42 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
496 | } | 488 | } |
497 | 489 | ||
498 | static int | 490 | static int |
499 | intel_dp_i2c_init(struct intel_encoder *intel_encoder, | 491 | intel_dp_i2c_init(struct intel_dp *intel_dp, |
500 | struct intel_connector *intel_connector, const char *name) | 492 | struct intel_connector *intel_connector, const char *name) |
501 | { | 493 | { |
502 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
503 | |||
504 | DRM_DEBUG_KMS("i2c_init %s\n", name); | 494 | DRM_DEBUG_KMS("i2c_init %s\n", name); |
505 | dp_priv->algo.running = false; | 495 | intel_dp->algo.running = false; |
506 | dp_priv->algo.address = 0; | 496 | intel_dp->algo.address = 0; |
507 | dp_priv->algo.aux_ch = intel_dp_i2c_aux_ch; | 497 | intel_dp->algo.aux_ch = intel_dp_i2c_aux_ch; |
508 | 498 | ||
509 | memset(&dp_priv->adapter, '\0', sizeof (dp_priv->adapter)); | 499 | memset(&intel_dp->adapter, '\0', sizeof (intel_dp->adapter)); |
510 | dp_priv->adapter.owner = THIS_MODULE; | 500 | intel_dp->adapter.owner = THIS_MODULE; |
511 | dp_priv->adapter.class = I2C_CLASS_DDC; | 501 | intel_dp->adapter.class = I2C_CLASS_DDC; |
512 | strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1); | 502 | strncpy (intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1); |
513 | dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0'; | 503 | intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0'; |
514 | dp_priv->adapter.algo_data = &dp_priv->algo; | 504 | intel_dp->adapter.algo_data = &intel_dp->algo; |
515 | dp_priv->adapter.dev.parent = &intel_connector->base.kdev; | 505 | intel_dp->adapter.dev.parent = &intel_connector->base.kdev; |
516 | 506 | ||
517 | return i2c_dp_aux_add_bus(&dp_priv->adapter); | 507 | return i2c_dp_aux_add_bus(&intel_dp->adapter); |
518 | } | 508 | } |
519 | 509 | ||
520 | static bool | 510 | static bool |
521 | intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | 511 | intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, |
522 | struct drm_display_mode *adjusted_mode) | 512 | struct drm_display_mode *adjusted_mode) |
523 | { | 513 | { |
524 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
525 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
526 | struct drm_device *dev = encoder->dev; | 514 | struct drm_device *dev = encoder->dev; |
527 | struct drm_i915_private *dev_priv = dev->dev_private; | 515 | struct drm_i915_private *dev_priv = dev->dev_private; |
516 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | ||
528 | int lane_count, clock; | 517 | int lane_count, clock; |
529 | int max_lane_count = intel_dp_max_lane_count(intel_encoder); | 518 | int max_lane_count = intel_dp_max_lane_count(intel_dp); |
530 | int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0; | 519 | int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; |
531 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; | 520 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; |
532 | 521 | ||
533 | if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) && | 522 | if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) && |
534 | dev_priv->panel_fixed_mode) { | 523 | dev_priv->panel_fixed_mode) { |
535 | struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode; | 524 | intel_fixed_panel_mode(dev_priv->panel_fixed_mode, adjusted_mode); |
536 | 525 | intel_pch_panel_fitting(dev, DRM_MODE_SCALE_FULLSCREEN, | |
537 | adjusted_mode->hdisplay = fixed_mode->hdisplay; | 526 | mode, adjusted_mode); |
538 | adjusted_mode->hsync_start = fixed_mode->hsync_start; | ||
539 | adjusted_mode->hsync_end = fixed_mode->hsync_end; | ||
540 | adjusted_mode->htotal = fixed_mode->htotal; | ||
541 | |||
542 | adjusted_mode->vdisplay = fixed_mode->vdisplay; | ||
543 | adjusted_mode->vsync_start = fixed_mode->vsync_start; | ||
544 | adjusted_mode->vsync_end = fixed_mode->vsync_end; | ||
545 | adjusted_mode->vtotal = fixed_mode->vtotal; | ||
546 | |||
547 | adjusted_mode->clock = fixed_mode->clock; | ||
548 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
549 | |||
550 | /* | 527 | /* |
551 | * the mode->clock is used to calculate the Data&Link M/N | 528 | * the mode->clock is used to calculate the Data&Link M/N |
552 | * of the pipe. For the eDP the fixed clock should be used. | 529 | * of the pipe. For the eDP the fixed clock should be used. |
@@ -558,31 +535,33 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
558 | for (clock = 0; clock <= max_clock; clock++) { | 535 | for (clock = 0; clock <= max_clock; clock++) { |
559 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); | 536 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); |
560 | 537 | ||
561 | if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock) | 538 | if (intel_dp_link_required(encoder->dev, intel_dp, mode->clock) |
562 | <= link_avail) { | 539 | <= link_avail) { |
563 | dp_priv->link_bw = bws[clock]; | 540 | intel_dp->link_bw = bws[clock]; |
564 | dp_priv->lane_count = lane_count; | 541 | intel_dp->lane_count = lane_count; |
565 | adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); | 542 | adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw); |
566 | DRM_DEBUG_KMS("Display port link bw %02x lane " | 543 | DRM_DEBUG_KMS("Display port link bw %02x lane " |
567 | "count %d clock %d\n", | 544 | "count %d clock %d\n", |
568 | dp_priv->link_bw, dp_priv->lane_count, | 545 | intel_dp->link_bw, intel_dp->lane_count, |
569 | adjusted_mode->clock); | 546 | adjusted_mode->clock); |
570 | return true; | 547 | return true; |
571 | } | 548 | } |
572 | } | 549 | } |
573 | } | 550 | } |
574 | 551 | ||
575 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { | 552 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) { |
576 | /* okay we failed just pick the highest */ | 553 | /* okay we failed just pick the highest */ |
577 | dp_priv->lane_count = max_lane_count; | 554 | intel_dp->lane_count = max_lane_count; |
578 | dp_priv->link_bw = bws[max_clock]; | 555 | intel_dp->link_bw = bws[max_clock]; |
579 | adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); | 556 | adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw); |
580 | DRM_DEBUG_KMS("Force picking display port link bw %02x lane " | 557 | DRM_DEBUG_KMS("Force picking display port link bw %02x lane " |
581 | "count %d clock %d\n", | 558 | "count %d clock %d\n", |
582 | dp_priv->link_bw, dp_priv->lane_count, | 559 | intel_dp->link_bw, intel_dp->lane_count, |
583 | adjusted_mode->clock); | 560 | adjusted_mode->clock); |
561 | |||
584 | return true; | 562 | return true; |
585 | } | 563 | } |
564 | |||
586 | return false; | 565 | return false; |
587 | } | 566 | } |
588 | 567 | ||
@@ -626,17 +605,14 @@ bool intel_pch_has_edp(struct drm_crtc *crtc) | |||
626 | struct drm_encoder *encoder; | 605 | struct drm_encoder *encoder; |
627 | 606 | ||
628 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | 607 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
629 | struct intel_encoder *intel_encoder; | 608 | struct intel_dp *intel_dp; |
630 | struct intel_dp_priv *dp_priv; | ||
631 | 609 | ||
632 | if (!encoder || encoder->crtc != crtc) | 610 | if (encoder->crtc != crtc) |
633 | continue; | 611 | continue; |
634 | 612 | ||
635 | intel_encoder = enc_to_intel_encoder(encoder); | 613 | intel_dp = enc_to_intel_dp(encoder); |
636 | dp_priv = intel_encoder->dev_priv; | 614 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) |
637 | 615 | return intel_dp->is_pch_edp; | |
638 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) | ||
639 | return dp_priv->is_pch_edp; | ||
640 | } | 616 | } |
641 | return false; | 617 | return false; |
642 | } | 618 | } |
@@ -657,18 +633,15 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
657 | * Find the lane count in the intel_encoder private | 633 | * Find the lane count in the intel_encoder private |
658 | */ | 634 | */ |
659 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | 635 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
660 | struct intel_encoder *intel_encoder; | 636 | struct intel_dp *intel_dp; |
661 | struct intel_dp_priv *dp_priv; | ||
662 | 637 | ||
663 | if (encoder->crtc != crtc) | 638 | if (encoder->crtc != crtc) |
664 | continue; | 639 | continue; |
665 | 640 | ||
666 | intel_encoder = enc_to_intel_encoder(encoder); | 641 | intel_dp = enc_to_intel_dp(encoder); |
667 | dp_priv = intel_encoder->dev_priv; | 642 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) { |
668 | 643 | lane_count = intel_dp->lane_count; | |
669 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { | 644 | if (IS_PCH_eDP(intel_dp)) |
670 | lane_count = dp_priv->lane_count; | ||
671 | if (IS_PCH_eDP(dp_priv)) | ||
672 | bpp = dev_priv->edp_bpp; | 645 | bpp = dev_priv->edp_bpp; |
673 | break; | 646 | break; |
674 | } | 647 | } |
@@ -724,107 +697,114 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
724 | struct drm_display_mode *adjusted_mode) | 697 | struct drm_display_mode *adjusted_mode) |
725 | { | 698 | { |
726 | struct drm_device *dev = encoder->dev; | 699 | struct drm_device *dev = encoder->dev; |
727 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 700 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
728 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 701 | struct drm_crtc *crtc = intel_dp->base.enc.crtc; |
729 | struct drm_crtc *crtc = intel_encoder->enc.crtc; | ||
730 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 702 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
731 | 703 | ||
732 | dp_priv->DP = (DP_VOLTAGE_0_4 | | 704 | intel_dp->DP = (DP_VOLTAGE_0_4 | |
733 | DP_PRE_EMPHASIS_0); | 705 | DP_PRE_EMPHASIS_0); |
734 | 706 | ||
735 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 707 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
736 | dp_priv->DP |= DP_SYNC_HS_HIGH; | 708 | intel_dp->DP |= DP_SYNC_HS_HIGH; |
737 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) | 709 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) |
738 | dp_priv->DP |= DP_SYNC_VS_HIGH; | 710 | intel_dp->DP |= DP_SYNC_VS_HIGH; |
739 | 711 | ||
740 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 712 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
741 | dp_priv->DP |= DP_LINK_TRAIN_OFF_CPT; | 713 | intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; |
742 | else | 714 | else |
743 | dp_priv->DP |= DP_LINK_TRAIN_OFF; | 715 | intel_dp->DP |= DP_LINK_TRAIN_OFF; |
744 | 716 | ||
745 | switch (dp_priv->lane_count) { | 717 | switch (intel_dp->lane_count) { |
746 | case 1: | 718 | case 1: |
747 | dp_priv->DP |= DP_PORT_WIDTH_1; | 719 | intel_dp->DP |= DP_PORT_WIDTH_1; |
748 | break; | 720 | break; |
749 | case 2: | 721 | case 2: |
750 | dp_priv->DP |= DP_PORT_WIDTH_2; | 722 | intel_dp->DP |= DP_PORT_WIDTH_2; |
751 | break; | 723 | break; |
752 | case 4: | 724 | case 4: |
753 | dp_priv->DP |= DP_PORT_WIDTH_4; | 725 | intel_dp->DP |= DP_PORT_WIDTH_4; |
754 | break; | 726 | break; |
755 | } | 727 | } |
756 | if (dp_priv->has_audio) | 728 | if (intel_dp->has_audio) |
757 | dp_priv->DP |= DP_AUDIO_OUTPUT_ENABLE; | 729 | intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE; |
758 | 730 | ||
759 | memset(dp_priv->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); | 731 | memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); |
760 | dp_priv->link_configuration[0] = dp_priv->link_bw; | 732 | intel_dp->link_configuration[0] = intel_dp->link_bw; |
761 | dp_priv->link_configuration[1] = dp_priv->lane_count; | 733 | intel_dp->link_configuration[1] = intel_dp->lane_count; |
762 | 734 | ||
763 | /* | 735 | /* |
764 | * Check for DPCD version > 1.1 and enhanced framing support | 736 | * Check for DPCD version > 1.1 and enhanced framing support |
765 | */ | 737 | */ |
766 | if (dp_priv->dpcd[0] >= 0x11 && (dp_priv->dpcd[2] & DP_ENHANCED_FRAME_CAP)) { | 738 | if (intel_dp->dpcd[0] >= 0x11 && (intel_dp->dpcd[2] & DP_ENHANCED_FRAME_CAP)) { |
767 | dp_priv->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; | 739 | intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; |
768 | dp_priv->DP |= DP_ENHANCED_FRAMING; | 740 | intel_dp->DP |= DP_ENHANCED_FRAMING; |
769 | } | 741 | } |
770 | 742 | ||
771 | /* CPT DP's pipe select is decided in TRANS_DP_CTL */ | 743 | /* CPT DP's pipe select is decided in TRANS_DP_CTL */ |
772 | if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev)) | 744 | if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev)) |
773 | dp_priv->DP |= DP_PIPEB_SELECT; | 745 | intel_dp->DP |= DP_PIPEB_SELECT; |
774 | 746 | ||
775 | if (IS_eDP(intel_encoder)) { | 747 | if (IS_eDP(intel_dp)) { |
776 | /* don't miss out required setting for eDP */ | 748 | /* don't miss out required setting for eDP */ |
777 | dp_priv->DP |= DP_PLL_ENABLE; | 749 | intel_dp->DP |= DP_PLL_ENABLE; |
778 | if (adjusted_mode->clock < 200000) | 750 | if (adjusted_mode->clock < 200000) |
779 | dp_priv->DP |= DP_PLL_FREQ_160MHZ; | 751 | intel_dp->DP |= DP_PLL_FREQ_160MHZ; |
780 | else | 752 | else |
781 | dp_priv->DP |= DP_PLL_FREQ_270MHZ; | 753 | intel_dp->DP |= DP_PLL_FREQ_270MHZ; |
782 | } | 754 | } |
783 | } | 755 | } |
784 | 756 | ||
785 | static void ironlake_edp_panel_on (struct drm_device *dev) | 757 | static void ironlake_edp_panel_on (struct drm_device *dev) |
786 | { | 758 | { |
787 | struct drm_i915_private *dev_priv = dev->dev_private; | 759 | struct drm_i915_private *dev_priv = dev->dev_private; |
788 | unsigned long timeout = jiffies + msecs_to_jiffies(5000); | 760 | u32 pp; |
789 | u32 pp, pp_status; | ||
790 | 761 | ||
791 | pp_status = I915_READ(PCH_PP_STATUS); | 762 | if (I915_READ(PCH_PP_STATUS) & PP_ON) |
792 | if (pp_status & PP_ON) | ||
793 | return; | 763 | return; |
794 | 764 | ||
795 | pp = I915_READ(PCH_PP_CONTROL); | 765 | pp = I915_READ(PCH_PP_CONTROL); |
766 | |||
767 | /* ILK workaround: disable reset around power sequence */ | ||
768 | pp &= ~PANEL_POWER_RESET; | ||
769 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
770 | POSTING_READ(PCH_PP_CONTROL); | ||
771 | |||
796 | pp |= PANEL_UNLOCK_REGS | POWER_TARGET_ON; | 772 | pp |= PANEL_UNLOCK_REGS | POWER_TARGET_ON; |
797 | I915_WRITE(PCH_PP_CONTROL, pp); | 773 | I915_WRITE(PCH_PP_CONTROL, pp); |
798 | do { | ||
799 | pp_status = I915_READ(PCH_PP_STATUS); | ||
800 | } while (((pp_status & PP_ON) == 0) && !time_after(jiffies, timeout)); | ||
801 | 774 | ||
802 | if (time_after(jiffies, timeout)) | 775 | if (wait_for(I915_READ(PCH_PP_STATUS) & PP_ON, 5000, 10)) |
803 | DRM_DEBUG_KMS("panel on wait timed out: 0x%08x\n", pp_status); | 776 | DRM_ERROR("panel on wait timed out: 0x%08x\n", |
777 | I915_READ(PCH_PP_STATUS)); | ||
804 | 778 | ||
805 | pp &= ~(PANEL_UNLOCK_REGS | EDP_FORCE_VDD); | 779 | pp &= ~(PANEL_UNLOCK_REGS | EDP_FORCE_VDD); |
780 | pp |= PANEL_POWER_RESET; /* restore panel reset bit */ | ||
806 | I915_WRITE(PCH_PP_CONTROL, pp); | 781 | I915_WRITE(PCH_PP_CONTROL, pp); |
782 | POSTING_READ(PCH_PP_CONTROL); | ||
807 | } | 783 | } |
808 | 784 | ||
809 | static void ironlake_edp_panel_off (struct drm_device *dev) | 785 | static void ironlake_edp_panel_off (struct drm_device *dev) |
810 | { | 786 | { |
811 | struct drm_i915_private *dev_priv = dev->dev_private; | 787 | struct drm_i915_private *dev_priv = dev->dev_private; |
812 | unsigned long timeout = jiffies + msecs_to_jiffies(5000); | 788 | u32 pp; |
813 | u32 pp, pp_status; | ||
814 | 789 | ||
815 | pp = I915_READ(PCH_PP_CONTROL); | 790 | pp = I915_READ(PCH_PP_CONTROL); |
791 | |||
792 | /* ILK workaround: disable reset around power sequence */ | ||
793 | pp &= ~PANEL_POWER_RESET; | ||
794 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
795 | POSTING_READ(PCH_PP_CONTROL); | ||
796 | |||
816 | pp &= ~POWER_TARGET_ON; | 797 | pp &= ~POWER_TARGET_ON; |
817 | I915_WRITE(PCH_PP_CONTROL, pp); | 798 | I915_WRITE(PCH_PP_CONTROL, pp); |
818 | do { | ||
819 | pp_status = I915_READ(PCH_PP_STATUS); | ||
820 | } while ((pp_status & PP_ON) && !time_after(jiffies, timeout)); | ||
821 | 799 | ||
822 | if (time_after(jiffies, timeout)) | 800 | if (wait_for((I915_READ(PCH_PP_STATUS) & PP_ON) == 0, 5000, 10)) |
823 | DRM_DEBUG_KMS("panel off wait timed out\n"); | 801 | DRM_ERROR("panel off wait timed out: 0x%08x\n", |
802 | I915_READ(PCH_PP_STATUS)); | ||
824 | 803 | ||
825 | /* Make sure VDD is enabled so DP AUX will work */ | 804 | /* Make sure VDD is enabled so DP AUX will work */ |
826 | pp |= EDP_FORCE_VDD; | 805 | pp |= EDP_FORCE_VDD | PANEL_POWER_RESET; /* restore panel reset bit */ |
827 | I915_WRITE(PCH_PP_CONTROL, pp); | 806 | I915_WRITE(PCH_PP_CONTROL, pp); |
807 | POSTING_READ(PCH_PP_CONTROL); | ||
828 | } | 808 | } |
829 | 809 | ||
830 | static void ironlake_edp_backlight_on (struct drm_device *dev) | 810 | static void ironlake_edp_backlight_on (struct drm_device *dev) |
@@ -849,33 +829,87 @@ static void ironlake_edp_backlight_off (struct drm_device *dev) | |||
849 | I915_WRITE(PCH_PP_CONTROL, pp); | 829 | I915_WRITE(PCH_PP_CONTROL, pp); |
850 | } | 830 | } |
851 | 831 | ||
832 | static void ironlake_edp_pll_on(struct drm_encoder *encoder) | ||
833 | { | ||
834 | struct drm_device *dev = encoder->dev; | ||
835 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
836 | u32 dpa_ctl; | ||
837 | |||
838 | DRM_DEBUG_KMS("\n"); | ||
839 | dpa_ctl = I915_READ(DP_A); | ||
840 | dpa_ctl &= ~DP_PLL_ENABLE; | ||
841 | I915_WRITE(DP_A, dpa_ctl); | ||
842 | } | ||
843 | |||
844 | static void ironlake_edp_pll_off(struct drm_encoder *encoder) | ||
845 | { | ||
846 | struct drm_device *dev = encoder->dev; | ||
847 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
848 | u32 dpa_ctl; | ||
849 | |||
850 | dpa_ctl = I915_READ(DP_A); | ||
851 | dpa_ctl |= DP_PLL_ENABLE; | ||
852 | I915_WRITE(DP_A, dpa_ctl); | ||
853 | udelay(200); | ||
854 | } | ||
855 | |||
856 | static void intel_dp_prepare(struct drm_encoder *encoder) | ||
857 | { | ||
858 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | ||
859 | struct drm_device *dev = encoder->dev; | ||
860 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
861 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); | ||
862 | |||
863 | if (IS_eDP(intel_dp)) { | ||
864 | ironlake_edp_backlight_off(dev); | ||
865 | ironlake_edp_panel_on(dev); | ||
866 | ironlake_edp_pll_on(encoder); | ||
867 | } | ||
868 | if (dp_reg & DP_PORT_EN) | ||
869 | intel_dp_link_down(intel_dp); | ||
870 | } | ||
871 | |||
872 | static void intel_dp_commit(struct drm_encoder *encoder) | ||
873 | { | ||
874 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | ||
875 | struct drm_device *dev = encoder->dev; | ||
876 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
877 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); | ||
878 | |||
879 | if (!(dp_reg & DP_PORT_EN)) { | ||
880 | intel_dp_link_train(intel_dp); | ||
881 | } | ||
882 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) | ||
883 | ironlake_edp_backlight_on(dev); | ||
884 | } | ||
885 | |||
852 | static void | 886 | static void |
853 | intel_dp_dpms(struct drm_encoder *encoder, int mode) | 887 | intel_dp_dpms(struct drm_encoder *encoder, int mode) |
854 | { | 888 | { |
855 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 889 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
856 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
857 | struct drm_device *dev = encoder->dev; | 890 | struct drm_device *dev = encoder->dev; |
858 | struct drm_i915_private *dev_priv = dev->dev_private; | 891 | struct drm_i915_private *dev_priv = dev->dev_private; |
859 | uint32_t dp_reg = I915_READ(dp_priv->output_reg); | 892 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); |
860 | 893 | ||
861 | if (mode != DRM_MODE_DPMS_ON) { | 894 | if (mode != DRM_MODE_DPMS_ON) { |
862 | if (dp_reg & DP_PORT_EN) { | 895 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) { |
863 | intel_dp_link_down(intel_encoder, dp_priv->DP); | 896 | ironlake_edp_backlight_off(dev); |
864 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { | 897 | ironlake_edp_panel_off(dev); |
865 | ironlake_edp_backlight_off(dev); | ||
866 | ironlake_edp_panel_off(dev); | ||
867 | } | ||
868 | } | 898 | } |
899 | if (dp_reg & DP_PORT_EN) | ||
900 | intel_dp_link_down(intel_dp); | ||
901 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) | ||
902 | ironlake_edp_pll_off(encoder); | ||
869 | } else { | 903 | } else { |
870 | if (!(dp_reg & DP_PORT_EN)) { | 904 | if (!(dp_reg & DP_PORT_EN)) { |
871 | intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); | 905 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) |
872 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { | ||
873 | ironlake_edp_panel_on(dev); | 906 | ironlake_edp_panel_on(dev); |
907 | intel_dp_link_train(intel_dp); | ||
908 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) | ||
874 | ironlake_edp_backlight_on(dev); | 909 | ironlake_edp_backlight_on(dev); |
875 | } | ||
876 | } | 910 | } |
877 | } | 911 | } |
878 | dp_priv->dpms_mode = mode; | 912 | intel_dp->dpms_mode = mode; |
879 | } | 913 | } |
880 | 914 | ||
881 | /* | 915 | /* |
@@ -883,12 +917,12 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
883 | * link status information | 917 | * link status information |
884 | */ | 918 | */ |
885 | static bool | 919 | static bool |
886 | intel_dp_get_link_status(struct intel_encoder *intel_encoder, | 920 | intel_dp_get_link_status(struct intel_dp *intel_dp, |
887 | uint8_t link_status[DP_LINK_STATUS_SIZE]) | 921 | uint8_t link_status[DP_LINK_STATUS_SIZE]) |
888 | { | 922 | { |
889 | int ret; | 923 | int ret; |
890 | 924 | ||
891 | ret = intel_dp_aux_native_read(intel_encoder, | 925 | ret = intel_dp_aux_native_read(intel_dp, |
892 | DP_LANE0_1_STATUS, | 926 | DP_LANE0_1_STATUS, |
893 | link_status, DP_LINK_STATUS_SIZE); | 927 | link_status, DP_LINK_STATUS_SIZE); |
894 | if (ret != DP_LINK_STATUS_SIZE) | 928 | if (ret != DP_LINK_STATUS_SIZE) |
@@ -965,7 +999,7 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing) | |||
965 | } | 999 | } |
966 | 1000 | ||
967 | static void | 1001 | static void |
968 | intel_get_adjust_train(struct intel_encoder *intel_encoder, | 1002 | intel_get_adjust_train(struct intel_dp *intel_dp, |
969 | uint8_t link_status[DP_LINK_STATUS_SIZE], | 1003 | uint8_t link_status[DP_LINK_STATUS_SIZE], |
970 | int lane_count, | 1004 | int lane_count, |
971 | uint8_t train_set[4]) | 1005 | uint8_t train_set[4]) |
@@ -1101,27 +1135,27 @@ intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count) | |||
1101 | } | 1135 | } |
1102 | 1136 | ||
1103 | static bool | 1137 | static bool |
1104 | intel_dp_set_link_train(struct intel_encoder *intel_encoder, | 1138 | intel_dp_set_link_train(struct intel_dp *intel_dp, |
1105 | uint32_t dp_reg_value, | 1139 | uint32_t dp_reg_value, |
1106 | uint8_t dp_train_pat, | 1140 | uint8_t dp_train_pat, |
1107 | uint8_t train_set[4], | 1141 | uint8_t train_set[4], |
1108 | bool first) | 1142 | bool first) |
1109 | { | 1143 | { |
1110 | struct drm_device *dev = intel_encoder->enc.dev; | 1144 | struct drm_device *dev = intel_dp->base.enc.dev; |
1111 | struct drm_i915_private *dev_priv = dev->dev_private; | 1145 | struct drm_i915_private *dev_priv = dev->dev_private; |
1112 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 1146 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc); |
1113 | int ret; | 1147 | int ret; |
1114 | 1148 | ||
1115 | I915_WRITE(dp_priv->output_reg, dp_reg_value); | 1149 | I915_WRITE(intel_dp->output_reg, dp_reg_value); |
1116 | POSTING_READ(dp_priv->output_reg); | 1150 | POSTING_READ(intel_dp->output_reg); |
1117 | if (first) | 1151 | if (first) |
1118 | intel_wait_for_vblank(dev); | 1152 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1119 | 1153 | ||
1120 | intel_dp_aux_native_write_1(intel_encoder, | 1154 | intel_dp_aux_native_write_1(intel_dp, |
1121 | DP_TRAINING_PATTERN_SET, | 1155 | DP_TRAINING_PATTERN_SET, |
1122 | dp_train_pat); | 1156 | dp_train_pat); |
1123 | 1157 | ||
1124 | ret = intel_dp_aux_native_write(intel_encoder, | 1158 | ret = intel_dp_aux_native_write(intel_dp, |
1125 | DP_TRAINING_LANE0_SET, train_set, 4); | 1159 | DP_TRAINING_LANE0_SET, train_set, 4); |
1126 | if (ret != 4) | 1160 | if (ret != 4) |
1127 | return false; | 1161 | return false; |
@@ -1130,12 +1164,10 @@ intel_dp_set_link_train(struct intel_encoder *intel_encoder, | |||
1130 | } | 1164 | } |
1131 | 1165 | ||
1132 | static void | 1166 | static void |
1133 | intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | 1167 | intel_dp_link_train(struct intel_dp *intel_dp) |
1134 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]) | ||
1135 | { | 1168 | { |
1136 | struct drm_device *dev = intel_encoder->enc.dev; | 1169 | struct drm_device *dev = intel_dp->base.enc.dev; |
1137 | struct drm_i915_private *dev_priv = dev->dev_private; | 1170 | struct drm_i915_private *dev_priv = dev->dev_private; |
1138 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
1139 | uint8_t train_set[4]; | 1171 | uint8_t train_set[4]; |
1140 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | 1172 | uint8_t link_status[DP_LINK_STATUS_SIZE]; |
1141 | int i; | 1173 | int i; |
@@ -1145,13 +1177,15 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
1145 | bool first = true; | 1177 | bool first = true; |
1146 | int tries; | 1178 | int tries; |
1147 | u32 reg; | 1179 | u32 reg; |
1180 | uint32_t DP = intel_dp->DP; | ||
1148 | 1181 | ||
1149 | /* Write the link configuration data */ | 1182 | /* Write the link configuration data */ |
1150 | intel_dp_aux_native_write(intel_encoder, DP_LINK_BW_SET, | 1183 | intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, |
1151 | link_configuration, DP_LINK_CONFIGURATION_SIZE); | 1184 | intel_dp->link_configuration, |
1185 | DP_LINK_CONFIGURATION_SIZE); | ||
1152 | 1186 | ||
1153 | DP |= DP_PORT_EN; | 1187 | DP |= DP_PORT_EN; |
1154 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 1188 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
1155 | DP &= ~DP_LINK_TRAIN_MASK_CPT; | 1189 | DP &= ~DP_LINK_TRAIN_MASK_CPT; |
1156 | else | 1190 | else |
1157 | DP &= ~DP_LINK_TRAIN_MASK; | 1191 | DP &= ~DP_LINK_TRAIN_MASK; |
@@ -1162,39 +1196,39 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
1162 | for (;;) { | 1196 | for (;;) { |
1163 | /* Use train_set[0] to set the voltage and pre emphasis values */ | 1197 | /* Use train_set[0] to set the voltage and pre emphasis values */ |
1164 | uint32_t signal_levels; | 1198 | uint32_t signal_levels; |
1165 | if (IS_GEN6(dev) && IS_eDP(intel_encoder)) { | 1199 | if (IS_GEN6(dev) && IS_eDP(intel_dp)) { |
1166 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); | 1200 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); |
1167 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1201 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
1168 | } else { | 1202 | } else { |
1169 | signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); | 1203 | signal_levels = intel_dp_signal_levels(train_set[0], intel_dp->lane_count); |
1170 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1204 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1171 | } | 1205 | } |
1172 | 1206 | ||
1173 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 1207 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
1174 | reg = DP | DP_LINK_TRAIN_PAT_1_CPT; | 1208 | reg = DP | DP_LINK_TRAIN_PAT_1_CPT; |
1175 | else | 1209 | else |
1176 | reg = DP | DP_LINK_TRAIN_PAT_1; | 1210 | reg = DP | DP_LINK_TRAIN_PAT_1; |
1177 | 1211 | ||
1178 | if (!intel_dp_set_link_train(intel_encoder, reg, | 1212 | if (!intel_dp_set_link_train(intel_dp, reg, |
1179 | DP_TRAINING_PATTERN_1, train_set, first)) | 1213 | DP_TRAINING_PATTERN_1, train_set, first)) |
1180 | break; | 1214 | break; |
1181 | first = false; | 1215 | first = false; |
1182 | /* Set training pattern 1 */ | 1216 | /* Set training pattern 1 */ |
1183 | 1217 | ||
1184 | udelay(100); | 1218 | udelay(100); |
1185 | if (!intel_dp_get_link_status(intel_encoder, link_status)) | 1219 | if (!intel_dp_get_link_status(intel_dp, link_status)) |
1186 | break; | 1220 | break; |
1187 | 1221 | ||
1188 | if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) { | 1222 | if (intel_clock_recovery_ok(link_status, intel_dp->lane_count)) { |
1189 | clock_recovery = true; | 1223 | clock_recovery = true; |
1190 | break; | 1224 | break; |
1191 | } | 1225 | } |
1192 | 1226 | ||
1193 | /* Check to see if we've tried the max voltage */ | 1227 | /* Check to see if we've tried the max voltage */ |
1194 | for (i = 0; i < dp_priv->lane_count; i++) | 1228 | for (i = 0; i < intel_dp->lane_count; i++) |
1195 | if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | 1229 | if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) |
1196 | break; | 1230 | break; |
1197 | if (i == dp_priv->lane_count) | 1231 | if (i == intel_dp->lane_count) |
1198 | break; | 1232 | break; |
1199 | 1233 | ||
1200 | /* Check to see if we've tried the same voltage 5 times */ | 1234 | /* Check to see if we've tried the same voltage 5 times */ |
@@ -1207,7 +1241,7 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
1207 | voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | 1241 | voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; |
1208 | 1242 | ||
1209 | /* Compute new train_set as requested by target */ | 1243 | /* Compute new train_set as requested by target */ |
1210 | intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set); | 1244 | intel_get_adjust_train(intel_dp, link_status, intel_dp->lane_count, train_set); |
1211 | } | 1245 | } |
1212 | 1246 | ||
1213 | /* channel equalization */ | 1247 | /* channel equalization */ |
@@ -1217,30 +1251,30 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
1217 | /* Use train_set[0] to set the voltage and pre emphasis values */ | 1251 | /* Use train_set[0] to set the voltage and pre emphasis values */ |
1218 | uint32_t signal_levels; | 1252 | uint32_t signal_levels; |
1219 | 1253 | ||
1220 | if (IS_GEN6(dev) && IS_eDP(intel_encoder)) { | 1254 | if (IS_GEN6(dev) && IS_eDP(intel_dp)) { |
1221 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); | 1255 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); |
1222 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1256 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
1223 | } else { | 1257 | } else { |
1224 | signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); | 1258 | signal_levels = intel_dp_signal_levels(train_set[0], intel_dp->lane_count); |
1225 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1259 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1226 | } | 1260 | } |
1227 | 1261 | ||
1228 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 1262 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
1229 | reg = DP | DP_LINK_TRAIN_PAT_2_CPT; | 1263 | reg = DP | DP_LINK_TRAIN_PAT_2_CPT; |
1230 | else | 1264 | else |
1231 | reg = DP | DP_LINK_TRAIN_PAT_2; | 1265 | reg = DP | DP_LINK_TRAIN_PAT_2; |
1232 | 1266 | ||
1233 | /* channel eq pattern */ | 1267 | /* channel eq pattern */ |
1234 | if (!intel_dp_set_link_train(intel_encoder, reg, | 1268 | if (!intel_dp_set_link_train(intel_dp, reg, |
1235 | DP_TRAINING_PATTERN_2, train_set, | 1269 | DP_TRAINING_PATTERN_2, train_set, |
1236 | false)) | 1270 | false)) |
1237 | break; | 1271 | break; |
1238 | 1272 | ||
1239 | udelay(400); | 1273 | udelay(400); |
1240 | if (!intel_dp_get_link_status(intel_encoder, link_status)) | 1274 | if (!intel_dp_get_link_status(intel_dp, link_status)) |
1241 | break; | 1275 | break; |
1242 | 1276 | ||
1243 | if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) { | 1277 | if (intel_channel_eq_ok(link_status, intel_dp->lane_count)) { |
1244 | channel_eq = true; | 1278 | channel_eq = true; |
1245 | break; | 1279 | break; |
1246 | } | 1280 | } |
@@ -1250,53 +1284,53 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
1250 | break; | 1284 | break; |
1251 | 1285 | ||
1252 | /* Compute new train_set as requested by target */ | 1286 | /* Compute new train_set as requested by target */ |
1253 | intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set); | 1287 | intel_get_adjust_train(intel_dp, link_status, intel_dp->lane_count, train_set); |
1254 | ++tries; | 1288 | ++tries; |
1255 | } | 1289 | } |
1256 | 1290 | ||
1257 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 1291 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
1258 | reg = DP | DP_LINK_TRAIN_OFF_CPT; | 1292 | reg = DP | DP_LINK_TRAIN_OFF_CPT; |
1259 | else | 1293 | else |
1260 | reg = DP | DP_LINK_TRAIN_OFF; | 1294 | reg = DP | DP_LINK_TRAIN_OFF; |
1261 | 1295 | ||
1262 | I915_WRITE(dp_priv->output_reg, reg); | 1296 | I915_WRITE(intel_dp->output_reg, reg); |
1263 | POSTING_READ(dp_priv->output_reg); | 1297 | POSTING_READ(intel_dp->output_reg); |
1264 | intel_dp_aux_native_write_1(intel_encoder, | 1298 | intel_dp_aux_native_write_1(intel_dp, |
1265 | DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); | 1299 | DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); |
1266 | } | 1300 | } |
1267 | 1301 | ||
1268 | static void | 1302 | static void |
1269 | intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP) | 1303 | intel_dp_link_down(struct intel_dp *intel_dp) |
1270 | { | 1304 | { |
1271 | struct drm_device *dev = intel_encoder->enc.dev; | 1305 | struct drm_device *dev = intel_dp->base.enc.dev; |
1272 | struct drm_i915_private *dev_priv = dev->dev_private; | 1306 | struct drm_i915_private *dev_priv = dev->dev_private; |
1273 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 1307 | uint32_t DP = intel_dp->DP; |
1274 | 1308 | ||
1275 | DRM_DEBUG_KMS("\n"); | 1309 | DRM_DEBUG_KMS("\n"); |
1276 | 1310 | ||
1277 | if (IS_eDP(intel_encoder)) { | 1311 | if (IS_eDP(intel_dp)) { |
1278 | DP &= ~DP_PLL_ENABLE; | 1312 | DP &= ~DP_PLL_ENABLE; |
1279 | I915_WRITE(dp_priv->output_reg, DP); | 1313 | I915_WRITE(intel_dp->output_reg, DP); |
1280 | POSTING_READ(dp_priv->output_reg); | 1314 | POSTING_READ(intel_dp->output_reg); |
1281 | udelay(100); | 1315 | udelay(100); |
1282 | } | 1316 | } |
1283 | 1317 | ||
1284 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) { | 1318 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) { |
1285 | DP &= ~DP_LINK_TRAIN_MASK_CPT; | 1319 | DP &= ~DP_LINK_TRAIN_MASK_CPT; |
1286 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT); | 1320 | I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT); |
1287 | POSTING_READ(dp_priv->output_reg); | 1321 | POSTING_READ(intel_dp->output_reg); |
1288 | } else { | 1322 | } else { |
1289 | DP &= ~DP_LINK_TRAIN_MASK; | 1323 | DP &= ~DP_LINK_TRAIN_MASK; |
1290 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); | 1324 | I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); |
1291 | POSTING_READ(dp_priv->output_reg); | 1325 | POSTING_READ(intel_dp->output_reg); |
1292 | } | 1326 | } |
1293 | 1327 | ||
1294 | udelay(17000); | 1328 | udelay(17000); |
1295 | 1329 | ||
1296 | if (IS_eDP(intel_encoder)) | 1330 | if (IS_eDP(intel_dp)) |
1297 | DP |= DP_LINK_TRAIN_OFF; | 1331 | DP |= DP_LINK_TRAIN_OFF; |
1298 | I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); | 1332 | I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); |
1299 | POSTING_READ(dp_priv->output_reg); | 1333 | POSTING_READ(intel_dp->output_reg); |
1300 | } | 1334 | } |
1301 | 1335 | ||
1302 | /* | 1336 | /* |
@@ -1309,41 +1343,39 @@ intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP) | |||
1309 | */ | 1343 | */ |
1310 | 1344 | ||
1311 | static void | 1345 | static void |
1312 | intel_dp_check_link_status(struct intel_encoder *intel_encoder) | 1346 | intel_dp_check_link_status(struct intel_dp *intel_dp) |
1313 | { | 1347 | { |
1314 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
1315 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | 1348 | uint8_t link_status[DP_LINK_STATUS_SIZE]; |
1316 | 1349 | ||
1317 | if (!intel_encoder->enc.crtc) | 1350 | if (!intel_dp->base.enc.crtc) |
1318 | return; | 1351 | return; |
1319 | 1352 | ||
1320 | if (!intel_dp_get_link_status(intel_encoder, link_status)) { | 1353 | if (!intel_dp_get_link_status(intel_dp, link_status)) { |
1321 | intel_dp_link_down(intel_encoder, dp_priv->DP); | 1354 | intel_dp_link_down(intel_dp); |
1322 | return; | 1355 | return; |
1323 | } | 1356 | } |
1324 | 1357 | ||
1325 | if (!intel_channel_eq_ok(link_status, dp_priv->lane_count)) | 1358 | if (!intel_channel_eq_ok(link_status, intel_dp->lane_count)) |
1326 | intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); | 1359 | intel_dp_link_train(intel_dp); |
1327 | } | 1360 | } |
1328 | 1361 | ||
1329 | static enum drm_connector_status | 1362 | static enum drm_connector_status |
1330 | ironlake_dp_detect(struct drm_connector *connector) | 1363 | ironlake_dp_detect(struct drm_connector *connector) |
1331 | { | 1364 | { |
1332 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1365 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1333 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1366 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1334 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
1335 | enum drm_connector_status status; | 1367 | enum drm_connector_status status; |
1336 | 1368 | ||
1337 | status = connector_status_disconnected; | 1369 | status = connector_status_disconnected; |
1338 | if (intel_dp_aux_native_read(intel_encoder, | 1370 | if (intel_dp_aux_native_read(intel_dp, |
1339 | 0x000, dp_priv->dpcd, | 1371 | 0x000, intel_dp->dpcd, |
1340 | sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) | 1372 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) |
1341 | { | 1373 | { |
1342 | if (dp_priv->dpcd[0] != 0) | 1374 | if (intel_dp->dpcd[0] != 0) |
1343 | status = connector_status_connected; | 1375 | status = connector_status_connected; |
1344 | } | 1376 | } |
1345 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", dp_priv->dpcd[0], | 1377 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0], |
1346 | dp_priv->dpcd[1], dp_priv->dpcd[2], dp_priv->dpcd[3]); | 1378 | intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]); |
1347 | return status; | 1379 | return status; |
1348 | } | 1380 | } |
1349 | 1381 | ||
@@ -1357,19 +1389,18 @@ static enum drm_connector_status | |||
1357 | intel_dp_detect(struct drm_connector *connector) | 1389 | intel_dp_detect(struct drm_connector *connector) |
1358 | { | 1390 | { |
1359 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1391 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1360 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1392 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1361 | struct drm_device *dev = intel_encoder->enc.dev; | 1393 | struct drm_device *dev = intel_dp->base.enc.dev; |
1362 | struct drm_i915_private *dev_priv = dev->dev_private; | 1394 | struct drm_i915_private *dev_priv = dev->dev_private; |
1363 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
1364 | uint32_t temp, bit; | 1395 | uint32_t temp, bit; |
1365 | enum drm_connector_status status; | 1396 | enum drm_connector_status status; |
1366 | 1397 | ||
1367 | dp_priv->has_audio = false; | 1398 | intel_dp->has_audio = false; |
1368 | 1399 | ||
1369 | if (HAS_PCH_SPLIT(dev)) | 1400 | if (HAS_PCH_SPLIT(dev)) |
1370 | return ironlake_dp_detect(connector); | 1401 | return ironlake_dp_detect(connector); |
1371 | 1402 | ||
1372 | switch (dp_priv->output_reg) { | 1403 | switch (intel_dp->output_reg) { |
1373 | case DP_B: | 1404 | case DP_B: |
1374 | bit = DPB_HOTPLUG_INT_STATUS; | 1405 | bit = DPB_HOTPLUG_INT_STATUS; |
1375 | break; | 1406 | break; |
@@ -1389,11 +1420,11 @@ intel_dp_detect(struct drm_connector *connector) | |||
1389 | return connector_status_disconnected; | 1420 | return connector_status_disconnected; |
1390 | 1421 | ||
1391 | status = connector_status_disconnected; | 1422 | status = connector_status_disconnected; |
1392 | if (intel_dp_aux_native_read(intel_encoder, | 1423 | if (intel_dp_aux_native_read(intel_dp, |
1393 | 0x000, dp_priv->dpcd, | 1424 | 0x000, intel_dp->dpcd, |
1394 | sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) | 1425 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) |
1395 | { | 1426 | { |
1396 | if (dp_priv->dpcd[0] != 0) | 1427 | if (intel_dp->dpcd[0] != 0) |
1397 | status = connector_status_connected; | 1428 | status = connector_status_connected; |
1398 | } | 1429 | } |
1399 | return status; | 1430 | return status; |
@@ -1402,18 +1433,17 @@ intel_dp_detect(struct drm_connector *connector) | |||
1402 | static int intel_dp_get_modes(struct drm_connector *connector) | 1433 | static int intel_dp_get_modes(struct drm_connector *connector) |
1403 | { | 1434 | { |
1404 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1435 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1405 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1436 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1406 | struct drm_device *dev = intel_encoder->enc.dev; | 1437 | struct drm_device *dev = intel_dp->base.enc.dev; |
1407 | struct drm_i915_private *dev_priv = dev->dev_private; | 1438 | struct drm_i915_private *dev_priv = dev->dev_private; |
1408 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
1409 | int ret; | 1439 | int ret; |
1410 | 1440 | ||
1411 | /* We should parse the EDID data and find out if it has an audio sink | 1441 | /* We should parse the EDID data and find out if it has an audio sink |
1412 | */ | 1442 | */ |
1413 | 1443 | ||
1414 | ret = intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 1444 | ret = intel_ddc_get_modes(connector, intel_dp->base.ddc_bus); |
1415 | if (ret) { | 1445 | if (ret) { |
1416 | if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) && | 1446 | if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) && |
1417 | !dev_priv->panel_fixed_mode) { | 1447 | !dev_priv->panel_fixed_mode) { |
1418 | struct drm_display_mode *newmode; | 1448 | struct drm_display_mode *newmode; |
1419 | list_for_each_entry(newmode, &connector->probed_modes, | 1449 | list_for_each_entry(newmode, &connector->probed_modes, |
@@ -1430,7 +1460,7 @@ static int intel_dp_get_modes(struct drm_connector *connector) | |||
1430 | } | 1460 | } |
1431 | 1461 | ||
1432 | /* if eDP has no EDID, try to use fixed panel mode from VBT */ | 1462 | /* if eDP has no EDID, try to use fixed panel mode from VBT */ |
1433 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { | 1463 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) { |
1434 | if (dev_priv->panel_fixed_mode != NULL) { | 1464 | if (dev_priv->panel_fixed_mode != NULL) { |
1435 | struct drm_display_mode *mode; | 1465 | struct drm_display_mode *mode; |
1436 | mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); | 1466 | mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); |
@@ -1452,9 +1482,9 @@ intel_dp_destroy (struct drm_connector *connector) | |||
1452 | static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { | 1482 | static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { |
1453 | .dpms = intel_dp_dpms, | 1483 | .dpms = intel_dp_dpms, |
1454 | .mode_fixup = intel_dp_mode_fixup, | 1484 | .mode_fixup = intel_dp_mode_fixup, |
1455 | .prepare = intel_encoder_prepare, | 1485 | .prepare = intel_dp_prepare, |
1456 | .mode_set = intel_dp_mode_set, | 1486 | .mode_set = intel_dp_mode_set, |
1457 | .commit = intel_encoder_commit, | 1487 | .commit = intel_dp_commit, |
1458 | }; | 1488 | }; |
1459 | 1489 | ||
1460 | static const struct drm_connector_funcs intel_dp_connector_funcs = { | 1490 | static const struct drm_connector_funcs intel_dp_connector_funcs = { |
@@ -1470,27 +1500,17 @@ static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = | |||
1470 | .best_encoder = intel_attached_encoder, | 1500 | .best_encoder = intel_attached_encoder, |
1471 | }; | 1501 | }; |
1472 | 1502 | ||
1473 | static void intel_dp_enc_destroy(struct drm_encoder *encoder) | ||
1474 | { | ||
1475 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1476 | |||
1477 | if (intel_encoder->i2c_bus) | ||
1478 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
1479 | drm_encoder_cleanup(encoder); | ||
1480 | kfree(intel_encoder); | ||
1481 | } | ||
1482 | |||
1483 | static const struct drm_encoder_funcs intel_dp_enc_funcs = { | 1503 | static const struct drm_encoder_funcs intel_dp_enc_funcs = { |
1484 | .destroy = intel_dp_enc_destroy, | 1504 | .destroy = intel_encoder_destroy, |
1485 | }; | 1505 | }; |
1486 | 1506 | ||
1487 | void | 1507 | void |
1488 | intel_dp_hot_plug(struct intel_encoder *intel_encoder) | 1508 | intel_dp_hot_plug(struct intel_encoder *intel_encoder) |
1489 | { | 1509 | { |
1490 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 1510 | struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); |
1491 | 1511 | ||
1492 | if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON) | 1512 | if (intel_dp->dpms_mode == DRM_MODE_DPMS_ON) |
1493 | intel_dp_check_link_status(intel_encoder); | 1513 | intel_dp_check_link_status(intel_dp); |
1494 | } | 1514 | } |
1495 | 1515 | ||
1496 | /* Return which DP Port should be selected for Transcoder DP control */ | 1516 | /* Return which DP Port should be selected for Transcoder DP control */ |
@@ -1500,18 +1520,18 @@ intel_trans_dp_port_sel (struct drm_crtc *crtc) | |||
1500 | struct drm_device *dev = crtc->dev; | 1520 | struct drm_device *dev = crtc->dev; |
1501 | struct drm_mode_config *mode_config = &dev->mode_config; | 1521 | struct drm_mode_config *mode_config = &dev->mode_config; |
1502 | struct drm_encoder *encoder; | 1522 | struct drm_encoder *encoder; |
1503 | struct intel_encoder *intel_encoder = NULL; | ||
1504 | 1523 | ||
1505 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | 1524 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
1525 | struct intel_dp *intel_dp; | ||
1526 | |||
1506 | if (encoder->crtc != crtc) | 1527 | if (encoder->crtc != crtc) |
1507 | continue; | 1528 | continue; |
1508 | 1529 | ||
1509 | intel_encoder = enc_to_intel_encoder(encoder); | 1530 | intel_dp = enc_to_intel_dp(encoder); |
1510 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { | 1531 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) |
1511 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 1532 | return intel_dp->output_reg; |
1512 | return dp_priv->output_reg; | ||
1513 | } | ||
1514 | } | 1533 | } |
1534 | |||
1515 | return -1; | 1535 | return -1; |
1516 | } | 1536 | } |
1517 | 1537 | ||
@@ -1540,30 +1560,28 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1540 | { | 1560 | { |
1541 | struct drm_i915_private *dev_priv = dev->dev_private; | 1561 | struct drm_i915_private *dev_priv = dev->dev_private; |
1542 | struct drm_connector *connector; | 1562 | struct drm_connector *connector; |
1563 | struct intel_dp *intel_dp; | ||
1543 | struct intel_encoder *intel_encoder; | 1564 | struct intel_encoder *intel_encoder; |
1544 | struct intel_connector *intel_connector; | 1565 | struct intel_connector *intel_connector; |
1545 | struct intel_dp_priv *dp_priv; | ||
1546 | const char *name = NULL; | 1566 | const char *name = NULL; |
1547 | int type; | 1567 | int type; |
1548 | 1568 | ||
1549 | intel_encoder = kcalloc(sizeof(struct intel_encoder) + | 1569 | intel_dp = kzalloc(sizeof(struct intel_dp), GFP_KERNEL); |
1550 | sizeof(struct intel_dp_priv), 1, GFP_KERNEL); | 1570 | if (!intel_dp) |
1551 | if (!intel_encoder) | ||
1552 | return; | 1571 | return; |
1553 | 1572 | ||
1554 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 1573 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
1555 | if (!intel_connector) { | 1574 | if (!intel_connector) { |
1556 | kfree(intel_encoder); | 1575 | kfree(intel_dp); |
1557 | return; | 1576 | return; |
1558 | } | 1577 | } |
1578 | intel_encoder = &intel_dp->base; | ||
1559 | 1579 | ||
1560 | dp_priv = (struct intel_dp_priv *)(intel_encoder + 1); | 1580 | if (HAS_PCH_SPLIT(dev) && output_reg == PCH_DP_D) |
1561 | |||
1562 | if (HAS_PCH_SPLIT(dev) && (output_reg == PCH_DP_D)) | ||
1563 | if (intel_dpd_is_edp(dev)) | 1581 | if (intel_dpd_is_edp(dev)) |
1564 | dp_priv->is_pch_edp = true; | 1582 | intel_dp->is_pch_edp = true; |
1565 | 1583 | ||
1566 | if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) { | 1584 | if (output_reg == DP_A || IS_PCH_eDP(intel_dp)) { |
1567 | type = DRM_MODE_CONNECTOR_eDP; | 1585 | type = DRM_MODE_CONNECTOR_eDP; |
1568 | intel_encoder->type = INTEL_OUTPUT_EDP; | 1586 | intel_encoder->type = INTEL_OUTPUT_EDP; |
1569 | } else { | 1587 | } else { |
@@ -1584,18 +1602,16 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1584 | else if (output_reg == DP_D || output_reg == PCH_DP_D) | 1602 | else if (output_reg == DP_D || output_reg == PCH_DP_D) |
1585 | intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); | 1603 | intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); |
1586 | 1604 | ||
1587 | if (IS_eDP(intel_encoder)) | 1605 | if (IS_eDP(intel_dp)) |
1588 | intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT); | 1606 | intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT); |
1589 | 1607 | ||
1590 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 1608 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
1591 | connector->interlace_allowed = true; | 1609 | connector->interlace_allowed = true; |
1592 | connector->doublescan_allowed = 0; | 1610 | connector->doublescan_allowed = 0; |
1593 | 1611 | ||
1594 | dp_priv->intel_encoder = intel_encoder; | 1612 | intel_dp->output_reg = output_reg; |
1595 | dp_priv->output_reg = output_reg; | 1613 | intel_dp->has_audio = false; |
1596 | dp_priv->has_audio = false; | 1614 | intel_dp->dpms_mode = DRM_MODE_DPMS_ON; |
1597 | dp_priv->dpms_mode = DRM_MODE_DPMS_ON; | ||
1598 | intel_encoder->dev_priv = dp_priv; | ||
1599 | 1615 | ||
1600 | drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs, | 1616 | drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs, |
1601 | DRM_MODE_ENCODER_TMDS); | 1617 | DRM_MODE_ENCODER_TMDS); |
@@ -1630,12 +1646,12 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1630 | break; | 1646 | break; |
1631 | } | 1647 | } |
1632 | 1648 | ||
1633 | intel_dp_i2c_init(intel_encoder, intel_connector, name); | 1649 | intel_dp_i2c_init(intel_dp, intel_connector, name); |
1634 | 1650 | ||
1635 | intel_encoder->ddc_bus = &dp_priv->adapter; | 1651 | intel_encoder->ddc_bus = &intel_dp->adapter; |
1636 | intel_encoder->hot_plug = intel_dp_hot_plug; | 1652 | intel_encoder->hot_plug = intel_dp_hot_plug; |
1637 | 1653 | ||
1638 | if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) { | 1654 | if (output_reg == DP_A || IS_PCH_eDP(intel_dp)) { |
1639 | /* initialize panel mode from VBT if available for eDP */ | 1655 | /* initialize panel mode from VBT if available for eDP */ |
1640 | if (dev_priv->lfp_lvds_vbt_mode) { | 1656 | if (dev_priv->lfp_lvds_vbt_mode) { |
1641 | dev_priv->panel_fixed_mode = | 1657 | dev_priv->panel_fixed_mode = |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index b2190148703..ad312ca6b3e 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -32,6 +32,20 @@ | |||
32 | #include "drm_crtc.h" | 32 | #include "drm_crtc.h" |
33 | 33 | ||
34 | #include "drm_crtc_helper.h" | 34 | #include "drm_crtc_helper.h" |
35 | |||
36 | #define wait_for(COND, MS, W) ({ \ | ||
37 | unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \ | ||
38 | int ret__ = 0; \ | ||
39 | while (! (COND)) { \ | ||
40 | if (time_after(jiffies, timeout__)) { \ | ||
41 | ret__ = -ETIMEDOUT; \ | ||
42 | break; \ | ||
43 | } \ | ||
44 | if (W) msleep(W); \ | ||
45 | } \ | ||
46 | ret__; \ | ||
47 | }) | ||
48 | |||
35 | /* | 49 | /* |
36 | * Display related stuff | 50 | * Display related stuff |
37 | */ | 51 | */ |
@@ -102,7 +116,6 @@ struct intel_encoder { | |||
102 | struct i2c_adapter *ddc_bus; | 116 | struct i2c_adapter *ddc_bus; |
103 | bool load_detect_temp; | 117 | bool load_detect_temp; |
104 | bool needs_tv_clock; | 118 | bool needs_tv_clock; |
105 | void *dev_priv; | ||
106 | void (*hot_plug)(struct intel_encoder *); | 119 | void (*hot_plug)(struct intel_encoder *); |
107 | int crtc_mask; | 120 | int crtc_mask; |
108 | int clone_mask; | 121 | int clone_mask; |
@@ -110,7 +123,6 @@ struct intel_encoder { | |||
110 | 123 | ||
111 | struct intel_connector { | 124 | struct intel_connector { |
112 | struct drm_connector base; | 125 | struct drm_connector base; |
113 | void *dev_priv; | ||
114 | }; | 126 | }; |
115 | 127 | ||
116 | struct intel_crtc; | 128 | struct intel_crtc; |
@@ -156,7 +168,7 @@ struct intel_crtc { | |||
156 | uint32_t cursor_addr; | 168 | uint32_t cursor_addr; |
157 | int16_t cursor_x, cursor_y; | 169 | int16_t cursor_x, cursor_y; |
158 | int16_t cursor_width, cursor_height; | 170 | int16_t cursor_width, cursor_height; |
159 | bool cursor_visble; | 171 | bool cursor_visible, cursor_on; |
160 | }; | 172 | }; |
161 | 173 | ||
162 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) | 174 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) |
@@ -164,6 +176,16 @@ struct intel_crtc { | |||
164 | #define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc) | 176 | #define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc) |
165 | #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) | 177 | #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) |
166 | 178 | ||
179 | struct intel_unpin_work { | ||
180 | struct work_struct work; | ||
181 | struct drm_device *dev; | ||
182 | struct drm_gem_object *old_fb_obj; | ||
183 | struct drm_gem_object *pending_flip_obj; | ||
184 | struct drm_pending_vblank_event *event; | ||
185 | int pending; | ||
186 | bool enable_stall_check; | ||
187 | }; | ||
188 | |||
167 | struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, | 189 | struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, |
168 | const char *name); | 190 | const char *name); |
169 | void intel_i2c_destroy(struct i2c_adapter *adapter); | 191 | void intel_i2c_destroy(struct i2c_adapter *adapter); |
@@ -188,10 +210,18 @@ extern bool intel_dpd_is_edp(struct drm_device *dev); | |||
188 | extern void intel_edp_link_config (struct intel_encoder *, int *, int *); | 210 | extern void intel_edp_link_config (struct intel_encoder *, int *, int *); |
189 | 211 | ||
190 | 212 | ||
213 | extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, | ||
214 | struct drm_display_mode *adjusted_mode); | ||
215 | extern void intel_pch_panel_fitting(struct drm_device *dev, | ||
216 | int fitting_mode, | ||
217 | struct drm_display_mode *mode, | ||
218 | struct drm_display_mode *adjusted_mode); | ||
219 | |||
191 | extern int intel_panel_fitter_pipe (struct drm_device *dev); | 220 | extern int intel_panel_fitter_pipe (struct drm_device *dev); |
192 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); | 221 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); |
193 | extern void intel_encoder_prepare (struct drm_encoder *encoder); | 222 | extern void intel_encoder_prepare (struct drm_encoder *encoder); |
194 | extern void intel_encoder_commit (struct drm_encoder *encoder); | 223 | extern void intel_encoder_commit (struct drm_encoder *encoder); |
224 | extern void intel_encoder_destroy(struct drm_encoder *encoder); | ||
195 | 225 | ||
196 | extern struct drm_encoder *intel_attached_encoder(struct drm_connector *connector); | 226 | extern struct drm_encoder *intel_attached_encoder(struct drm_connector *connector); |
197 | 227 | ||
@@ -199,7 +229,8 @@ extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, | |||
199 | struct drm_crtc *crtc); | 229 | struct drm_crtc *crtc); |
200 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 230 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
201 | struct drm_file *file_priv); | 231 | struct drm_file *file_priv); |
202 | extern void intel_wait_for_vblank(struct drm_device *dev); | 232 | extern void intel_wait_for_vblank_off(struct drm_device *dev, int pipe); |
233 | extern void intel_wait_for_vblank(struct drm_device *dev, int pipe); | ||
203 | extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); | 234 | extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); |
204 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, | 235 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, |
205 | struct drm_connector *connector, | 236 | struct drm_connector *connector, |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 227feca7cf8..a399f4b2c1c 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #define CH7xxx_ADDR 0x76 | 38 | #define CH7xxx_ADDR 0x76 |
39 | #define TFP410_ADDR 0x38 | 39 | #define TFP410_ADDR 0x38 |
40 | 40 | ||
41 | static struct intel_dvo_device intel_dvo_devices[] = { | 41 | static const struct intel_dvo_device intel_dvo_devices[] = { |
42 | { | 42 | { |
43 | .type = INTEL_DVO_CHIP_TMDS, | 43 | .type = INTEL_DVO_CHIP_TMDS, |
44 | .name = "sil164", | 44 | .name = "sil164", |
@@ -77,20 +77,33 @@ static struct intel_dvo_device intel_dvo_devices[] = { | |||
77 | } | 77 | } |
78 | }; | 78 | }; |
79 | 79 | ||
80 | struct intel_dvo { | ||
81 | struct intel_encoder base; | ||
82 | |||
83 | struct intel_dvo_device dev; | ||
84 | |||
85 | struct drm_display_mode *panel_fixed_mode; | ||
86 | bool panel_wants_dither; | ||
87 | }; | ||
88 | |||
89 | static struct intel_dvo *enc_to_intel_dvo(struct drm_encoder *encoder) | ||
90 | { | ||
91 | return container_of(enc_to_intel_encoder(encoder), struct intel_dvo, base); | ||
92 | } | ||
93 | |||
80 | static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) | 94 | static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) |
81 | { | 95 | { |
82 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | 96 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
83 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 97 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
84 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 98 | u32 dvo_reg = intel_dvo->dev.dvo_reg; |
85 | u32 dvo_reg = dvo->dvo_reg; | ||
86 | u32 temp = I915_READ(dvo_reg); | 99 | u32 temp = I915_READ(dvo_reg); |
87 | 100 | ||
88 | if (mode == DRM_MODE_DPMS_ON) { | 101 | if (mode == DRM_MODE_DPMS_ON) { |
89 | I915_WRITE(dvo_reg, temp | DVO_ENABLE); | 102 | I915_WRITE(dvo_reg, temp | DVO_ENABLE); |
90 | I915_READ(dvo_reg); | 103 | I915_READ(dvo_reg); |
91 | dvo->dev_ops->dpms(dvo, mode); | 104 | intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode); |
92 | } else { | 105 | } else { |
93 | dvo->dev_ops->dpms(dvo, mode); | 106 | intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode); |
94 | I915_WRITE(dvo_reg, temp & ~DVO_ENABLE); | 107 | I915_WRITE(dvo_reg, temp & ~DVO_ENABLE); |
95 | I915_READ(dvo_reg); | 108 | I915_READ(dvo_reg); |
96 | } | 109 | } |
@@ -100,38 +113,36 @@ static int intel_dvo_mode_valid(struct drm_connector *connector, | |||
100 | struct drm_display_mode *mode) | 113 | struct drm_display_mode *mode) |
101 | { | 114 | { |
102 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 115 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
103 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 116 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
104 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
105 | 117 | ||
106 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 118 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
107 | return MODE_NO_DBLESCAN; | 119 | return MODE_NO_DBLESCAN; |
108 | 120 | ||
109 | /* XXX: Validate clock range */ | 121 | /* XXX: Validate clock range */ |
110 | 122 | ||
111 | if (dvo->panel_fixed_mode) { | 123 | if (intel_dvo->panel_fixed_mode) { |
112 | if (mode->hdisplay > dvo->panel_fixed_mode->hdisplay) | 124 | if (mode->hdisplay > intel_dvo->panel_fixed_mode->hdisplay) |
113 | return MODE_PANEL; | 125 | return MODE_PANEL; |
114 | if (mode->vdisplay > dvo->panel_fixed_mode->vdisplay) | 126 | if (mode->vdisplay > intel_dvo->panel_fixed_mode->vdisplay) |
115 | return MODE_PANEL; | 127 | return MODE_PANEL; |
116 | } | 128 | } |
117 | 129 | ||
118 | return dvo->dev_ops->mode_valid(dvo, mode); | 130 | return intel_dvo->dev.dev_ops->mode_valid(&intel_dvo->dev, mode); |
119 | } | 131 | } |
120 | 132 | ||
121 | static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, | 133 | static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, |
122 | struct drm_display_mode *mode, | 134 | struct drm_display_mode *mode, |
123 | struct drm_display_mode *adjusted_mode) | 135 | struct drm_display_mode *adjusted_mode) |
124 | { | 136 | { |
125 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 137 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
126 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
127 | 138 | ||
128 | /* If we have timings from the BIOS for the panel, put them in | 139 | /* If we have timings from the BIOS for the panel, put them in |
129 | * to the adjusted mode. The CRTC will be set up for this mode, | 140 | * to the adjusted mode. The CRTC will be set up for this mode, |
130 | * with the panel scaling set up to source from the H/VDisplay | 141 | * with the panel scaling set up to source from the H/VDisplay |
131 | * of the original mode. | 142 | * of the original mode. |
132 | */ | 143 | */ |
133 | if (dvo->panel_fixed_mode != NULL) { | 144 | if (intel_dvo->panel_fixed_mode != NULL) { |
134 | #define C(x) adjusted_mode->x = dvo->panel_fixed_mode->x | 145 | #define C(x) adjusted_mode->x = intel_dvo->panel_fixed_mode->x |
135 | C(hdisplay); | 146 | C(hdisplay); |
136 | C(hsync_start); | 147 | C(hsync_start); |
137 | C(hsync_end); | 148 | C(hsync_end); |
@@ -145,8 +156,8 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, | |||
145 | #undef C | 156 | #undef C |
146 | } | 157 | } |
147 | 158 | ||
148 | if (dvo->dev_ops->mode_fixup) | 159 | if (intel_dvo->dev.dev_ops->mode_fixup) |
149 | return dvo->dev_ops->mode_fixup(dvo, mode, adjusted_mode); | 160 | return intel_dvo->dev.dev_ops->mode_fixup(&intel_dvo->dev, mode, adjusted_mode); |
150 | 161 | ||
151 | return true; | 162 | return true; |
152 | } | 163 | } |
@@ -158,11 +169,10 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, | |||
158 | struct drm_device *dev = encoder->dev; | 169 | struct drm_device *dev = encoder->dev; |
159 | struct drm_i915_private *dev_priv = dev->dev_private; | 170 | struct drm_i915_private *dev_priv = dev->dev_private; |
160 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 171 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
161 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 172 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
162 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
163 | int pipe = intel_crtc->pipe; | 173 | int pipe = intel_crtc->pipe; |
164 | u32 dvo_val; | 174 | u32 dvo_val; |
165 | u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg; | 175 | u32 dvo_reg = intel_dvo->dev.dvo_reg, dvo_srcdim_reg; |
166 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; | 176 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; |
167 | 177 | ||
168 | switch (dvo_reg) { | 178 | switch (dvo_reg) { |
@@ -178,7 +188,7 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, | |||
178 | break; | 188 | break; |
179 | } | 189 | } |
180 | 190 | ||
181 | dvo->dev_ops->mode_set(dvo, mode, adjusted_mode); | 191 | intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev, mode, adjusted_mode); |
182 | 192 | ||
183 | /* Save the data order, since I don't know what it should be set to. */ | 193 | /* Save the data order, since I don't know what it should be set to. */ |
184 | dvo_val = I915_READ(dvo_reg) & | 194 | dvo_val = I915_READ(dvo_reg) & |
@@ -214,40 +224,38 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, | |||
214 | static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) | 224 | static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) |
215 | { | 225 | { |
216 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 226 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
217 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 227 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
218 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
219 | 228 | ||
220 | return dvo->dev_ops->detect(dvo); | 229 | return intel_dvo->dev.dev_ops->detect(&intel_dvo->dev); |
221 | } | 230 | } |
222 | 231 | ||
223 | static int intel_dvo_get_modes(struct drm_connector *connector) | 232 | static int intel_dvo_get_modes(struct drm_connector *connector) |
224 | { | 233 | { |
225 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 234 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
226 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 235 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
227 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
228 | 236 | ||
229 | /* We should probably have an i2c driver get_modes function for those | 237 | /* We should probably have an i2c driver get_modes function for those |
230 | * devices which will have a fixed set of modes determined by the chip | 238 | * devices which will have a fixed set of modes determined by the chip |
231 | * (TV-out, for example), but for now with just TMDS and LVDS, | 239 | * (TV-out, for example), but for now with just TMDS and LVDS, |
232 | * that's not the case. | 240 | * that's not the case. |
233 | */ | 241 | */ |
234 | intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 242 | intel_ddc_get_modes(connector, intel_dvo->base.ddc_bus); |
235 | if (!list_empty(&connector->probed_modes)) | 243 | if (!list_empty(&connector->probed_modes)) |
236 | return 1; | 244 | return 1; |
237 | 245 | ||
238 | 246 | if (intel_dvo->panel_fixed_mode != NULL) { | |
239 | if (dvo->panel_fixed_mode != NULL) { | ||
240 | struct drm_display_mode *mode; | 247 | struct drm_display_mode *mode; |
241 | mode = drm_mode_duplicate(connector->dev, dvo->panel_fixed_mode); | 248 | mode = drm_mode_duplicate(connector->dev, intel_dvo->panel_fixed_mode); |
242 | if (mode) { | 249 | if (mode) { |
243 | drm_mode_probed_add(connector, mode); | 250 | drm_mode_probed_add(connector, mode); |
244 | return 1; | 251 | return 1; |
245 | } | 252 | } |
246 | } | 253 | } |
254 | |||
247 | return 0; | 255 | return 0; |
248 | } | 256 | } |
249 | 257 | ||
250 | static void intel_dvo_destroy (struct drm_connector *connector) | 258 | static void intel_dvo_destroy(struct drm_connector *connector) |
251 | { | 259 | { |
252 | drm_sysfs_connector_remove(connector); | 260 | drm_sysfs_connector_remove(connector); |
253 | drm_connector_cleanup(connector); | 261 | drm_connector_cleanup(connector); |
@@ -277,28 +285,20 @@ static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs | |||
277 | 285 | ||
278 | static void intel_dvo_enc_destroy(struct drm_encoder *encoder) | 286 | static void intel_dvo_enc_destroy(struct drm_encoder *encoder) |
279 | { | 287 | { |
280 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 288 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
281 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 289 | |
282 | 290 | if (intel_dvo->dev.dev_ops->destroy) | |
283 | if (dvo) { | 291 | intel_dvo->dev.dev_ops->destroy(&intel_dvo->dev); |
284 | if (dvo->dev_ops->destroy) | 292 | |
285 | dvo->dev_ops->destroy(dvo); | 293 | kfree(intel_dvo->panel_fixed_mode); |
286 | if (dvo->panel_fixed_mode) | 294 | |
287 | kfree(dvo->panel_fixed_mode); | 295 | intel_encoder_destroy(encoder); |
288 | } | ||
289 | if (intel_encoder->i2c_bus) | ||
290 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
291 | if (intel_encoder->ddc_bus) | ||
292 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
293 | drm_encoder_cleanup(encoder); | ||
294 | kfree(intel_encoder); | ||
295 | } | 296 | } |
296 | 297 | ||
297 | static const struct drm_encoder_funcs intel_dvo_enc_funcs = { | 298 | static const struct drm_encoder_funcs intel_dvo_enc_funcs = { |
298 | .destroy = intel_dvo_enc_destroy, | 299 | .destroy = intel_dvo_enc_destroy, |
299 | }; | 300 | }; |
300 | 301 | ||
301 | |||
302 | /** | 302 | /** |
303 | * Attempts to get a fixed panel timing for LVDS (currently only the i830). | 303 | * Attempts to get a fixed panel timing for LVDS (currently only the i830). |
304 | * | 304 | * |
@@ -306,15 +306,13 @@ static const struct drm_encoder_funcs intel_dvo_enc_funcs = { | |||
306 | * chip being on DVOB/C and having multiple pipes. | 306 | * chip being on DVOB/C and having multiple pipes. |
307 | */ | 307 | */ |
308 | static struct drm_display_mode * | 308 | static struct drm_display_mode * |
309 | intel_dvo_get_current_mode (struct drm_connector *connector) | 309 | intel_dvo_get_current_mode(struct drm_connector *connector) |
310 | { | 310 | { |
311 | struct drm_device *dev = connector->dev; | 311 | struct drm_device *dev = connector->dev; |
312 | struct drm_i915_private *dev_priv = dev->dev_private; | 312 | struct drm_i915_private *dev_priv = dev->dev_private; |
313 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 313 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
314 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 314 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
315 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 315 | uint32_t dvo_val = I915_READ(intel_dvo->dev.dvo_reg); |
316 | uint32_t dvo_reg = dvo->dvo_reg; | ||
317 | uint32_t dvo_val = I915_READ(dvo_reg); | ||
318 | struct drm_display_mode *mode = NULL; | 316 | struct drm_display_mode *mode = NULL; |
319 | 317 | ||
320 | /* If the DVO port is active, that'll be the LVDS, so we can pull out | 318 | /* If the DVO port is active, that'll be the LVDS, so we can pull out |
@@ -327,7 +325,6 @@ intel_dvo_get_current_mode (struct drm_connector *connector) | |||
327 | crtc = intel_get_crtc_from_pipe(dev, pipe); | 325 | crtc = intel_get_crtc_from_pipe(dev, pipe); |
328 | if (crtc) { | 326 | if (crtc) { |
329 | mode = intel_crtc_mode_get(dev, crtc); | 327 | mode = intel_crtc_mode_get(dev, crtc); |
330 | |||
331 | if (mode) { | 328 | if (mode) { |
332 | mode->type |= DRM_MODE_TYPE_PREFERRED; | 329 | mode->type |= DRM_MODE_TYPE_PREFERRED; |
333 | if (dvo_val & DVO_HSYNC_ACTIVE_HIGH) | 330 | if (dvo_val & DVO_HSYNC_ACTIVE_HIGH) |
@@ -337,28 +334,32 @@ intel_dvo_get_current_mode (struct drm_connector *connector) | |||
337 | } | 334 | } |
338 | } | 335 | } |
339 | } | 336 | } |
337 | |||
340 | return mode; | 338 | return mode; |
341 | } | 339 | } |
342 | 340 | ||
343 | void intel_dvo_init(struct drm_device *dev) | 341 | void intel_dvo_init(struct drm_device *dev) |
344 | { | 342 | { |
345 | struct intel_encoder *intel_encoder; | 343 | struct intel_encoder *intel_encoder; |
344 | struct intel_dvo *intel_dvo; | ||
346 | struct intel_connector *intel_connector; | 345 | struct intel_connector *intel_connector; |
347 | struct intel_dvo_device *dvo; | ||
348 | struct i2c_adapter *i2cbus = NULL; | 346 | struct i2c_adapter *i2cbus = NULL; |
349 | int ret = 0; | 347 | int ret = 0; |
350 | int i; | 348 | int i; |
351 | int encoder_type = DRM_MODE_ENCODER_NONE; | 349 | int encoder_type = DRM_MODE_ENCODER_NONE; |
352 | intel_encoder = kzalloc (sizeof(struct intel_encoder), GFP_KERNEL); | 350 | |
353 | if (!intel_encoder) | 351 | intel_dvo = kzalloc(sizeof(struct intel_dvo), GFP_KERNEL); |
352 | if (!intel_dvo) | ||
354 | return; | 353 | return; |
355 | 354 | ||
356 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 355 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
357 | if (!intel_connector) { | 356 | if (!intel_connector) { |
358 | kfree(intel_encoder); | 357 | kfree(intel_dvo); |
359 | return; | 358 | return; |
360 | } | 359 | } |
361 | 360 | ||
361 | intel_encoder = &intel_dvo->base; | ||
362 | |||
362 | /* Set up the DDC bus */ | 363 | /* Set up the DDC bus */ |
363 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); | 364 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); |
364 | if (!intel_encoder->ddc_bus) | 365 | if (!intel_encoder->ddc_bus) |
@@ -367,10 +368,9 @@ void intel_dvo_init(struct drm_device *dev) | |||
367 | /* Now, try to find a controller */ | 368 | /* Now, try to find a controller */ |
368 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { | 369 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { |
369 | struct drm_connector *connector = &intel_connector->base; | 370 | struct drm_connector *connector = &intel_connector->base; |
371 | const struct intel_dvo_device *dvo = &intel_dvo_devices[i]; | ||
370 | int gpio; | 372 | int gpio; |
371 | 373 | ||
372 | dvo = &intel_dvo_devices[i]; | ||
373 | |||
374 | /* Allow the I2C driver info to specify the GPIO to be used in | 374 | /* Allow the I2C driver info to specify the GPIO to be used in |
375 | * special cases, but otherwise default to what's defined | 375 | * special cases, but otherwise default to what's defined |
376 | * in the spec. | 376 | * in the spec. |
@@ -393,11 +393,8 @@ void intel_dvo_init(struct drm_device *dev) | |||
393 | continue; | 393 | continue; |
394 | } | 394 | } |
395 | 395 | ||
396 | if (dvo->dev_ops!= NULL) | 396 | intel_dvo->dev = *dvo; |
397 | ret = dvo->dev_ops->init(dvo, i2cbus); | 397 | ret = dvo->dev_ops->init(&intel_dvo->dev, i2cbus); |
398 | else | ||
399 | ret = false; | ||
400 | |||
401 | if (!ret) | 398 | if (!ret) |
402 | continue; | 399 | continue; |
403 | 400 | ||
@@ -429,9 +426,6 @@ void intel_dvo_init(struct drm_device *dev) | |||
429 | connector->interlace_allowed = false; | 426 | connector->interlace_allowed = false; |
430 | connector->doublescan_allowed = false; | 427 | connector->doublescan_allowed = false; |
431 | 428 | ||
432 | intel_encoder->dev_priv = dvo; | ||
433 | intel_encoder->i2c_bus = i2cbus; | ||
434 | |||
435 | drm_encoder_init(dev, &intel_encoder->enc, | 429 | drm_encoder_init(dev, &intel_encoder->enc, |
436 | &intel_dvo_enc_funcs, encoder_type); | 430 | &intel_dvo_enc_funcs, encoder_type); |
437 | drm_encoder_helper_add(&intel_encoder->enc, | 431 | drm_encoder_helper_add(&intel_encoder->enc, |
@@ -447,9 +441,9 @@ void intel_dvo_init(struct drm_device *dev) | |||
447 | * headers, likely), so for now, just get the current | 441 | * headers, likely), so for now, just get the current |
448 | * mode being output through DVO. | 442 | * mode being output through DVO. |
449 | */ | 443 | */ |
450 | dvo->panel_fixed_mode = | 444 | intel_dvo->panel_fixed_mode = |
451 | intel_dvo_get_current_mode(connector); | 445 | intel_dvo_get_current_mode(connector); |
452 | dvo->panel_wants_dither = true; | 446 | intel_dvo->panel_wants_dither = true; |
453 | } | 447 | } |
454 | 448 | ||
455 | drm_sysfs_connector_add(connector); | 449 | drm_sysfs_connector_add(connector); |
@@ -461,6 +455,6 @@ void intel_dvo_init(struct drm_device *dev) | |||
461 | if (i2cbus != NULL) | 455 | if (i2cbus != NULL) |
462 | intel_i2c_destroy(i2cbus); | 456 | intel_i2c_destroy(i2cbus); |
463 | free_intel: | 457 | free_intel: |
464 | kfree(intel_encoder); | 458 | kfree(intel_dvo); |
465 | kfree(intel_connector); | 459 | kfree(intel_connector); |
466 | } | 460 | } |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 197887ed182..ccd4c97e652 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -37,11 +37,17 @@ | |||
37 | #include "i915_drm.h" | 37 | #include "i915_drm.h" |
38 | #include "i915_drv.h" | 38 | #include "i915_drv.h" |
39 | 39 | ||
40 | struct intel_hdmi_priv { | 40 | struct intel_hdmi { |
41 | struct intel_encoder base; | ||
41 | u32 sdvox_reg; | 42 | u32 sdvox_reg; |
42 | bool has_hdmi_sink; | 43 | bool has_hdmi_sink; |
43 | }; | 44 | }; |
44 | 45 | ||
46 | static struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder) | ||
47 | { | ||
48 | return container_of(enc_to_intel_encoder(encoder), struct intel_hdmi, base); | ||
49 | } | ||
50 | |||
45 | static void intel_hdmi_mode_set(struct drm_encoder *encoder, | 51 | static void intel_hdmi_mode_set(struct drm_encoder *encoder, |
46 | struct drm_display_mode *mode, | 52 | struct drm_display_mode *mode, |
47 | struct drm_display_mode *adjusted_mode) | 53 | struct drm_display_mode *adjusted_mode) |
@@ -50,8 +56,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
50 | struct drm_i915_private *dev_priv = dev->dev_private; | 56 | struct drm_i915_private *dev_priv = dev->dev_private; |
51 | struct drm_crtc *crtc = encoder->crtc; | 57 | struct drm_crtc *crtc = encoder->crtc; |
52 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 58 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
53 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 59 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
54 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; | ||
55 | u32 sdvox; | 60 | u32 sdvox; |
56 | 61 | ||
57 | sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE; | 62 | sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE; |
@@ -60,7 +65,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
60 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 65 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
61 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; | 66 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; |
62 | 67 | ||
63 | if (hdmi_priv->has_hdmi_sink) { | 68 | if (intel_hdmi->has_hdmi_sink) { |
64 | sdvox |= SDVO_AUDIO_ENABLE; | 69 | sdvox |= SDVO_AUDIO_ENABLE; |
65 | if (HAS_PCH_CPT(dev)) | 70 | if (HAS_PCH_CPT(dev)) |
66 | sdvox |= HDMI_MODE_SELECT; | 71 | sdvox |= HDMI_MODE_SELECT; |
@@ -73,26 +78,25 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
73 | sdvox |= SDVO_PIPE_B_SELECT; | 78 | sdvox |= SDVO_PIPE_B_SELECT; |
74 | } | 79 | } |
75 | 80 | ||
76 | I915_WRITE(hdmi_priv->sdvox_reg, sdvox); | 81 | I915_WRITE(intel_hdmi->sdvox_reg, sdvox); |
77 | POSTING_READ(hdmi_priv->sdvox_reg); | 82 | POSTING_READ(intel_hdmi->sdvox_reg); |
78 | } | 83 | } |
79 | 84 | ||
80 | static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) | 85 | static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) |
81 | { | 86 | { |
82 | struct drm_device *dev = encoder->dev; | 87 | struct drm_device *dev = encoder->dev; |
83 | struct drm_i915_private *dev_priv = dev->dev_private; | 88 | struct drm_i915_private *dev_priv = dev->dev_private; |
84 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 89 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
85 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; | ||
86 | u32 temp; | 90 | u32 temp; |
87 | 91 | ||
88 | temp = I915_READ(hdmi_priv->sdvox_reg); | 92 | temp = I915_READ(intel_hdmi->sdvox_reg); |
89 | 93 | ||
90 | /* HW workaround, need to toggle enable bit off and on for 12bpc, but | 94 | /* HW workaround, need to toggle enable bit off and on for 12bpc, but |
91 | * we do this anyway which shows more stable in testing. | 95 | * we do this anyway which shows more stable in testing. |
92 | */ | 96 | */ |
93 | if (HAS_PCH_SPLIT(dev)) { | 97 | if (HAS_PCH_SPLIT(dev)) { |
94 | I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE); | 98 | I915_WRITE(intel_hdmi->sdvox_reg, temp & ~SDVO_ENABLE); |
95 | POSTING_READ(hdmi_priv->sdvox_reg); | 99 | POSTING_READ(intel_hdmi->sdvox_reg); |
96 | } | 100 | } |
97 | 101 | ||
98 | if (mode != DRM_MODE_DPMS_ON) { | 102 | if (mode != DRM_MODE_DPMS_ON) { |
@@ -101,15 +105,15 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) | |||
101 | temp |= SDVO_ENABLE; | 105 | temp |= SDVO_ENABLE; |
102 | } | 106 | } |
103 | 107 | ||
104 | I915_WRITE(hdmi_priv->sdvox_reg, temp); | 108 | I915_WRITE(intel_hdmi->sdvox_reg, temp); |
105 | POSTING_READ(hdmi_priv->sdvox_reg); | 109 | POSTING_READ(intel_hdmi->sdvox_reg); |
106 | 110 | ||
107 | /* HW workaround, need to write this twice for issue that may result | 111 | /* HW workaround, need to write this twice for issue that may result |
108 | * in first write getting masked. | 112 | * in first write getting masked. |
109 | */ | 113 | */ |
110 | if (HAS_PCH_SPLIT(dev)) { | 114 | if (HAS_PCH_SPLIT(dev)) { |
111 | I915_WRITE(hdmi_priv->sdvox_reg, temp); | 115 | I915_WRITE(intel_hdmi->sdvox_reg, temp); |
112 | POSTING_READ(hdmi_priv->sdvox_reg); | 116 | POSTING_READ(intel_hdmi->sdvox_reg); |
113 | } | 117 | } |
114 | } | 118 | } |
115 | 119 | ||
@@ -138,19 +142,17 @@ static enum drm_connector_status | |||
138 | intel_hdmi_detect(struct drm_connector *connector) | 142 | intel_hdmi_detect(struct drm_connector *connector) |
139 | { | 143 | { |
140 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 144 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
141 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 145 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
142 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; | ||
143 | struct edid *edid = NULL; | 146 | struct edid *edid = NULL; |
144 | enum drm_connector_status status = connector_status_disconnected; | 147 | enum drm_connector_status status = connector_status_disconnected; |
145 | 148 | ||
146 | hdmi_priv->has_hdmi_sink = false; | 149 | intel_hdmi->has_hdmi_sink = false; |
147 | edid = drm_get_edid(connector, | 150 | edid = drm_get_edid(connector, intel_hdmi->base.ddc_bus); |
148 | intel_encoder->ddc_bus); | ||
149 | 151 | ||
150 | if (edid) { | 152 | if (edid) { |
151 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { | 153 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { |
152 | status = connector_status_connected; | 154 | status = connector_status_connected; |
153 | hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); | 155 | intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid); |
154 | } | 156 | } |
155 | connector->display_info.raw_edid = NULL; | 157 | connector->display_info.raw_edid = NULL; |
156 | kfree(edid); | 158 | kfree(edid); |
@@ -162,13 +164,13 @@ intel_hdmi_detect(struct drm_connector *connector) | |||
162 | static int intel_hdmi_get_modes(struct drm_connector *connector) | 164 | static int intel_hdmi_get_modes(struct drm_connector *connector) |
163 | { | 165 | { |
164 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 166 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
165 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 167 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
166 | 168 | ||
167 | /* We should parse the EDID data and find out if it's an HDMI sink so | 169 | /* We should parse the EDID data and find out if it's an HDMI sink so |
168 | * we can send audio to it. | 170 | * we can send audio to it. |
169 | */ | 171 | */ |
170 | 172 | ||
171 | return intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 173 | return intel_ddc_get_modes(connector, intel_hdmi->base.ddc_bus); |
172 | } | 174 | } |
173 | 175 | ||
174 | static void intel_hdmi_destroy(struct drm_connector *connector) | 176 | static void intel_hdmi_destroy(struct drm_connector *connector) |
@@ -199,18 +201,8 @@ static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs | |||
199 | .best_encoder = intel_attached_encoder, | 201 | .best_encoder = intel_attached_encoder, |
200 | }; | 202 | }; |
201 | 203 | ||
202 | static void intel_hdmi_enc_destroy(struct drm_encoder *encoder) | ||
203 | { | ||
204 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
205 | |||
206 | if (intel_encoder->i2c_bus) | ||
207 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
208 | drm_encoder_cleanup(encoder); | ||
209 | kfree(intel_encoder); | ||
210 | } | ||
211 | |||
212 | static const struct drm_encoder_funcs intel_hdmi_enc_funcs = { | 204 | static const struct drm_encoder_funcs intel_hdmi_enc_funcs = { |
213 | .destroy = intel_hdmi_enc_destroy, | 205 | .destroy = intel_encoder_destroy, |
214 | }; | 206 | }; |
215 | 207 | ||
216 | void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | 208 | void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) |
@@ -219,21 +211,19 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
219 | struct drm_connector *connector; | 211 | struct drm_connector *connector; |
220 | struct intel_encoder *intel_encoder; | 212 | struct intel_encoder *intel_encoder; |
221 | struct intel_connector *intel_connector; | 213 | struct intel_connector *intel_connector; |
222 | struct intel_hdmi_priv *hdmi_priv; | 214 | struct intel_hdmi *intel_hdmi; |
223 | 215 | ||
224 | intel_encoder = kcalloc(sizeof(struct intel_encoder) + | 216 | intel_hdmi = kzalloc(sizeof(struct intel_hdmi), GFP_KERNEL); |
225 | sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL); | 217 | if (!intel_hdmi) |
226 | if (!intel_encoder) | ||
227 | return; | 218 | return; |
228 | 219 | ||
229 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 220 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
230 | if (!intel_connector) { | 221 | if (!intel_connector) { |
231 | kfree(intel_encoder); | 222 | kfree(intel_hdmi); |
232 | return; | 223 | return; |
233 | } | 224 | } |
234 | 225 | ||
235 | hdmi_priv = (struct intel_hdmi_priv *)(intel_encoder + 1); | 226 | intel_encoder = &intel_hdmi->base; |
236 | |||
237 | connector = &intel_connector->base; | 227 | connector = &intel_connector->base; |
238 | drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, | 228 | drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, |
239 | DRM_MODE_CONNECTOR_HDMIA); | 229 | DRM_MODE_CONNECTOR_HDMIA); |
@@ -274,8 +264,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
274 | if (!intel_encoder->ddc_bus) | 264 | if (!intel_encoder->ddc_bus) |
275 | goto err_connector; | 265 | goto err_connector; |
276 | 266 | ||
277 | hdmi_priv->sdvox_reg = sdvox_reg; | 267 | intel_hdmi->sdvox_reg = sdvox_reg; |
278 | intel_encoder->dev_priv = hdmi_priv; | ||
279 | 268 | ||
280 | drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs, | 269 | drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs, |
281 | DRM_MODE_ENCODER_TMDS); | 270 | DRM_MODE_ENCODER_TMDS); |
@@ -298,7 +287,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
298 | 287 | ||
299 | err_connector: | 288 | err_connector: |
300 | drm_connector_cleanup(connector); | 289 | drm_connector_cleanup(connector); |
301 | kfree(intel_encoder); | 290 | kfree(intel_hdmi); |
302 | kfree(intel_connector); | 291 | kfree(intel_connector); |
303 | 292 | ||
304 | return; | 293 | return; |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 0a2e60059fb..b819c108114 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -41,12 +41,18 @@ | |||
41 | #include <linux/acpi.h> | 41 | #include <linux/acpi.h> |
42 | 42 | ||
43 | /* Private structure for the integrated LVDS support */ | 43 | /* Private structure for the integrated LVDS support */ |
44 | struct intel_lvds_priv { | 44 | struct intel_lvds { |
45 | struct intel_encoder base; | ||
45 | int fitting_mode; | 46 | int fitting_mode; |
46 | u32 pfit_control; | 47 | u32 pfit_control; |
47 | u32 pfit_pgm_ratios; | 48 | u32 pfit_pgm_ratios; |
48 | }; | 49 | }; |
49 | 50 | ||
51 | static struct intel_lvds *enc_to_intel_lvds(struct drm_encoder *encoder) | ||
52 | { | ||
53 | return container_of(enc_to_intel_encoder(encoder), struct intel_lvds, base); | ||
54 | } | ||
55 | |||
50 | /** | 56 | /** |
51 | * Sets the backlight level. | 57 | * Sets the backlight level. |
52 | * | 58 | * |
@@ -90,7 +96,7 @@ static u32 intel_lvds_get_max_backlight(struct drm_device *dev) | |||
90 | static void intel_lvds_set_power(struct drm_device *dev, bool on) | 96 | static void intel_lvds_set_power(struct drm_device *dev, bool on) |
91 | { | 97 | { |
92 | struct drm_i915_private *dev_priv = dev->dev_private; | 98 | struct drm_i915_private *dev_priv = dev->dev_private; |
93 | u32 pp_status, ctl_reg, status_reg, lvds_reg; | 99 | u32 ctl_reg, status_reg, lvds_reg; |
94 | 100 | ||
95 | if (HAS_PCH_SPLIT(dev)) { | 101 | if (HAS_PCH_SPLIT(dev)) { |
96 | ctl_reg = PCH_PP_CONTROL; | 102 | ctl_reg = PCH_PP_CONTROL; |
@@ -108,9 +114,8 @@ static void intel_lvds_set_power(struct drm_device *dev, bool on) | |||
108 | 114 | ||
109 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | | 115 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | |
110 | POWER_TARGET_ON); | 116 | POWER_TARGET_ON); |
111 | do { | 117 | if (wait_for(I915_READ(status_reg) & PP_ON, 1000, 0)) |
112 | pp_status = I915_READ(status_reg); | 118 | DRM_ERROR("timed out waiting to enable LVDS pipe"); |
113 | } while ((pp_status & PP_ON) == 0); | ||
114 | 119 | ||
115 | intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle); | 120 | intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle); |
116 | } else { | 121 | } else { |
@@ -118,9 +123,8 @@ static void intel_lvds_set_power(struct drm_device *dev, bool on) | |||
118 | 123 | ||
119 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & | 124 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & |
120 | ~POWER_TARGET_ON); | 125 | ~POWER_TARGET_ON); |
121 | do { | 126 | if (wait_for((I915_READ(status_reg) & PP_ON) == 0, 1000, 0)) |
122 | pp_status = I915_READ(status_reg); | 127 | DRM_ERROR("timed out waiting for LVDS pipe to turn off"); |
123 | } while (pp_status & PP_ON); | ||
124 | 128 | ||
125 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); | 129 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); |
126 | POSTING_READ(lvds_reg); | 130 | POSTING_READ(lvds_reg); |
@@ -219,9 +223,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
219 | struct drm_device *dev = encoder->dev; | 223 | struct drm_device *dev = encoder->dev; |
220 | struct drm_i915_private *dev_priv = dev->dev_private; | 224 | struct drm_i915_private *dev_priv = dev->dev_private; |
221 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 225 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
226 | struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder); | ||
222 | struct drm_encoder *tmp_encoder; | 227 | struct drm_encoder *tmp_encoder; |
223 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
224 | struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; | ||
225 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; | 228 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; |
226 | 229 | ||
227 | /* Should never happen!! */ | 230 | /* Should never happen!! */ |
@@ -241,26 +244,20 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
241 | /* If we don't have a panel mode, there is nothing we can do */ | 244 | /* If we don't have a panel mode, there is nothing we can do */ |
242 | if (dev_priv->panel_fixed_mode == NULL) | 245 | if (dev_priv->panel_fixed_mode == NULL) |
243 | return true; | 246 | return true; |
247 | |||
244 | /* | 248 | /* |
245 | * We have timings from the BIOS for the panel, put them in | 249 | * We have timings from the BIOS for the panel, put them in |
246 | * to the adjusted mode. The CRTC will be set up for this mode, | 250 | * to the adjusted mode. The CRTC will be set up for this mode, |
247 | * with the panel scaling set up to source from the H/VDisplay | 251 | * with the panel scaling set up to source from the H/VDisplay |
248 | * of the original mode. | 252 | * of the original mode. |
249 | */ | 253 | */ |
250 | adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay; | 254 | intel_fixed_panel_mode(dev_priv->panel_fixed_mode, adjusted_mode); |
251 | adjusted_mode->hsync_start = | 255 | |
252 | dev_priv->panel_fixed_mode->hsync_start; | 256 | if (HAS_PCH_SPLIT(dev)) { |
253 | adjusted_mode->hsync_end = | 257 | intel_pch_panel_fitting(dev, intel_lvds->fitting_mode, |
254 | dev_priv->panel_fixed_mode->hsync_end; | 258 | mode, adjusted_mode); |
255 | adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal; | 259 | return true; |
256 | adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay; | 260 | } |
257 | adjusted_mode->vsync_start = | ||
258 | dev_priv->panel_fixed_mode->vsync_start; | ||
259 | adjusted_mode->vsync_end = | ||
260 | dev_priv->panel_fixed_mode->vsync_end; | ||
261 | adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal; | ||
262 | adjusted_mode->clock = dev_priv->panel_fixed_mode->clock; | ||
263 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
264 | 261 | ||
265 | /* Make sure pre-965s set dither correctly */ | 262 | /* Make sure pre-965s set dither correctly */ |
266 | if (!IS_I965G(dev)) { | 263 | if (!IS_I965G(dev)) { |
@@ -273,10 +270,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
273 | adjusted_mode->vdisplay == mode->vdisplay) | 270 | adjusted_mode->vdisplay == mode->vdisplay) |
274 | goto out; | 271 | goto out; |
275 | 272 | ||
276 | /* full screen scale for now */ | ||
277 | if (HAS_PCH_SPLIT(dev)) | ||
278 | goto out; | ||
279 | |||
280 | /* 965+ wants fuzzy fitting */ | 273 | /* 965+ wants fuzzy fitting */ |
281 | if (IS_I965G(dev)) | 274 | if (IS_I965G(dev)) |
282 | pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | | 275 | pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | |
@@ -288,12 +281,10 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
288 | * to register description and PRM. | 281 | * to register description and PRM. |
289 | * Change the value here to see the borders for debugging | 282 | * Change the value here to see the borders for debugging |
290 | */ | 283 | */ |
291 | if (!HAS_PCH_SPLIT(dev)) { | 284 | I915_WRITE(BCLRPAT_A, 0); |
292 | I915_WRITE(BCLRPAT_A, 0); | 285 | I915_WRITE(BCLRPAT_B, 0); |
293 | I915_WRITE(BCLRPAT_B, 0); | ||
294 | } | ||
295 | 286 | ||
296 | switch (lvds_priv->fitting_mode) { | 287 | switch (intel_lvds->fitting_mode) { |
297 | case DRM_MODE_SCALE_CENTER: | 288 | case DRM_MODE_SCALE_CENTER: |
298 | /* | 289 | /* |
299 | * For centered modes, we have to calculate border widths & | 290 | * For centered modes, we have to calculate border widths & |
@@ -378,8 +369,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
378 | } | 369 | } |
379 | 370 | ||
380 | out: | 371 | out: |
381 | lvds_priv->pfit_control = pfit_control; | 372 | intel_lvds->pfit_control = pfit_control; |
382 | lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios; | 373 | intel_lvds->pfit_pgm_ratios = pfit_pgm_ratios; |
383 | dev_priv->lvds_border_bits = border; | 374 | dev_priv->lvds_border_bits = border; |
384 | 375 | ||
385 | /* | 376 | /* |
@@ -427,8 +418,7 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, | |||
427 | { | 418 | { |
428 | struct drm_device *dev = encoder->dev; | 419 | struct drm_device *dev = encoder->dev; |
429 | struct drm_i915_private *dev_priv = dev->dev_private; | 420 | struct drm_i915_private *dev_priv = dev->dev_private; |
430 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 421 | struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder); |
431 | struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; | ||
432 | 422 | ||
433 | /* | 423 | /* |
434 | * The LVDS pin pair will already have been turned on in the | 424 | * The LVDS pin pair will already have been turned on in the |
@@ -444,8 +434,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, | |||
444 | * screen. Should be enabled before the pipe is enabled, according to | 434 | * screen. Should be enabled before the pipe is enabled, according to |
445 | * register description and PRM. | 435 | * register description and PRM. |
446 | */ | 436 | */ |
447 | I915_WRITE(PFIT_PGM_RATIOS, lvds_priv->pfit_pgm_ratios); | 437 | I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); |
448 | I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control); | 438 | I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); |
449 | } | 439 | } |
450 | 440 | ||
451 | /** | 441 | /** |
@@ -600,18 +590,17 @@ static int intel_lvds_set_property(struct drm_connector *connector, | |||
600 | connector->encoder) { | 590 | connector->encoder) { |
601 | struct drm_crtc *crtc = connector->encoder->crtc; | 591 | struct drm_crtc *crtc = connector->encoder->crtc; |
602 | struct drm_encoder *encoder = connector->encoder; | 592 | struct drm_encoder *encoder = connector->encoder; |
603 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 593 | struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder); |
604 | struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; | ||
605 | 594 | ||
606 | if (value == DRM_MODE_SCALE_NONE) { | 595 | if (value == DRM_MODE_SCALE_NONE) { |
607 | DRM_DEBUG_KMS("no scaling not supported\n"); | 596 | DRM_DEBUG_KMS("no scaling not supported\n"); |
608 | return 0; | 597 | return 0; |
609 | } | 598 | } |
610 | if (lvds_priv->fitting_mode == value) { | 599 | if (intel_lvds->fitting_mode == value) { |
611 | /* the LVDS scaling property is not changed */ | 600 | /* the LVDS scaling property is not changed */ |
612 | return 0; | 601 | return 0; |
613 | } | 602 | } |
614 | lvds_priv->fitting_mode = value; | 603 | intel_lvds->fitting_mode = value; |
615 | if (crtc && crtc->enabled) { | 604 | if (crtc && crtc->enabled) { |
616 | /* | 605 | /* |
617 | * If the CRTC is enabled, the display will be changed | 606 | * If the CRTC is enabled, the display will be changed |
@@ -647,19 +636,8 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = { | |||
647 | .destroy = intel_lvds_destroy, | 636 | .destroy = intel_lvds_destroy, |
648 | }; | 637 | }; |
649 | 638 | ||
650 | |||
651 | static void intel_lvds_enc_destroy(struct drm_encoder *encoder) | ||
652 | { | ||
653 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
654 | |||
655 | if (intel_encoder->ddc_bus) | ||
656 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
657 | drm_encoder_cleanup(encoder); | ||
658 | kfree(intel_encoder); | ||
659 | } | ||
660 | |||
661 | static const struct drm_encoder_funcs intel_lvds_enc_funcs = { | 639 | static const struct drm_encoder_funcs intel_lvds_enc_funcs = { |
662 | .destroy = intel_lvds_enc_destroy, | 640 | .destroy = intel_encoder_destroy, |
663 | }; | 641 | }; |
664 | 642 | ||
665 | static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) | 643 | static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) |
@@ -843,13 +821,13 @@ static int lvds_is_present_in_vbt(struct drm_device *dev) | |||
843 | void intel_lvds_init(struct drm_device *dev) | 821 | void intel_lvds_init(struct drm_device *dev) |
844 | { | 822 | { |
845 | struct drm_i915_private *dev_priv = dev->dev_private; | 823 | struct drm_i915_private *dev_priv = dev->dev_private; |
824 | struct intel_lvds *intel_lvds; | ||
846 | struct intel_encoder *intel_encoder; | 825 | struct intel_encoder *intel_encoder; |
847 | struct intel_connector *intel_connector; | 826 | struct intel_connector *intel_connector; |
848 | struct drm_connector *connector; | 827 | struct drm_connector *connector; |
849 | struct drm_encoder *encoder; | 828 | struct drm_encoder *encoder; |
850 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ | 829 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ |
851 | struct drm_crtc *crtc; | 830 | struct drm_crtc *crtc; |
852 | struct intel_lvds_priv *lvds_priv; | ||
853 | u32 lvds; | 831 | u32 lvds; |
854 | int pipe, gpio = GPIOC; | 832 | int pipe, gpio = GPIOC; |
855 | 833 | ||
@@ -872,20 +850,20 @@ void intel_lvds_init(struct drm_device *dev) | |||
872 | gpio = PCH_GPIOC; | 850 | gpio = PCH_GPIOC; |
873 | } | 851 | } |
874 | 852 | ||
875 | intel_encoder = kzalloc(sizeof(struct intel_encoder) + | 853 | intel_lvds = kzalloc(sizeof(struct intel_lvds), GFP_KERNEL); |
876 | sizeof(struct intel_lvds_priv), GFP_KERNEL); | 854 | if (!intel_lvds) { |
877 | if (!intel_encoder) { | ||
878 | return; | 855 | return; |
879 | } | 856 | } |
880 | 857 | ||
881 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 858 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
882 | if (!intel_connector) { | 859 | if (!intel_connector) { |
883 | kfree(intel_encoder); | 860 | kfree(intel_lvds); |
884 | return; | 861 | return; |
885 | } | 862 | } |
886 | 863 | ||
887 | connector = &intel_connector->base; | 864 | intel_encoder = &intel_lvds->base; |
888 | encoder = &intel_encoder->enc; | 865 | encoder = &intel_encoder->enc; |
866 | connector = &intel_connector->base; | ||
889 | drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs, | 867 | drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs, |
890 | DRM_MODE_CONNECTOR_LVDS); | 868 | DRM_MODE_CONNECTOR_LVDS); |
891 | 869 | ||
@@ -905,8 +883,6 @@ void intel_lvds_init(struct drm_device *dev) | |||
905 | connector->interlace_allowed = false; | 883 | connector->interlace_allowed = false; |
906 | connector->doublescan_allowed = false; | 884 | connector->doublescan_allowed = false; |
907 | 885 | ||
908 | lvds_priv = (struct intel_lvds_priv *)(intel_encoder + 1); | ||
909 | intel_encoder->dev_priv = lvds_priv; | ||
910 | /* create the scaling mode property */ | 886 | /* create the scaling mode property */ |
911 | drm_mode_create_scaling_mode_property(dev); | 887 | drm_mode_create_scaling_mode_property(dev); |
912 | /* | 888 | /* |
@@ -916,7 +892,7 @@ void intel_lvds_init(struct drm_device *dev) | |||
916 | drm_connector_attach_property(&intel_connector->base, | 892 | drm_connector_attach_property(&intel_connector->base, |
917 | dev->mode_config.scaling_mode_property, | 893 | dev->mode_config.scaling_mode_property, |
918 | DRM_MODE_SCALE_ASPECT); | 894 | DRM_MODE_SCALE_ASPECT); |
919 | lvds_priv->fitting_mode = DRM_MODE_SCALE_ASPECT; | 895 | intel_lvds->fitting_mode = DRM_MODE_SCALE_ASPECT; |
920 | /* | 896 | /* |
921 | * LVDS discovery: | 897 | * LVDS discovery: |
922 | * 1) check for EDID on DDC | 898 | * 1) check for EDID on DDC |
@@ -1024,6 +1000,6 @@ failed: | |||
1024 | intel_i2c_destroy(intel_encoder->ddc_bus); | 1000 | intel_i2c_destroy(intel_encoder->ddc_bus); |
1025 | drm_connector_cleanup(connector); | 1001 | drm_connector_cleanup(connector); |
1026 | drm_encoder_cleanup(encoder); | 1002 | drm_encoder_cleanup(encoder); |
1027 | kfree(intel_encoder); | 1003 | kfree(intel_lvds); |
1028 | kfree(intel_connector); | 1004 | kfree(intel_connector); |
1029 | } | 1005 | } |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index d39aea24eab..1d306a458be 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -25,6 +25,8 @@ | |||
25 | * | 25 | * |
26 | * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c | 26 | * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c |
27 | */ | 27 | */ |
28 | |||
29 | #include <linux/seq_file.h> | ||
28 | #include "drmP.h" | 30 | #include "drmP.h" |
29 | #include "drm.h" | 31 | #include "drm.h" |
30 | #include "i915_drm.h" | 32 | #include "i915_drm.h" |
@@ -1367,7 +1369,8 @@ void intel_setup_overlay(struct drm_device *dev) | |||
1367 | overlay->flip_addr = overlay->reg_bo->gtt_offset; | 1369 | overlay->flip_addr = overlay->reg_bo->gtt_offset; |
1368 | } else { | 1370 | } else { |
1369 | ret = i915_gem_attach_phys_object(dev, reg_bo, | 1371 | ret = i915_gem_attach_phys_object(dev, reg_bo, |
1370 | I915_GEM_PHYS_OVERLAY_REGS); | 1372 | I915_GEM_PHYS_OVERLAY_REGS, |
1373 | 0); | ||
1371 | if (ret) { | 1374 | if (ret) { |
1372 | DRM_ERROR("failed to attach phys overlay regs\n"); | 1375 | DRM_ERROR("failed to attach phys overlay regs\n"); |
1373 | goto out_free_bo; | 1376 | goto out_free_bo; |
@@ -1416,3 +1419,99 @@ void intel_cleanup_overlay(struct drm_device *dev) | |||
1416 | kfree(dev_priv->overlay); | 1419 | kfree(dev_priv->overlay); |
1417 | } | 1420 | } |
1418 | } | 1421 | } |
1422 | |||
1423 | struct intel_overlay_error_state { | ||
1424 | struct overlay_registers regs; | ||
1425 | unsigned long base; | ||
1426 | u32 dovsta; | ||
1427 | u32 isr; | ||
1428 | }; | ||
1429 | |||
1430 | struct intel_overlay_error_state * | ||
1431 | intel_overlay_capture_error_state(struct drm_device *dev) | ||
1432 | { | ||
1433 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1434 | struct intel_overlay *overlay = dev_priv->overlay; | ||
1435 | struct intel_overlay_error_state *error; | ||
1436 | struct overlay_registers __iomem *regs; | ||
1437 | |||
1438 | if (!overlay || !overlay->active) | ||
1439 | return NULL; | ||
1440 | |||
1441 | error = kmalloc(sizeof(*error), GFP_ATOMIC); | ||
1442 | if (error == NULL) | ||
1443 | return NULL; | ||
1444 | |||
1445 | error->dovsta = I915_READ(DOVSTA); | ||
1446 | error->isr = I915_READ(ISR); | ||
1447 | if (OVERLAY_NONPHYSICAL(overlay->dev)) | ||
1448 | error->base = (long) overlay->reg_bo->gtt_offset; | ||
1449 | else | ||
1450 | error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr; | ||
1451 | |||
1452 | regs = intel_overlay_map_regs_atomic(overlay); | ||
1453 | if (!regs) | ||
1454 | goto err; | ||
1455 | |||
1456 | memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers)); | ||
1457 | intel_overlay_unmap_regs_atomic(overlay); | ||
1458 | |||
1459 | return error; | ||
1460 | |||
1461 | err: | ||
1462 | kfree(error); | ||
1463 | return NULL; | ||
1464 | } | ||
1465 | |||
1466 | void | ||
1467 | intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error) | ||
1468 | { | ||
1469 | seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n", | ||
1470 | error->dovsta, error->isr); | ||
1471 | seq_printf(m, " Register file at 0x%08lx:\n", | ||
1472 | error->base); | ||
1473 | |||
1474 | #define P(x) seq_printf(m, " " #x ": 0x%08x\n", error->regs.x) | ||
1475 | P(OBUF_0Y); | ||
1476 | P(OBUF_1Y); | ||
1477 | P(OBUF_0U); | ||
1478 | P(OBUF_0V); | ||
1479 | P(OBUF_1U); | ||
1480 | P(OBUF_1V); | ||
1481 | P(OSTRIDE); | ||
1482 | P(YRGB_VPH); | ||
1483 | P(UV_VPH); | ||
1484 | P(HORZ_PH); | ||
1485 | P(INIT_PHS); | ||
1486 | P(DWINPOS); | ||
1487 | P(DWINSZ); | ||
1488 | P(SWIDTH); | ||
1489 | P(SWIDTHSW); | ||
1490 | P(SHEIGHT); | ||
1491 | P(YRGBSCALE); | ||
1492 | P(UVSCALE); | ||
1493 | P(OCLRC0); | ||
1494 | P(OCLRC1); | ||
1495 | P(DCLRKV); | ||
1496 | P(DCLRKM); | ||
1497 | P(SCLRKVH); | ||
1498 | P(SCLRKVL); | ||
1499 | P(SCLRKEN); | ||
1500 | P(OCONFIG); | ||
1501 | P(OCMD); | ||
1502 | P(OSTART_0Y); | ||
1503 | P(OSTART_1Y); | ||
1504 | P(OSTART_0U); | ||
1505 | P(OSTART_0V); | ||
1506 | P(OSTART_1U); | ||
1507 | P(OSTART_1V); | ||
1508 | P(OTILEOFF_0Y); | ||
1509 | P(OTILEOFF_1Y); | ||
1510 | P(OTILEOFF_0U); | ||
1511 | P(OTILEOFF_0V); | ||
1512 | P(OTILEOFF_1U); | ||
1513 | P(OTILEOFF_1V); | ||
1514 | P(FASTHSCALE); | ||
1515 | P(UVSCALEV); | ||
1516 | #undef P | ||
1517 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c new file mode 100644 index 00000000000..e7f5299d9d5 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * Copyright © 2006-2010 Intel Corporation | ||
3 | * Copyright (c) 2006 Dave Airlie <airlied@linux.ie> | ||
4 | * | ||
5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
6 | * copy of this software and associated documentation files (the "Software"), | ||
7 | * to deal in the Software without restriction, including without limitation | ||
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
9 | * and/or sell copies of the Software, and to permit persons to whom the | ||
10 | * Software is furnished to do so, subject to the following conditions: | ||
11 | * | ||
12 | * The above copyright notice and this permission notice (including the next | ||
13 | * paragraph) shall be included in all copies or substantial portions of the | ||
14 | * Software. | ||
15 | * | ||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
22 | * DEALINGS IN THE SOFTWARE. | ||
23 | * | ||
24 | * Authors: | ||
25 | * Eric Anholt <eric@anholt.net> | ||
26 | * Dave Airlie <airlied@linux.ie> | ||
27 | * Jesse Barnes <jesse.barnes@intel.com> | ||
28 | * Chris Wilson <chris@chris-wilson.co.uk> | ||
29 | */ | ||
30 | |||
31 | #include "intel_drv.h" | ||
32 | |||
33 | void | ||
34 | intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, | ||
35 | struct drm_display_mode *adjusted_mode) | ||
36 | { | ||
37 | adjusted_mode->hdisplay = fixed_mode->hdisplay; | ||
38 | adjusted_mode->hsync_start = fixed_mode->hsync_start; | ||
39 | adjusted_mode->hsync_end = fixed_mode->hsync_end; | ||
40 | adjusted_mode->htotal = fixed_mode->htotal; | ||
41 | |||
42 | adjusted_mode->vdisplay = fixed_mode->vdisplay; | ||
43 | adjusted_mode->vsync_start = fixed_mode->vsync_start; | ||
44 | adjusted_mode->vsync_end = fixed_mode->vsync_end; | ||
45 | adjusted_mode->vtotal = fixed_mode->vtotal; | ||
46 | |||
47 | adjusted_mode->clock = fixed_mode->clock; | ||
48 | |||
49 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
50 | } | ||
51 | |||
52 | /* adjusted_mode has been preset to be the panel's fixed mode */ | ||
53 | void | ||
54 | intel_pch_panel_fitting(struct drm_device *dev, | ||
55 | int fitting_mode, | ||
56 | struct drm_display_mode *mode, | ||
57 | struct drm_display_mode *adjusted_mode) | ||
58 | { | ||
59 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
60 | int x, y, width, height; | ||
61 | |||
62 | x = y = width = height = 0; | ||
63 | |||
64 | /* Native modes don't need fitting */ | ||
65 | if (adjusted_mode->hdisplay == mode->hdisplay && | ||
66 | adjusted_mode->vdisplay == mode->vdisplay) | ||
67 | goto done; | ||
68 | |||
69 | switch (fitting_mode) { | ||
70 | case DRM_MODE_SCALE_CENTER: | ||
71 | width = mode->hdisplay; | ||
72 | height = mode->vdisplay; | ||
73 | x = (adjusted_mode->hdisplay - width + 1)/2; | ||
74 | y = (adjusted_mode->vdisplay - height + 1)/2; | ||
75 | break; | ||
76 | |||
77 | case DRM_MODE_SCALE_ASPECT: | ||
78 | /* Scale but preserve the aspect ratio */ | ||
79 | { | ||
80 | u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; | ||
81 | u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; | ||
82 | if (scaled_width > scaled_height) { /* pillar */ | ||
83 | width = scaled_height / mode->vdisplay; | ||
84 | x = (adjusted_mode->hdisplay - width + 1) / 2; | ||
85 | y = 0; | ||
86 | height = adjusted_mode->vdisplay; | ||
87 | } else if (scaled_width < scaled_height) { /* letter */ | ||
88 | height = scaled_width / mode->hdisplay; | ||
89 | y = (adjusted_mode->vdisplay - height + 1) / 2; | ||
90 | x = 0; | ||
91 | width = adjusted_mode->hdisplay; | ||
92 | } else { | ||
93 | x = y = 0; | ||
94 | width = adjusted_mode->hdisplay; | ||
95 | height = adjusted_mode->vdisplay; | ||
96 | } | ||
97 | } | ||
98 | break; | ||
99 | |||
100 | default: | ||
101 | case DRM_MODE_SCALE_FULLSCREEN: | ||
102 | x = y = 0; | ||
103 | width = adjusted_mode->hdisplay; | ||
104 | height = adjusted_mode->vdisplay; | ||
105 | break; | ||
106 | } | ||
107 | |||
108 | done: | ||
109 | dev_priv->pch_pf_pos = (x << 16) | y; | ||
110 | dev_priv->pch_pf_size = (width << 16) | height; | ||
111 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 26362f8495a..cb3508f78bc 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -33,18 +33,35 @@ | |||
33 | #include "i915_drm.h" | 33 | #include "i915_drm.h" |
34 | #include "i915_trace.h" | 34 | #include "i915_trace.h" |
35 | 35 | ||
36 | static u32 i915_gem_get_seqno(struct drm_device *dev) | ||
37 | { | ||
38 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
39 | u32 seqno; | ||
40 | |||
41 | seqno = dev_priv->next_seqno; | ||
42 | |||
43 | /* reserve 0 for non-seqno */ | ||
44 | if (++dev_priv->next_seqno == 0) | ||
45 | dev_priv->next_seqno = 1; | ||
46 | |||
47 | return seqno; | ||
48 | } | ||
49 | |||
36 | static void | 50 | static void |
37 | render_ring_flush(struct drm_device *dev, | 51 | render_ring_flush(struct drm_device *dev, |
38 | struct intel_ring_buffer *ring, | 52 | struct intel_ring_buffer *ring, |
39 | u32 invalidate_domains, | 53 | u32 invalidate_domains, |
40 | u32 flush_domains) | 54 | u32 flush_domains) |
41 | { | 55 | { |
56 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
57 | u32 cmd; | ||
58 | |||
42 | #if WATCH_EXEC | 59 | #if WATCH_EXEC |
43 | DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, | 60 | DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, |
44 | invalidate_domains, flush_domains); | 61 | invalidate_domains, flush_domains); |
45 | #endif | 62 | #endif |
46 | u32 cmd; | 63 | |
47 | trace_i915_gem_request_flush(dev, ring->next_seqno, | 64 | trace_i915_gem_request_flush(dev, dev_priv->next_seqno, |
48 | invalidate_domains, flush_domains); | 65 | invalidate_domains, flush_domains); |
49 | 66 | ||
50 | if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) { | 67 | if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) { |
@@ -203,9 +220,13 @@ static int init_render_ring(struct drm_device *dev, | |||
203 | { | 220 | { |
204 | drm_i915_private_t *dev_priv = dev->dev_private; | 221 | drm_i915_private_t *dev_priv = dev->dev_private; |
205 | int ret = init_ring_common(dev, ring); | 222 | int ret = init_ring_common(dev, ring); |
223 | int mode; | ||
224 | |||
206 | if (IS_I9XX(dev) && !IS_GEN3(dev)) { | 225 | if (IS_I9XX(dev) && !IS_GEN3(dev)) { |
207 | I915_WRITE(MI_MODE, | 226 | mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH; |
208 | (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH); | 227 | if (IS_GEN6(dev)) |
228 | mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE; | ||
229 | I915_WRITE(MI_MODE, mode); | ||
209 | } | 230 | } |
210 | return ret; | 231 | return ret; |
211 | } | 232 | } |
@@ -233,9 +254,10 @@ render_ring_add_request(struct drm_device *dev, | |||
233 | struct drm_file *file_priv, | 254 | struct drm_file *file_priv, |
234 | u32 flush_domains) | 255 | u32 flush_domains) |
235 | { | 256 | { |
236 | u32 seqno; | ||
237 | drm_i915_private_t *dev_priv = dev->dev_private; | 257 | drm_i915_private_t *dev_priv = dev->dev_private; |
238 | seqno = intel_ring_get_seqno(dev, ring); | 258 | u32 seqno; |
259 | |||
260 | seqno = i915_gem_get_seqno(dev); | ||
239 | 261 | ||
240 | if (IS_GEN6(dev)) { | 262 | if (IS_GEN6(dev)) { |
241 | BEGIN_LP_RING(6); | 263 | BEGIN_LP_RING(6); |
@@ -405,7 +427,9 @@ bsd_ring_add_request(struct drm_device *dev, | |||
405 | u32 flush_domains) | 427 | u32 flush_domains) |
406 | { | 428 | { |
407 | u32 seqno; | 429 | u32 seqno; |
408 | seqno = intel_ring_get_seqno(dev, ring); | 430 | |
431 | seqno = i915_gem_get_seqno(dev); | ||
432 | |||
409 | intel_ring_begin(dev, ring, 4); | 433 | intel_ring_begin(dev, ring, 4); |
410 | intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); | 434 | intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); |
411 | intel_ring_emit(dev, ring, | 435 | intel_ring_emit(dev, ring, |
@@ -479,7 +503,7 @@ render_ring_dispatch_gem_execbuffer(struct drm_device *dev, | |||
479 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; | 503 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; |
480 | exec_len = (uint32_t) exec->batch_len; | 504 | exec_len = (uint32_t) exec->batch_len; |
481 | 505 | ||
482 | trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1); | 506 | trace_i915_gem_request_submit(dev, dev_priv->next_seqno + 1); |
483 | 507 | ||
484 | count = nbox ? nbox : 1; | 508 | count = nbox ? nbox : 1; |
485 | 509 | ||
@@ -515,7 +539,16 @@ render_ring_dispatch_gem_execbuffer(struct drm_device *dev, | |||
515 | intel_ring_advance(dev, ring); | 539 | intel_ring_advance(dev, ring); |
516 | } | 540 | } |
517 | 541 | ||
542 | if (IS_G4X(dev) || IS_IRONLAKE(dev)) { | ||
543 | intel_ring_begin(dev, ring, 2); | ||
544 | intel_ring_emit(dev, ring, MI_FLUSH | | ||
545 | MI_NO_WRITE_FLUSH | | ||
546 | MI_INVALIDATE_ISP ); | ||
547 | intel_ring_emit(dev, ring, MI_NOOP); | ||
548 | intel_ring_advance(dev, ring); | ||
549 | } | ||
518 | /* XXX breadcrumb */ | 550 | /* XXX breadcrumb */ |
551 | |||
519 | return 0; | 552 | return 0; |
520 | } | 553 | } |
521 | 554 | ||
@@ -588,9 +621,10 @@ err: | |||
588 | int intel_init_ring_buffer(struct drm_device *dev, | 621 | int intel_init_ring_buffer(struct drm_device *dev, |
589 | struct intel_ring_buffer *ring) | 622 | struct intel_ring_buffer *ring) |
590 | { | 623 | { |
591 | int ret; | ||
592 | struct drm_i915_gem_object *obj_priv; | 624 | struct drm_i915_gem_object *obj_priv; |
593 | struct drm_gem_object *obj; | 625 | struct drm_gem_object *obj; |
626 | int ret; | ||
627 | |||
594 | ring->dev = dev; | 628 | ring->dev = dev; |
595 | 629 | ||
596 | if (I915_NEED_GFX_HWS(dev)) { | 630 | if (I915_NEED_GFX_HWS(dev)) { |
@@ -603,16 +637,14 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
603 | if (obj == NULL) { | 637 | if (obj == NULL) { |
604 | DRM_ERROR("Failed to allocate ringbuffer\n"); | 638 | DRM_ERROR("Failed to allocate ringbuffer\n"); |
605 | ret = -ENOMEM; | 639 | ret = -ENOMEM; |
606 | goto cleanup; | 640 | goto err_hws; |
607 | } | 641 | } |
608 | 642 | ||
609 | ring->gem_object = obj; | 643 | ring->gem_object = obj; |
610 | 644 | ||
611 | ret = i915_gem_object_pin(obj, ring->alignment); | 645 | ret = i915_gem_object_pin(obj, ring->alignment); |
612 | if (ret != 0) { | 646 | if (ret) |
613 | drm_gem_object_unreference(obj); | 647 | goto err_unref; |
614 | goto cleanup; | ||
615 | } | ||
616 | 648 | ||
617 | obj_priv = to_intel_bo(obj); | 649 | obj_priv = to_intel_bo(obj); |
618 | ring->map.size = ring->size; | 650 | ring->map.size = ring->size; |
@@ -624,18 +656,14 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
624 | drm_core_ioremap_wc(&ring->map, dev); | 656 | drm_core_ioremap_wc(&ring->map, dev); |
625 | if (ring->map.handle == NULL) { | 657 | if (ring->map.handle == NULL) { |
626 | DRM_ERROR("Failed to map ringbuffer.\n"); | 658 | DRM_ERROR("Failed to map ringbuffer.\n"); |
627 | i915_gem_object_unpin(obj); | ||
628 | drm_gem_object_unreference(obj); | ||
629 | ret = -EINVAL; | 659 | ret = -EINVAL; |
630 | goto cleanup; | 660 | goto err_unpin; |
631 | } | 661 | } |
632 | 662 | ||
633 | ring->virtual_start = ring->map.handle; | 663 | ring->virtual_start = ring->map.handle; |
634 | ret = ring->init(dev, ring); | 664 | ret = ring->init(dev, ring); |
635 | if (ret != 0) { | 665 | if (ret) |
636 | intel_cleanup_ring_buffer(dev, ring); | 666 | goto err_unmap; |
637 | return ret; | ||
638 | } | ||
639 | 667 | ||
640 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 668 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
641 | i915_kernel_lost_context(dev); | 669 | i915_kernel_lost_context(dev); |
@@ -649,7 +677,15 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
649 | INIT_LIST_HEAD(&ring->active_list); | 677 | INIT_LIST_HEAD(&ring->active_list); |
650 | INIT_LIST_HEAD(&ring->request_list); | 678 | INIT_LIST_HEAD(&ring->request_list); |
651 | return ret; | 679 | return ret; |
652 | cleanup: | 680 | |
681 | err_unmap: | ||
682 | drm_core_ioremapfree(&ring->map, dev); | ||
683 | err_unpin: | ||
684 | i915_gem_object_unpin(obj); | ||
685 | err_unref: | ||
686 | drm_gem_object_unreference(obj); | ||
687 | ring->gem_object = NULL; | ||
688 | err_hws: | ||
653 | cleanup_status_page(dev, ring); | 689 | cleanup_status_page(dev, ring); |
654 | return ret; | 690 | return ret; |
655 | } | 691 | } |
@@ -682,9 +718,11 @@ int intel_wrap_ring_buffer(struct drm_device *dev, | |||
682 | } | 718 | } |
683 | 719 | ||
684 | virt = (unsigned int *)(ring->virtual_start + ring->tail); | 720 | virt = (unsigned int *)(ring->virtual_start + ring->tail); |
685 | rem /= 4; | 721 | rem /= 8; |
686 | while (rem--) | 722 | while (rem--) { |
723 | *virt++ = MI_NOOP; | ||
687 | *virt++ = MI_NOOP; | 724 | *virt++ = MI_NOOP; |
725 | } | ||
688 | 726 | ||
689 | ring->tail = 0; | 727 | ring->tail = 0; |
690 | ring->space = ring->head - 8; | 728 | ring->space = ring->head - 8; |
@@ -729,21 +767,14 @@ void intel_ring_begin(struct drm_device *dev, | |||
729 | intel_wrap_ring_buffer(dev, ring); | 767 | intel_wrap_ring_buffer(dev, ring); |
730 | if (unlikely(ring->space < n)) | 768 | if (unlikely(ring->space < n)) |
731 | intel_wait_ring_buffer(dev, ring, n); | 769 | intel_wait_ring_buffer(dev, ring, n); |
732 | } | ||
733 | 770 | ||
734 | void intel_ring_emit(struct drm_device *dev, | 771 | ring->space -= n; |
735 | struct intel_ring_buffer *ring, unsigned int data) | ||
736 | { | ||
737 | unsigned int *virt = ring->virtual_start + ring->tail; | ||
738 | *virt = data; | ||
739 | ring->tail += 4; | ||
740 | ring->tail &= ring->size - 1; | ||
741 | ring->space -= 4; | ||
742 | } | 772 | } |
743 | 773 | ||
744 | void intel_ring_advance(struct drm_device *dev, | 774 | void intel_ring_advance(struct drm_device *dev, |
745 | struct intel_ring_buffer *ring) | 775 | struct intel_ring_buffer *ring) |
746 | { | 776 | { |
777 | ring->tail &= ring->size - 1; | ||
747 | ring->advance_ring(dev, ring); | 778 | ring->advance_ring(dev, ring); |
748 | } | 779 | } |
749 | 780 | ||
@@ -762,18 +793,6 @@ void intel_fill_struct(struct drm_device *dev, | |||
762 | intel_ring_advance(dev, ring); | 793 | intel_ring_advance(dev, ring); |
763 | } | 794 | } |
764 | 795 | ||
765 | u32 intel_ring_get_seqno(struct drm_device *dev, | ||
766 | struct intel_ring_buffer *ring) | ||
767 | { | ||
768 | u32 seqno; | ||
769 | seqno = ring->next_seqno; | ||
770 | |||
771 | /* reserve 0 for non-seqno */ | ||
772 | if (++ring->next_seqno == 0) | ||
773 | ring->next_seqno = 1; | ||
774 | return seqno; | ||
775 | } | ||
776 | |||
777 | struct intel_ring_buffer render_ring = { | 796 | struct intel_ring_buffer render_ring = { |
778 | .name = "render ring", | 797 | .name = "render ring", |
779 | .regs = { | 798 | .regs = { |
@@ -791,7 +810,6 @@ struct intel_ring_buffer render_ring = { | |||
791 | .head = 0, | 810 | .head = 0, |
792 | .tail = 0, | 811 | .tail = 0, |
793 | .space = 0, | 812 | .space = 0, |
794 | .next_seqno = 1, | ||
795 | .user_irq_refcount = 0, | 813 | .user_irq_refcount = 0, |
796 | .irq_gem_seqno = 0, | 814 | .irq_gem_seqno = 0, |
797 | .waiting_gem_seqno = 0, | 815 | .waiting_gem_seqno = 0, |
@@ -830,7 +848,6 @@ struct intel_ring_buffer bsd_ring = { | |||
830 | .head = 0, | 848 | .head = 0, |
831 | .tail = 0, | 849 | .tail = 0, |
832 | .space = 0, | 850 | .space = 0, |
833 | .next_seqno = 1, | ||
834 | .user_irq_refcount = 0, | 851 | .user_irq_refcount = 0, |
835 | .irq_gem_seqno = 0, | 852 | .irq_gem_seqno = 0, |
836 | .waiting_gem_seqno = 0, | 853 | .waiting_gem_seqno = 0, |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index d5568d3766d..525e7d3edda 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -26,7 +26,6 @@ struct intel_ring_buffer { | |||
26 | unsigned int head; | 26 | unsigned int head; |
27 | unsigned int tail; | 27 | unsigned int tail; |
28 | unsigned int space; | 28 | unsigned int space; |
29 | u32 next_seqno; | ||
30 | struct intel_hw_status_page status_page; | 29 | struct intel_hw_status_page status_page; |
31 | 30 | ||
32 | u32 irq_gem_seqno; /* last seq seem at irq time */ | 31 | u32 irq_gem_seqno; /* last seq seem at irq time */ |
@@ -106,8 +105,16 @@ int intel_wrap_ring_buffer(struct drm_device *dev, | |||
106 | struct intel_ring_buffer *ring); | 105 | struct intel_ring_buffer *ring); |
107 | void intel_ring_begin(struct drm_device *dev, | 106 | void intel_ring_begin(struct drm_device *dev, |
108 | struct intel_ring_buffer *ring, int n); | 107 | struct intel_ring_buffer *ring, int n); |
109 | void intel_ring_emit(struct drm_device *dev, | 108 | |
110 | struct intel_ring_buffer *ring, u32 data); | 109 | static inline void intel_ring_emit(struct drm_device *dev, |
110 | struct intel_ring_buffer *ring, | ||
111 | unsigned int data) | ||
112 | { | ||
113 | unsigned int *virt = ring->virtual_start + ring->tail; | ||
114 | *virt = data; | ||
115 | ring->tail += 4; | ||
116 | } | ||
117 | |||
111 | void intel_fill_struct(struct drm_device *dev, | 118 | void intel_fill_struct(struct drm_device *dev, |
112 | struct intel_ring_buffer *ring, | 119 | struct intel_ring_buffer *ring, |
113 | void *data, | 120 | void *data, |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d9d4d51aa89..e3b7a7ee39c 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -31,8 +31,8 @@ | |||
31 | #include "drmP.h" | 31 | #include "drmP.h" |
32 | #include "drm.h" | 32 | #include "drm.h" |
33 | #include "drm_crtc.h" | 33 | #include "drm_crtc.h" |
34 | #include "intel_drv.h" | ||
35 | #include "drm_edid.h" | 34 | #include "drm_edid.h" |
35 | #include "intel_drv.h" | ||
36 | #include "i915_drm.h" | 36 | #include "i915_drm.h" |
37 | #include "i915_drv.h" | 37 | #include "i915_drv.h" |
38 | #include "intel_sdvo_regs.h" | 38 | #include "intel_sdvo_regs.h" |
@@ -47,9 +47,10 @@ | |||
47 | 47 | ||
48 | #define IS_TV(c) (c->output_flag & SDVO_TV_MASK) | 48 | #define IS_TV(c) (c->output_flag & SDVO_TV_MASK) |
49 | #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) | 49 | #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) |
50 | #define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK)) | ||
50 | 51 | ||
51 | 52 | ||
52 | static char *tv_format_names[] = { | 53 | static const char *tv_format_names[] = { |
53 | "NTSC_M" , "NTSC_J" , "NTSC_443", | 54 | "NTSC_M" , "NTSC_J" , "NTSC_443", |
54 | "PAL_B" , "PAL_D" , "PAL_G" , | 55 | "PAL_B" , "PAL_D" , "PAL_G" , |
55 | "PAL_H" , "PAL_I" , "PAL_M" , | 56 | "PAL_H" , "PAL_I" , "PAL_M" , |
@@ -61,7 +62,9 @@ static char *tv_format_names[] = { | |||
61 | 62 | ||
62 | #define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names)) | 63 | #define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names)) |
63 | 64 | ||
64 | struct intel_sdvo_priv { | 65 | struct intel_sdvo { |
66 | struct intel_encoder base; | ||
67 | |||
65 | u8 slave_addr; | 68 | u8 slave_addr; |
66 | 69 | ||
67 | /* Register for the SDVO device: SDVOB or SDVOC */ | 70 | /* Register for the SDVO device: SDVOB or SDVOC */ |
@@ -95,7 +98,7 @@ struct intel_sdvo_priv { | |||
95 | bool is_tv; | 98 | bool is_tv; |
96 | 99 | ||
97 | /* This is for current tv format name */ | 100 | /* This is for current tv format name */ |
98 | char *tv_format_name; | 101 | int tv_format_index; |
99 | 102 | ||
100 | /** | 103 | /** |
101 | * This is set if we treat the device as HDMI, instead of DVI. | 104 | * This is set if we treat the device as HDMI, instead of DVI. |
@@ -132,37 +135,40 @@ struct intel_sdvo_priv { | |||
132 | }; | 135 | }; |
133 | 136 | ||
134 | struct intel_sdvo_connector { | 137 | struct intel_sdvo_connector { |
138 | struct intel_connector base; | ||
139 | |||
135 | /* Mark the type of connector */ | 140 | /* Mark the type of connector */ |
136 | uint16_t output_flag; | 141 | uint16_t output_flag; |
137 | 142 | ||
138 | /* This contains all current supported TV format */ | 143 | /* This contains all current supported TV format */ |
139 | char *tv_format_supported[TV_FORMAT_NUM]; | 144 | u8 tv_format_supported[TV_FORMAT_NUM]; |
140 | int format_supported_num; | 145 | int format_supported_num; |
141 | struct drm_property *tv_format_property; | 146 | struct drm_property *tv_format; |
142 | struct drm_property *tv_format_name_property[TV_FORMAT_NUM]; | ||
143 | |||
144 | /** | ||
145 | * Returned SDTV resolutions allowed for the current format, if the | ||
146 | * device reported it. | ||
147 | */ | ||
148 | struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions; | ||
149 | 147 | ||
150 | /* add the property for the SDVO-TV */ | 148 | /* add the property for the SDVO-TV */ |
151 | struct drm_property *left_property; | 149 | struct drm_property *left; |
152 | struct drm_property *right_property; | 150 | struct drm_property *right; |
153 | struct drm_property *top_property; | 151 | struct drm_property *top; |
154 | struct drm_property *bottom_property; | 152 | struct drm_property *bottom; |
155 | struct drm_property *hpos_property; | 153 | struct drm_property *hpos; |
156 | struct drm_property *vpos_property; | 154 | struct drm_property *vpos; |
155 | struct drm_property *contrast; | ||
156 | struct drm_property *saturation; | ||
157 | struct drm_property *hue; | ||
158 | struct drm_property *sharpness; | ||
159 | struct drm_property *flicker_filter; | ||
160 | struct drm_property *flicker_filter_adaptive; | ||
161 | struct drm_property *flicker_filter_2d; | ||
162 | struct drm_property *tv_chroma_filter; | ||
163 | struct drm_property *tv_luma_filter; | ||
164 | struct drm_property *dot_crawl; | ||
157 | 165 | ||
158 | /* add the property for the SDVO-TV/LVDS */ | 166 | /* add the property for the SDVO-TV/LVDS */ |
159 | struct drm_property *brightness_property; | 167 | struct drm_property *brightness; |
160 | struct drm_property *contrast_property; | ||
161 | struct drm_property *saturation_property; | ||
162 | struct drm_property *hue_property; | ||
163 | 168 | ||
164 | /* Add variable to record current setting for the above property */ | 169 | /* Add variable to record current setting for the above property */ |
165 | u32 left_margin, right_margin, top_margin, bottom_margin; | 170 | u32 left_margin, right_margin, top_margin, bottom_margin; |
171 | |||
166 | /* this is to get the range of margin.*/ | 172 | /* this is to get the range of margin.*/ |
167 | u32 max_hscan, max_vscan; | 173 | u32 max_hscan, max_vscan; |
168 | u32 max_hpos, cur_hpos; | 174 | u32 max_hpos, cur_hpos; |
@@ -171,36 +177,54 @@ struct intel_sdvo_connector { | |||
171 | u32 cur_contrast, max_contrast; | 177 | u32 cur_contrast, max_contrast; |
172 | u32 cur_saturation, max_saturation; | 178 | u32 cur_saturation, max_saturation; |
173 | u32 cur_hue, max_hue; | 179 | u32 cur_hue, max_hue; |
180 | u32 cur_sharpness, max_sharpness; | ||
181 | u32 cur_flicker_filter, max_flicker_filter; | ||
182 | u32 cur_flicker_filter_adaptive, max_flicker_filter_adaptive; | ||
183 | u32 cur_flicker_filter_2d, max_flicker_filter_2d; | ||
184 | u32 cur_tv_chroma_filter, max_tv_chroma_filter; | ||
185 | u32 cur_tv_luma_filter, max_tv_luma_filter; | ||
186 | u32 cur_dot_crawl, max_dot_crawl; | ||
174 | }; | 187 | }; |
175 | 188 | ||
189 | static struct intel_sdvo *enc_to_intel_sdvo(struct drm_encoder *encoder) | ||
190 | { | ||
191 | return container_of(enc_to_intel_encoder(encoder), struct intel_sdvo, base); | ||
192 | } | ||
193 | |||
194 | static struct intel_sdvo_connector *to_intel_sdvo_connector(struct drm_connector *connector) | ||
195 | { | ||
196 | return container_of(to_intel_connector(connector), struct intel_sdvo_connector, base); | ||
197 | } | ||
198 | |||
176 | static bool | 199 | static bool |
177 | intel_sdvo_output_setup(struct intel_encoder *intel_encoder, | 200 | intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags); |
178 | uint16_t flags); | 201 | static bool |
179 | static void | 202 | intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, |
180 | intel_sdvo_tv_create_property(struct drm_connector *connector, int type); | 203 | struct intel_sdvo_connector *intel_sdvo_connector, |
181 | static void | 204 | int type); |
182 | intel_sdvo_create_enhance_property(struct drm_connector *connector); | 205 | static bool |
206 | intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, | ||
207 | struct intel_sdvo_connector *intel_sdvo_connector); | ||
183 | 208 | ||
184 | /** | 209 | /** |
185 | * Writes the SDVOB or SDVOC with the given value, but always writes both | 210 | * Writes the SDVOB or SDVOC with the given value, but always writes both |
186 | * SDVOB and SDVOC to work around apparent hardware issues (according to | 211 | * SDVOB and SDVOC to work around apparent hardware issues (according to |
187 | * comments in the BIOS). | 212 | * comments in the BIOS). |
188 | */ | 213 | */ |
189 | static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val) | 214 | static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val) |
190 | { | 215 | { |
191 | struct drm_device *dev = intel_encoder->enc.dev; | 216 | struct drm_device *dev = intel_sdvo->base.enc.dev; |
192 | struct drm_i915_private *dev_priv = dev->dev_private; | 217 | struct drm_i915_private *dev_priv = dev->dev_private; |
193 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
194 | u32 bval = val, cval = val; | 218 | u32 bval = val, cval = val; |
195 | int i; | 219 | int i; |
196 | 220 | ||
197 | if (sdvo_priv->sdvo_reg == PCH_SDVOB) { | 221 | if (intel_sdvo->sdvo_reg == PCH_SDVOB) { |
198 | I915_WRITE(sdvo_priv->sdvo_reg, val); | 222 | I915_WRITE(intel_sdvo->sdvo_reg, val); |
199 | I915_READ(sdvo_priv->sdvo_reg); | 223 | I915_READ(intel_sdvo->sdvo_reg); |
200 | return; | 224 | return; |
201 | } | 225 | } |
202 | 226 | ||
203 | if (sdvo_priv->sdvo_reg == SDVOB) { | 227 | if (intel_sdvo->sdvo_reg == SDVOB) { |
204 | cval = I915_READ(SDVOC); | 228 | cval = I915_READ(SDVOC); |
205 | } else { | 229 | } else { |
206 | bval = I915_READ(SDVOB); | 230 | bval = I915_READ(SDVOB); |
@@ -219,33 +243,27 @@ static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val) | |||
219 | } | 243 | } |
220 | } | 244 | } |
221 | 245 | ||
222 | static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr, | 246 | static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, u8 *ch) |
223 | u8 *ch) | ||
224 | { | 247 | { |
225 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 248 | u8 out_buf[2] = { addr, 0 }; |
226 | u8 out_buf[2]; | ||
227 | u8 buf[2]; | 249 | u8 buf[2]; |
228 | int ret; | ||
229 | |||
230 | struct i2c_msg msgs[] = { | 250 | struct i2c_msg msgs[] = { |
231 | { | 251 | { |
232 | .addr = sdvo_priv->slave_addr >> 1, | 252 | .addr = intel_sdvo->slave_addr >> 1, |
233 | .flags = 0, | 253 | .flags = 0, |
234 | .len = 1, | 254 | .len = 1, |
235 | .buf = out_buf, | 255 | .buf = out_buf, |
236 | }, | 256 | }, |
237 | { | 257 | { |
238 | .addr = sdvo_priv->slave_addr >> 1, | 258 | .addr = intel_sdvo->slave_addr >> 1, |
239 | .flags = I2C_M_RD, | 259 | .flags = I2C_M_RD, |
240 | .len = 1, | 260 | .len = 1, |
241 | .buf = buf, | 261 | .buf = buf, |
242 | } | 262 | } |
243 | }; | 263 | }; |
264 | int ret; | ||
244 | 265 | ||
245 | out_buf[0] = addr; | 266 | if ((ret = i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 2)) == 2) |
246 | out_buf[1] = 0; | ||
247 | |||
248 | if ((ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 2)) == 2) | ||
249 | { | 267 | { |
250 | *ch = buf[0]; | 268 | *ch = buf[0]; |
251 | return true; | 269 | return true; |
@@ -255,35 +273,26 @@ static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr, | |||
255 | return false; | 273 | return false; |
256 | } | 274 | } |
257 | 275 | ||
258 | static bool intel_sdvo_write_byte(struct intel_encoder *intel_encoder, int addr, | 276 | static bool intel_sdvo_write_byte(struct intel_sdvo *intel_sdvo, int addr, u8 ch) |
259 | u8 ch) | ||
260 | { | 277 | { |
261 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 278 | u8 out_buf[2] = { addr, ch }; |
262 | u8 out_buf[2]; | ||
263 | struct i2c_msg msgs[] = { | 279 | struct i2c_msg msgs[] = { |
264 | { | 280 | { |
265 | .addr = sdvo_priv->slave_addr >> 1, | 281 | .addr = intel_sdvo->slave_addr >> 1, |
266 | .flags = 0, | 282 | .flags = 0, |
267 | .len = 2, | 283 | .len = 2, |
268 | .buf = out_buf, | 284 | .buf = out_buf, |
269 | } | 285 | } |
270 | }; | 286 | }; |
271 | 287 | ||
272 | out_buf[0] = addr; | 288 | return i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 1) == 1; |
273 | out_buf[1] = ch; | ||
274 | |||
275 | if (i2c_transfer(intel_encoder->i2c_bus, msgs, 1) == 1) | ||
276 | { | ||
277 | return true; | ||
278 | } | ||
279 | return false; | ||
280 | } | 289 | } |
281 | 290 | ||
282 | #define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} | 291 | #define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} |
283 | /** Mapping of command numbers to names, for debug output */ | 292 | /** Mapping of command numbers to names, for debug output */ |
284 | static const struct _sdvo_cmd_name { | 293 | static const struct _sdvo_cmd_name { |
285 | u8 cmd; | 294 | u8 cmd; |
286 | char *name; | 295 | const char *name; |
287 | } sdvo_cmd_names[] = { | 296 | } sdvo_cmd_names[] = { |
288 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET), | 297 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET), |
289 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS), | 298 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS), |
@@ -328,13 +337,14 @@ static const struct _sdvo_cmd_name { | |||
328 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), | 337 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), |
329 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT), | 338 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT), |
330 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), | 339 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), |
340 | |||
331 | /* Add the op code for SDVO enhancements */ | 341 | /* Add the op code for SDVO enhancements */ |
332 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_H), | 342 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HPOS), |
333 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_H), | 343 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HPOS), |
334 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_H), | 344 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HPOS), |
335 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_V), | 345 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_VPOS), |
336 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_V), | 346 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_VPOS), |
337 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_V), | 347 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_VPOS), |
338 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION), | 348 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION), |
339 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION), | 349 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION), |
340 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION), | 350 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION), |
@@ -353,6 +363,27 @@ static const struct _sdvo_cmd_name { | |||
353 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V), | 363 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V), |
354 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V), | 364 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V), |
355 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V), | 365 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V), |
366 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER), | ||
367 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER), | ||
368 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER), | ||
369 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE), | ||
370 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE), | ||
371 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE), | ||
372 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_2D), | ||
373 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_2D), | ||
374 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_2D), | ||
375 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SHARPNESS), | ||
376 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SHARPNESS), | ||
377 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SHARPNESS), | ||
378 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DOT_CRAWL), | ||
379 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DOT_CRAWL), | ||
380 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_CHROMA_FILTER), | ||
381 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_CHROMA_FILTER), | ||
382 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_CHROMA_FILTER), | ||
383 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_LUMA_FILTER), | ||
384 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_LUMA_FILTER), | ||
385 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_LUMA_FILTER), | ||
386 | |||
356 | /* HDMI op code */ | 387 | /* HDMI op code */ |
357 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE), | 388 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE), |
358 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE), | 389 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE), |
@@ -377,17 +408,15 @@ static const struct _sdvo_cmd_name { | |||
377 | }; | 408 | }; |
378 | 409 | ||
379 | #define IS_SDVOB(reg) (reg == SDVOB || reg == PCH_SDVOB) | 410 | #define IS_SDVOB(reg) (reg == SDVOB || reg == PCH_SDVOB) |
380 | #define SDVO_NAME(dev_priv) (IS_SDVOB((dev_priv)->sdvo_reg) ? "SDVOB" : "SDVOC") | 411 | #define SDVO_NAME(svdo) (IS_SDVOB((svdo)->sdvo_reg) ? "SDVOB" : "SDVOC") |
381 | #define SDVO_PRIV(encoder) ((struct intel_sdvo_priv *) (encoder)->dev_priv) | ||
382 | 412 | ||
383 | static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd, | 413 | static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd, |
384 | void *args, int args_len) | 414 | const void *args, int args_len) |
385 | { | 415 | { |
386 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
387 | int i; | 416 | int i; |
388 | 417 | ||
389 | DRM_DEBUG_KMS("%s: W: %02X ", | 418 | DRM_DEBUG_KMS("%s: W: %02X ", |
390 | SDVO_NAME(sdvo_priv), cmd); | 419 | SDVO_NAME(intel_sdvo), cmd); |
391 | for (i = 0; i < args_len; i++) | 420 | for (i = 0; i < args_len; i++) |
392 | DRM_LOG_KMS("%02X ", ((u8 *)args)[i]); | 421 | DRM_LOG_KMS("%02X ", ((u8 *)args)[i]); |
393 | for (; i < 8; i++) | 422 | for (; i < 8; i++) |
@@ -403,19 +432,20 @@ static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd, | |||
403 | DRM_LOG_KMS("\n"); | 432 | DRM_LOG_KMS("\n"); |
404 | } | 433 | } |
405 | 434 | ||
406 | static void intel_sdvo_write_cmd(struct intel_encoder *intel_encoder, u8 cmd, | 435 | static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, |
407 | void *args, int args_len) | 436 | const void *args, int args_len) |
408 | { | 437 | { |
409 | int i; | 438 | int i; |
410 | 439 | ||
411 | intel_sdvo_debug_write(intel_encoder, cmd, args, args_len); | 440 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); |
412 | 441 | ||
413 | for (i = 0; i < args_len; i++) { | 442 | for (i = 0; i < args_len; i++) { |
414 | intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0 - i, | 443 | if (!intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_ARG_0 - i, |
415 | ((u8*)args)[i]); | 444 | ((u8*)args)[i])) |
445 | return false; | ||
416 | } | 446 | } |
417 | 447 | ||
418 | intel_sdvo_write_byte(intel_encoder, SDVO_I2C_OPCODE, cmd); | 448 | return intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_OPCODE, cmd); |
419 | } | 449 | } |
420 | 450 | ||
421 | static const char *cmd_status_names[] = { | 451 | static const char *cmd_status_names[] = { |
@@ -428,14 +458,13 @@ static const char *cmd_status_names[] = { | |||
428 | "Scaling not supported" | 458 | "Scaling not supported" |
429 | }; | 459 | }; |
430 | 460 | ||
431 | static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder, | 461 | static void intel_sdvo_debug_response(struct intel_sdvo *intel_sdvo, |
432 | void *response, int response_len, | 462 | void *response, int response_len, |
433 | u8 status) | 463 | u8 status) |
434 | { | 464 | { |
435 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
436 | int i; | 465 | int i; |
437 | 466 | ||
438 | DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv)); | 467 | DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(intel_sdvo)); |
439 | for (i = 0; i < response_len; i++) | 468 | for (i = 0; i < response_len; i++) |
440 | DRM_LOG_KMS("%02X ", ((u8 *)response)[i]); | 469 | DRM_LOG_KMS("%02X ", ((u8 *)response)[i]); |
441 | for (; i < 8; i++) | 470 | for (; i < 8; i++) |
@@ -447,8 +476,8 @@ static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder, | |||
447 | DRM_LOG_KMS("\n"); | 476 | DRM_LOG_KMS("\n"); |
448 | } | 477 | } |
449 | 478 | ||
450 | static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder, | 479 | static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, |
451 | void *response, int response_len) | 480 | void *response, int response_len) |
452 | { | 481 | { |
453 | int i; | 482 | int i; |
454 | u8 status; | 483 | u8 status; |
@@ -457,24 +486,26 @@ static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder, | |||
457 | while (retry--) { | 486 | while (retry--) { |
458 | /* Read the command response */ | 487 | /* Read the command response */ |
459 | for (i = 0; i < response_len; i++) { | 488 | for (i = 0; i < response_len; i++) { |
460 | intel_sdvo_read_byte(intel_encoder, | 489 | if (!intel_sdvo_read_byte(intel_sdvo, |
461 | SDVO_I2C_RETURN_0 + i, | 490 | SDVO_I2C_RETURN_0 + i, |
462 | &((u8 *)response)[i]); | 491 | &((u8 *)response)[i])) |
492 | return false; | ||
463 | } | 493 | } |
464 | 494 | ||
465 | /* read the return status */ | 495 | /* read the return status */ |
466 | intel_sdvo_read_byte(intel_encoder, SDVO_I2C_CMD_STATUS, | 496 | if (!intel_sdvo_read_byte(intel_sdvo, SDVO_I2C_CMD_STATUS, |
467 | &status); | 497 | &status)) |
498 | return false; | ||
468 | 499 | ||
469 | intel_sdvo_debug_response(intel_encoder, response, response_len, | 500 | intel_sdvo_debug_response(intel_sdvo, response, response_len, |
470 | status); | 501 | status); |
471 | if (status != SDVO_CMD_STATUS_PENDING) | 502 | if (status != SDVO_CMD_STATUS_PENDING) |
472 | return status; | 503 | break; |
473 | 504 | ||
474 | mdelay(50); | 505 | mdelay(50); |
475 | } | 506 | } |
476 | 507 | ||
477 | return status; | 508 | return status == SDVO_CMD_STATUS_SUCCESS; |
478 | } | 509 | } |
479 | 510 | ||
480 | static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) | 511 | static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) |
@@ -494,37 +525,36 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) | |||
494 | * another I2C transaction after issuing the DDC bus switch, it will be | 525 | * another I2C transaction after issuing the DDC bus switch, it will be |
495 | * switched to the internal SDVO register. | 526 | * switched to the internal SDVO register. |
496 | */ | 527 | */ |
497 | static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encoder, | 528 | static void intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo, |
498 | u8 target) | 529 | u8 target) |
499 | { | 530 | { |
500 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
501 | u8 out_buf[2], cmd_buf[2], ret_value[2], ret; | 531 | u8 out_buf[2], cmd_buf[2], ret_value[2], ret; |
502 | struct i2c_msg msgs[] = { | 532 | struct i2c_msg msgs[] = { |
503 | { | 533 | { |
504 | .addr = sdvo_priv->slave_addr >> 1, | 534 | .addr = intel_sdvo->slave_addr >> 1, |
505 | .flags = 0, | 535 | .flags = 0, |
506 | .len = 2, | 536 | .len = 2, |
507 | .buf = out_buf, | 537 | .buf = out_buf, |
508 | }, | 538 | }, |
509 | /* the following two are to read the response */ | 539 | /* the following two are to read the response */ |
510 | { | 540 | { |
511 | .addr = sdvo_priv->slave_addr >> 1, | 541 | .addr = intel_sdvo->slave_addr >> 1, |
512 | .flags = 0, | 542 | .flags = 0, |
513 | .len = 1, | 543 | .len = 1, |
514 | .buf = cmd_buf, | 544 | .buf = cmd_buf, |
515 | }, | 545 | }, |
516 | { | 546 | { |
517 | .addr = sdvo_priv->slave_addr >> 1, | 547 | .addr = intel_sdvo->slave_addr >> 1, |
518 | .flags = I2C_M_RD, | 548 | .flags = I2C_M_RD, |
519 | .len = 1, | 549 | .len = 1, |
520 | .buf = ret_value, | 550 | .buf = ret_value, |
521 | }, | 551 | }, |
522 | }; | 552 | }; |
523 | 553 | ||
524 | intel_sdvo_debug_write(intel_encoder, SDVO_CMD_SET_CONTROL_BUS_SWITCH, | 554 | intel_sdvo_debug_write(intel_sdvo, SDVO_CMD_SET_CONTROL_BUS_SWITCH, |
525 | &target, 1); | 555 | &target, 1); |
526 | /* write the DDC switch command argument */ | 556 | /* write the DDC switch command argument */ |
527 | intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0, target); | 557 | intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_ARG_0, target); |
528 | 558 | ||
529 | out_buf[0] = SDVO_I2C_OPCODE; | 559 | out_buf[0] = SDVO_I2C_OPCODE; |
530 | out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH; | 560 | out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH; |
@@ -533,7 +563,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encode | |||
533 | ret_value[0] = 0; | 563 | ret_value[0] = 0; |
534 | ret_value[1] = 0; | 564 | ret_value[1] = 0; |
535 | 565 | ||
536 | ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 3); | 566 | ret = i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 3); |
537 | if (ret != 3) { | 567 | if (ret != 3) { |
538 | /* failure in I2C transfer */ | 568 | /* failure in I2C transfer */ |
539 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); | 569 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); |
@@ -547,23 +577,29 @@ static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encode | |||
547 | return; | 577 | return; |
548 | } | 578 | } |
549 | 579 | ||
550 | static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, bool target_0, bool target_1) | 580 | static bool intel_sdvo_set_value(struct intel_sdvo *intel_sdvo, u8 cmd, const void *data, int len) |
551 | { | 581 | { |
552 | struct intel_sdvo_set_target_input_args targets = {0}; | 582 | if (!intel_sdvo_write_cmd(intel_sdvo, cmd, data, len)) |
553 | u8 status; | 583 | return false; |
554 | |||
555 | if (target_0 && target_1) | ||
556 | return SDVO_CMD_STATUS_NOTSUPP; | ||
557 | 584 | ||
558 | if (target_1) | 585 | return intel_sdvo_read_response(intel_sdvo, NULL, 0); |
559 | targets.target_1 = 1; | 586 | } |
560 | 587 | ||
561 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_INPUT, &targets, | 588 | static bool |
562 | sizeof(targets)); | 589 | intel_sdvo_get_value(struct intel_sdvo *intel_sdvo, u8 cmd, void *value, int len) |
590 | { | ||
591 | if (!intel_sdvo_write_cmd(intel_sdvo, cmd, NULL, 0)) | ||
592 | return false; | ||
563 | 593 | ||
564 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | 594 | return intel_sdvo_read_response(intel_sdvo, value, len); |
595 | } | ||
565 | 596 | ||
566 | return (status == SDVO_CMD_STATUS_SUCCESS); | 597 | static bool intel_sdvo_set_target_input(struct intel_sdvo *intel_sdvo) |
598 | { | ||
599 | struct intel_sdvo_set_target_input_args targets = {0}; | ||
600 | return intel_sdvo_set_value(intel_sdvo, | ||
601 | SDVO_CMD_SET_TARGET_INPUT, | ||
602 | &targets, sizeof(targets)); | ||
567 | } | 603 | } |
568 | 604 | ||
569 | /** | 605 | /** |
@@ -572,14 +608,12 @@ static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, boo | |||
572 | * This function is making an assumption about the layout of the response, | 608 | * This function is making an assumption about the layout of the response, |
573 | * which should be checked against the docs. | 609 | * which should be checked against the docs. |
574 | */ | 610 | */ |
575 | static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, bool *input_1, bool *input_2) | 611 | static bool intel_sdvo_get_trained_inputs(struct intel_sdvo *intel_sdvo, bool *input_1, bool *input_2) |
576 | { | 612 | { |
577 | struct intel_sdvo_get_trained_inputs_response response; | 613 | struct intel_sdvo_get_trained_inputs_response response; |
578 | u8 status; | ||
579 | 614 | ||
580 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0); | 615 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_TRAINED_INPUTS, |
581 | status = intel_sdvo_read_response(intel_encoder, &response, sizeof(response)); | 616 | &response, sizeof(response))) |
582 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
583 | return false; | 617 | return false; |
584 | 618 | ||
585 | *input_1 = response.input0_trained; | 619 | *input_1 = response.input0_trained; |
@@ -587,21 +621,18 @@ static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, b | |||
587 | return true; | 621 | return true; |
588 | } | 622 | } |
589 | 623 | ||
590 | static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder, | 624 | static bool intel_sdvo_set_active_outputs(struct intel_sdvo *intel_sdvo, |
591 | u16 outputs) | 625 | u16 outputs) |
592 | { | 626 | { |
593 | u8 status; | 627 | return intel_sdvo_set_value(intel_sdvo, |
594 | 628 | SDVO_CMD_SET_ACTIVE_OUTPUTS, | |
595 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs, | 629 | &outputs, sizeof(outputs)); |
596 | sizeof(outputs)); | ||
597 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
598 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
599 | } | 630 | } |
600 | 631 | ||
601 | static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encoder, | 632 | static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo, |
602 | int mode) | 633 | int mode) |
603 | { | 634 | { |
604 | u8 status, state = SDVO_ENCODER_STATE_ON; | 635 | u8 state = SDVO_ENCODER_STATE_ON; |
605 | 636 | ||
606 | switch (mode) { | 637 | switch (mode) { |
607 | case DRM_MODE_DPMS_ON: | 638 | case DRM_MODE_DPMS_ON: |
@@ -618,88 +649,63 @@ static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encod | |||
618 | break; | 649 | break; |
619 | } | 650 | } |
620 | 651 | ||
621 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODER_POWER_STATE, &state, | 652 | return intel_sdvo_set_value(intel_sdvo, |
622 | sizeof(state)); | 653 | SDVO_CMD_SET_ENCODER_POWER_STATE, &state, sizeof(state)); |
623 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
624 | |||
625 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
626 | } | 654 | } |
627 | 655 | ||
628 | static bool intel_sdvo_get_input_pixel_clock_range(struct intel_encoder *intel_encoder, | 656 | static bool intel_sdvo_get_input_pixel_clock_range(struct intel_sdvo *intel_sdvo, |
629 | int *clock_min, | 657 | int *clock_min, |
630 | int *clock_max) | 658 | int *clock_max) |
631 | { | 659 | { |
632 | struct intel_sdvo_pixel_clock_range clocks; | 660 | struct intel_sdvo_pixel_clock_range clocks; |
633 | u8 status; | ||
634 | |||
635 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, | ||
636 | NULL, 0); | ||
637 | |||
638 | status = intel_sdvo_read_response(intel_encoder, &clocks, sizeof(clocks)); | ||
639 | 661 | ||
640 | if (status != SDVO_CMD_STATUS_SUCCESS) | 662 | if (!intel_sdvo_get_value(intel_sdvo, |
663 | SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, | ||
664 | &clocks, sizeof(clocks))) | ||
641 | return false; | 665 | return false; |
642 | 666 | ||
643 | /* Convert the values from units of 10 kHz to kHz. */ | 667 | /* Convert the values from units of 10 kHz to kHz. */ |
644 | *clock_min = clocks.min * 10; | 668 | *clock_min = clocks.min * 10; |
645 | *clock_max = clocks.max * 10; | 669 | *clock_max = clocks.max * 10; |
646 | |||
647 | return true; | 670 | return true; |
648 | } | 671 | } |
649 | 672 | ||
650 | static bool intel_sdvo_set_target_output(struct intel_encoder *intel_encoder, | 673 | static bool intel_sdvo_set_target_output(struct intel_sdvo *intel_sdvo, |
651 | u16 outputs) | 674 | u16 outputs) |
652 | { | 675 | { |
653 | u8 status; | 676 | return intel_sdvo_set_value(intel_sdvo, |
654 | 677 | SDVO_CMD_SET_TARGET_OUTPUT, | |
655 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_OUTPUT, &outputs, | 678 | &outputs, sizeof(outputs)); |
656 | sizeof(outputs)); | ||
657 | |||
658 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
659 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
660 | } | 679 | } |
661 | 680 | ||
662 | static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd, | 681 | static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd, |
663 | struct intel_sdvo_dtd *dtd) | 682 | struct intel_sdvo_dtd *dtd) |
664 | { | 683 | { |
665 | u8 status; | 684 | return intel_sdvo_set_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) && |
666 | 685 | intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); | |
667 | intel_sdvo_write_cmd(intel_encoder, cmd, &dtd->part1, sizeof(dtd->part1)); | ||
668 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
669 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
670 | return false; | ||
671 | |||
672 | intel_sdvo_write_cmd(intel_encoder, cmd + 1, &dtd->part2, sizeof(dtd->part2)); | ||
673 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
674 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
675 | return false; | ||
676 | |||
677 | return true; | ||
678 | } | 686 | } |
679 | 687 | ||
680 | static bool intel_sdvo_set_input_timing(struct intel_encoder *intel_encoder, | 688 | static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo, |
681 | struct intel_sdvo_dtd *dtd) | 689 | struct intel_sdvo_dtd *dtd) |
682 | { | 690 | { |
683 | return intel_sdvo_set_timing(intel_encoder, | 691 | return intel_sdvo_set_timing(intel_sdvo, |
684 | SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd); | 692 | SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd); |
685 | } | 693 | } |
686 | 694 | ||
687 | static bool intel_sdvo_set_output_timing(struct intel_encoder *intel_encoder, | 695 | static bool intel_sdvo_set_output_timing(struct intel_sdvo *intel_sdvo, |
688 | struct intel_sdvo_dtd *dtd) | 696 | struct intel_sdvo_dtd *dtd) |
689 | { | 697 | { |
690 | return intel_sdvo_set_timing(intel_encoder, | 698 | return intel_sdvo_set_timing(intel_sdvo, |
691 | SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); | 699 | SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); |
692 | } | 700 | } |
693 | 701 | ||
694 | static bool | 702 | static bool |
695 | intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder, | 703 | intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo, |
696 | uint16_t clock, | 704 | uint16_t clock, |
697 | uint16_t width, | 705 | uint16_t width, |
698 | uint16_t height) | 706 | uint16_t height) |
699 | { | 707 | { |
700 | struct intel_sdvo_preferred_input_timing_args args; | 708 | struct intel_sdvo_preferred_input_timing_args args; |
701 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
702 | uint8_t status; | ||
703 | 709 | ||
704 | memset(&args, 0, sizeof(args)); | 710 | memset(&args, 0, sizeof(args)); |
705 | args.clock = clock; | 711 | args.clock = clock; |
@@ -707,59 +713,32 @@ intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder, | |||
707 | args.height = height; | 713 | args.height = height; |
708 | args.interlace = 0; | 714 | args.interlace = 0; |
709 | 715 | ||
710 | if (sdvo_priv->is_lvds && | 716 | if (intel_sdvo->is_lvds && |
711 | (sdvo_priv->sdvo_lvds_fixed_mode->hdisplay != width || | 717 | (intel_sdvo->sdvo_lvds_fixed_mode->hdisplay != width || |
712 | sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height)) | 718 | intel_sdvo->sdvo_lvds_fixed_mode->vdisplay != height)) |
713 | args.scaled = 1; | 719 | args.scaled = 1; |
714 | 720 | ||
715 | intel_sdvo_write_cmd(intel_encoder, | 721 | return intel_sdvo_set_value(intel_sdvo, |
716 | SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, | 722 | SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, |
717 | &args, sizeof(args)); | 723 | &args, sizeof(args)); |
718 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
719 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
720 | return false; | ||
721 | |||
722 | return true; | ||
723 | } | 724 | } |
724 | 725 | ||
725 | static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *intel_encoder, | 726 | static bool intel_sdvo_get_preferred_input_timing(struct intel_sdvo *intel_sdvo, |
726 | struct intel_sdvo_dtd *dtd) | 727 | struct intel_sdvo_dtd *dtd) |
727 | { | 728 | { |
728 | bool status; | 729 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, |
729 | 730 | &dtd->part1, sizeof(dtd->part1)) && | |
730 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, | 731 | intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, |
731 | NULL, 0); | 732 | &dtd->part2, sizeof(dtd->part2)); |
732 | |||
733 | status = intel_sdvo_read_response(intel_encoder, &dtd->part1, | ||
734 | sizeof(dtd->part1)); | ||
735 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
736 | return false; | ||
737 | |||
738 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, | ||
739 | NULL, 0); | ||
740 | |||
741 | status = intel_sdvo_read_response(intel_encoder, &dtd->part2, | ||
742 | sizeof(dtd->part2)); | ||
743 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
744 | return false; | ||
745 | |||
746 | return false; | ||
747 | } | 733 | } |
748 | 734 | ||
749 | static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val) | 735 | static bool intel_sdvo_set_clock_rate_mult(struct intel_sdvo *intel_sdvo, u8 val) |
750 | { | 736 | { |
751 | u8 status; | 737 | return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); |
752 | |||
753 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); | ||
754 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
755 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
756 | return false; | ||
757 | |||
758 | return true; | ||
759 | } | 738 | } |
760 | 739 | ||
761 | static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, | 740 | static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, |
762 | struct drm_display_mode *mode) | 741 | const struct drm_display_mode *mode) |
763 | { | 742 | { |
764 | uint16_t width, height; | 743 | uint16_t width, height; |
765 | uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; | 744 | uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; |
@@ -808,7 +787,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, | |||
808 | } | 787 | } |
809 | 788 | ||
810 | static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, | 789 | static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, |
811 | struct intel_sdvo_dtd *dtd) | 790 | const struct intel_sdvo_dtd *dtd) |
812 | { | 791 | { |
813 | mode->hdisplay = dtd->part1.h_active; | 792 | mode->hdisplay = dtd->part1.h_active; |
814 | mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; | 793 | mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; |
@@ -840,45 +819,33 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, | |||
840 | mode->flags |= DRM_MODE_FLAG_PVSYNC; | 819 | mode->flags |= DRM_MODE_FLAG_PVSYNC; |
841 | } | 820 | } |
842 | 821 | ||
843 | static bool intel_sdvo_get_supp_encode(struct intel_encoder *intel_encoder, | 822 | static bool intel_sdvo_get_supp_encode(struct intel_sdvo *intel_sdvo, |
844 | struct intel_sdvo_encode *encode) | 823 | struct intel_sdvo_encode *encode) |
845 | { | 824 | { |
846 | uint8_t status; | 825 | if (intel_sdvo_get_value(intel_sdvo, |
847 | 826 | SDVO_CMD_GET_SUPP_ENCODE, | |
848 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0); | 827 | encode, sizeof(*encode))) |
849 | status = intel_sdvo_read_response(intel_encoder, encode, sizeof(*encode)); | 828 | return true; |
850 | if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */ | ||
851 | memset(encode, 0, sizeof(*encode)); | ||
852 | return false; | ||
853 | } | ||
854 | 829 | ||
855 | return true; | 830 | /* non-support means DVI */ |
831 | memset(encode, 0, sizeof(*encode)); | ||
832 | return false; | ||
856 | } | 833 | } |
857 | 834 | ||
858 | static bool intel_sdvo_set_encode(struct intel_encoder *intel_encoder, | 835 | static bool intel_sdvo_set_encode(struct intel_sdvo *intel_sdvo, |
859 | uint8_t mode) | 836 | uint8_t mode) |
860 | { | 837 | { |
861 | uint8_t status; | 838 | return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_ENCODE, &mode, 1); |
862 | |||
863 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODE, &mode, 1); | ||
864 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
865 | |||
866 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
867 | } | 839 | } |
868 | 840 | ||
869 | static bool intel_sdvo_set_colorimetry(struct intel_encoder *intel_encoder, | 841 | static bool intel_sdvo_set_colorimetry(struct intel_sdvo *intel_sdvo, |
870 | uint8_t mode) | 842 | uint8_t mode) |
871 | { | 843 | { |
872 | uint8_t status; | 844 | return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_COLORIMETRY, &mode, 1); |
873 | |||
874 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_COLORIMETRY, &mode, 1); | ||
875 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
876 | |||
877 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
878 | } | 845 | } |
879 | 846 | ||
880 | #if 0 | 847 | #if 0 |
881 | static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder) | 848 | static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) |
882 | { | 849 | { |
883 | int i, j; | 850 | int i, j; |
884 | uint8_t set_buf_index[2]; | 851 | uint8_t set_buf_index[2]; |
@@ -887,8 +854,7 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder) | |||
887 | uint8_t buf[48]; | 854 | uint8_t buf[48]; |
888 | uint8_t *pos; | 855 | uint8_t *pos; |
889 | 856 | ||
890 | intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0); | 857 | intel_sdvo_get_value(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, &av_split, 1); |
891 | intel_sdvo_read_response(encoder, &av_split, 1); | ||
892 | 858 | ||
893 | for (i = 0; i <= av_split; i++) { | 859 | for (i = 0; i <= av_split; i++) { |
894 | set_buf_index[0] = i; set_buf_index[1] = 0; | 860 | set_buf_index[0] = i; set_buf_index[1] = 0; |
@@ -908,7 +874,7 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder) | |||
908 | } | 874 | } |
909 | #endif | 875 | #endif |
910 | 876 | ||
911 | static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder, | 877 | static bool intel_sdvo_set_hdmi_buf(struct intel_sdvo *intel_sdvo, |
912 | int index, | 878 | int index, |
913 | uint8_t *data, int8_t size, uint8_t tx_rate) | 879 | uint8_t *data, int8_t size, uint8_t tx_rate) |
914 | { | 880 | { |
@@ -917,15 +883,18 @@ static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder, | |||
917 | set_buf_index[0] = index; | 883 | set_buf_index[0] = index; |
918 | set_buf_index[1] = 0; | 884 | set_buf_index[1] = 0; |
919 | 885 | ||
920 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_INDEX, | 886 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_INDEX, |
921 | set_buf_index, 2); | 887 | set_buf_index, 2)) |
888 | return false; | ||
922 | 889 | ||
923 | for (; size > 0; size -= 8) { | 890 | for (; size > 0; size -= 8) { |
924 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_DATA, data, 8); | 891 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_DATA, data, 8)) |
892 | return false; | ||
893 | |||
925 | data += 8; | 894 | data += 8; |
926 | } | 895 | } |
927 | 896 | ||
928 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); | 897 | return intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); |
929 | } | 898 | } |
930 | 899 | ||
931 | static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) | 900 | static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) |
@@ -1000,7 +969,7 @@ struct dip_infoframe { | |||
1000 | } __attribute__ ((packed)) u; | 969 | } __attribute__ ((packed)) u; |
1001 | } __attribute__((packed)); | 970 | } __attribute__((packed)); |
1002 | 971 | ||
1003 | static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder, | 972 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo, |
1004 | struct drm_display_mode * mode) | 973 | struct drm_display_mode * mode) |
1005 | { | 974 | { |
1006 | struct dip_infoframe avi_if = { | 975 | struct dip_infoframe avi_if = { |
@@ -1011,133 +980,107 @@ static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder, | |||
1011 | 980 | ||
1012 | avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if, | 981 | avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if, |
1013 | 4 + avi_if.len); | 982 | 4 + avi_if.len); |
1014 | intel_sdvo_set_hdmi_buf(intel_encoder, 1, (uint8_t *)&avi_if, | 983 | return intel_sdvo_set_hdmi_buf(intel_sdvo, 1, (uint8_t *)&avi_if, |
1015 | 4 + avi_if.len, | 984 | 4 + avi_if.len, |
1016 | SDVO_HBUF_TX_VSYNC); | 985 | SDVO_HBUF_TX_VSYNC); |
1017 | } | 986 | } |
1018 | 987 | ||
1019 | static void intel_sdvo_set_tv_format(struct intel_encoder *intel_encoder) | 988 | static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) |
1020 | { | 989 | { |
1021 | |||
1022 | struct intel_sdvo_tv_format format; | 990 | struct intel_sdvo_tv_format format; |
1023 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 991 | uint32_t format_map; |
1024 | uint32_t format_map, i; | ||
1025 | uint8_t status; | ||
1026 | |||
1027 | for (i = 0; i < TV_FORMAT_NUM; i++) | ||
1028 | if (tv_format_names[i] == sdvo_priv->tv_format_name) | ||
1029 | break; | ||
1030 | 992 | ||
1031 | format_map = 1 << i; | 993 | format_map = 1 << intel_sdvo->tv_format_index; |
1032 | memset(&format, 0, sizeof(format)); | 994 | memset(&format, 0, sizeof(format)); |
1033 | memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ? | 995 | memcpy(&format, &format_map, min(sizeof(format), sizeof(format_map))); |
1034 | sizeof(format) : sizeof(format_map)); | ||
1035 | 996 | ||
1036 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TV_FORMAT, &format, | 997 | BUILD_BUG_ON(sizeof(format) != 6); |
1037 | sizeof(format)); | 998 | return intel_sdvo_set_value(intel_sdvo, |
1038 | 999 | SDVO_CMD_SET_TV_FORMAT, | |
1039 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | 1000 | &format, sizeof(format)); |
1040 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
1041 | DRM_DEBUG_KMS("%s: Failed to set TV format\n", | ||
1042 | SDVO_NAME(sdvo_priv)); | ||
1043 | } | 1001 | } |
1044 | 1002 | ||
1045 | static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | 1003 | static bool |
1046 | struct drm_display_mode *mode, | 1004 | intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo, |
1047 | struct drm_display_mode *adjusted_mode) | 1005 | struct drm_display_mode *mode) |
1048 | { | 1006 | { |
1049 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1007 | struct intel_sdvo_dtd output_dtd; |
1050 | struct intel_sdvo_priv *dev_priv = intel_encoder->dev_priv; | ||
1051 | 1008 | ||
1052 | if (dev_priv->is_tv) { | 1009 | if (!intel_sdvo_set_target_output(intel_sdvo, |
1053 | struct intel_sdvo_dtd output_dtd; | 1010 | intel_sdvo->attached_output)) |
1054 | bool success; | 1011 | return false; |
1055 | 1012 | ||
1056 | /* We need to construct preferred input timings based on our | 1013 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); |
1057 | * output timings. To do that, we have to set the output | 1014 | if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd)) |
1058 | * timings, even though this isn't really the right place in | 1015 | return false; |
1059 | * the sequence to do it. Oh well. | ||
1060 | */ | ||
1061 | 1016 | ||
1017 | return true; | ||
1018 | } | ||
1062 | 1019 | ||
1063 | /* Set output timings */ | 1020 | static bool |
1064 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); | 1021 | intel_sdvo_set_input_timings_for_mode(struct intel_sdvo *intel_sdvo, |
1065 | intel_sdvo_set_target_output(intel_encoder, | 1022 | struct drm_display_mode *mode, |
1066 | dev_priv->attached_output); | 1023 | struct drm_display_mode *adjusted_mode) |
1067 | intel_sdvo_set_output_timing(intel_encoder, &output_dtd); | 1024 | { |
1025 | struct intel_sdvo_dtd input_dtd; | ||
1068 | 1026 | ||
1069 | /* Set the input timing to the screen. Assume always input 0. */ | 1027 | /* Reset the input timing to the screen. Assume always input 0. */ |
1070 | intel_sdvo_set_target_input(intel_encoder, true, false); | 1028 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
1029 | return false; | ||
1071 | 1030 | ||
1031 | if (!intel_sdvo_create_preferred_input_timing(intel_sdvo, | ||
1032 | mode->clock / 10, | ||
1033 | mode->hdisplay, | ||
1034 | mode->vdisplay)) | ||
1035 | return false; | ||
1072 | 1036 | ||
1073 | success = intel_sdvo_create_preferred_input_timing(intel_encoder, | 1037 | if (!intel_sdvo_get_preferred_input_timing(intel_sdvo, |
1074 | mode->clock / 10, | 1038 | &input_dtd)) |
1075 | mode->hdisplay, | 1039 | return false; |
1076 | mode->vdisplay); | ||
1077 | if (success) { | ||
1078 | struct intel_sdvo_dtd input_dtd; | ||
1079 | 1040 | ||
1080 | intel_sdvo_get_preferred_input_timing(intel_encoder, | 1041 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); |
1081 | &input_dtd); | 1042 | intel_sdvo->sdvo_flags = input_dtd.part2.sdvo_flags; |
1082 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | ||
1083 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
1084 | 1043 | ||
1085 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 1044 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
1045 | mode->clock = adjusted_mode->clock; | ||
1046 | return true; | ||
1047 | } | ||
1086 | 1048 | ||
1087 | mode->clock = adjusted_mode->clock; | 1049 | static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, |
1050 | struct drm_display_mode *mode, | ||
1051 | struct drm_display_mode *adjusted_mode) | ||
1052 | { | ||
1053 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | ||
1088 | 1054 | ||
1089 | adjusted_mode->clock *= | 1055 | /* We need to construct preferred input timings based on our |
1090 | intel_sdvo_get_pixel_multiplier(mode); | 1056 | * output timings. To do that, we have to set the output |
1091 | } else { | 1057 | * timings, even though this isn't really the right place in |
1058 | * the sequence to do it. Oh well. | ||
1059 | */ | ||
1060 | if (intel_sdvo->is_tv) { | ||
1061 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) | ||
1092 | return false; | 1062 | return false; |
1093 | } | ||
1094 | } else if (dev_priv->is_lvds) { | ||
1095 | struct intel_sdvo_dtd output_dtd; | ||
1096 | bool success; | ||
1097 | |||
1098 | drm_mode_set_crtcinfo(dev_priv->sdvo_lvds_fixed_mode, 0); | ||
1099 | /* Set output timings */ | ||
1100 | intel_sdvo_get_dtd_from_mode(&output_dtd, | ||
1101 | dev_priv->sdvo_lvds_fixed_mode); | ||
1102 | |||
1103 | intel_sdvo_set_target_output(intel_encoder, | ||
1104 | dev_priv->attached_output); | ||
1105 | intel_sdvo_set_output_timing(intel_encoder, &output_dtd); | ||
1106 | |||
1107 | /* Set the input timing to the screen. Assume always input 0. */ | ||
1108 | intel_sdvo_set_target_input(intel_encoder, true, false); | ||
1109 | |||
1110 | |||
1111 | success = intel_sdvo_create_preferred_input_timing( | ||
1112 | intel_encoder, | ||
1113 | mode->clock / 10, | ||
1114 | mode->hdisplay, | ||
1115 | mode->vdisplay); | ||
1116 | |||
1117 | if (success) { | ||
1118 | struct intel_sdvo_dtd input_dtd; | ||
1119 | |||
1120 | intel_sdvo_get_preferred_input_timing(intel_encoder, | ||
1121 | &input_dtd); | ||
1122 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | ||
1123 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
1124 | 1063 | ||
1125 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 1064 | (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, |
1065 | mode, | ||
1066 | adjusted_mode); | ||
1067 | } else if (intel_sdvo->is_lvds) { | ||
1068 | drm_mode_set_crtcinfo(intel_sdvo->sdvo_lvds_fixed_mode, 0); | ||
1126 | 1069 | ||
1127 | mode->clock = adjusted_mode->clock; | 1070 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, |
1128 | 1071 | intel_sdvo->sdvo_lvds_fixed_mode)) | |
1129 | adjusted_mode->clock *= | ||
1130 | intel_sdvo_get_pixel_multiplier(mode); | ||
1131 | } else { | ||
1132 | return false; | 1072 | return false; |
1133 | } | ||
1134 | 1073 | ||
1135 | } else { | 1074 | (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, |
1136 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | 1075 | mode, |
1137 | * SDVO device will be told of the multiplier during mode_set. | 1076 | adjusted_mode); |
1138 | */ | ||
1139 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
1140 | } | 1077 | } |
1078 | |||
1079 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | ||
1080 | * SDVO device will be told of the multiplier during mode_set. | ||
1081 | */ | ||
1082 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
1083 | |||
1141 | return true; | 1084 | return true; |
1142 | } | 1085 | } |
1143 | 1086 | ||
@@ -1149,13 +1092,11 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1149 | struct drm_i915_private *dev_priv = dev->dev_private; | 1092 | struct drm_i915_private *dev_priv = dev->dev_private; |
1150 | struct drm_crtc *crtc = encoder->crtc; | 1093 | struct drm_crtc *crtc = encoder->crtc; |
1151 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1094 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1152 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1095 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1153 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1154 | u32 sdvox = 0; | 1096 | u32 sdvox = 0; |
1155 | int sdvo_pixel_multiply; | 1097 | int sdvo_pixel_multiply, rate; |
1156 | struct intel_sdvo_in_out_map in_out; | 1098 | struct intel_sdvo_in_out_map in_out; |
1157 | struct intel_sdvo_dtd input_dtd; | 1099 | struct intel_sdvo_dtd input_dtd; |
1158 | u8 status; | ||
1159 | 1100 | ||
1160 | if (!mode) | 1101 | if (!mode) |
1161 | return; | 1102 | return; |
@@ -1166,41 +1107,46 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1166 | * channel on the motherboard. In a two-input device, the first input | 1107 | * channel on the motherboard. In a two-input device, the first input |
1167 | * will be SDVOB and the second SDVOC. | 1108 | * will be SDVOB and the second SDVOC. |
1168 | */ | 1109 | */ |
1169 | in_out.in0 = sdvo_priv->attached_output; | 1110 | in_out.in0 = intel_sdvo->attached_output; |
1170 | in_out.in1 = 0; | 1111 | in_out.in1 = 0; |
1171 | 1112 | ||
1172 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP, | 1113 | intel_sdvo_set_value(intel_sdvo, |
1114 | SDVO_CMD_SET_IN_OUT_MAP, | ||
1173 | &in_out, sizeof(in_out)); | 1115 | &in_out, sizeof(in_out)); |
1174 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
1175 | 1116 | ||
1176 | if (sdvo_priv->is_hdmi) { | 1117 | if (intel_sdvo->is_hdmi) { |
1177 | intel_sdvo_set_avi_infoframe(intel_encoder, mode); | 1118 | if (!intel_sdvo_set_avi_infoframe(intel_sdvo, mode)) |
1119 | return; | ||
1120 | |||
1178 | sdvox |= SDVO_AUDIO_ENABLE; | 1121 | sdvox |= SDVO_AUDIO_ENABLE; |
1179 | } | 1122 | } |
1180 | 1123 | ||
1181 | /* We have tried to get input timing in mode_fixup, and filled into | 1124 | /* We have tried to get input timing in mode_fixup, and filled into |
1182 | adjusted_mode */ | 1125 | adjusted_mode */ |
1183 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { | 1126 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
1184 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | 1127 | if (intel_sdvo->is_tv || intel_sdvo->is_lvds) |
1185 | input_dtd.part2.sdvo_flags = sdvo_priv->sdvo_flags; | 1128 | input_dtd.part2.sdvo_flags = intel_sdvo->sdvo_flags; |
1186 | } else | ||
1187 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); | ||
1188 | 1129 | ||
1189 | /* If it's a TV, we already set the output timing in mode_fixup. | 1130 | /* If it's a TV, we already set the output timing in mode_fixup. |
1190 | * Otherwise, the output timing is equal to the input timing. | 1131 | * Otherwise, the output timing is equal to the input timing. |
1191 | */ | 1132 | */ |
1192 | if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) { | 1133 | if (!intel_sdvo->is_tv && !intel_sdvo->is_lvds) { |
1193 | /* Set the output timing to the screen */ | 1134 | /* Set the output timing to the screen */ |
1194 | intel_sdvo_set_target_output(intel_encoder, | 1135 | if (!intel_sdvo_set_target_output(intel_sdvo, |
1195 | sdvo_priv->attached_output); | 1136 | intel_sdvo->attached_output)) |
1196 | intel_sdvo_set_output_timing(intel_encoder, &input_dtd); | 1137 | return; |
1138 | |||
1139 | (void) intel_sdvo_set_output_timing(intel_sdvo, &input_dtd); | ||
1197 | } | 1140 | } |
1198 | 1141 | ||
1199 | /* Set the input timing to the screen. Assume always input 0. */ | 1142 | /* Set the input timing to the screen. Assume always input 0. */ |
1200 | intel_sdvo_set_target_input(intel_encoder, true, false); | 1143 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
1144 | return; | ||
1201 | 1145 | ||
1202 | if (sdvo_priv->is_tv) | 1146 | if (intel_sdvo->is_tv) { |
1203 | intel_sdvo_set_tv_format(intel_encoder); | 1147 | if (!intel_sdvo_set_tv_format(intel_sdvo)) |
1148 | return; | ||
1149 | } | ||
1204 | 1150 | ||
1205 | /* We would like to use intel_sdvo_create_preferred_input_timing() to | 1151 | /* We would like to use intel_sdvo_create_preferred_input_timing() to |
1206 | * provide the device with a timing it can support, if it supports that | 1152 | * provide the device with a timing it can support, if it supports that |
@@ -1217,23 +1163,17 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1217 | intel_sdvo_set_input_timing(encoder, &input_dtd); | 1163 | intel_sdvo_set_input_timing(encoder, &input_dtd); |
1218 | } | 1164 | } |
1219 | #else | 1165 | #else |
1220 | intel_sdvo_set_input_timing(intel_encoder, &input_dtd); | 1166 | (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); |
1221 | #endif | 1167 | #endif |
1222 | 1168 | ||
1223 | switch (intel_sdvo_get_pixel_multiplier(mode)) { | 1169 | sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode); |
1224 | case 1: | 1170 | switch (sdvo_pixel_multiply) { |
1225 | intel_sdvo_set_clock_rate_mult(intel_encoder, | 1171 | case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break; |
1226 | SDVO_CLOCK_RATE_MULT_1X); | 1172 | case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break; |
1227 | break; | 1173 | case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break; |
1228 | case 2: | ||
1229 | intel_sdvo_set_clock_rate_mult(intel_encoder, | ||
1230 | SDVO_CLOCK_RATE_MULT_2X); | ||
1231 | break; | ||
1232 | case 4: | ||
1233 | intel_sdvo_set_clock_rate_mult(intel_encoder, | ||
1234 | SDVO_CLOCK_RATE_MULT_4X); | ||
1235 | break; | ||
1236 | } | 1174 | } |
1175 | if (!intel_sdvo_set_clock_rate_mult(intel_sdvo, rate)) | ||
1176 | return; | ||
1237 | 1177 | ||
1238 | /* Set the SDVO control regs. */ | 1178 | /* Set the SDVO control regs. */ |
1239 | if (IS_I965G(dev)) { | 1179 | if (IS_I965G(dev)) { |
@@ -1243,8 +1183,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1243 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 1183 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
1244 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; | 1184 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; |
1245 | } else { | 1185 | } else { |
1246 | sdvox |= I915_READ(sdvo_priv->sdvo_reg); | 1186 | sdvox |= I915_READ(intel_sdvo->sdvo_reg); |
1247 | switch (sdvo_priv->sdvo_reg) { | 1187 | switch (intel_sdvo->sdvo_reg) { |
1248 | case SDVOB: | 1188 | case SDVOB: |
1249 | sdvox &= SDVOB_PRESERVE_MASK; | 1189 | sdvox &= SDVOB_PRESERVE_MASK; |
1250 | break; | 1190 | break; |
@@ -1257,7 +1197,6 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1257 | if (intel_crtc->pipe == 1) | 1197 | if (intel_crtc->pipe == 1) |
1258 | sdvox |= SDVO_PIPE_B_SELECT; | 1198 | sdvox |= SDVO_PIPE_B_SELECT; |
1259 | 1199 | ||
1260 | sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode); | ||
1261 | if (IS_I965G(dev)) { | 1200 | if (IS_I965G(dev)) { |
1262 | /* done in crtc_mode_set as the dpll_md reg must be written early */ | 1201 | /* done in crtc_mode_set as the dpll_md reg must be written early */ |
1263 | } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { | 1202 | } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { |
@@ -1266,28 +1205,28 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1266 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; | 1205 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; |
1267 | } | 1206 | } |
1268 | 1207 | ||
1269 | if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL) | 1208 | if (intel_sdvo->sdvo_flags & SDVO_NEED_TO_STALL) |
1270 | sdvox |= SDVO_STALL_SELECT; | 1209 | sdvox |= SDVO_STALL_SELECT; |
1271 | intel_sdvo_write_sdvox(intel_encoder, sdvox); | 1210 | intel_sdvo_write_sdvox(intel_sdvo, sdvox); |
1272 | } | 1211 | } |
1273 | 1212 | ||
1274 | static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) | 1213 | static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) |
1275 | { | 1214 | { |
1276 | struct drm_device *dev = encoder->dev; | 1215 | struct drm_device *dev = encoder->dev; |
1277 | struct drm_i915_private *dev_priv = dev->dev_private; | 1216 | struct drm_i915_private *dev_priv = dev->dev_private; |
1278 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1217 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1279 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1218 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
1280 | u32 temp; | 1219 | u32 temp; |
1281 | 1220 | ||
1282 | if (mode != DRM_MODE_DPMS_ON) { | 1221 | if (mode != DRM_MODE_DPMS_ON) { |
1283 | intel_sdvo_set_active_outputs(intel_encoder, 0); | 1222 | intel_sdvo_set_active_outputs(intel_sdvo, 0); |
1284 | if (0) | 1223 | if (0) |
1285 | intel_sdvo_set_encoder_power_state(intel_encoder, mode); | 1224 | intel_sdvo_set_encoder_power_state(intel_sdvo, mode); |
1286 | 1225 | ||
1287 | if (mode == DRM_MODE_DPMS_OFF) { | 1226 | if (mode == DRM_MODE_DPMS_OFF) { |
1288 | temp = I915_READ(sdvo_priv->sdvo_reg); | 1227 | temp = I915_READ(intel_sdvo->sdvo_reg); |
1289 | if ((temp & SDVO_ENABLE) != 0) { | 1228 | if ((temp & SDVO_ENABLE) != 0) { |
1290 | intel_sdvo_write_sdvox(intel_encoder, temp & ~SDVO_ENABLE); | 1229 | intel_sdvo_write_sdvox(intel_sdvo, temp & ~SDVO_ENABLE); |
1291 | } | 1230 | } |
1292 | } | 1231 | } |
1293 | } else { | 1232 | } else { |
@@ -1295,28 +1234,25 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) | |||
1295 | int i; | 1234 | int i; |
1296 | u8 status; | 1235 | u8 status; |
1297 | 1236 | ||
1298 | temp = I915_READ(sdvo_priv->sdvo_reg); | 1237 | temp = I915_READ(intel_sdvo->sdvo_reg); |
1299 | if ((temp & SDVO_ENABLE) == 0) | 1238 | if ((temp & SDVO_ENABLE) == 0) |
1300 | intel_sdvo_write_sdvox(intel_encoder, temp | SDVO_ENABLE); | 1239 | intel_sdvo_write_sdvox(intel_sdvo, temp | SDVO_ENABLE); |
1301 | for (i = 0; i < 2; i++) | 1240 | for (i = 0; i < 2; i++) |
1302 | intel_wait_for_vblank(dev); | 1241 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1303 | |||
1304 | status = intel_sdvo_get_trained_inputs(intel_encoder, &input1, | ||
1305 | &input2); | ||
1306 | |||
1307 | 1242 | ||
1243 | status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2); | ||
1308 | /* Warn if the device reported failure to sync. | 1244 | /* Warn if the device reported failure to sync. |
1309 | * A lot of SDVO devices fail to notify of sync, but it's | 1245 | * A lot of SDVO devices fail to notify of sync, but it's |
1310 | * a given it the status is a success, we succeeded. | 1246 | * a given it the status is a success, we succeeded. |
1311 | */ | 1247 | */ |
1312 | if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { | 1248 | if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { |
1313 | DRM_DEBUG_KMS("First %s output reported failure to " | 1249 | DRM_DEBUG_KMS("First %s output reported failure to " |
1314 | "sync\n", SDVO_NAME(sdvo_priv)); | 1250 | "sync\n", SDVO_NAME(intel_sdvo)); |
1315 | } | 1251 | } |
1316 | 1252 | ||
1317 | if (0) | 1253 | if (0) |
1318 | intel_sdvo_set_encoder_power_state(intel_encoder, mode); | 1254 | intel_sdvo_set_encoder_power_state(intel_sdvo, mode); |
1319 | intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->attached_output); | 1255 | intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); |
1320 | } | 1256 | } |
1321 | return; | 1257 | return; |
1322 | } | 1258 | } |
@@ -1325,42 +1261,31 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector, | |||
1325 | struct drm_display_mode *mode) | 1261 | struct drm_display_mode *mode) |
1326 | { | 1262 | { |
1327 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1263 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1328 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1264 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1329 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1330 | 1265 | ||
1331 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 1266 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
1332 | return MODE_NO_DBLESCAN; | 1267 | return MODE_NO_DBLESCAN; |
1333 | 1268 | ||
1334 | if (sdvo_priv->pixel_clock_min > mode->clock) | 1269 | if (intel_sdvo->pixel_clock_min > mode->clock) |
1335 | return MODE_CLOCK_LOW; | 1270 | return MODE_CLOCK_LOW; |
1336 | 1271 | ||
1337 | if (sdvo_priv->pixel_clock_max < mode->clock) | 1272 | if (intel_sdvo->pixel_clock_max < mode->clock) |
1338 | return MODE_CLOCK_HIGH; | 1273 | return MODE_CLOCK_HIGH; |
1339 | 1274 | ||
1340 | if (sdvo_priv->is_lvds == true) { | 1275 | if (intel_sdvo->is_lvds) { |
1341 | if (sdvo_priv->sdvo_lvds_fixed_mode == NULL) | 1276 | if (mode->hdisplay > intel_sdvo->sdvo_lvds_fixed_mode->hdisplay) |
1342 | return MODE_PANEL; | 1277 | return MODE_PANEL; |
1343 | 1278 | ||
1344 | if (mode->hdisplay > sdvo_priv->sdvo_lvds_fixed_mode->hdisplay) | 1279 | if (mode->vdisplay > intel_sdvo->sdvo_lvds_fixed_mode->vdisplay) |
1345 | return MODE_PANEL; | ||
1346 | |||
1347 | if (mode->vdisplay > sdvo_priv->sdvo_lvds_fixed_mode->vdisplay) | ||
1348 | return MODE_PANEL; | 1280 | return MODE_PANEL; |
1349 | } | 1281 | } |
1350 | 1282 | ||
1351 | return MODE_OK; | 1283 | return MODE_OK; |
1352 | } | 1284 | } |
1353 | 1285 | ||
1354 | static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, struct intel_sdvo_caps *caps) | 1286 | static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct intel_sdvo_caps *caps) |
1355 | { | 1287 | { |
1356 | u8 status; | 1288 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_DEVICE_CAPS, caps, sizeof(*caps)); |
1357 | |||
1358 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0); | ||
1359 | status = intel_sdvo_read_response(intel_encoder, caps, sizeof(*caps)); | ||
1360 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
1361 | return false; | ||
1362 | |||
1363 | return true; | ||
1364 | } | 1289 | } |
1365 | 1290 | ||
1366 | /* No use! */ | 1291 | /* No use! */ |
@@ -1368,12 +1293,12 @@ static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, str | |||
1368 | struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB) | 1293 | struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB) |
1369 | { | 1294 | { |
1370 | struct drm_connector *connector = NULL; | 1295 | struct drm_connector *connector = NULL; |
1371 | struct intel_encoder *iout = NULL; | 1296 | struct intel_sdvo *iout = NULL; |
1372 | struct intel_sdvo_priv *sdvo; | 1297 | struct intel_sdvo *sdvo; |
1373 | 1298 | ||
1374 | /* find the sdvo connector */ | 1299 | /* find the sdvo connector */ |
1375 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1300 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
1376 | iout = to_intel_encoder(connector); | 1301 | iout = to_intel_sdvo(connector); |
1377 | 1302 | ||
1378 | if (iout->type != INTEL_OUTPUT_SDVO) | 1303 | if (iout->type != INTEL_OUTPUT_SDVO) |
1379 | continue; | 1304 | continue; |
@@ -1395,75 +1320,69 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector) | |||
1395 | { | 1320 | { |
1396 | u8 response[2]; | 1321 | u8 response[2]; |
1397 | u8 status; | 1322 | u8 status; |
1398 | struct intel_encoder *intel_encoder; | 1323 | struct intel_sdvo *intel_sdvo; |
1399 | DRM_DEBUG_KMS("\n"); | 1324 | DRM_DEBUG_KMS("\n"); |
1400 | 1325 | ||
1401 | if (!connector) | 1326 | if (!connector) |
1402 | return 0; | 1327 | return 0; |
1403 | 1328 | ||
1404 | intel_encoder = to_intel_encoder(connector); | 1329 | intel_sdvo = to_intel_sdvo(connector); |
1405 | |||
1406 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); | ||
1407 | status = intel_sdvo_read_response(intel_encoder, &response, 2); | ||
1408 | |||
1409 | if (response[0] !=0) | ||
1410 | return 1; | ||
1411 | 1330 | ||
1412 | return 0; | 1331 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, |
1332 | &response, 2) && response[0]; | ||
1413 | } | 1333 | } |
1414 | 1334 | ||
1415 | void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) | 1335 | void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) |
1416 | { | 1336 | { |
1417 | u8 response[2]; | 1337 | u8 response[2]; |
1418 | u8 status; | 1338 | u8 status; |
1419 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1339 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(connector); |
1420 | 1340 | ||
1421 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); | 1341 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); |
1422 | intel_sdvo_read_response(intel_encoder, &response, 2); | 1342 | intel_sdvo_read_response(intel_sdvo, &response, 2); |
1423 | 1343 | ||
1424 | if (on) { | 1344 | if (on) { |
1425 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); | 1345 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); |
1426 | status = intel_sdvo_read_response(intel_encoder, &response, 2); | 1346 | status = intel_sdvo_read_response(intel_sdvo, &response, 2); |
1427 | 1347 | ||
1428 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); | 1348 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); |
1429 | } else { | 1349 | } else { |
1430 | response[0] = 0; | 1350 | response[0] = 0; |
1431 | response[1] = 0; | 1351 | response[1] = 0; |
1432 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); | 1352 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); |
1433 | } | 1353 | } |
1434 | 1354 | ||
1435 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); | 1355 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); |
1436 | intel_sdvo_read_response(intel_encoder, &response, 2); | 1356 | intel_sdvo_read_response(intel_sdvo, &response, 2); |
1437 | } | 1357 | } |
1438 | #endif | 1358 | #endif |
1439 | 1359 | ||
1440 | static bool | 1360 | static bool |
1441 | intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder) | 1361 | intel_sdvo_multifunc_encoder(struct intel_sdvo *intel_sdvo) |
1442 | { | 1362 | { |
1443 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1444 | int caps = 0; | 1363 | int caps = 0; |
1445 | 1364 | ||
1446 | if (sdvo_priv->caps.output_flags & | 1365 | if (intel_sdvo->caps.output_flags & |
1447 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) | 1366 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) |
1448 | caps++; | 1367 | caps++; |
1449 | if (sdvo_priv->caps.output_flags & | 1368 | if (intel_sdvo->caps.output_flags & |
1450 | (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)) | 1369 | (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)) |
1451 | caps++; | 1370 | caps++; |
1452 | if (sdvo_priv->caps.output_flags & | 1371 | if (intel_sdvo->caps.output_flags & |
1453 | (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID1)) | 1372 | (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID1)) |
1454 | caps++; | 1373 | caps++; |
1455 | if (sdvo_priv->caps.output_flags & | 1374 | if (intel_sdvo->caps.output_flags & |
1456 | (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1)) | 1375 | (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1)) |
1457 | caps++; | 1376 | caps++; |
1458 | if (sdvo_priv->caps.output_flags & | 1377 | if (intel_sdvo->caps.output_flags & |
1459 | (SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_YPRPB1)) | 1378 | (SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_YPRPB1)) |
1460 | caps++; | 1379 | caps++; |
1461 | 1380 | ||
1462 | if (sdvo_priv->caps.output_flags & | 1381 | if (intel_sdvo->caps.output_flags & |
1463 | (SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1)) | 1382 | (SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1)) |
1464 | caps++; | 1383 | caps++; |
1465 | 1384 | ||
1466 | if (sdvo_priv->caps.output_flags & | 1385 | if (intel_sdvo->caps.output_flags & |
1467 | (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)) | 1386 | (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)) |
1468 | caps++; | 1387 | caps++; |
1469 | 1388 | ||
@@ -1475,11 +1394,11 @@ intel_find_analog_connector(struct drm_device *dev) | |||
1475 | { | 1394 | { |
1476 | struct drm_connector *connector; | 1395 | struct drm_connector *connector; |
1477 | struct drm_encoder *encoder; | 1396 | struct drm_encoder *encoder; |
1478 | struct intel_encoder *intel_encoder; | 1397 | struct intel_sdvo *intel_sdvo; |
1479 | 1398 | ||
1480 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 1399 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
1481 | intel_encoder = enc_to_intel_encoder(encoder); | 1400 | intel_sdvo = enc_to_intel_sdvo(encoder); |
1482 | if (intel_encoder->type == INTEL_OUTPUT_ANALOG) { | 1401 | if (intel_sdvo->base.type == INTEL_OUTPUT_ANALOG) { |
1483 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1402 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
1484 | if (encoder == intel_attached_encoder(connector)) | 1403 | if (encoder == intel_attached_encoder(connector)) |
1485 | return connector; | 1404 | return connector; |
@@ -1493,8 +1412,8 @@ static int | |||
1493 | intel_analog_is_connected(struct drm_device *dev) | 1412 | intel_analog_is_connected(struct drm_device *dev) |
1494 | { | 1413 | { |
1495 | struct drm_connector *analog_connector; | 1414 | struct drm_connector *analog_connector; |
1496 | analog_connector = intel_find_analog_connector(dev); | ||
1497 | 1415 | ||
1416 | analog_connector = intel_find_analog_connector(dev); | ||
1498 | if (!analog_connector) | 1417 | if (!analog_connector) |
1499 | return false; | 1418 | return false; |
1500 | 1419 | ||
@@ -1509,54 +1428,52 @@ enum drm_connector_status | |||
1509 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | 1428 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) |
1510 | { | 1429 | { |
1511 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1430 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1512 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1431 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1513 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1432 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1514 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
1515 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
1516 | enum drm_connector_status status = connector_status_connected; | 1433 | enum drm_connector_status status = connector_status_connected; |
1517 | struct edid *edid = NULL; | 1434 | struct edid *edid = NULL; |
1518 | 1435 | ||
1519 | edid = drm_get_edid(connector, intel_encoder->ddc_bus); | 1436 | edid = drm_get_edid(connector, intel_sdvo->base.ddc_bus); |
1520 | 1437 | ||
1521 | /* This is only applied to SDVO cards with multiple outputs */ | 1438 | /* This is only applied to SDVO cards with multiple outputs */ |
1522 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) { | 1439 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_sdvo)) { |
1523 | uint8_t saved_ddc, temp_ddc; | 1440 | uint8_t saved_ddc, temp_ddc; |
1524 | saved_ddc = sdvo_priv->ddc_bus; | 1441 | saved_ddc = intel_sdvo->ddc_bus; |
1525 | temp_ddc = sdvo_priv->ddc_bus >> 1; | 1442 | temp_ddc = intel_sdvo->ddc_bus >> 1; |
1526 | /* | 1443 | /* |
1527 | * Don't use the 1 as the argument of DDC bus switch to get | 1444 | * Don't use the 1 as the argument of DDC bus switch to get |
1528 | * the EDID. It is used for SDVO SPD ROM. | 1445 | * the EDID. It is used for SDVO SPD ROM. |
1529 | */ | 1446 | */ |
1530 | while(temp_ddc > 1) { | 1447 | while(temp_ddc > 1) { |
1531 | sdvo_priv->ddc_bus = temp_ddc; | 1448 | intel_sdvo->ddc_bus = temp_ddc; |
1532 | edid = drm_get_edid(connector, intel_encoder->ddc_bus); | 1449 | edid = drm_get_edid(connector, intel_sdvo->base.ddc_bus); |
1533 | if (edid) { | 1450 | if (edid) { |
1534 | /* | 1451 | /* |
1535 | * When we can get the EDID, maybe it is the | 1452 | * When we can get the EDID, maybe it is the |
1536 | * correct DDC bus. Update it. | 1453 | * correct DDC bus. Update it. |
1537 | */ | 1454 | */ |
1538 | sdvo_priv->ddc_bus = temp_ddc; | 1455 | intel_sdvo->ddc_bus = temp_ddc; |
1539 | break; | 1456 | break; |
1540 | } | 1457 | } |
1541 | temp_ddc >>= 1; | 1458 | temp_ddc >>= 1; |
1542 | } | 1459 | } |
1543 | if (edid == NULL) | 1460 | if (edid == NULL) |
1544 | sdvo_priv->ddc_bus = saved_ddc; | 1461 | intel_sdvo->ddc_bus = saved_ddc; |
1545 | } | 1462 | } |
1546 | /* when there is no edid and no monitor is connected with VGA | 1463 | /* when there is no edid and no monitor is connected with VGA |
1547 | * port, try to use the CRT ddc to read the EDID for DVI-connector | 1464 | * port, try to use the CRT ddc to read the EDID for DVI-connector |
1548 | */ | 1465 | */ |
1549 | if (edid == NULL && sdvo_priv->analog_ddc_bus && | 1466 | if (edid == NULL && intel_sdvo->analog_ddc_bus && |
1550 | !intel_analog_is_connected(connector->dev)) | 1467 | !intel_analog_is_connected(connector->dev)) |
1551 | edid = drm_get_edid(connector, sdvo_priv->analog_ddc_bus); | 1468 | edid = drm_get_edid(connector, intel_sdvo->analog_ddc_bus); |
1552 | 1469 | ||
1553 | if (edid != NULL) { | 1470 | if (edid != NULL) { |
1554 | bool is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); | 1471 | bool is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); |
1555 | bool need_digital = !!(sdvo_connector->output_flag & SDVO_TMDS_MASK); | 1472 | bool need_digital = !!(intel_sdvo_connector->output_flag & SDVO_TMDS_MASK); |
1556 | 1473 | ||
1557 | /* DDC bus is shared, match EDID to connector type */ | 1474 | /* DDC bus is shared, match EDID to connector type */ |
1558 | if (is_digital && need_digital) | 1475 | if (is_digital && need_digital) |
1559 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); | 1476 | intel_sdvo->is_hdmi = drm_detect_hdmi_monitor(edid); |
1560 | else if (is_digital != need_digital) | 1477 | else if (is_digital != need_digital) |
1561 | status = connector_status_disconnected; | 1478 | status = connector_status_disconnected; |
1562 | 1479 | ||
@@ -1572,33 +1489,29 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | |||
1572 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) | 1489 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) |
1573 | { | 1490 | { |
1574 | uint16_t response; | 1491 | uint16_t response; |
1575 | u8 status; | ||
1576 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1492 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1577 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1493 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1578 | struct intel_connector *intel_connector = to_intel_connector(connector); | 1494 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1579 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1580 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
1581 | enum drm_connector_status ret; | 1495 | enum drm_connector_status ret; |
1582 | 1496 | ||
1583 | intel_sdvo_write_cmd(intel_encoder, | 1497 | if (!intel_sdvo_write_cmd(intel_sdvo, |
1584 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); | 1498 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0)) |
1585 | if (sdvo_priv->is_tv) { | 1499 | return connector_status_unknown; |
1500 | if (intel_sdvo->is_tv) { | ||
1586 | /* add 30ms delay when the output type is SDVO-TV */ | 1501 | /* add 30ms delay when the output type is SDVO-TV */ |
1587 | mdelay(30); | 1502 | mdelay(30); |
1588 | } | 1503 | } |
1589 | status = intel_sdvo_read_response(intel_encoder, &response, 2); | 1504 | if (!intel_sdvo_read_response(intel_sdvo, &response, 2)) |
1505 | return connector_status_unknown; | ||
1590 | 1506 | ||
1591 | DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); | 1507 | DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); |
1592 | 1508 | ||
1593 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
1594 | return connector_status_unknown; | ||
1595 | |||
1596 | if (response == 0) | 1509 | if (response == 0) |
1597 | return connector_status_disconnected; | 1510 | return connector_status_disconnected; |
1598 | 1511 | ||
1599 | sdvo_priv->attached_output = response; | 1512 | intel_sdvo->attached_output = response; |
1600 | 1513 | ||
1601 | if ((sdvo_connector->output_flag & response) == 0) | 1514 | if ((intel_sdvo_connector->output_flag & response) == 0) |
1602 | ret = connector_status_disconnected; | 1515 | ret = connector_status_disconnected; |
1603 | else if (response & SDVO_TMDS_MASK) | 1516 | else if (response & SDVO_TMDS_MASK) |
1604 | ret = intel_sdvo_hdmi_sink_detect(connector); | 1517 | ret = intel_sdvo_hdmi_sink_detect(connector); |
@@ -1607,16 +1520,16 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1607 | 1520 | ||
1608 | /* May update encoder flag for like clock for SDVO TV, etc.*/ | 1521 | /* May update encoder flag for like clock for SDVO TV, etc.*/ |
1609 | if (ret == connector_status_connected) { | 1522 | if (ret == connector_status_connected) { |
1610 | sdvo_priv->is_tv = false; | 1523 | intel_sdvo->is_tv = false; |
1611 | sdvo_priv->is_lvds = false; | 1524 | intel_sdvo->is_lvds = false; |
1612 | intel_encoder->needs_tv_clock = false; | 1525 | intel_sdvo->base.needs_tv_clock = false; |
1613 | 1526 | ||
1614 | if (response & SDVO_TV_MASK) { | 1527 | if (response & SDVO_TV_MASK) { |
1615 | sdvo_priv->is_tv = true; | 1528 | intel_sdvo->is_tv = true; |
1616 | intel_encoder->needs_tv_clock = true; | 1529 | intel_sdvo->base.needs_tv_clock = true; |
1617 | } | 1530 | } |
1618 | if (response & SDVO_LVDS_MASK) | 1531 | if (response & SDVO_LVDS_MASK) |
1619 | sdvo_priv->is_lvds = true; | 1532 | intel_sdvo->is_lvds = intel_sdvo->sdvo_lvds_fixed_mode != NULL; |
1620 | } | 1533 | } |
1621 | 1534 | ||
1622 | return ret; | 1535 | return ret; |
@@ -1625,12 +1538,11 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1625 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | 1538 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) |
1626 | { | 1539 | { |
1627 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1540 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1628 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1541 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1629 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1630 | int num_modes; | 1542 | int num_modes; |
1631 | 1543 | ||
1632 | /* set the bus switch and get the modes */ | 1544 | /* set the bus switch and get the modes */ |
1633 | num_modes = intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 1545 | num_modes = intel_ddc_get_modes(connector, intel_sdvo->base.ddc_bus); |
1634 | 1546 | ||
1635 | /* | 1547 | /* |
1636 | * Mac mini hack. On this device, the DVI-I connector shares one DDC | 1548 | * Mac mini hack. On this device, the DVI-I connector shares one DDC |
@@ -1639,11 +1551,11 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | |||
1639 | * which case we'll look there for the digital DDC data. | 1551 | * which case we'll look there for the digital DDC data. |
1640 | */ | 1552 | */ |
1641 | if (num_modes == 0 && | 1553 | if (num_modes == 0 && |
1642 | sdvo_priv->analog_ddc_bus && | 1554 | intel_sdvo->analog_ddc_bus && |
1643 | !intel_analog_is_connected(connector->dev)) { | 1555 | !intel_analog_is_connected(connector->dev)) { |
1644 | /* Switch to the analog ddc bus and try that | 1556 | /* Switch to the analog ddc bus and try that |
1645 | */ | 1557 | */ |
1646 | (void) intel_ddc_get_modes(connector, sdvo_priv->analog_ddc_bus); | 1558 | (void) intel_ddc_get_modes(connector, intel_sdvo->analog_ddc_bus); |
1647 | } | 1559 | } |
1648 | } | 1560 | } |
1649 | 1561 | ||
@@ -1715,52 +1627,43 @@ struct drm_display_mode sdvo_tv_modes[] = { | |||
1715 | static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | 1627 | static void intel_sdvo_get_tv_modes(struct drm_connector *connector) |
1716 | { | 1628 | { |
1717 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1629 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1718 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1630 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1719 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1720 | struct intel_sdvo_sdtv_resolution_request tv_res; | 1631 | struct intel_sdvo_sdtv_resolution_request tv_res; |
1721 | uint32_t reply = 0, format_map = 0; | 1632 | uint32_t reply = 0, format_map = 0; |
1722 | int i; | 1633 | int i; |
1723 | uint8_t status; | ||
1724 | |||
1725 | 1634 | ||
1726 | /* Read the list of supported input resolutions for the selected TV | 1635 | /* Read the list of supported input resolutions for the selected TV |
1727 | * format. | 1636 | * format. |
1728 | */ | 1637 | */ |
1729 | for (i = 0; i < TV_FORMAT_NUM; i++) | 1638 | format_map = 1 << intel_sdvo->tv_format_index; |
1730 | if (tv_format_names[i] == sdvo_priv->tv_format_name) | ||
1731 | break; | ||
1732 | |||
1733 | format_map = (1 << i); | ||
1734 | memcpy(&tv_res, &format_map, | 1639 | memcpy(&tv_res, &format_map, |
1735 | sizeof(struct intel_sdvo_sdtv_resolution_request) > | 1640 | min(sizeof(format_map), sizeof(struct intel_sdvo_sdtv_resolution_request))); |
1736 | sizeof(format_map) ? sizeof(format_map) : | ||
1737 | sizeof(struct intel_sdvo_sdtv_resolution_request)); | ||
1738 | 1641 | ||
1739 | intel_sdvo_set_target_output(intel_encoder, sdvo_priv->attached_output); | 1642 | if (!intel_sdvo_set_target_output(intel_sdvo, intel_sdvo->attached_output)) |
1643 | return; | ||
1740 | 1644 | ||
1741 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, | 1645 | BUILD_BUG_ON(sizeof(tv_res) != 3); |
1742 | &tv_res, sizeof(tv_res)); | 1646 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, |
1743 | status = intel_sdvo_read_response(intel_encoder, &reply, 3); | 1647 | &tv_res, sizeof(tv_res))) |
1744 | if (status != SDVO_CMD_STATUS_SUCCESS) | 1648 | return; |
1649 | if (!intel_sdvo_read_response(intel_sdvo, &reply, 3)) | ||
1745 | return; | 1650 | return; |
1746 | 1651 | ||
1747 | for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++) | 1652 | for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++) |
1748 | if (reply & (1 << i)) { | 1653 | if (reply & (1 << i)) { |
1749 | struct drm_display_mode *nmode; | 1654 | struct drm_display_mode *nmode; |
1750 | nmode = drm_mode_duplicate(connector->dev, | 1655 | nmode = drm_mode_duplicate(connector->dev, |
1751 | &sdvo_tv_modes[i]); | 1656 | &sdvo_tv_modes[i]); |
1752 | if (nmode) | 1657 | if (nmode) |
1753 | drm_mode_probed_add(connector, nmode); | 1658 | drm_mode_probed_add(connector, nmode); |
1754 | } | 1659 | } |
1755 | |||
1756 | } | 1660 | } |
1757 | 1661 | ||
1758 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | 1662 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) |
1759 | { | 1663 | { |
1760 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1664 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1761 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1665 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1762 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 1666 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
1763 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1764 | struct drm_display_mode *newmode; | 1667 | struct drm_display_mode *newmode; |
1765 | 1668 | ||
1766 | /* | 1669 | /* |
@@ -1768,7 +1671,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1768 | * Assume that the preferred modes are | 1671 | * Assume that the preferred modes are |
1769 | * arranged in priority order. | 1672 | * arranged in priority order. |
1770 | */ | 1673 | */ |
1771 | intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 1674 | intel_ddc_get_modes(connector, intel_sdvo->base.ddc_bus); |
1772 | if (list_empty(&connector->probed_modes) == false) | 1675 | if (list_empty(&connector->probed_modes) == false) |
1773 | goto end; | 1676 | goto end; |
1774 | 1677 | ||
@@ -1787,8 +1690,9 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1787 | end: | 1690 | end: |
1788 | list_for_each_entry(newmode, &connector->probed_modes, head) { | 1691 | list_for_each_entry(newmode, &connector->probed_modes, head) { |
1789 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { | 1692 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { |
1790 | sdvo_priv->sdvo_lvds_fixed_mode = | 1693 | intel_sdvo->sdvo_lvds_fixed_mode = |
1791 | drm_mode_duplicate(connector->dev, newmode); | 1694 | drm_mode_duplicate(connector->dev, newmode); |
1695 | intel_sdvo->is_lvds = true; | ||
1792 | break; | 1696 | break; |
1793 | } | 1697 | } |
1794 | } | 1698 | } |
@@ -1797,66 +1701,67 @@ end: | |||
1797 | 1701 | ||
1798 | static int intel_sdvo_get_modes(struct drm_connector *connector) | 1702 | static int intel_sdvo_get_modes(struct drm_connector *connector) |
1799 | { | 1703 | { |
1800 | struct intel_connector *intel_connector = to_intel_connector(connector); | 1704 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1801 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
1802 | 1705 | ||
1803 | if (IS_TV(sdvo_connector)) | 1706 | if (IS_TV(intel_sdvo_connector)) |
1804 | intel_sdvo_get_tv_modes(connector); | 1707 | intel_sdvo_get_tv_modes(connector); |
1805 | else if (IS_LVDS(sdvo_connector)) | 1708 | else if (IS_LVDS(intel_sdvo_connector)) |
1806 | intel_sdvo_get_lvds_modes(connector); | 1709 | intel_sdvo_get_lvds_modes(connector); |
1807 | else | 1710 | else |
1808 | intel_sdvo_get_ddc_modes(connector); | 1711 | intel_sdvo_get_ddc_modes(connector); |
1809 | 1712 | ||
1810 | if (list_empty(&connector->probed_modes)) | 1713 | return !list_empty(&connector->probed_modes); |
1811 | return 0; | ||
1812 | return 1; | ||
1813 | } | 1714 | } |
1814 | 1715 | ||
1815 | static | 1716 | static void |
1816 | void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) | 1717 | intel_sdvo_destroy_enhance_property(struct drm_connector *connector) |
1817 | { | 1718 | { |
1818 | struct intel_connector *intel_connector = to_intel_connector(connector); | 1719 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1819 | struct intel_sdvo_connector *sdvo_priv = intel_connector->dev_priv; | ||
1820 | struct drm_device *dev = connector->dev; | 1720 | struct drm_device *dev = connector->dev; |
1821 | 1721 | ||
1822 | if (IS_TV(sdvo_priv)) { | 1722 | if (intel_sdvo_connector->left) |
1823 | if (sdvo_priv->left_property) | 1723 | drm_property_destroy(dev, intel_sdvo_connector->left); |
1824 | drm_property_destroy(dev, sdvo_priv->left_property); | 1724 | if (intel_sdvo_connector->right) |
1825 | if (sdvo_priv->right_property) | 1725 | drm_property_destroy(dev, intel_sdvo_connector->right); |
1826 | drm_property_destroy(dev, sdvo_priv->right_property); | 1726 | if (intel_sdvo_connector->top) |
1827 | if (sdvo_priv->top_property) | 1727 | drm_property_destroy(dev, intel_sdvo_connector->top); |
1828 | drm_property_destroy(dev, sdvo_priv->top_property); | 1728 | if (intel_sdvo_connector->bottom) |
1829 | if (sdvo_priv->bottom_property) | 1729 | drm_property_destroy(dev, intel_sdvo_connector->bottom); |
1830 | drm_property_destroy(dev, sdvo_priv->bottom_property); | 1730 | if (intel_sdvo_connector->hpos) |
1831 | if (sdvo_priv->hpos_property) | 1731 | drm_property_destroy(dev, intel_sdvo_connector->hpos); |
1832 | drm_property_destroy(dev, sdvo_priv->hpos_property); | 1732 | if (intel_sdvo_connector->vpos) |
1833 | if (sdvo_priv->vpos_property) | 1733 | drm_property_destroy(dev, intel_sdvo_connector->vpos); |
1834 | drm_property_destroy(dev, sdvo_priv->vpos_property); | 1734 | if (intel_sdvo_connector->saturation) |
1835 | if (sdvo_priv->saturation_property) | 1735 | drm_property_destroy(dev, intel_sdvo_connector->saturation); |
1836 | drm_property_destroy(dev, | 1736 | if (intel_sdvo_connector->contrast) |
1837 | sdvo_priv->saturation_property); | 1737 | drm_property_destroy(dev, intel_sdvo_connector->contrast); |
1838 | if (sdvo_priv->contrast_property) | 1738 | if (intel_sdvo_connector->hue) |
1839 | drm_property_destroy(dev, | 1739 | drm_property_destroy(dev, intel_sdvo_connector->hue); |
1840 | sdvo_priv->contrast_property); | 1740 | if (intel_sdvo_connector->sharpness) |
1841 | if (sdvo_priv->hue_property) | 1741 | drm_property_destroy(dev, intel_sdvo_connector->sharpness); |
1842 | drm_property_destroy(dev, sdvo_priv->hue_property); | 1742 | if (intel_sdvo_connector->flicker_filter) |
1843 | } | 1743 | drm_property_destroy(dev, intel_sdvo_connector->flicker_filter); |
1844 | if (IS_TV(sdvo_priv) || IS_LVDS(sdvo_priv)) { | 1744 | if (intel_sdvo_connector->flicker_filter_2d) |
1845 | if (sdvo_priv->brightness_property) | 1745 | drm_property_destroy(dev, intel_sdvo_connector->flicker_filter_2d); |
1846 | drm_property_destroy(dev, | 1746 | if (intel_sdvo_connector->flicker_filter_adaptive) |
1847 | sdvo_priv->brightness_property); | 1747 | drm_property_destroy(dev, intel_sdvo_connector->flicker_filter_adaptive); |
1848 | } | 1748 | if (intel_sdvo_connector->tv_luma_filter) |
1849 | return; | 1749 | drm_property_destroy(dev, intel_sdvo_connector->tv_luma_filter); |
1750 | if (intel_sdvo_connector->tv_chroma_filter) | ||
1751 | drm_property_destroy(dev, intel_sdvo_connector->tv_chroma_filter); | ||
1752 | if (intel_sdvo_connector->dot_crawl) | ||
1753 | drm_property_destroy(dev, intel_sdvo_connector->dot_crawl); | ||
1754 | if (intel_sdvo_connector->brightness) | ||
1755 | drm_property_destroy(dev, intel_sdvo_connector->brightness); | ||
1850 | } | 1756 | } |
1851 | 1757 | ||
1852 | static void intel_sdvo_destroy(struct drm_connector *connector) | 1758 | static void intel_sdvo_destroy(struct drm_connector *connector) |
1853 | { | 1759 | { |
1854 | struct intel_connector *intel_connector = to_intel_connector(connector); | 1760 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1855 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
1856 | 1761 | ||
1857 | if (sdvo_connector->tv_format_property) | 1762 | if (intel_sdvo_connector->tv_format) |
1858 | drm_property_destroy(connector->dev, | 1763 | drm_property_destroy(connector->dev, |
1859 | sdvo_connector->tv_format_property); | 1764 | intel_sdvo_connector->tv_format); |
1860 | 1765 | ||
1861 | intel_sdvo_destroy_enhance_property(connector); | 1766 | intel_sdvo_destroy_enhance_property(connector); |
1862 | drm_sysfs_connector_remove(connector); | 1767 | drm_sysfs_connector_remove(connector); |
@@ -1870,132 +1775,118 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
1870 | uint64_t val) | 1775 | uint64_t val) |
1871 | { | 1776 | { |
1872 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1777 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1873 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1778 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1874 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1779 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1875 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
1876 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
1877 | struct drm_crtc *crtc = encoder->crtc; | ||
1878 | int ret = 0; | ||
1879 | bool changed = false; | ||
1880 | uint8_t cmd, status; | ||
1881 | uint16_t temp_value; | 1780 | uint16_t temp_value; |
1781 | uint8_t cmd; | ||
1782 | int ret; | ||
1882 | 1783 | ||
1883 | ret = drm_connector_property_set_value(connector, property, val); | 1784 | ret = drm_connector_property_set_value(connector, property, val); |
1884 | if (ret < 0) | 1785 | if (ret) |
1885 | goto out; | 1786 | return ret; |
1787 | |||
1788 | #define CHECK_PROPERTY(name, NAME) \ | ||
1789 | if (intel_sdvo_connector->name == property) { \ | ||
1790 | if (intel_sdvo_connector->cur_##name == temp_value) return 0; \ | ||
1791 | if (intel_sdvo_connector->max_##name < temp_value) return -EINVAL; \ | ||
1792 | cmd = SDVO_CMD_SET_##NAME; \ | ||
1793 | intel_sdvo_connector->cur_##name = temp_value; \ | ||
1794 | goto set_value; \ | ||
1795 | } | ||
1886 | 1796 | ||
1887 | if (property == sdvo_connector->tv_format_property) { | 1797 | if (property == intel_sdvo_connector->tv_format) { |
1888 | if (val >= TV_FORMAT_NUM) { | 1798 | if (val >= TV_FORMAT_NUM) |
1889 | ret = -EINVAL; | 1799 | return -EINVAL; |
1890 | goto out; | ||
1891 | } | ||
1892 | if (sdvo_priv->tv_format_name == | ||
1893 | sdvo_connector->tv_format_supported[val]) | ||
1894 | goto out; | ||
1895 | 1800 | ||
1896 | sdvo_priv->tv_format_name = sdvo_connector->tv_format_supported[val]; | 1801 | if (intel_sdvo->tv_format_index == |
1897 | changed = true; | 1802 | intel_sdvo_connector->tv_format_supported[val]) |
1898 | } | 1803 | return 0; |
1899 | 1804 | ||
1900 | if (IS_TV(sdvo_connector) || IS_LVDS(sdvo_connector)) { | 1805 | intel_sdvo->tv_format_index = intel_sdvo_connector->tv_format_supported[val]; |
1901 | cmd = 0; | 1806 | goto done; |
1807 | } else if (IS_TV_OR_LVDS(intel_sdvo_connector)) { | ||
1902 | temp_value = val; | 1808 | temp_value = val; |
1903 | if (sdvo_connector->left_property == property) { | 1809 | if (intel_sdvo_connector->left == property) { |
1904 | drm_connector_property_set_value(connector, | 1810 | drm_connector_property_set_value(connector, |
1905 | sdvo_connector->right_property, val); | 1811 | intel_sdvo_connector->right, val); |
1906 | if (sdvo_connector->left_margin == temp_value) | 1812 | if (intel_sdvo_connector->left_margin == temp_value) |
1907 | goto out; | 1813 | return 0; |
1908 | 1814 | ||
1909 | sdvo_connector->left_margin = temp_value; | 1815 | intel_sdvo_connector->left_margin = temp_value; |
1910 | sdvo_connector->right_margin = temp_value; | 1816 | intel_sdvo_connector->right_margin = temp_value; |
1911 | temp_value = sdvo_connector->max_hscan - | 1817 | temp_value = intel_sdvo_connector->max_hscan - |
1912 | sdvo_connector->left_margin; | 1818 | intel_sdvo_connector->left_margin; |
1913 | cmd = SDVO_CMD_SET_OVERSCAN_H; | 1819 | cmd = SDVO_CMD_SET_OVERSCAN_H; |
1914 | } else if (sdvo_connector->right_property == property) { | 1820 | goto set_value; |
1821 | } else if (intel_sdvo_connector->right == property) { | ||
1915 | drm_connector_property_set_value(connector, | 1822 | drm_connector_property_set_value(connector, |
1916 | sdvo_connector->left_property, val); | 1823 | intel_sdvo_connector->left, val); |
1917 | if (sdvo_connector->right_margin == temp_value) | 1824 | if (intel_sdvo_connector->right_margin == temp_value) |
1918 | goto out; | 1825 | return 0; |
1919 | 1826 | ||
1920 | sdvo_connector->left_margin = temp_value; | 1827 | intel_sdvo_connector->left_margin = temp_value; |
1921 | sdvo_connector->right_margin = temp_value; | 1828 | intel_sdvo_connector->right_margin = temp_value; |
1922 | temp_value = sdvo_connector->max_hscan - | 1829 | temp_value = intel_sdvo_connector->max_hscan - |
1923 | sdvo_connector->left_margin; | 1830 | intel_sdvo_connector->left_margin; |
1924 | cmd = SDVO_CMD_SET_OVERSCAN_H; | 1831 | cmd = SDVO_CMD_SET_OVERSCAN_H; |
1925 | } else if (sdvo_connector->top_property == property) { | 1832 | goto set_value; |
1833 | } else if (intel_sdvo_connector->top == property) { | ||
1926 | drm_connector_property_set_value(connector, | 1834 | drm_connector_property_set_value(connector, |
1927 | sdvo_connector->bottom_property, val); | 1835 | intel_sdvo_connector->bottom, val); |
1928 | if (sdvo_connector->top_margin == temp_value) | 1836 | if (intel_sdvo_connector->top_margin == temp_value) |
1929 | goto out; | 1837 | return 0; |
1930 | 1838 | ||
1931 | sdvo_connector->top_margin = temp_value; | 1839 | intel_sdvo_connector->top_margin = temp_value; |
1932 | sdvo_connector->bottom_margin = temp_value; | 1840 | intel_sdvo_connector->bottom_margin = temp_value; |
1933 | temp_value = sdvo_connector->max_vscan - | 1841 | temp_value = intel_sdvo_connector->max_vscan - |
1934 | sdvo_connector->top_margin; | 1842 | intel_sdvo_connector->top_margin; |
1935 | cmd = SDVO_CMD_SET_OVERSCAN_V; | 1843 | cmd = SDVO_CMD_SET_OVERSCAN_V; |
1936 | } else if (sdvo_connector->bottom_property == property) { | 1844 | goto set_value; |
1845 | } else if (intel_sdvo_connector->bottom == property) { | ||
1937 | drm_connector_property_set_value(connector, | 1846 | drm_connector_property_set_value(connector, |
1938 | sdvo_connector->top_property, val); | 1847 | intel_sdvo_connector->top, val); |
1939 | if (sdvo_connector->bottom_margin == temp_value) | 1848 | if (intel_sdvo_connector->bottom_margin == temp_value) |
1940 | goto out; | 1849 | return 0; |
1941 | sdvo_connector->top_margin = temp_value; | 1850 | |
1942 | sdvo_connector->bottom_margin = temp_value; | 1851 | intel_sdvo_connector->top_margin = temp_value; |
1943 | temp_value = sdvo_connector->max_vscan - | 1852 | intel_sdvo_connector->bottom_margin = temp_value; |
1944 | sdvo_connector->top_margin; | 1853 | temp_value = intel_sdvo_connector->max_vscan - |
1854 | intel_sdvo_connector->top_margin; | ||
1945 | cmd = SDVO_CMD_SET_OVERSCAN_V; | 1855 | cmd = SDVO_CMD_SET_OVERSCAN_V; |
1946 | } else if (sdvo_connector->hpos_property == property) { | 1856 | goto set_value; |
1947 | if (sdvo_connector->cur_hpos == temp_value) | ||
1948 | goto out; | ||
1949 | |||
1950 | cmd = SDVO_CMD_SET_POSITION_H; | ||
1951 | sdvo_connector->cur_hpos = temp_value; | ||
1952 | } else if (sdvo_connector->vpos_property == property) { | ||
1953 | if (sdvo_connector->cur_vpos == temp_value) | ||
1954 | goto out; | ||
1955 | |||
1956 | cmd = SDVO_CMD_SET_POSITION_V; | ||
1957 | sdvo_connector->cur_vpos = temp_value; | ||
1958 | } else if (sdvo_connector->saturation_property == property) { | ||
1959 | if (sdvo_connector->cur_saturation == temp_value) | ||
1960 | goto out; | ||
1961 | |||
1962 | cmd = SDVO_CMD_SET_SATURATION; | ||
1963 | sdvo_connector->cur_saturation = temp_value; | ||
1964 | } else if (sdvo_connector->contrast_property == property) { | ||
1965 | if (sdvo_connector->cur_contrast == temp_value) | ||
1966 | goto out; | ||
1967 | |||
1968 | cmd = SDVO_CMD_SET_CONTRAST; | ||
1969 | sdvo_connector->cur_contrast = temp_value; | ||
1970 | } else if (sdvo_connector->hue_property == property) { | ||
1971 | if (sdvo_connector->cur_hue == temp_value) | ||
1972 | goto out; | ||
1973 | |||
1974 | cmd = SDVO_CMD_SET_HUE; | ||
1975 | sdvo_connector->cur_hue = temp_value; | ||
1976 | } else if (sdvo_connector->brightness_property == property) { | ||
1977 | if (sdvo_connector->cur_brightness == temp_value) | ||
1978 | goto out; | ||
1979 | |||
1980 | cmd = SDVO_CMD_SET_BRIGHTNESS; | ||
1981 | sdvo_connector->cur_brightness = temp_value; | ||
1982 | } | ||
1983 | if (cmd) { | ||
1984 | intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2); | ||
1985 | status = intel_sdvo_read_response(intel_encoder, | ||
1986 | NULL, 0); | ||
1987 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
1988 | DRM_DEBUG_KMS("Incorrect SDVO command \n"); | ||
1989 | return -EINVAL; | ||
1990 | } | ||
1991 | changed = true; | ||
1992 | } | 1857 | } |
1858 | CHECK_PROPERTY(hpos, HPOS) | ||
1859 | CHECK_PROPERTY(vpos, VPOS) | ||
1860 | CHECK_PROPERTY(saturation, SATURATION) | ||
1861 | CHECK_PROPERTY(contrast, CONTRAST) | ||
1862 | CHECK_PROPERTY(hue, HUE) | ||
1863 | CHECK_PROPERTY(brightness, BRIGHTNESS) | ||
1864 | CHECK_PROPERTY(sharpness, SHARPNESS) | ||
1865 | CHECK_PROPERTY(flicker_filter, FLICKER_FILTER) | ||
1866 | CHECK_PROPERTY(flicker_filter_2d, FLICKER_FILTER_2D) | ||
1867 | CHECK_PROPERTY(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE) | ||
1868 | CHECK_PROPERTY(tv_chroma_filter, TV_CHROMA_FILTER) | ||
1869 | CHECK_PROPERTY(tv_luma_filter, TV_LUMA_FILTER) | ||
1870 | CHECK_PROPERTY(dot_crawl, DOT_CRAWL) | ||
1993 | } | 1871 | } |
1994 | if (changed && crtc) | 1872 | |
1873 | return -EINVAL; /* unknown property */ | ||
1874 | |||
1875 | set_value: | ||
1876 | if (!intel_sdvo_set_value(intel_sdvo, cmd, &temp_value, 2)) | ||
1877 | return -EIO; | ||
1878 | |||
1879 | |||
1880 | done: | ||
1881 | if (encoder->crtc) { | ||
1882 | struct drm_crtc *crtc = encoder->crtc; | ||
1883 | |||
1995 | drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, | 1884 | drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, |
1996 | crtc->y, crtc->fb); | 1885 | crtc->y, crtc->fb); |
1997 | out: | 1886 | } |
1998 | return ret; | 1887 | |
1888 | return 0; | ||
1889 | #undef CHECK_PROPERTY | ||
1999 | } | 1890 | } |
2000 | 1891 | ||
2001 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { | 1892 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { |
@@ -2022,28 +1913,57 @@ static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs | |||
2022 | 1913 | ||
2023 | static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) | 1914 | static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) |
2024 | { | 1915 | { |
2025 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1916 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
2026 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2027 | 1917 | ||
2028 | if (intel_encoder->i2c_bus) | 1918 | if (intel_sdvo->analog_ddc_bus) |
2029 | intel_i2c_destroy(intel_encoder->i2c_bus); | 1919 | intel_i2c_destroy(intel_sdvo->analog_ddc_bus); |
2030 | if (intel_encoder->ddc_bus) | ||
2031 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
2032 | if (sdvo_priv->analog_ddc_bus) | ||
2033 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); | ||
2034 | 1920 | ||
2035 | if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) | 1921 | if (intel_sdvo->sdvo_lvds_fixed_mode != NULL) |
2036 | drm_mode_destroy(encoder->dev, | 1922 | drm_mode_destroy(encoder->dev, |
2037 | sdvo_priv->sdvo_lvds_fixed_mode); | 1923 | intel_sdvo->sdvo_lvds_fixed_mode); |
2038 | 1924 | ||
2039 | drm_encoder_cleanup(encoder); | 1925 | intel_encoder_destroy(encoder); |
2040 | kfree(intel_encoder); | ||
2041 | } | 1926 | } |
2042 | 1927 | ||
2043 | static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { | 1928 | static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { |
2044 | .destroy = intel_sdvo_enc_destroy, | 1929 | .destroy = intel_sdvo_enc_destroy, |
2045 | }; | 1930 | }; |
2046 | 1931 | ||
1932 | static void | ||
1933 | intel_sdvo_guess_ddc_bus(struct intel_sdvo *sdvo) | ||
1934 | { | ||
1935 | uint16_t mask = 0; | ||
1936 | unsigned int num_bits; | ||
1937 | |||
1938 | /* Make a mask of outputs less than or equal to our own priority in the | ||
1939 | * list. | ||
1940 | */ | ||
1941 | switch (sdvo->controlled_output) { | ||
1942 | case SDVO_OUTPUT_LVDS1: | ||
1943 | mask |= SDVO_OUTPUT_LVDS1; | ||
1944 | case SDVO_OUTPUT_LVDS0: | ||
1945 | mask |= SDVO_OUTPUT_LVDS0; | ||
1946 | case SDVO_OUTPUT_TMDS1: | ||
1947 | mask |= SDVO_OUTPUT_TMDS1; | ||
1948 | case SDVO_OUTPUT_TMDS0: | ||
1949 | mask |= SDVO_OUTPUT_TMDS0; | ||
1950 | case SDVO_OUTPUT_RGB1: | ||
1951 | mask |= SDVO_OUTPUT_RGB1; | ||
1952 | case SDVO_OUTPUT_RGB0: | ||
1953 | mask |= SDVO_OUTPUT_RGB0; | ||
1954 | break; | ||
1955 | } | ||
1956 | |||
1957 | /* Count bits to find what number we are in the priority list. */ | ||
1958 | mask &= sdvo->caps.output_flags; | ||
1959 | num_bits = hweight16(mask); | ||
1960 | /* If more than 3 outputs, default to DDC bus 3 for now. */ | ||
1961 | if (num_bits > 3) | ||
1962 | num_bits = 3; | ||
1963 | |||
1964 | /* Corresponds to SDVO_CONTROL_BUS_DDCx */ | ||
1965 | sdvo->ddc_bus = 1 << num_bits; | ||
1966 | } | ||
2047 | 1967 | ||
2048 | /** | 1968 | /** |
2049 | * Choose the appropriate DDC bus for control bus switch command for this | 1969 | * Choose the appropriate DDC bus for control bus switch command for this |
@@ -2054,7 +1974,7 @@ static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { | |||
2054 | */ | 1974 | */ |
2055 | static void | 1975 | static void |
2056 | intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, | 1976 | intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, |
2057 | struct intel_sdvo_priv *sdvo, u32 reg) | 1977 | struct intel_sdvo *sdvo, u32 reg) |
2058 | { | 1978 | { |
2059 | struct sdvo_device_mapping *mapping; | 1979 | struct sdvo_device_mapping *mapping; |
2060 | 1980 | ||
@@ -2063,61 +1983,53 @@ intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, | |||
2063 | else | 1983 | else |
2064 | mapping = &(dev_priv->sdvo_mappings[1]); | 1984 | mapping = &(dev_priv->sdvo_mappings[1]); |
2065 | 1985 | ||
2066 | sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4); | 1986 | if (mapping->initialized) |
1987 | sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4); | ||
1988 | else | ||
1989 | intel_sdvo_guess_ddc_bus(sdvo); | ||
2067 | } | 1990 | } |
2068 | 1991 | ||
2069 | static bool | 1992 | static bool |
2070 | intel_sdvo_get_digital_encoding_mode(struct intel_encoder *output, int device) | 1993 | intel_sdvo_get_digital_encoding_mode(struct intel_sdvo *intel_sdvo, int device) |
2071 | { | 1994 | { |
2072 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 1995 | return intel_sdvo_set_target_output(intel_sdvo, |
2073 | uint8_t status; | 1996 | device == 0 ? SDVO_OUTPUT_TMDS0 : SDVO_OUTPUT_TMDS1) && |
2074 | 1997 | intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ENCODE, | |
2075 | if (device == 0) | 1998 | &intel_sdvo->is_hdmi, 1); |
2076 | intel_sdvo_set_target_output(output, SDVO_OUTPUT_TMDS0); | ||
2077 | else | ||
2078 | intel_sdvo_set_target_output(output, SDVO_OUTPUT_TMDS1); | ||
2079 | |||
2080 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_ENCODE, NULL, 0); | ||
2081 | status = intel_sdvo_read_response(output, &sdvo_priv->is_hdmi, 1); | ||
2082 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
2083 | return false; | ||
2084 | return true; | ||
2085 | } | 1999 | } |
2086 | 2000 | ||
2087 | static struct intel_encoder * | 2001 | static struct intel_sdvo * |
2088 | intel_sdvo_chan_to_intel_encoder(struct intel_i2c_chan *chan) | 2002 | intel_sdvo_chan_to_intel_sdvo(struct intel_i2c_chan *chan) |
2089 | { | 2003 | { |
2090 | struct drm_device *dev = chan->drm_dev; | 2004 | struct drm_device *dev = chan->drm_dev; |
2091 | struct drm_encoder *encoder; | 2005 | struct drm_encoder *encoder; |
2092 | struct intel_encoder *intel_encoder = NULL; | ||
2093 | 2006 | ||
2094 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 2007 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
2095 | intel_encoder = enc_to_intel_encoder(encoder); | 2008 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
2096 | if (intel_encoder->ddc_bus == &chan->adapter) | 2009 | if (intel_sdvo->base.ddc_bus == &chan->adapter) |
2097 | break; | 2010 | return intel_sdvo; |
2098 | } | 2011 | } |
2099 | return intel_encoder; | 2012 | |
2013 | return NULL; | ||
2100 | } | 2014 | } |
2101 | 2015 | ||
2102 | static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, | 2016 | static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, |
2103 | struct i2c_msg msgs[], int num) | 2017 | struct i2c_msg msgs[], int num) |
2104 | { | 2018 | { |
2105 | struct intel_encoder *intel_encoder; | 2019 | struct intel_sdvo *intel_sdvo; |
2106 | struct intel_sdvo_priv *sdvo_priv; | ||
2107 | struct i2c_algo_bit_data *algo_data; | 2020 | struct i2c_algo_bit_data *algo_data; |
2108 | const struct i2c_algorithm *algo; | 2021 | const struct i2c_algorithm *algo; |
2109 | 2022 | ||
2110 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; | 2023 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; |
2111 | intel_encoder = | 2024 | intel_sdvo = |
2112 | intel_sdvo_chan_to_intel_encoder( | 2025 | intel_sdvo_chan_to_intel_sdvo((struct intel_i2c_chan *) |
2113 | (struct intel_i2c_chan *)(algo_data->data)); | 2026 | (algo_data->data)); |
2114 | if (intel_encoder == NULL) | 2027 | if (intel_sdvo == NULL) |
2115 | return -EINVAL; | 2028 | return -EINVAL; |
2116 | 2029 | ||
2117 | sdvo_priv = intel_encoder->dev_priv; | 2030 | algo = intel_sdvo->base.i2c_bus->algo; |
2118 | algo = intel_encoder->i2c_bus->algo; | ||
2119 | 2031 | ||
2120 | intel_sdvo_set_control_bus_switch(intel_encoder, sdvo_priv->ddc_bus); | 2032 | intel_sdvo_set_control_bus_switch(intel_sdvo, intel_sdvo->ddc_bus); |
2121 | return algo->master_xfer(i2c_adap, msgs, num); | 2033 | return algo->master_xfer(i2c_adap, msgs, num); |
2122 | } | 2034 | } |
2123 | 2035 | ||
@@ -2162,27 +2074,9 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) | |||
2162 | return 0x72; | 2074 | return 0x72; |
2163 | } | 2075 | } |
2164 | 2076 | ||
2165 | static bool | ||
2166 | intel_sdvo_connector_alloc (struct intel_connector **ret) | ||
2167 | { | ||
2168 | struct intel_connector *intel_connector; | ||
2169 | struct intel_sdvo_connector *sdvo_connector; | ||
2170 | |||
2171 | *ret = kzalloc(sizeof(*intel_connector) + | ||
2172 | sizeof(*sdvo_connector), GFP_KERNEL); | ||
2173 | if (!*ret) | ||
2174 | return false; | ||
2175 | |||
2176 | intel_connector = *ret; | ||
2177 | sdvo_connector = (struct intel_sdvo_connector *)(intel_connector + 1); | ||
2178 | intel_connector->dev_priv = sdvo_connector; | ||
2179 | |||
2180 | return true; | ||
2181 | } | ||
2182 | |||
2183 | static void | 2077 | static void |
2184 | intel_sdvo_connector_create (struct drm_encoder *encoder, | 2078 | intel_sdvo_connector_init(struct drm_encoder *encoder, |
2185 | struct drm_connector *connector) | 2079 | struct drm_connector *connector) |
2186 | { | 2080 | { |
2187 | drm_connector_init(encoder->dev, connector, &intel_sdvo_connector_funcs, | 2081 | drm_connector_init(encoder->dev, connector, &intel_sdvo_connector_funcs, |
2188 | connector->connector_type); | 2082 | connector->connector_type); |
@@ -2198,582 +2092,470 @@ intel_sdvo_connector_create (struct drm_encoder *encoder, | |||
2198 | } | 2092 | } |
2199 | 2093 | ||
2200 | static bool | 2094 | static bool |
2201 | intel_sdvo_dvi_init(struct intel_encoder *intel_encoder, int device) | 2095 | intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) |
2202 | { | 2096 | { |
2203 | struct drm_encoder *encoder = &intel_encoder->enc; | 2097 | struct drm_encoder *encoder = &intel_sdvo->base.enc; |
2204 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2205 | struct drm_connector *connector; | 2098 | struct drm_connector *connector; |
2206 | struct intel_connector *intel_connector; | 2099 | struct intel_connector *intel_connector; |
2207 | struct intel_sdvo_connector *sdvo_connector; | 2100 | struct intel_sdvo_connector *intel_sdvo_connector; |
2208 | 2101 | ||
2209 | if (!intel_sdvo_connector_alloc(&intel_connector)) | 2102 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); |
2103 | if (!intel_sdvo_connector) | ||
2210 | return false; | 2104 | return false; |
2211 | 2105 | ||
2212 | sdvo_connector = intel_connector->dev_priv; | ||
2213 | |||
2214 | if (device == 0) { | 2106 | if (device == 0) { |
2215 | sdvo_priv->controlled_output |= SDVO_OUTPUT_TMDS0; | 2107 | intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS0; |
2216 | sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0; | 2108 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0; |
2217 | } else if (device == 1) { | 2109 | } else if (device == 1) { |
2218 | sdvo_priv->controlled_output |= SDVO_OUTPUT_TMDS1; | 2110 | intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS1; |
2219 | sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1; | 2111 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1; |
2220 | } | 2112 | } |
2221 | 2113 | ||
2114 | intel_connector = &intel_sdvo_connector->base; | ||
2222 | connector = &intel_connector->base; | 2115 | connector = &intel_connector->base; |
2223 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; | 2116 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; |
2224 | encoder->encoder_type = DRM_MODE_ENCODER_TMDS; | 2117 | encoder->encoder_type = DRM_MODE_ENCODER_TMDS; |
2225 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; | 2118 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; |
2226 | 2119 | ||
2227 | if (intel_sdvo_get_supp_encode(intel_encoder, &sdvo_priv->encode) | 2120 | if (intel_sdvo_get_supp_encode(intel_sdvo, &intel_sdvo->encode) |
2228 | && intel_sdvo_get_digital_encoding_mode(intel_encoder, device) | 2121 | && intel_sdvo_get_digital_encoding_mode(intel_sdvo, device) |
2229 | && sdvo_priv->is_hdmi) { | 2122 | && intel_sdvo->is_hdmi) { |
2230 | /* enable hdmi encoding mode if supported */ | 2123 | /* enable hdmi encoding mode if supported */ |
2231 | intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI); | 2124 | intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI); |
2232 | intel_sdvo_set_colorimetry(intel_encoder, | 2125 | intel_sdvo_set_colorimetry(intel_sdvo, |
2233 | SDVO_COLORIMETRY_RGB256); | 2126 | SDVO_COLORIMETRY_RGB256); |
2234 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | 2127 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; |
2235 | } | 2128 | } |
2236 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2129 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
2237 | (1 << INTEL_ANALOG_CLONE_BIT); | 2130 | (1 << INTEL_ANALOG_CLONE_BIT)); |
2238 | 2131 | ||
2239 | intel_sdvo_connector_create(encoder, connector); | 2132 | intel_sdvo_connector_init(encoder, connector); |
2240 | 2133 | ||
2241 | return true; | 2134 | return true; |
2242 | } | 2135 | } |
2243 | 2136 | ||
2244 | static bool | 2137 | static bool |
2245 | intel_sdvo_tv_init(struct intel_encoder *intel_encoder, int type) | 2138 | intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) |
2246 | { | 2139 | { |
2247 | struct drm_encoder *encoder = &intel_encoder->enc; | 2140 | struct drm_encoder *encoder = &intel_sdvo->base.enc; |
2248 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2249 | struct drm_connector *connector; | 2141 | struct drm_connector *connector; |
2250 | struct intel_connector *intel_connector; | 2142 | struct intel_connector *intel_connector; |
2251 | struct intel_sdvo_connector *sdvo_connector; | 2143 | struct intel_sdvo_connector *intel_sdvo_connector; |
2252 | 2144 | ||
2253 | if (!intel_sdvo_connector_alloc(&intel_connector)) | 2145 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); |
2254 | return false; | 2146 | if (!intel_sdvo_connector) |
2147 | return false; | ||
2255 | 2148 | ||
2149 | intel_connector = &intel_sdvo_connector->base; | ||
2256 | connector = &intel_connector->base; | 2150 | connector = &intel_connector->base; |
2257 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; | 2151 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; |
2258 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | 2152 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; |
2259 | sdvo_connector = intel_connector->dev_priv; | ||
2260 | 2153 | ||
2261 | sdvo_priv->controlled_output |= type; | 2154 | intel_sdvo->controlled_output |= type; |
2262 | sdvo_connector->output_flag = type; | 2155 | intel_sdvo_connector->output_flag = type; |
2263 | 2156 | ||
2264 | sdvo_priv->is_tv = true; | 2157 | intel_sdvo->is_tv = true; |
2265 | intel_encoder->needs_tv_clock = true; | 2158 | intel_sdvo->base.needs_tv_clock = true; |
2266 | intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | 2159 | intel_sdvo->base.clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; |
2267 | 2160 | ||
2268 | intel_sdvo_connector_create(encoder, connector); | 2161 | intel_sdvo_connector_init(encoder, connector); |
2269 | 2162 | ||
2270 | intel_sdvo_tv_create_property(connector, type); | 2163 | if (!intel_sdvo_tv_create_property(intel_sdvo, intel_sdvo_connector, type)) |
2164 | goto err; | ||
2271 | 2165 | ||
2272 | intel_sdvo_create_enhance_property(connector); | 2166 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) |
2167 | goto err; | ||
2273 | 2168 | ||
2274 | return true; | 2169 | return true; |
2170 | |||
2171 | err: | ||
2172 | intel_sdvo_destroy_enhance_property(connector); | ||
2173 | kfree(intel_sdvo_connector); | ||
2174 | return false; | ||
2275 | } | 2175 | } |
2276 | 2176 | ||
2277 | static bool | 2177 | static bool |
2278 | intel_sdvo_analog_init(struct intel_encoder *intel_encoder, int device) | 2178 | intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device) |
2279 | { | 2179 | { |
2280 | struct drm_encoder *encoder = &intel_encoder->enc; | 2180 | struct drm_encoder *encoder = &intel_sdvo->base.enc; |
2281 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2282 | struct drm_connector *connector; | 2181 | struct drm_connector *connector; |
2283 | struct intel_connector *intel_connector; | 2182 | struct intel_connector *intel_connector; |
2284 | struct intel_sdvo_connector *sdvo_connector; | 2183 | struct intel_sdvo_connector *intel_sdvo_connector; |
2285 | 2184 | ||
2286 | if (!intel_sdvo_connector_alloc(&intel_connector)) | 2185 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); |
2287 | return false; | 2186 | if (!intel_sdvo_connector) |
2187 | return false; | ||
2288 | 2188 | ||
2189 | intel_connector = &intel_sdvo_connector->base; | ||
2289 | connector = &intel_connector->base; | 2190 | connector = &intel_connector->base; |
2290 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | 2191 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
2291 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | 2192 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; |
2292 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | 2193 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; |
2293 | sdvo_connector = intel_connector->dev_priv; | ||
2294 | 2194 | ||
2295 | if (device == 0) { | 2195 | if (device == 0) { |
2296 | sdvo_priv->controlled_output |= SDVO_OUTPUT_RGB0; | 2196 | intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0; |
2297 | sdvo_connector->output_flag = SDVO_OUTPUT_RGB0; | 2197 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0; |
2298 | } else if (device == 1) { | 2198 | } else if (device == 1) { |
2299 | sdvo_priv->controlled_output |= SDVO_OUTPUT_RGB1; | 2199 | intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1; |
2300 | sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; | 2200 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; |
2301 | } | 2201 | } |
2302 | 2202 | ||
2303 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2203 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
2304 | (1 << INTEL_ANALOG_CLONE_BIT); | 2204 | (1 << INTEL_ANALOG_CLONE_BIT)); |
2305 | 2205 | ||
2306 | intel_sdvo_connector_create(encoder, connector); | 2206 | intel_sdvo_connector_init(encoder, connector); |
2307 | return true; | 2207 | return true; |
2308 | } | 2208 | } |
2309 | 2209 | ||
2310 | static bool | 2210 | static bool |
2311 | intel_sdvo_lvds_init(struct intel_encoder *intel_encoder, int device) | 2211 | intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) |
2312 | { | 2212 | { |
2313 | struct drm_encoder *encoder = &intel_encoder->enc; | 2213 | struct drm_encoder *encoder = &intel_sdvo->base.enc; |
2314 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2315 | struct drm_connector *connector; | 2214 | struct drm_connector *connector; |
2316 | struct intel_connector *intel_connector; | 2215 | struct intel_connector *intel_connector; |
2317 | struct intel_sdvo_connector *sdvo_connector; | 2216 | struct intel_sdvo_connector *intel_sdvo_connector; |
2318 | 2217 | ||
2319 | if (!intel_sdvo_connector_alloc(&intel_connector)) | 2218 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); |
2320 | return false; | 2219 | if (!intel_sdvo_connector) |
2220 | return false; | ||
2321 | 2221 | ||
2322 | connector = &intel_connector->base; | 2222 | intel_connector = &intel_sdvo_connector->base; |
2223 | connector = &intel_connector->base; | ||
2323 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | 2224 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; |
2324 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | 2225 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; |
2325 | sdvo_connector = intel_connector->dev_priv; | ||
2326 | |||
2327 | sdvo_priv->is_lvds = true; | ||
2328 | 2226 | ||
2329 | if (device == 0) { | 2227 | if (device == 0) { |
2330 | sdvo_priv->controlled_output |= SDVO_OUTPUT_LVDS0; | 2228 | intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0; |
2331 | sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0; | 2229 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0; |
2332 | } else if (device == 1) { | 2230 | } else if (device == 1) { |
2333 | sdvo_priv->controlled_output |= SDVO_OUTPUT_LVDS1; | 2231 | intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1; |
2334 | sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; | 2232 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; |
2335 | } | 2233 | } |
2336 | 2234 | ||
2337 | intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | 2235 | intel_sdvo->base.clone_mask = ((1 << INTEL_ANALOG_CLONE_BIT) | |
2338 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | 2236 | (1 << INTEL_SDVO_LVDS_CLONE_BIT)); |
2339 | 2237 | ||
2340 | intel_sdvo_connector_create(encoder, connector); | 2238 | intel_sdvo_connector_init(encoder, connector); |
2341 | intel_sdvo_create_enhance_property(connector); | 2239 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) |
2342 | return true; | 2240 | goto err; |
2241 | |||
2242 | return true; | ||
2243 | |||
2244 | err: | ||
2245 | intel_sdvo_destroy_enhance_property(connector); | ||
2246 | kfree(intel_sdvo_connector); | ||
2247 | return false; | ||
2343 | } | 2248 | } |
2344 | 2249 | ||
2345 | static bool | 2250 | static bool |
2346 | intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags) | 2251 | intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) |
2347 | { | 2252 | { |
2348 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 2253 | intel_sdvo->is_tv = false; |
2349 | 2254 | intel_sdvo->base.needs_tv_clock = false; | |
2350 | sdvo_priv->is_tv = false; | 2255 | intel_sdvo->is_lvds = false; |
2351 | intel_encoder->needs_tv_clock = false; | ||
2352 | sdvo_priv->is_lvds = false; | ||
2353 | 2256 | ||
2354 | /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ | 2257 | /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ |
2355 | 2258 | ||
2356 | if (flags & SDVO_OUTPUT_TMDS0) | 2259 | if (flags & SDVO_OUTPUT_TMDS0) |
2357 | if (!intel_sdvo_dvi_init(intel_encoder, 0)) | 2260 | if (!intel_sdvo_dvi_init(intel_sdvo, 0)) |
2358 | return false; | 2261 | return false; |
2359 | 2262 | ||
2360 | if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK) | 2263 | if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK) |
2361 | if (!intel_sdvo_dvi_init(intel_encoder, 1)) | 2264 | if (!intel_sdvo_dvi_init(intel_sdvo, 1)) |
2362 | return false; | 2265 | return false; |
2363 | 2266 | ||
2364 | /* TV has no XXX1 function block */ | 2267 | /* TV has no XXX1 function block */ |
2365 | if (flags & SDVO_OUTPUT_SVID0) | 2268 | if (flags & SDVO_OUTPUT_SVID0) |
2366 | if (!intel_sdvo_tv_init(intel_encoder, SDVO_OUTPUT_SVID0)) | 2269 | if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_SVID0)) |
2367 | return false; | 2270 | return false; |
2368 | 2271 | ||
2369 | if (flags & SDVO_OUTPUT_CVBS0) | 2272 | if (flags & SDVO_OUTPUT_CVBS0) |
2370 | if (!intel_sdvo_tv_init(intel_encoder, SDVO_OUTPUT_CVBS0)) | 2273 | if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_CVBS0)) |
2371 | return false; | 2274 | return false; |
2372 | 2275 | ||
2373 | if (flags & SDVO_OUTPUT_RGB0) | 2276 | if (flags & SDVO_OUTPUT_RGB0) |
2374 | if (!intel_sdvo_analog_init(intel_encoder, 0)) | 2277 | if (!intel_sdvo_analog_init(intel_sdvo, 0)) |
2375 | return false; | 2278 | return false; |
2376 | 2279 | ||
2377 | if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK) | 2280 | if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK) |
2378 | if (!intel_sdvo_analog_init(intel_encoder, 1)) | 2281 | if (!intel_sdvo_analog_init(intel_sdvo, 1)) |
2379 | return false; | 2282 | return false; |
2380 | 2283 | ||
2381 | if (flags & SDVO_OUTPUT_LVDS0) | 2284 | if (flags & SDVO_OUTPUT_LVDS0) |
2382 | if (!intel_sdvo_lvds_init(intel_encoder, 0)) | 2285 | if (!intel_sdvo_lvds_init(intel_sdvo, 0)) |
2383 | return false; | 2286 | return false; |
2384 | 2287 | ||
2385 | if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK) | 2288 | if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK) |
2386 | if (!intel_sdvo_lvds_init(intel_encoder, 1)) | 2289 | if (!intel_sdvo_lvds_init(intel_sdvo, 1)) |
2387 | return false; | 2290 | return false; |
2388 | 2291 | ||
2389 | if ((flags & SDVO_OUTPUT_MASK) == 0) { | 2292 | if ((flags & SDVO_OUTPUT_MASK) == 0) { |
2390 | unsigned char bytes[2]; | 2293 | unsigned char bytes[2]; |
2391 | 2294 | ||
2392 | sdvo_priv->controlled_output = 0; | 2295 | intel_sdvo->controlled_output = 0; |
2393 | memcpy(bytes, &sdvo_priv->caps.output_flags, 2); | 2296 | memcpy(bytes, &intel_sdvo->caps.output_flags, 2); |
2394 | DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n", | 2297 | DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n", |
2395 | SDVO_NAME(sdvo_priv), | 2298 | SDVO_NAME(intel_sdvo), |
2396 | bytes[0], bytes[1]); | 2299 | bytes[0], bytes[1]); |
2397 | return false; | 2300 | return false; |
2398 | } | 2301 | } |
2399 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 2302 | intel_sdvo->base.crtc_mask = (1 << 0) | (1 << 1); |
2400 | 2303 | ||
2401 | return true; | 2304 | return true; |
2402 | } | 2305 | } |
2403 | 2306 | ||
2404 | static void intel_sdvo_tv_create_property(struct drm_connector *connector, int type) | 2307 | static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, |
2308 | struct intel_sdvo_connector *intel_sdvo_connector, | ||
2309 | int type) | ||
2405 | { | 2310 | { |
2406 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 2311 | struct drm_device *dev = intel_sdvo->base.enc.dev; |
2407 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
2408 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2409 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
2410 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
2411 | struct intel_sdvo_tv_format format; | 2312 | struct intel_sdvo_tv_format format; |
2412 | uint32_t format_map, i; | 2313 | uint32_t format_map, i; |
2413 | uint8_t status; | ||
2414 | 2314 | ||
2415 | intel_sdvo_set_target_output(intel_encoder, type); | 2315 | if (!intel_sdvo_set_target_output(intel_sdvo, type)) |
2316 | return false; | ||
2416 | 2317 | ||
2417 | intel_sdvo_write_cmd(intel_encoder, | 2318 | if (!intel_sdvo_get_value(intel_sdvo, |
2418 | SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0); | 2319 | SDVO_CMD_GET_SUPPORTED_TV_FORMATS, |
2419 | status = intel_sdvo_read_response(intel_encoder, | 2320 | &format, sizeof(format))) |
2420 | &format, sizeof(format)); | 2321 | return false; |
2421 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
2422 | return; | ||
2423 | 2322 | ||
2424 | memcpy(&format_map, &format, sizeof(format) > sizeof(format_map) ? | 2323 | memcpy(&format_map, &format, min(sizeof(format_map), sizeof(format))); |
2425 | sizeof(format_map) : sizeof(format)); | ||
2426 | 2324 | ||
2427 | if (format_map == 0) | 2325 | if (format_map == 0) |
2428 | return; | 2326 | return false; |
2429 | 2327 | ||
2430 | sdvo_connector->format_supported_num = 0; | 2328 | intel_sdvo_connector->format_supported_num = 0; |
2431 | for (i = 0 ; i < TV_FORMAT_NUM; i++) | 2329 | for (i = 0 ; i < TV_FORMAT_NUM; i++) |
2432 | if (format_map & (1 << i)) { | 2330 | if (format_map & (1 << i)) |
2433 | sdvo_connector->tv_format_supported | 2331 | intel_sdvo_connector->tv_format_supported[intel_sdvo_connector->format_supported_num++] = i; |
2434 | [sdvo_connector->format_supported_num++] = | ||
2435 | tv_format_names[i]; | ||
2436 | } | ||
2437 | 2332 | ||
2438 | 2333 | ||
2439 | sdvo_connector->tv_format_property = | 2334 | intel_sdvo_connector->tv_format = |
2440 | drm_property_create( | 2335 | drm_property_create(dev, DRM_MODE_PROP_ENUM, |
2441 | connector->dev, DRM_MODE_PROP_ENUM, | 2336 | "mode", intel_sdvo_connector->format_supported_num); |
2442 | "mode", sdvo_connector->format_supported_num); | 2337 | if (!intel_sdvo_connector->tv_format) |
2338 | return false; | ||
2443 | 2339 | ||
2444 | for (i = 0; i < sdvo_connector->format_supported_num; i++) | 2340 | for (i = 0; i < intel_sdvo_connector->format_supported_num; i++) |
2445 | drm_property_add_enum( | 2341 | drm_property_add_enum( |
2446 | sdvo_connector->tv_format_property, i, | 2342 | intel_sdvo_connector->tv_format, i, |
2447 | i, sdvo_connector->tv_format_supported[i]); | 2343 | i, tv_format_names[intel_sdvo_connector->tv_format_supported[i]]); |
2448 | 2344 | ||
2449 | sdvo_priv->tv_format_name = sdvo_connector->tv_format_supported[0]; | 2345 | intel_sdvo->tv_format_index = intel_sdvo_connector->tv_format_supported[0]; |
2450 | drm_connector_attach_property( | 2346 | drm_connector_attach_property(&intel_sdvo_connector->base.base, |
2451 | connector, sdvo_connector->tv_format_property, 0); | 2347 | intel_sdvo_connector->tv_format, 0); |
2348 | return true; | ||
2452 | 2349 | ||
2453 | } | 2350 | } |
2454 | 2351 | ||
2455 | static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | 2352 | #define ENHANCEMENT(name, NAME) do { \ |
2353 | if (enhancements.name) { \ | ||
2354 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_MAX_##NAME, &data_value, 4) || \ | ||
2355 | !intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_##NAME, &response, 2)) \ | ||
2356 | return false; \ | ||
2357 | intel_sdvo_connector->max_##name = data_value[0]; \ | ||
2358 | intel_sdvo_connector->cur_##name = response; \ | ||
2359 | intel_sdvo_connector->name = \ | ||
2360 | drm_property_create(dev, DRM_MODE_PROP_RANGE, #name, 2); \ | ||
2361 | if (!intel_sdvo_connector->name) return false; \ | ||
2362 | intel_sdvo_connector->name->values[0] = 0; \ | ||
2363 | intel_sdvo_connector->name->values[1] = data_value[0]; \ | ||
2364 | drm_connector_attach_property(connector, \ | ||
2365 | intel_sdvo_connector->name, \ | ||
2366 | intel_sdvo_connector->cur_##name); \ | ||
2367 | DRM_DEBUG_KMS(#name ": max %d, default %d, current %d\n", \ | ||
2368 | data_value[0], data_value[1], response); \ | ||
2369 | } \ | ||
2370 | } while(0) | ||
2371 | |||
2372 | static bool | ||
2373 | intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, | ||
2374 | struct intel_sdvo_connector *intel_sdvo_connector, | ||
2375 | struct intel_sdvo_enhancements_reply enhancements) | ||
2456 | { | 2376 | { |
2457 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 2377 | struct drm_device *dev = intel_sdvo->base.enc.dev; |
2458 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 2378 | struct drm_connector *connector = &intel_sdvo_connector->base.base; |
2459 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
2460 | struct intel_sdvo_connector *sdvo_priv = intel_connector->dev_priv; | ||
2461 | struct intel_sdvo_enhancements_reply sdvo_data; | ||
2462 | struct drm_device *dev = connector->dev; | ||
2463 | uint8_t status; | ||
2464 | uint16_t response, data_value[2]; | 2379 | uint16_t response, data_value[2]; |
2465 | 2380 | ||
2466 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, | 2381 | /* when horizontal overscan is supported, Add the left/right property */ |
2467 | NULL, 0); | 2382 | if (enhancements.overscan_h) { |
2468 | status = intel_sdvo_read_response(intel_encoder, &sdvo_data, | 2383 | if (!intel_sdvo_get_value(intel_sdvo, |
2469 | sizeof(sdvo_data)); | 2384 | SDVO_CMD_GET_MAX_OVERSCAN_H, |
2470 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2385 | &data_value, 4)) |
2471 | DRM_DEBUG_KMS(" incorrect response is returned\n"); | 2386 | return false; |
2472 | return; | 2387 | |
2388 | if (!intel_sdvo_get_value(intel_sdvo, | ||
2389 | SDVO_CMD_GET_OVERSCAN_H, | ||
2390 | &response, 2)) | ||
2391 | return false; | ||
2392 | |||
2393 | intel_sdvo_connector->max_hscan = data_value[0]; | ||
2394 | intel_sdvo_connector->left_margin = data_value[0] - response; | ||
2395 | intel_sdvo_connector->right_margin = intel_sdvo_connector->left_margin; | ||
2396 | intel_sdvo_connector->left = | ||
2397 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2398 | "left_margin", 2); | ||
2399 | if (!intel_sdvo_connector->left) | ||
2400 | return false; | ||
2401 | |||
2402 | intel_sdvo_connector->left->values[0] = 0; | ||
2403 | intel_sdvo_connector->left->values[1] = data_value[0]; | ||
2404 | drm_connector_attach_property(connector, | ||
2405 | intel_sdvo_connector->left, | ||
2406 | intel_sdvo_connector->left_margin); | ||
2407 | |||
2408 | intel_sdvo_connector->right = | ||
2409 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2410 | "right_margin", 2); | ||
2411 | if (!intel_sdvo_connector->right) | ||
2412 | return false; | ||
2413 | |||
2414 | intel_sdvo_connector->right->values[0] = 0; | ||
2415 | intel_sdvo_connector->right->values[1] = data_value[0]; | ||
2416 | drm_connector_attach_property(connector, | ||
2417 | intel_sdvo_connector->right, | ||
2418 | intel_sdvo_connector->right_margin); | ||
2419 | DRM_DEBUG_KMS("h_overscan: max %d, " | ||
2420 | "default %d, current %d\n", | ||
2421 | data_value[0], data_value[1], response); | ||
2473 | } | 2422 | } |
2474 | response = *((uint16_t *)&sdvo_data); | 2423 | |
2475 | if (!response) { | 2424 | if (enhancements.overscan_v) { |
2476 | DRM_DEBUG_KMS("No enhancement is supported\n"); | 2425 | if (!intel_sdvo_get_value(intel_sdvo, |
2477 | return; | 2426 | SDVO_CMD_GET_MAX_OVERSCAN_V, |
2427 | &data_value, 4)) | ||
2428 | return false; | ||
2429 | |||
2430 | if (!intel_sdvo_get_value(intel_sdvo, | ||
2431 | SDVO_CMD_GET_OVERSCAN_V, | ||
2432 | &response, 2)) | ||
2433 | return false; | ||
2434 | |||
2435 | intel_sdvo_connector->max_vscan = data_value[0]; | ||
2436 | intel_sdvo_connector->top_margin = data_value[0] - response; | ||
2437 | intel_sdvo_connector->bottom_margin = intel_sdvo_connector->top_margin; | ||
2438 | intel_sdvo_connector->top = | ||
2439 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2440 | "top_margin", 2); | ||
2441 | if (!intel_sdvo_connector->top) | ||
2442 | return false; | ||
2443 | |||
2444 | intel_sdvo_connector->top->values[0] = 0; | ||
2445 | intel_sdvo_connector->top->values[1] = data_value[0]; | ||
2446 | drm_connector_attach_property(connector, | ||
2447 | intel_sdvo_connector->top, | ||
2448 | intel_sdvo_connector->top_margin); | ||
2449 | |||
2450 | intel_sdvo_connector->bottom = | ||
2451 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2452 | "bottom_margin", 2); | ||
2453 | if (!intel_sdvo_connector->bottom) | ||
2454 | return false; | ||
2455 | |||
2456 | intel_sdvo_connector->bottom->values[0] = 0; | ||
2457 | intel_sdvo_connector->bottom->values[1] = data_value[0]; | ||
2458 | drm_connector_attach_property(connector, | ||
2459 | intel_sdvo_connector->bottom, | ||
2460 | intel_sdvo_connector->bottom_margin); | ||
2461 | DRM_DEBUG_KMS("v_overscan: max %d, " | ||
2462 | "default %d, current %d\n", | ||
2463 | data_value[0], data_value[1], response); | ||
2478 | } | 2464 | } |
2479 | if (IS_TV(sdvo_priv)) { | 2465 | |
2480 | /* when horizontal overscan is supported, Add the left/right | 2466 | ENHANCEMENT(hpos, HPOS); |
2481 | * property | 2467 | ENHANCEMENT(vpos, VPOS); |
2482 | */ | 2468 | ENHANCEMENT(saturation, SATURATION); |
2483 | if (sdvo_data.overscan_h) { | 2469 | ENHANCEMENT(contrast, CONTRAST); |
2484 | intel_sdvo_write_cmd(intel_encoder, | 2470 | ENHANCEMENT(hue, HUE); |
2485 | SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0); | 2471 | ENHANCEMENT(sharpness, SHARPNESS); |
2486 | status = intel_sdvo_read_response(intel_encoder, | 2472 | ENHANCEMENT(brightness, BRIGHTNESS); |
2487 | &data_value, 4); | 2473 | ENHANCEMENT(flicker_filter, FLICKER_FILTER); |
2488 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2474 | ENHANCEMENT(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE); |
2489 | DRM_DEBUG_KMS("Incorrect SDVO max " | 2475 | ENHANCEMENT(flicker_filter_2d, FLICKER_FILTER_2D); |
2490 | "h_overscan\n"); | 2476 | ENHANCEMENT(tv_chroma_filter, TV_CHROMA_FILTER); |
2491 | return; | 2477 | ENHANCEMENT(tv_luma_filter, TV_LUMA_FILTER); |
2492 | } | 2478 | |
2493 | intel_sdvo_write_cmd(intel_encoder, | 2479 | if (enhancements.dot_crawl) { |
2494 | SDVO_CMD_GET_OVERSCAN_H, NULL, 0); | 2480 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_DOT_CRAWL, &response, 2)) |
2495 | status = intel_sdvo_read_response(intel_encoder, | 2481 | return false; |
2496 | &response, 2); | 2482 | |
2497 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2483 | intel_sdvo_connector->max_dot_crawl = 1; |
2498 | DRM_DEBUG_KMS("Incorrect SDVO h_overscan\n"); | 2484 | intel_sdvo_connector->cur_dot_crawl = response & 0x1; |
2499 | return; | 2485 | intel_sdvo_connector->dot_crawl = |
2500 | } | 2486 | drm_property_create(dev, DRM_MODE_PROP_RANGE, "dot_crawl", 2); |
2501 | sdvo_priv->max_hscan = data_value[0]; | 2487 | if (!intel_sdvo_connector->dot_crawl) |
2502 | sdvo_priv->left_margin = data_value[0] - response; | 2488 | return false; |
2503 | sdvo_priv->right_margin = sdvo_priv->left_margin; | 2489 | |
2504 | sdvo_priv->left_property = | 2490 | intel_sdvo_connector->dot_crawl->values[0] = 0; |
2505 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 2491 | intel_sdvo_connector->dot_crawl->values[1] = 1; |
2506 | "left_margin", 2); | 2492 | drm_connector_attach_property(connector, |
2507 | sdvo_priv->left_property->values[0] = 0; | 2493 | intel_sdvo_connector->dot_crawl, |
2508 | sdvo_priv->left_property->values[1] = data_value[0]; | 2494 | intel_sdvo_connector->cur_dot_crawl); |
2509 | drm_connector_attach_property(connector, | 2495 | DRM_DEBUG_KMS("dot crawl: current %d\n", response); |
2510 | sdvo_priv->left_property, | ||
2511 | sdvo_priv->left_margin); | ||
2512 | sdvo_priv->right_property = | ||
2513 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2514 | "right_margin", 2); | ||
2515 | sdvo_priv->right_property->values[0] = 0; | ||
2516 | sdvo_priv->right_property->values[1] = data_value[0]; | ||
2517 | drm_connector_attach_property(connector, | ||
2518 | sdvo_priv->right_property, | ||
2519 | sdvo_priv->right_margin); | ||
2520 | DRM_DEBUG_KMS("h_overscan: max %d, " | ||
2521 | "default %d, current %d\n", | ||
2522 | data_value[0], data_value[1], response); | ||
2523 | } | ||
2524 | if (sdvo_data.overscan_v) { | ||
2525 | intel_sdvo_write_cmd(intel_encoder, | ||
2526 | SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0); | ||
2527 | status = intel_sdvo_read_response(intel_encoder, | ||
2528 | &data_value, 4); | ||
2529 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2530 | DRM_DEBUG_KMS("Incorrect SDVO max " | ||
2531 | "v_overscan\n"); | ||
2532 | return; | ||
2533 | } | ||
2534 | intel_sdvo_write_cmd(intel_encoder, | ||
2535 | SDVO_CMD_GET_OVERSCAN_V, NULL, 0); | ||
2536 | status = intel_sdvo_read_response(intel_encoder, | ||
2537 | &response, 2); | ||
2538 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2539 | DRM_DEBUG_KMS("Incorrect SDVO v_overscan\n"); | ||
2540 | return; | ||
2541 | } | ||
2542 | sdvo_priv->max_vscan = data_value[0]; | ||
2543 | sdvo_priv->top_margin = data_value[0] - response; | ||
2544 | sdvo_priv->bottom_margin = sdvo_priv->top_margin; | ||
2545 | sdvo_priv->top_property = | ||
2546 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2547 | "top_margin", 2); | ||
2548 | sdvo_priv->top_property->values[0] = 0; | ||
2549 | sdvo_priv->top_property->values[1] = data_value[0]; | ||
2550 | drm_connector_attach_property(connector, | ||
2551 | sdvo_priv->top_property, | ||
2552 | sdvo_priv->top_margin); | ||
2553 | sdvo_priv->bottom_property = | ||
2554 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2555 | "bottom_margin", 2); | ||
2556 | sdvo_priv->bottom_property->values[0] = 0; | ||
2557 | sdvo_priv->bottom_property->values[1] = data_value[0]; | ||
2558 | drm_connector_attach_property(connector, | ||
2559 | sdvo_priv->bottom_property, | ||
2560 | sdvo_priv->bottom_margin); | ||
2561 | DRM_DEBUG_KMS("v_overscan: max %d, " | ||
2562 | "default %d, current %d\n", | ||
2563 | data_value[0], data_value[1], response); | ||
2564 | } | ||
2565 | if (sdvo_data.position_h) { | ||
2566 | intel_sdvo_write_cmd(intel_encoder, | ||
2567 | SDVO_CMD_GET_MAX_POSITION_H, NULL, 0); | ||
2568 | status = intel_sdvo_read_response(intel_encoder, | ||
2569 | &data_value, 4); | ||
2570 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2571 | DRM_DEBUG_KMS("Incorrect SDVO Max h_pos\n"); | ||
2572 | return; | ||
2573 | } | ||
2574 | intel_sdvo_write_cmd(intel_encoder, | ||
2575 | SDVO_CMD_GET_POSITION_H, NULL, 0); | ||
2576 | status = intel_sdvo_read_response(intel_encoder, | ||
2577 | &response, 2); | ||
2578 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2579 | DRM_DEBUG_KMS("Incorrect SDVO get h_postion\n"); | ||
2580 | return; | ||
2581 | } | ||
2582 | sdvo_priv->max_hpos = data_value[0]; | ||
2583 | sdvo_priv->cur_hpos = response; | ||
2584 | sdvo_priv->hpos_property = | ||
2585 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2586 | "hpos", 2); | ||
2587 | sdvo_priv->hpos_property->values[0] = 0; | ||
2588 | sdvo_priv->hpos_property->values[1] = data_value[0]; | ||
2589 | drm_connector_attach_property(connector, | ||
2590 | sdvo_priv->hpos_property, | ||
2591 | sdvo_priv->cur_hpos); | ||
2592 | DRM_DEBUG_KMS("h_position: max %d, " | ||
2593 | "default %d, current %d\n", | ||
2594 | data_value[0], data_value[1], response); | ||
2595 | } | ||
2596 | if (sdvo_data.position_v) { | ||
2597 | intel_sdvo_write_cmd(intel_encoder, | ||
2598 | SDVO_CMD_GET_MAX_POSITION_V, NULL, 0); | ||
2599 | status = intel_sdvo_read_response(intel_encoder, | ||
2600 | &data_value, 4); | ||
2601 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2602 | DRM_DEBUG_KMS("Incorrect SDVO Max v_pos\n"); | ||
2603 | return; | ||
2604 | } | ||
2605 | intel_sdvo_write_cmd(intel_encoder, | ||
2606 | SDVO_CMD_GET_POSITION_V, NULL, 0); | ||
2607 | status = intel_sdvo_read_response(intel_encoder, | ||
2608 | &response, 2); | ||
2609 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2610 | DRM_DEBUG_KMS("Incorrect SDVO get v_postion\n"); | ||
2611 | return; | ||
2612 | } | ||
2613 | sdvo_priv->max_vpos = data_value[0]; | ||
2614 | sdvo_priv->cur_vpos = response; | ||
2615 | sdvo_priv->vpos_property = | ||
2616 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2617 | "vpos", 2); | ||
2618 | sdvo_priv->vpos_property->values[0] = 0; | ||
2619 | sdvo_priv->vpos_property->values[1] = data_value[0]; | ||
2620 | drm_connector_attach_property(connector, | ||
2621 | sdvo_priv->vpos_property, | ||
2622 | sdvo_priv->cur_vpos); | ||
2623 | DRM_DEBUG_KMS("v_position: max %d, " | ||
2624 | "default %d, current %d\n", | ||
2625 | data_value[0], data_value[1], response); | ||
2626 | } | ||
2627 | if (sdvo_data.saturation) { | ||
2628 | intel_sdvo_write_cmd(intel_encoder, | ||
2629 | SDVO_CMD_GET_MAX_SATURATION, NULL, 0); | ||
2630 | status = intel_sdvo_read_response(intel_encoder, | ||
2631 | &data_value, 4); | ||
2632 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2633 | DRM_DEBUG_KMS("Incorrect SDVO Max sat\n"); | ||
2634 | return; | ||
2635 | } | ||
2636 | intel_sdvo_write_cmd(intel_encoder, | ||
2637 | SDVO_CMD_GET_SATURATION, NULL, 0); | ||
2638 | status = intel_sdvo_read_response(intel_encoder, | ||
2639 | &response, 2); | ||
2640 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2641 | DRM_DEBUG_KMS("Incorrect SDVO get sat\n"); | ||
2642 | return; | ||
2643 | } | ||
2644 | sdvo_priv->max_saturation = data_value[0]; | ||
2645 | sdvo_priv->cur_saturation = response; | ||
2646 | sdvo_priv->saturation_property = | ||
2647 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2648 | "saturation", 2); | ||
2649 | sdvo_priv->saturation_property->values[0] = 0; | ||
2650 | sdvo_priv->saturation_property->values[1] = | ||
2651 | data_value[0]; | ||
2652 | drm_connector_attach_property(connector, | ||
2653 | sdvo_priv->saturation_property, | ||
2654 | sdvo_priv->cur_saturation); | ||
2655 | DRM_DEBUG_KMS("saturation: max %d, " | ||
2656 | "default %d, current %d\n", | ||
2657 | data_value[0], data_value[1], response); | ||
2658 | } | ||
2659 | if (sdvo_data.contrast) { | ||
2660 | intel_sdvo_write_cmd(intel_encoder, | ||
2661 | SDVO_CMD_GET_MAX_CONTRAST, NULL, 0); | ||
2662 | status = intel_sdvo_read_response(intel_encoder, | ||
2663 | &data_value, 4); | ||
2664 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2665 | DRM_DEBUG_KMS("Incorrect SDVO Max contrast\n"); | ||
2666 | return; | ||
2667 | } | ||
2668 | intel_sdvo_write_cmd(intel_encoder, | ||
2669 | SDVO_CMD_GET_CONTRAST, NULL, 0); | ||
2670 | status = intel_sdvo_read_response(intel_encoder, | ||
2671 | &response, 2); | ||
2672 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2673 | DRM_DEBUG_KMS("Incorrect SDVO get contrast\n"); | ||
2674 | return; | ||
2675 | } | ||
2676 | sdvo_priv->max_contrast = data_value[0]; | ||
2677 | sdvo_priv->cur_contrast = response; | ||
2678 | sdvo_priv->contrast_property = | ||
2679 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2680 | "contrast", 2); | ||
2681 | sdvo_priv->contrast_property->values[0] = 0; | ||
2682 | sdvo_priv->contrast_property->values[1] = data_value[0]; | ||
2683 | drm_connector_attach_property(connector, | ||
2684 | sdvo_priv->contrast_property, | ||
2685 | sdvo_priv->cur_contrast); | ||
2686 | DRM_DEBUG_KMS("contrast: max %d, " | ||
2687 | "default %d, current %d\n", | ||
2688 | data_value[0], data_value[1], response); | ||
2689 | } | ||
2690 | if (sdvo_data.hue) { | ||
2691 | intel_sdvo_write_cmd(intel_encoder, | ||
2692 | SDVO_CMD_GET_MAX_HUE, NULL, 0); | ||
2693 | status = intel_sdvo_read_response(intel_encoder, | ||
2694 | &data_value, 4); | ||
2695 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2696 | DRM_DEBUG_KMS("Incorrect SDVO Max hue\n"); | ||
2697 | return; | ||
2698 | } | ||
2699 | intel_sdvo_write_cmd(intel_encoder, | ||
2700 | SDVO_CMD_GET_HUE, NULL, 0); | ||
2701 | status = intel_sdvo_read_response(intel_encoder, | ||
2702 | &response, 2); | ||
2703 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2704 | DRM_DEBUG_KMS("Incorrect SDVO get hue\n"); | ||
2705 | return; | ||
2706 | } | ||
2707 | sdvo_priv->max_hue = data_value[0]; | ||
2708 | sdvo_priv->cur_hue = response; | ||
2709 | sdvo_priv->hue_property = | ||
2710 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2711 | "hue", 2); | ||
2712 | sdvo_priv->hue_property->values[0] = 0; | ||
2713 | sdvo_priv->hue_property->values[1] = | ||
2714 | data_value[0]; | ||
2715 | drm_connector_attach_property(connector, | ||
2716 | sdvo_priv->hue_property, | ||
2717 | sdvo_priv->cur_hue); | ||
2718 | DRM_DEBUG_KMS("hue: max %d, default %d, current %d\n", | ||
2719 | data_value[0], data_value[1], response); | ||
2720 | } | ||
2721 | } | 2496 | } |
2722 | if (IS_TV(sdvo_priv) || IS_LVDS(sdvo_priv)) { | 2497 | |
2723 | if (sdvo_data.brightness) { | 2498 | return true; |
2724 | intel_sdvo_write_cmd(intel_encoder, | 2499 | } |
2725 | SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0); | 2500 | |
2726 | status = intel_sdvo_read_response(intel_encoder, | 2501 | static bool |
2727 | &data_value, 4); | 2502 | intel_sdvo_create_enhance_property_lvds(struct intel_sdvo *intel_sdvo, |
2728 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2503 | struct intel_sdvo_connector *intel_sdvo_connector, |
2729 | DRM_DEBUG_KMS("Incorrect SDVO Max bright\n"); | 2504 | struct intel_sdvo_enhancements_reply enhancements) |
2730 | return; | 2505 | { |
2731 | } | 2506 | struct drm_device *dev = intel_sdvo->base.enc.dev; |
2732 | intel_sdvo_write_cmd(intel_encoder, | 2507 | struct drm_connector *connector = &intel_sdvo_connector->base.base; |
2733 | SDVO_CMD_GET_BRIGHTNESS, NULL, 0); | 2508 | uint16_t response, data_value[2]; |
2734 | status = intel_sdvo_read_response(intel_encoder, | 2509 | |
2735 | &response, 2); | 2510 | ENHANCEMENT(brightness, BRIGHTNESS); |
2736 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2511 | |
2737 | DRM_DEBUG_KMS("Incorrect SDVO get brigh\n"); | 2512 | return true; |
2738 | return; | 2513 | } |
2739 | } | 2514 | #undef ENHANCEMENT |
2740 | sdvo_priv->max_brightness = data_value[0]; | 2515 | |
2741 | sdvo_priv->cur_brightness = response; | 2516 | static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, |
2742 | sdvo_priv->brightness_property = | 2517 | struct intel_sdvo_connector *intel_sdvo_connector) |
2743 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 2518 | { |
2744 | "brightness", 2); | 2519 | union { |
2745 | sdvo_priv->brightness_property->values[0] = 0; | 2520 | struct intel_sdvo_enhancements_reply reply; |
2746 | sdvo_priv->brightness_property->values[1] = | 2521 | uint16_t response; |
2747 | data_value[0]; | 2522 | } enhancements; |
2748 | drm_connector_attach_property(connector, | 2523 | |
2749 | sdvo_priv->brightness_property, | 2524 | if (!intel_sdvo_get_value(intel_sdvo, |
2750 | sdvo_priv->cur_brightness); | 2525 | SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, |
2751 | DRM_DEBUG_KMS("brightness: max %d, " | 2526 | &enhancements, sizeof(enhancements))) |
2752 | "default %d, current %d\n", | 2527 | return false; |
2753 | data_value[0], data_value[1], response); | 2528 | |
2754 | } | 2529 | if (enhancements.response == 0) { |
2530 | DRM_DEBUG_KMS("No enhancement is supported\n"); | ||
2531 | return true; | ||
2755 | } | 2532 | } |
2756 | return; | 2533 | |
2534 | if (IS_TV(intel_sdvo_connector)) | ||
2535 | return intel_sdvo_create_enhance_property_tv(intel_sdvo, intel_sdvo_connector, enhancements.reply); | ||
2536 | else if(IS_LVDS(intel_sdvo_connector)) | ||
2537 | return intel_sdvo_create_enhance_property_lvds(intel_sdvo, intel_sdvo_connector, enhancements.reply); | ||
2538 | else | ||
2539 | return true; | ||
2540 | |||
2757 | } | 2541 | } |
2758 | 2542 | ||
2759 | bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | 2543 | bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) |
2760 | { | 2544 | { |
2761 | struct drm_i915_private *dev_priv = dev->dev_private; | 2545 | struct drm_i915_private *dev_priv = dev->dev_private; |
2762 | struct intel_encoder *intel_encoder; | 2546 | struct intel_encoder *intel_encoder; |
2763 | struct intel_sdvo_priv *sdvo_priv; | 2547 | struct intel_sdvo *intel_sdvo; |
2764 | u8 ch[0x40]; | 2548 | u8 ch[0x40]; |
2765 | int i; | 2549 | int i; |
2766 | u32 i2c_reg, ddc_reg, analog_ddc_reg; | 2550 | u32 i2c_reg, ddc_reg, analog_ddc_reg; |
2767 | 2551 | ||
2768 | intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); | 2552 | intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL); |
2769 | if (!intel_encoder) { | 2553 | if (!intel_sdvo) |
2770 | return false; | 2554 | return false; |
2771 | } | ||
2772 | 2555 | ||
2773 | sdvo_priv = (struct intel_sdvo_priv *)(intel_encoder + 1); | 2556 | intel_sdvo->sdvo_reg = sdvo_reg; |
2774 | sdvo_priv->sdvo_reg = sdvo_reg; | ||
2775 | 2557 | ||
2776 | intel_encoder->dev_priv = sdvo_priv; | 2558 | intel_encoder = &intel_sdvo->base; |
2777 | intel_encoder->type = INTEL_OUTPUT_SDVO; | 2559 | intel_encoder->type = INTEL_OUTPUT_SDVO; |
2778 | 2560 | ||
2779 | if (HAS_PCH_SPLIT(dev)) { | 2561 | if (HAS_PCH_SPLIT(dev)) { |
@@ -2795,14 +2577,14 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2795 | if (!intel_encoder->i2c_bus) | 2577 | if (!intel_encoder->i2c_bus) |
2796 | goto err_inteloutput; | 2578 | goto err_inteloutput; |
2797 | 2579 | ||
2798 | sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg); | 2580 | intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg); |
2799 | 2581 | ||
2800 | /* Save the bit-banging i2c functionality for use by the DDC wrapper */ | 2582 | /* Save the bit-banging i2c functionality for use by the DDC wrapper */ |
2801 | intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality; | 2583 | intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality; |
2802 | 2584 | ||
2803 | /* Read the regs to test if we can talk to the device */ | 2585 | /* Read the regs to test if we can talk to the device */ |
2804 | for (i = 0; i < 0x40; i++) { | 2586 | for (i = 0; i < 0x40; i++) { |
2805 | if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) { | 2587 | if (!intel_sdvo_read_byte(intel_sdvo, i, &ch[i])) { |
2806 | DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", | 2588 | DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", |
2807 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); | 2589 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); |
2808 | goto err_i2c; | 2590 | goto err_i2c; |
@@ -2812,17 +2594,16 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2812 | /* setup the DDC bus. */ | 2594 | /* setup the DDC bus. */ |
2813 | if (IS_SDVOB(sdvo_reg)) { | 2595 | if (IS_SDVOB(sdvo_reg)) { |
2814 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOB DDC BUS"); | 2596 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOB DDC BUS"); |
2815 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, | 2597 | intel_sdvo->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, |
2816 | "SDVOB/VGA DDC BUS"); | 2598 | "SDVOB/VGA DDC BUS"); |
2817 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; | 2599 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; |
2818 | } else { | 2600 | } else { |
2819 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOC DDC BUS"); | 2601 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOC DDC BUS"); |
2820 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, | 2602 | intel_sdvo->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, |
2821 | "SDVOC/VGA DDC BUS"); | 2603 | "SDVOC/VGA DDC BUS"); |
2822 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; | 2604 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; |
2823 | } | 2605 | } |
2824 | 2606 | if (intel_encoder->ddc_bus == NULL || intel_sdvo->analog_ddc_bus == NULL) | |
2825 | if (intel_encoder->ddc_bus == NULL) | ||
2826 | goto err_i2c; | 2607 | goto err_i2c; |
2827 | 2608 | ||
2828 | /* Wrap with our custom algo which switches to DDC mode */ | 2609 | /* Wrap with our custom algo which switches to DDC mode */ |
@@ -2833,53 +2614,56 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2833 | drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs); | 2614 | drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs); |
2834 | 2615 | ||
2835 | /* In default case sdvo lvds is false */ | 2616 | /* In default case sdvo lvds is false */ |
2836 | intel_sdvo_get_capabilities(intel_encoder, &sdvo_priv->caps); | 2617 | if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) |
2618 | goto err_enc; | ||
2837 | 2619 | ||
2838 | if (intel_sdvo_output_setup(intel_encoder, | 2620 | if (intel_sdvo_output_setup(intel_sdvo, |
2839 | sdvo_priv->caps.output_flags) != true) { | 2621 | intel_sdvo->caps.output_flags) != true) { |
2840 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", | 2622 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", |
2841 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); | 2623 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); |
2842 | goto err_i2c; | 2624 | goto err_enc; |
2843 | } | 2625 | } |
2844 | 2626 | ||
2845 | intel_sdvo_select_ddc_bus(dev_priv, sdvo_priv, sdvo_reg); | 2627 | intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg); |
2846 | 2628 | ||
2847 | /* Set the input timing to the screen. Assume always input 0. */ | 2629 | /* Set the input timing to the screen. Assume always input 0. */ |
2848 | intel_sdvo_set_target_input(intel_encoder, true, false); | 2630 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
2849 | 2631 | goto err_enc; | |
2850 | intel_sdvo_get_input_pixel_clock_range(intel_encoder, | ||
2851 | &sdvo_priv->pixel_clock_min, | ||
2852 | &sdvo_priv->pixel_clock_max); | ||
2853 | 2632 | ||
2633 | if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, | ||
2634 | &intel_sdvo->pixel_clock_min, | ||
2635 | &intel_sdvo->pixel_clock_max)) | ||
2636 | goto err_enc; | ||
2854 | 2637 | ||
2855 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " | 2638 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " |
2856 | "clock range %dMHz - %dMHz, " | 2639 | "clock range %dMHz - %dMHz, " |
2857 | "input 1: %c, input 2: %c, " | 2640 | "input 1: %c, input 2: %c, " |
2858 | "output 1: %c, output 2: %c\n", | 2641 | "output 1: %c, output 2: %c\n", |
2859 | SDVO_NAME(sdvo_priv), | 2642 | SDVO_NAME(intel_sdvo), |
2860 | sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id, | 2643 | intel_sdvo->caps.vendor_id, intel_sdvo->caps.device_id, |
2861 | sdvo_priv->caps.device_rev_id, | 2644 | intel_sdvo->caps.device_rev_id, |
2862 | sdvo_priv->pixel_clock_min / 1000, | 2645 | intel_sdvo->pixel_clock_min / 1000, |
2863 | sdvo_priv->pixel_clock_max / 1000, | 2646 | intel_sdvo->pixel_clock_max / 1000, |
2864 | (sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N', | 2647 | (intel_sdvo->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N', |
2865 | (sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N', | 2648 | (intel_sdvo->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N', |
2866 | /* check currently supported outputs */ | 2649 | /* check currently supported outputs */ |
2867 | sdvo_priv->caps.output_flags & | 2650 | intel_sdvo->caps.output_flags & |
2868 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N', | 2651 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N', |
2869 | sdvo_priv->caps.output_flags & | 2652 | intel_sdvo->caps.output_flags & |
2870 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); | 2653 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); |
2871 | |||
2872 | return true; | 2654 | return true; |
2873 | 2655 | ||
2656 | err_enc: | ||
2657 | drm_encoder_cleanup(&intel_encoder->enc); | ||
2874 | err_i2c: | 2658 | err_i2c: |
2875 | if (sdvo_priv->analog_ddc_bus != NULL) | 2659 | if (intel_sdvo->analog_ddc_bus != NULL) |
2876 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); | 2660 | intel_i2c_destroy(intel_sdvo->analog_ddc_bus); |
2877 | if (intel_encoder->ddc_bus != NULL) | 2661 | if (intel_encoder->ddc_bus != NULL) |
2878 | intel_i2c_destroy(intel_encoder->ddc_bus); | 2662 | intel_i2c_destroy(intel_encoder->ddc_bus); |
2879 | if (intel_encoder->i2c_bus != NULL) | 2663 | if (intel_encoder->i2c_bus != NULL) |
2880 | intel_i2c_destroy(intel_encoder->i2c_bus); | 2664 | intel_i2c_destroy(intel_encoder->i2c_bus); |
2881 | err_inteloutput: | 2665 | err_inteloutput: |
2882 | kfree(intel_encoder); | 2666 | kfree(intel_sdvo); |
2883 | 2667 | ||
2884 | return false; | 2668 | return false; |
2885 | } | 2669 | } |
diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h index ba5cdf8ae40..a386b022e53 100644 --- a/drivers/gpu/drm/i915/intel_sdvo_regs.h +++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h | |||
@@ -312,7 +312,7 @@ struct intel_sdvo_set_target_input_args { | |||
312 | # define SDVO_CLOCK_RATE_MULT_4X (1 << 3) | 312 | # define SDVO_CLOCK_RATE_MULT_4X (1 << 3) |
313 | 313 | ||
314 | #define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27 | 314 | #define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27 |
315 | /** 5 bytes of bit flags for TV formats shared by all TV format functions */ | 315 | /** 6 bytes of bit flags for TV formats shared by all TV format functions */ |
316 | struct intel_sdvo_tv_format { | 316 | struct intel_sdvo_tv_format { |
317 | unsigned int ntsc_m:1; | 317 | unsigned int ntsc_m:1; |
318 | unsigned int ntsc_j:1; | 318 | unsigned int ntsc_j:1; |
@@ -596,32 +596,32 @@ struct intel_sdvo_enhancements_reply { | |||
596 | unsigned int overscan_h:1; | 596 | unsigned int overscan_h:1; |
597 | 597 | ||
598 | unsigned int overscan_v:1; | 598 | unsigned int overscan_v:1; |
599 | unsigned int position_h:1; | 599 | unsigned int hpos:1; |
600 | unsigned int position_v:1; | 600 | unsigned int vpos:1; |
601 | unsigned int sharpness:1; | 601 | unsigned int sharpness:1; |
602 | unsigned int dot_crawl:1; | 602 | unsigned int dot_crawl:1; |
603 | unsigned int dither:1; | 603 | unsigned int dither:1; |
604 | unsigned int max_tv_chroma_filter:1; | 604 | unsigned int tv_chroma_filter:1; |
605 | unsigned int max_tv_luma_filter:1; | 605 | unsigned int tv_luma_filter:1; |
606 | } __attribute__((packed)); | 606 | } __attribute__((packed)); |
607 | 607 | ||
608 | /* Picture enhancement limits below are dependent on the current TV format, | 608 | /* Picture enhancement limits below are dependent on the current TV format, |
609 | * and thus need to be queried and set after it. | 609 | * and thus need to be queried and set after it. |
610 | */ | 610 | */ |
611 | #define SDVO_CMD_GET_MAX_FLICKER_FITER 0x4d | 611 | #define SDVO_CMD_GET_MAX_FLICKER_FILTER 0x4d |
612 | #define SDVO_CMD_GET_MAX_ADAPTIVE_FLICKER_FITER 0x7b | 612 | #define SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE 0x7b |
613 | #define SDVO_CMD_GET_MAX_2D_FLICKER_FITER 0x52 | 613 | #define SDVO_CMD_GET_MAX_FLICKER_FILTER_2D 0x52 |
614 | #define SDVO_CMD_GET_MAX_SATURATION 0x55 | 614 | #define SDVO_CMD_GET_MAX_SATURATION 0x55 |
615 | #define SDVO_CMD_GET_MAX_HUE 0x58 | 615 | #define SDVO_CMD_GET_MAX_HUE 0x58 |
616 | #define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5b | 616 | #define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5b |
617 | #define SDVO_CMD_GET_MAX_CONTRAST 0x5e | 617 | #define SDVO_CMD_GET_MAX_CONTRAST 0x5e |
618 | #define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61 | 618 | #define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61 |
619 | #define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64 | 619 | #define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64 |
620 | #define SDVO_CMD_GET_MAX_POSITION_H 0x67 | 620 | #define SDVO_CMD_GET_MAX_HPOS 0x67 |
621 | #define SDVO_CMD_GET_MAX_POSITION_V 0x6a | 621 | #define SDVO_CMD_GET_MAX_VPOS 0x6a |
622 | #define SDVO_CMD_GET_MAX_SHARPNESS_V 0x6d | 622 | #define SDVO_CMD_GET_MAX_SHARPNESS 0x6d |
623 | #define SDVO_CMD_GET_MAX_TV_CHROMA 0x74 | 623 | #define SDVO_CMD_GET_MAX_TV_CHROMA_FILTER 0x74 |
624 | #define SDVO_CMD_GET_MAX_TV_LUMA 0x77 | 624 | #define SDVO_CMD_GET_MAX_TV_LUMA_FILTER 0x77 |
625 | struct intel_sdvo_enhancement_limits_reply { | 625 | struct intel_sdvo_enhancement_limits_reply { |
626 | u16 max_value; | 626 | u16 max_value; |
627 | u16 default_value; | 627 | u16 default_value; |
@@ -638,10 +638,10 @@ struct intel_sdvo_enhancement_limits_reply { | |||
638 | 638 | ||
639 | #define SDVO_CMD_GET_FLICKER_FILTER 0x4e | 639 | #define SDVO_CMD_GET_FLICKER_FILTER 0x4e |
640 | #define SDVO_CMD_SET_FLICKER_FILTER 0x4f | 640 | #define SDVO_CMD_SET_FLICKER_FILTER 0x4f |
641 | #define SDVO_CMD_GET_ADAPTIVE_FLICKER_FITER 0x50 | 641 | #define SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE 0x50 |
642 | #define SDVO_CMD_SET_ADAPTIVE_FLICKER_FITER 0x51 | 642 | #define SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE 0x51 |
643 | #define SDVO_CMD_GET_2D_FLICKER_FITER 0x53 | 643 | #define SDVO_CMD_GET_FLICKER_FILTER_2D 0x53 |
644 | #define SDVO_CMD_SET_2D_FLICKER_FITER 0x54 | 644 | #define SDVO_CMD_SET_FLICKER_FILTER_2D 0x54 |
645 | #define SDVO_CMD_GET_SATURATION 0x56 | 645 | #define SDVO_CMD_GET_SATURATION 0x56 |
646 | #define SDVO_CMD_SET_SATURATION 0x57 | 646 | #define SDVO_CMD_SET_SATURATION 0x57 |
647 | #define SDVO_CMD_GET_HUE 0x59 | 647 | #define SDVO_CMD_GET_HUE 0x59 |
@@ -654,16 +654,16 @@ struct intel_sdvo_enhancement_limits_reply { | |||
654 | #define SDVO_CMD_SET_OVERSCAN_H 0x63 | 654 | #define SDVO_CMD_SET_OVERSCAN_H 0x63 |
655 | #define SDVO_CMD_GET_OVERSCAN_V 0x65 | 655 | #define SDVO_CMD_GET_OVERSCAN_V 0x65 |
656 | #define SDVO_CMD_SET_OVERSCAN_V 0x66 | 656 | #define SDVO_CMD_SET_OVERSCAN_V 0x66 |
657 | #define SDVO_CMD_GET_POSITION_H 0x68 | 657 | #define SDVO_CMD_GET_HPOS 0x68 |
658 | #define SDVO_CMD_SET_POSITION_H 0x69 | 658 | #define SDVO_CMD_SET_HPOS 0x69 |
659 | #define SDVO_CMD_GET_POSITION_V 0x6b | 659 | #define SDVO_CMD_GET_VPOS 0x6b |
660 | #define SDVO_CMD_SET_POSITION_V 0x6c | 660 | #define SDVO_CMD_SET_VPOS 0x6c |
661 | #define SDVO_CMD_GET_SHARPNESS 0x6e | 661 | #define SDVO_CMD_GET_SHARPNESS 0x6e |
662 | #define SDVO_CMD_SET_SHARPNESS 0x6f | 662 | #define SDVO_CMD_SET_SHARPNESS 0x6f |
663 | #define SDVO_CMD_GET_TV_CHROMA 0x75 | 663 | #define SDVO_CMD_GET_TV_CHROMA_FILTER 0x75 |
664 | #define SDVO_CMD_SET_TV_CHROMA 0x76 | 664 | #define SDVO_CMD_SET_TV_CHROMA_FILTER 0x76 |
665 | #define SDVO_CMD_GET_TV_LUMA 0x78 | 665 | #define SDVO_CMD_GET_TV_LUMA_FILTER 0x78 |
666 | #define SDVO_CMD_SET_TV_LUMA 0x79 | 666 | #define SDVO_CMD_SET_TV_LUMA_FILTER 0x79 |
667 | struct intel_sdvo_enhancements_arg { | 667 | struct intel_sdvo_enhancements_arg { |
668 | u16 value; | 668 | u16 value; |
669 | }__attribute__((packed)); | 669 | }__attribute__((packed)); |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index cc3726a4a1c..c671f60ce80 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -44,7 +44,9 @@ enum tv_margin { | |||
44 | }; | 44 | }; |
45 | 45 | ||
46 | /** Private structure for the integrated TV support */ | 46 | /** Private structure for the integrated TV support */ |
47 | struct intel_tv_priv { | 47 | struct intel_tv { |
48 | struct intel_encoder base; | ||
49 | |||
48 | int type; | 50 | int type; |
49 | char *tv_format; | 51 | char *tv_format; |
50 | int margin[4]; | 52 | int margin[4]; |
@@ -896,6 +898,11 @@ static const struct tv_mode tv_modes[] = { | |||
896 | }, | 898 | }, |
897 | }; | 899 | }; |
898 | 900 | ||
901 | static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder) | ||
902 | { | ||
903 | return container_of(enc_to_intel_encoder(encoder), struct intel_tv, base); | ||
904 | } | ||
905 | |||
899 | static void | 906 | static void |
900 | intel_tv_dpms(struct drm_encoder *encoder, int mode) | 907 | intel_tv_dpms(struct drm_encoder *encoder, int mode) |
901 | { | 908 | { |
@@ -929,19 +936,17 @@ intel_tv_mode_lookup (char *tv_format) | |||
929 | } | 936 | } |
930 | 937 | ||
931 | static const struct tv_mode * | 938 | static const struct tv_mode * |
932 | intel_tv_mode_find (struct intel_encoder *intel_encoder) | 939 | intel_tv_mode_find (struct intel_tv *intel_tv) |
933 | { | 940 | { |
934 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 941 | return intel_tv_mode_lookup(intel_tv->tv_format); |
935 | |||
936 | return intel_tv_mode_lookup(tv_priv->tv_format); | ||
937 | } | 942 | } |
938 | 943 | ||
939 | static enum drm_mode_status | 944 | static enum drm_mode_status |
940 | intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) | 945 | intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) |
941 | { | 946 | { |
942 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 947 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
943 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 948 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
944 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | 949 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
945 | 950 | ||
946 | /* Ensure TV refresh is close to desired refresh */ | 951 | /* Ensure TV refresh is close to desired refresh */ |
947 | if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) | 952 | if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) |
@@ -957,8 +962,8 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
957 | { | 962 | { |
958 | struct drm_device *dev = encoder->dev; | 963 | struct drm_device *dev = encoder->dev; |
959 | struct drm_mode_config *drm_config = &dev->mode_config; | 964 | struct drm_mode_config *drm_config = &dev->mode_config; |
960 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 965 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
961 | const struct tv_mode *tv_mode = intel_tv_mode_find (intel_encoder); | 966 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
962 | struct drm_encoder *other_encoder; | 967 | struct drm_encoder *other_encoder; |
963 | 968 | ||
964 | if (!tv_mode) | 969 | if (!tv_mode) |
@@ -983,9 +988,8 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
983 | struct drm_i915_private *dev_priv = dev->dev_private; | 988 | struct drm_i915_private *dev_priv = dev->dev_private; |
984 | struct drm_crtc *crtc = encoder->crtc; | 989 | struct drm_crtc *crtc = encoder->crtc; |
985 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 990 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
986 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 991 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
987 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 992 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
988 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | ||
989 | u32 tv_ctl; | 993 | u32 tv_ctl; |
990 | u32 hctl1, hctl2, hctl3; | 994 | u32 hctl1, hctl2, hctl3; |
991 | u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; | 995 | u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; |
@@ -1001,7 +1005,7 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
1001 | tv_ctl = I915_READ(TV_CTL); | 1005 | tv_ctl = I915_READ(TV_CTL); |
1002 | tv_ctl &= TV_CTL_SAVE; | 1006 | tv_ctl &= TV_CTL_SAVE; |
1003 | 1007 | ||
1004 | switch (tv_priv->type) { | 1008 | switch (intel_tv->type) { |
1005 | default: | 1009 | default: |
1006 | case DRM_MODE_CONNECTOR_Unknown: | 1010 | case DRM_MODE_CONNECTOR_Unknown: |
1007 | case DRM_MODE_CONNECTOR_Composite: | 1011 | case DRM_MODE_CONNECTOR_Composite: |
@@ -1154,11 +1158,11 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
1154 | 1158 | ||
1155 | /* Wait for vblank for the disable to take effect */ | 1159 | /* Wait for vblank for the disable to take effect */ |
1156 | if (!IS_I9XX(dev)) | 1160 | if (!IS_I9XX(dev)) |
1157 | intel_wait_for_vblank(dev); | 1161 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1158 | 1162 | ||
1159 | I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE); | 1163 | I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE); |
1160 | /* Wait for vblank for the disable to take effect. */ | 1164 | /* Wait for vblank for the disable to take effect. */ |
1161 | intel_wait_for_vblank(dev); | 1165 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1162 | 1166 | ||
1163 | /* Filter ctl must be set before TV_WIN_SIZE */ | 1167 | /* Filter ctl must be set before TV_WIN_SIZE */ |
1164 | I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE); | 1168 | I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE); |
@@ -1168,12 +1172,12 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
1168 | else | 1172 | else |
1169 | ysize = 2*tv_mode->nbr_end + 1; | 1173 | ysize = 2*tv_mode->nbr_end + 1; |
1170 | 1174 | ||
1171 | xpos += tv_priv->margin[TV_MARGIN_LEFT]; | 1175 | xpos += intel_tv->margin[TV_MARGIN_LEFT]; |
1172 | ypos += tv_priv->margin[TV_MARGIN_TOP]; | 1176 | ypos += intel_tv->margin[TV_MARGIN_TOP]; |
1173 | xsize -= (tv_priv->margin[TV_MARGIN_LEFT] + | 1177 | xsize -= (intel_tv->margin[TV_MARGIN_LEFT] + |
1174 | tv_priv->margin[TV_MARGIN_RIGHT]); | 1178 | intel_tv->margin[TV_MARGIN_RIGHT]); |
1175 | ysize -= (tv_priv->margin[TV_MARGIN_TOP] + | 1179 | ysize -= (intel_tv->margin[TV_MARGIN_TOP] + |
1176 | tv_priv->margin[TV_MARGIN_BOTTOM]); | 1180 | intel_tv->margin[TV_MARGIN_BOTTOM]); |
1177 | I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos); | 1181 | I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos); |
1178 | I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize); | 1182 | I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize); |
1179 | 1183 | ||
@@ -1222,9 +1226,9 @@ static const struct drm_display_mode reported_modes[] = { | |||
1222 | * \return false if TV is disconnected. | 1226 | * \return false if TV is disconnected. |
1223 | */ | 1227 | */ |
1224 | static int | 1228 | static int |
1225 | intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder) | 1229 | intel_tv_detect_type (struct intel_tv *intel_tv) |
1226 | { | 1230 | { |
1227 | struct drm_encoder *encoder = &intel_encoder->enc; | 1231 | struct drm_encoder *encoder = &intel_tv->base.enc; |
1228 | struct drm_device *dev = encoder->dev; | 1232 | struct drm_device *dev = encoder->dev; |
1229 | struct drm_i915_private *dev_priv = dev->dev_private; | 1233 | struct drm_i915_private *dev_priv = dev->dev_private; |
1230 | unsigned long irqflags; | 1234 | unsigned long irqflags; |
@@ -1263,11 +1267,15 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
1263 | DAC_C_0_7_V); | 1267 | DAC_C_0_7_V); |
1264 | I915_WRITE(TV_CTL, tv_ctl); | 1268 | I915_WRITE(TV_CTL, tv_ctl); |
1265 | I915_WRITE(TV_DAC, tv_dac); | 1269 | I915_WRITE(TV_DAC, tv_dac); |
1266 | intel_wait_for_vblank(dev); | 1270 | POSTING_READ(TV_DAC); |
1271 | msleep(20); | ||
1272 | |||
1267 | tv_dac = I915_READ(TV_DAC); | 1273 | tv_dac = I915_READ(TV_DAC); |
1268 | I915_WRITE(TV_DAC, save_tv_dac); | 1274 | I915_WRITE(TV_DAC, save_tv_dac); |
1269 | I915_WRITE(TV_CTL, save_tv_ctl); | 1275 | I915_WRITE(TV_CTL, save_tv_ctl); |
1270 | intel_wait_for_vblank(dev); | 1276 | POSTING_READ(TV_CTL); |
1277 | msleep(20); | ||
1278 | |||
1271 | /* | 1279 | /* |
1272 | * A B C | 1280 | * A B C |
1273 | * 0 1 1 Composite | 1281 | * 0 1 1 Composite |
@@ -1304,12 +1312,11 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
1304 | static void intel_tv_find_better_format(struct drm_connector *connector) | 1312 | static void intel_tv_find_better_format(struct drm_connector *connector) |
1305 | { | 1313 | { |
1306 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1314 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1307 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1315 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
1308 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 1316 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
1309 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | ||
1310 | int i; | 1317 | int i; |
1311 | 1318 | ||
1312 | if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) == | 1319 | if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) == |
1313 | tv_mode->component_only) | 1320 | tv_mode->component_only) |
1314 | return; | 1321 | return; |
1315 | 1322 | ||
@@ -1317,12 +1324,12 @@ static void intel_tv_find_better_format(struct drm_connector *connector) | |||
1317 | for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) { | 1324 | for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) { |
1318 | tv_mode = tv_modes + i; | 1325 | tv_mode = tv_modes + i; |
1319 | 1326 | ||
1320 | if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) == | 1327 | if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) == |
1321 | tv_mode->component_only) | 1328 | tv_mode->component_only) |
1322 | break; | 1329 | break; |
1323 | } | 1330 | } |
1324 | 1331 | ||
1325 | tv_priv->tv_format = tv_mode->name; | 1332 | intel_tv->tv_format = tv_mode->name; |
1326 | drm_connector_property_set_value(connector, | 1333 | drm_connector_property_set_value(connector, |
1327 | connector->dev->mode_config.tv_mode_property, i); | 1334 | connector->dev->mode_config.tv_mode_property, i); |
1328 | } | 1335 | } |
@@ -1336,31 +1343,31 @@ static void intel_tv_find_better_format(struct drm_connector *connector) | |||
1336 | static enum drm_connector_status | 1343 | static enum drm_connector_status |
1337 | intel_tv_detect(struct drm_connector *connector) | 1344 | intel_tv_detect(struct drm_connector *connector) |
1338 | { | 1345 | { |
1339 | struct drm_crtc *crtc; | ||
1340 | struct drm_display_mode mode; | 1346 | struct drm_display_mode mode; |
1341 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1347 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1342 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1348 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
1343 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 1349 | int type; |
1344 | int dpms_mode; | ||
1345 | int type = tv_priv->type; | ||
1346 | 1350 | ||
1347 | mode = reported_modes[0]; | 1351 | mode = reported_modes[0]; |
1348 | drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); | 1352 | drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); |
1349 | 1353 | ||
1350 | if (encoder->crtc && encoder->crtc->enabled) { | 1354 | if (encoder->crtc && encoder->crtc->enabled) { |
1351 | type = intel_tv_detect_type(encoder->crtc, intel_encoder); | 1355 | type = intel_tv_detect_type(intel_tv); |
1352 | } else { | 1356 | } else { |
1353 | crtc = intel_get_load_detect_pipe(intel_encoder, connector, | 1357 | struct drm_crtc *crtc; |
1358 | int dpms_mode; | ||
1359 | |||
1360 | crtc = intel_get_load_detect_pipe(&intel_tv->base, connector, | ||
1354 | &mode, &dpms_mode); | 1361 | &mode, &dpms_mode); |
1355 | if (crtc) { | 1362 | if (crtc) { |
1356 | type = intel_tv_detect_type(crtc, intel_encoder); | 1363 | type = intel_tv_detect_type(intel_tv); |
1357 | intel_release_load_detect_pipe(intel_encoder, connector, | 1364 | intel_release_load_detect_pipe(&intel_tv->base, connector, |
1358 | dpms_mode); | 1365 | dpms_mode); |
1359 | } else | 1366 | } else |
1360 | type = -1; | 1367 | type = -1; |
1361 | } | 1368 | } |
1362 | 1369 | ||
1363 | tv_priv->type = type; | 1370 | intel_tv->type = type; |
1364 | 1371 | ||
1365 | if (type < 0) | 1372 | if (type < 0) |
1366 | return connector_status_disconnected; | 1373 | return connector_status_disconnected; |
@@ -1391,8 +1398,8 @@ intel_tv_chose_preferred_modes(struct drm_connector *connector, | |||
1391 | struct drm_display_mode *mode_ptr) | 1398 | struct drm_display_mode *mode_ptr) |
1392 | { | 1399 | { |
1393 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1400 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1394 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1401 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
1395 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | 1402 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
1396 | 1403 | ||
1397 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) | 1404 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) |
1398 | mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; | 1405 | mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; |
@@ -1417,8 +1424,8 @@ intel_tv_get_modes(struct drm_connector *connector) | |||
1417 | { | 1424 | { |
1418 | struct drm_display_mode *mode_ptr; | 1425 | struct drm_display_mode *mode_ptr; |
1419 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1426 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1420 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1427 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
1421 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | 1428 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
1422 | int j, count = 0; | 1429 | int j, count = 0; |
1423 | u64 tmp; | 1430 | u64 tmp; |
1424 | 1431 | ||
@@ -1483,8 +1490,7 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop | |||
1483 | { | 1490 | { |
1484 | struct drm_device *dev = connector->dev; | 1491 | struct drm_device *dev = connector->dev; |
1485 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1492 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1486 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1493 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
1487 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | ||
1488 | struct drm_crtc *crtc = encoder->crtc; | 1494 | struct drm_crtc *crtc = encoder->crtc; |
1489 | int ret = 0; | 1495 | int ret = 0; |
1490 | bool changed = false; | 1496 | bool changed = false; |
@@ -1494,30 +1500,30 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop | |||
1494 | goto out; | 1500 | goto out; |
1495 | 1501 | ||
1496 | if (property == dev->mode_config.tv_left_margin_property && | 1502 | if (property == dev->mode_config.tv_left_margin_property && |
1497 | tv_priv->margin[TV_MARGIN_LEFT] != val) { | 1503 | intel_tv->margin[TV_MARGIN_LEFT] != val) { |
1498 | tv_priv->margin[TV_MARGIN_LEFT] = val; | 1504 | intel_tv->margin[TV_MARGIN_LEFT] = val; |
1499 | changed = true; | 1505 | changed = true; |
1500 | } else if (property == dev->mode_config.tv_right_margin_property && | 1506 | } else if (property == dev->mode_config.tv_right_margin_property && |
1501 | tv_priv->margin[TV_MARGIN_RIGHT] != val) { | 1507 | intel_tv->margin[TV_MARGIN_RIGHT] != val) { |
1502 | tv_priv->margin[TV_MARGIN_RIGHT] = val; | 1508 | intel_tv->margin[TV_MARGIN_RIGHT] = val; |
1503 | changed = true; | 1509 | changed = true; |
1504 | } else if (property == dev->mode_config.tv_top_margin_property && | 1510 | } else if (property == dev->mode_config.tv_top_margin_property && |
1505 | tv_priv->margin[TV_MARGIN_TOP] != val) { | 1511 | intel_tv->margin[TV_MARGIN_TOP] != val) { |
1506 | tv_priv->margin[TV_MARGIN_TOP] = val; | 1512 | intel_tv->margin[TV_MARGIN_TOP] = val; |
1507 | changed = true; | 1513 | changed = true; |
1508 | } else if (property == dev->mode_config.tv_bottom_margin_property && | 1514 | } else if (property == dev->mode_config.tv_bottom_margin_property && |
1509 | tv_priv->margin[TV_MARGIN_BOTTOM] != val) { | 1515 | intel_tv->margin[TV_MARGIN_BOTTOM] != val) { |
1510 | tv_priv->margin[TV_MARGIN_BOTTOM] = val; | 1516 | intel_tv->margin[TV_MARGIN_BOTTOM] = val; |
1511 | changed = true; | 1517 | changed = true; |
1512 | } else if (property == dev->mode_config.tv_mode_property) { | 1518 | } else if (property == dev->mode_config.tv_mode_property) { |
1513 | if (val >= ARRAY_SIZE(tv_modes)) { | 1519 | if (val >= ARRAY_SIZE(tv_modes)) { |
1514 | ret = -EINVAL; | 1520 | ret = -EINVAL; |
1515 | goto out; | 1521 | goto out; |
1516 | } | 1522 | } |
1517 | if (!strcmp(tv_priv->tv_format, tv_modes[val].name)) | 1523 | if (!strcmp(intel_tv->tv_format, tv_modes[val].name)) |
1518 | goto out; | 1524 | goto out; |
1519 | 1525 | ||
1520 | tv_priv->tv_format = tv_modes[val].name; | 1526 | intel_tv->tv_format = tv_modes[val].name; |
1521 | changed = true; | 1527 | changed = true; |
1522 | } else { | 1528 | } else { |
1523 | ret = -EINVAL; | 1529 | ret = -EINVAL; |
@@ -1553,16 +1559,8 @@ static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = | |||
1553 | .best_encoder = intel_attached_encoder, | 1559 | .best_encoder = intel_attached_encoder, |
1554 | }; | 1560 | }; |
1555 | 1561 | ||
1556 | static void intel_tv_enc_destroy(struct drm_encoder *encoder) | ||
1557 | { | ||
1558 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1559 | |||
1560 | drm_encoder_cleanup(encoder); | ||
1561 | kfree(intel_encoder); | ||
1562 | } | ||
1563 | |||
1564 | static const struct drm_encoder_funcs intel_tv_enc_funcs = { | 1562 | static const struct drm_encoder_funcs intel_tv_enc_funcs = { |
1565 | .destroy = intel_tv_enc_destroy, | 1563 | .destroy = intel_encoder_destroy, |
1566 | }; | 1564 | }; |
1567 | 1565 | ||
1568 | /* | 1566 | /* |
@@ -1606,9 +1604,9 @@ intel_tv_init(struct drm_device *dev) | |||
1606 | { | 1604 | { |
1607 | struct drm_i915_private *dev_priv = dev->dev_private; | 1605 | struct drm_i915_private *dev_priv = dev->dev_private; |
1608 | struct drm_connector *connector; | 1606 | struct drm_connector *connector; |
1607 | struct intel_tv *intel_tv; | ||
1609 | struct intel_encoder *intel_encoder; | 1608 | struct intel_encoder *intel_encoder; |
1610 | struct intel_connector *intel_connector; | 1609 | struct intel_connector *intel_connector; |
1611 | struct intel_tv_priv *tv_priv; | ||
1612 | u32 tv_dac_on, tv_dac_off, save_tv_dac; | 1610 | u32 tv_dac_on, tv_dac_off, save_tv_dac; |
1613 | char **tv_format_names; | 1611 | char **tv_format_names; |
1614 | int i, initial_mode = 0; | 1612 | int i, initial_mode = 0; |
@@ -1647,18 +1645,18 @@ intel_tv_init(struct drm_device *dev) | |||
1647 | (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) | 1645 | (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) |
1648 | return; | 1646 | return; |
1649 | 1647 | ||
1650 | intel_encoder = kzalloc(sizeof(struct intel_encoder) + | 1648 | intel_tv = kzalloc(sizeof(struct intel_tv), GFP_KERNEL); |
1651 | sizeof(struct intel_tv_priv), GFP_KERNEL); | 1649 | if (!intel_tv) { |
1652 | if (!intel_encoder) { | ||
1653 | return; | 1650 | return; |
1654 | } | 1651 | } |
1655 | 1652 | ||
1656 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 1653 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
1657 | if (!intel_connector) { | 1654 | if (!intel_connector) { |
1658 | kfree(intel_encoder); | 1655 | kfree(intel_tv); |
1659 | return; | 1656 | return; |
1660 | } | 1657 | } |
1661 | 1658 | ||
1659 | intel_encoder = &intel_tv->base; | ||
1662 | connector = &intel_connector->base; | 1660 | connector = &intel_connector->base; |
1663 | 1661 | ||
1664 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, | 1662 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, |
@@ -1668,22 +1666,20 @@ intel_tv_init(struct drm_device *dev) | |||
1668 | DRM_MODE_ENCODER_TVDAC); | 1666 | DRM_MODE_ENCODER_TVDAC); |
1669 | 1667 | ||
1670 | drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc); | 1668 | drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc); |
1671 | tv_priv = (struct intel_tv_priv *)(intel_encoder + 1); | ||
1672 | intel_encoder->type = INTEL_OUTPUT_TVOUT; | 1669 | intel_encoder->type = INTEL_OUTPUT_TVOUT; |
1673 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 1670 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
1674 | intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT); | 1671 | intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT); |
1675 | intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1)); | 1672 | intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1)); |
1676 | intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); | 1673 | intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); |
1677 | intel_encoder->dev_priv = tv_priv; | 1674 | intel_tv->type = DRM_MODE_CONNECTOR_Unknown; |
1678 | tv_priv->type = DRM_MODE_CONNECTOR_Unknown; | ||
1679 | 1675 | ||
1680 | /* BIOS margin values */ | 1676 | /* BIOS margin values */ |
1681 | tv_priv->margin[TV_MARGIN_LEFT] = 54; | 1677 | intel_tv->margin[TV_MARGIN_LEFT] = 54; |
1682 | tv_priv->margin[TV_MARGIN_TOP] = 36; | 1678 | intel_tv->margin[TV_MARGIN_TOP] = 36; |
1683 | tv_priv->margin[TV_MARGIN_RIGHT] = 46; | 1679 | intel_tv->margin[TV_MARGIN_RIGHT] = 46; |
1684 | tv_priv->margin[TV_MARGIN_BOTTOM] = 37; | 1680 | intel_tv->margin[TV_MARGIN_BOTTOM] = 37; |
1685 | 1681 | ||
1686 | tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); | 1682 | intel_tv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); |
1687 | 1683 | ||
1688 | drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs); | 1684 | drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs); |
1689 | drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); | 1685 | drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); |
@@ -1703,16 +1699,16 @@ intel_tv_init(struct drm_device *dev) | |||
1703 | initial_mode); | 1699 | initial_mode); |
1704 | drm_connector_attach_property(connector, | 1700 | drm_connector_attach_property(connector, |
1705 | dev->mode_config.tv_left_margin_property, | 1701 | dev->mode_config.tv_left_margin_property, |
1706 | tv_priv->margin[TV_MARGIN_LEFT]); | 1702 | intel_tv->margin[TV_MARGIN_LEFT]); |
1707 | drm_connector_attach_property(connector, | 1703 | drm_connector_attach_property(connector, |
1708 | dev->mode_config.tv_top_margin_property, | 1704 | dev->mode_config.tv_top_margin_property, |
1709 | tv_priv->margin[TV_MARGIN_TOP]); | 1705 | intel_tv->margin[TV_MARGIN_TOP]); |
1710 | drm_connector_attach_property(connector, | 1706 | drm_connector_attach_property(connector, |
1711 | dev->mode_config.tv_right_margin_property, | 1707 | dev->mode_config.tv_right_margin_property, |
1712 | tv_priv->margin[TV_MARGIN_RIGHT]); | 1708 | intel_tv->margin[TV_MARGIN_RIGHT]); |
1713 | drm_connector_attach_property(connector, | 1709 | drm_connector_attach_property(connector, |
1714 | dev->mode_config.tv_bottom_margin_property, | 1710 | dev->mode_config.tv_bottom_margin_property, |
1715 | tv_priv->margin[TV_MARGIN_BOTTOM]); | 1711 | intel_tv->margin[TV_MARGIN_BOTTOM]); |
1716 | out: | 1712 | out: |
1717 | drm_sysfs_connector_add(connector); | 1713 | drm_sysfs_connector_add(connector); |
1718 | } | 1714 | } |
diff --git a/drivers/gpu/drm/mga/mga_state.c b/drivers/gpu/drm/mga/mga_state.c index fff82045c42..9ce2827f8c0 100644 --- a/drivers/gpu/drm/mga/mga_state.c +++ b/drivers/gpu/drm/mga/mga_state.c | |||
@@ -1085,19 +1085,19 @@ file_priv) | |||
1085 | } | 1085 | } |
1086 | 1086 | ||
1087 | struct drm_ioctl_desc mga_ioctls[] = { | 1087 | struct drm_ioctl_desc mga_ioctls[] = { |
1088 | DRM_IOCTL_DEF(DRM_MGA_INIT, mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1088 | DRM_IOCTL_DEF_DRV(MGA_INIT, mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1089 | DRM_IOCTL_DEF(DRM_MGA_FLUSH, mga_dma_flush, DRM_AUTH), | 1089 | DRM_IOCTL_DEF_DRV(MGA_FLUSH, mga_dma_flush, DRM_AUTH), |
1090 | DRM_IOCTL_DEF(DRM_MGA_RESET, mga_dma_reset, DRM_AUTH), | 1090 | DRM_IOCTL_DEF_DRV(MGA_RESET, mga_dma_reset, DRM_AUTH), |
1091 | DRM_IOCTL_DEF(DRM_MGA_SWAP, mga_dma_swap, DRM_AUTH), | 1091 | DRM_IOCTL_DEF_DRV(MGA_SWAP, mga_dma_swap, DRM_AUTH), |
1092 | DRM_IOCTL_DEF(DRM_MGA_CLEAR, mga_dma_clear, DRM_AUTH), | 1092 | DRM_IOCTL_DEF_DRV(MGA_CLEAR, mga_dma_clear, DRM_AUTH), |
1093 | DRM_IOCTL_DEF(DRM_MGA_VERTEX, mga_dma_vertex, DRM_AUTH), | 1093 | DRM_IOCTL_DEF_DRV(MGA_VERTEX, mga_dma_vertex, DRM_AUTH), |
1094 | DRM_IOCTL_DEF(DRM_MGA_INDICES, mga_dma_indices, DRM_AUTH), | 1094 | DRM_IOCTL_DEF_DRV(MGA_INDICES, mga_dma_indices, DRM_AUTH), |
1095 | DRM_IOCTL_DEF(DRM_MGA_ILOAD, mga_dma_iload, DRM_AUTH), | 1095 | DRM_IOCTL_DEF_DRV(MGA_ILOAD, mga_dma_iload, DRM_AUTH), |
1096 | DRM_IOCTL_DEF(DRM_MGA_BLIT, mga_dma_blit, DRM_AUTH), | 1096 | DRM_IOCTL_DEF_DRV(MGA_BLIT, mga_dma_blit, DRM_AUTH), |
1097 | DRM_IOCTL_DEF(DRM_MGA_GETPARAM, mga_getparam, DRM_AUTH), | 1097 | DRM_IOCTL_DEF_DRV(MGA_GETPARAM, mga_getparam, DRM_AUTH), |
1098 | DRM_IOCTL_DEF(DRM_MGA_SET_FENCE, mga_set_fence, DRM_AUTH), | 1098 | DRM_IOCTL_DEF_DRV(MGA_SET_FENCE, mga_set_fence, DRM_AUTH), |
1099 | DRM_IOCTL_DEF(DRM_MGA_WAIT_FENCE, mga_wait_fence, DRM_AUTH), | 1099 | DRM_IOCTL_DEF_DRV(MGA_WAIT_FENCE, mga_wait_fence, DRM_AUTH), |
1100 | DRM_IOCTL_DEF(DRM_MGA_DMA_BOOTSTRAP, mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1100 | DRM_IOCTL_DEF_DRV(MGA_DMA_BOOTSTRAP, mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1101 | }; | 1101 | }; |
1102 | 1102 | ||
1103 | int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls); | 1103 | int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 0b69a9628c9..974b0f8ae04 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
@@ -2166,7 +2166,7 @@ peek_fb(struct drm_device *dev, struct io_mapping *fb, | |||
2166 | uint32_t val = 0; | 2166 | uint32_t val = 0; |
2167 | 2167 | ||
2168 | if (off < pci_resource_len(dev->pdev, 1)) { | 2168 | if (off < pci_resource_len(dev->pdev, 1)) { |
2169 | uint32_t __iomem *p = | 2169 | uint8_t __iomem *p = |
2170 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0); | 2170 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0); |
2171 | 2171 | ||
2172 | val = ioread32(p + (off & ~PAGE_MASK)); | 2172 | val = ioread32(p + (off & ~PAGE_MASK)); |
@@ -2182,7 +2182,7 @@ poke_fb(struct drm_device *dev, struct io_mapping *fb, | |||
2182 | uint32_t off, uint32_t val) | 2182 | uint32_t off, uint32_t val) |
2183 | { | 2183 | { |
2184 | if (off < pci_resource_len(dev->pdev, 1)) { | 2184 | if (off < pci_resource_len(dev->pdev, 1)) { |
2185 | uint32_t __iomem *p = | 2185 | uint8_t __iomem *p = |
2186 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0); | 2186 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0); |
2187 | 2187 | ||
2188 | iowrite32(val, p + (off & ~PAGE_MASK)); | 2188 | iowrite32(val, p + (off & ~PAGE_MASK)); |
@@ -3869,27 +3869,10 @@ static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_entr | |||
3869 | } | 3869 | } |
3870 | #ifdef __powerpc__ | 3870 | #ifdef __powerpc__ |
3871 | /* Powerbook specific quirks */ | 3871 | /* Powerbook specific quirks */ |
3872 | if ((dev->pci_device & 0xffff) == 0x0179 || | 3872 | if (script == LVDS_RESET && |
3873 | (dev->pci_device & 0xffff) == 0x0189 || | 3873 | (dev->pci_device == 0x0179 || dev->pci_device == 0x0189 || |
3874 | (dev->pci_device & 0xffff) == 0x0329) { | 3874 | dev->pci_device == 0x0329)) |
3875 | if (script == LVDS_RESET) { | 3875 | nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72); |
3876 | nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72); | ||
3877 | |||
3878 | } else if (script == LVDS_PANEL_ON) { | ||
3879 | bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL, | ||
3880 | bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL) | ||
3881 | | (1 << 31)); | ||
3882 | bios_wr32(bios, NV_PCRTC_GPIO_EXT, | ||
3883 | bios_rd32(bios, NV_PCRTC_GPIO_EXT) | 1); | ||
3884 | |||
3885 | } else if (script == LVDS_PANEL_OFF) { | ||
3886 | bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL, | ||
3887 | bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL) | ||
3888 | & ~(1 << 31)); | ||
3889 | bios_wr32(bios, NV_PCRTC_GPIO_EXT, | ||
3890 | bios_rd32(bios, NV_PCRTC_GPIO_EXT) & ~3); | ||
3891 | } | ||
3892 | } | ||
3893 | #endif | 3876 | #endif |
3894 | 3877 | ||
3895 | return 0; | 3878 | return 0; |
@@ -4381,11 +4364,8 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b | |||
4381 | * | 4364 | * |
4382 | * For the moment, a quirk will do :) | 4365 | * For the moment, a quirk will do :) |
4383 | */ | 4366 | */ |
4384 | if ((dev->pdev->device == 0x01d7) && | 4367 | if (nv_match_device(dev, 0x01d7, 0x1028, 0x01c2)) |
4385 | (dev->pdev->subsystem_vendor == 0x1028) && | ||
4386 | (dev->pdev->subsystem_device == 0x01c2)) { | ||
4387 | bios->fp.duallink_transition_clk = 80000; | 4368 | bios->fp.duallink_transition_clk = 80000; |
4388 | } | ||
4389 | 4369 | ||
4390 | /* set dual_link flag for EDID case */ | 4370 | /* set dual_link flag for EDID case */ |
4391 | if (pxclk && (chip_version < 0x25 || chip_version > 0x28)) | 4371 | if (pxclk && (chip_version < 0x25 || chip_version > 0x28)) |
@@ -4587,7 +4567,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
4587 | return 1; | 4567 | return 1; |
4588 | } | 4568 | } |
4589 | 4569 | ||
4590 | NV_TRACE(dev, "0x%04X: parsing output script 0\n", script); | 4570 | NV_DEBUG_KMS(dev, "0x%04X: parsing output script 0\n", script); |
4591 | nouveau_bios_run_init_table(dev, script, dcbent); | 4571 | nouveau_bios_run_init_table(dev, script, dcbent); |
4592 | } else | 4572 | } else |
4593 | if (pxclk == -1) { | 4573 | if (pxclk == -1) { |
@@ -4597,7 +4577,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
4597 | return 1; | 4577 | return 1; |
4598 | } | 4578 | } |
4599 | 4579 | ||
4600 | NV_TRACE(dev, "0x%04X: parsing output script 1\n", script); | 4580 | NV_DEBUG_KMS(dev, "0x%04X: parsing output script 1\n", script); |
4601 | nouveau_bios_run_init_table(dev, script, dcbent); | 4581 | nouveau_bios_run_init_table(dev, script, dcbent); |
4602 | } else | 4582 | } else |
4603 | if (pxclk == -2) { | 4583 | if (pxclk == -2) { |
@@ -4610,7 +4590,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
4610 | return 1; | 4590 | return 1; |
4611 | } | 4591 | } |
4612 | 4592 | ||
4613 | NV_TRACE(dev, "0x%04X: parsing output script 2\n", script); | 4593 | NV_DEBUG_KMS(dev, "0x%04X: parsing output script 2\n", script); |
4614 | nouveau_bios_run_init_table(dev, script, dcbent); | 4594 | nouveau_bios_run_init_table(dev, script, dcbent); |
4615 | } else | 4595 | } else |
4616 | if (pxclk > 0) { | 4596 | if (pxclk > 0) { |
@@ -4622,7 +4602,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
4622 | return 1; | 4602 | return 1; |
4623 | } | 4603 | } |
4624 | 4604 | ||
4625 | NV_TRACE(dev, "0x%04X: parsing clock script 0\n", script); | 4605 | NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 0\n", script); |
4626 | nouveau_bios_run_init_table(dev, script, dcbent); | 4606 | nouveau_bios_run_init_table(dev, script, dcbent); |
4627 | } else | 4607 | } else |
4628 | if (pxclk < 0) { | 4608 | if (pxclk < 0) { |
@@ -4634,7 +4614,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
4634 | return 1; | 4614 | return 1; |
4635 | } | 4615 | } |
4636 | 4616 | ||
4637 | NV_TRACE(dev, "0x%04X: parsing clock script 1\n", script); | 4617 | NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 1\n", script); |
4638 | nouveau_bios_run_init_table(dev, script, dcbent); | 4618 | nouveau_bios_run_init_table(dev, script, dcbent); |
4639 | } | 4619 | } |
4640 | 4620 | ||
@@ -5357,19 +5337,17 @@ static int parse_bit_tmds_tbl_entry(struct drm_device *dev, struct nvbios *bios, | |||
5357 | } | 5337 | } |
5358 | 5338 | ||
5359 | tmdstableptr = ROM16(bios->data[bitentry->offset]); | 5339 | tmdstableptr = ROM16(bios->data[bitentry->offset]); |
5360 | 5340 | if (!tmdstableptr) { | |
5361 | if (tmdstableptr == 0x0) { | ||
5362 | NV_ERROR(dev, "Pointer to TMDS table invalid\n"); | 5341 | NV_ERROR(dev, "Pointer to TMDS table invalid\n"); |
5363 | return -EINVAL; | 5342 | return -EINVAL; |
5364 | } | 5343 | } |
5365 | 5344 | ||
5345 | NV_INFO(dev, "TMDS table version %d.%d\n", | ||
5346 | bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf); | ||
5347 | |||
5366 | /* nv50+ has v2.0, but we don't parse it atm */ | 5348 | /* nv50+ has v2.0, but we don't parse it atm */ |
5367 | if (bios->data[tmdstableptr] != 0x11) { | 5349 | if (bios->data[tmdstableptr] != 0x11) |
5368 | NV_WARN(dev, | ||
5369 | "TMDS table revision %d.%d not currently supported\n", | ||
5370 | bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf); | ||
5371 | return -ENOSYS; | 5350 | return -ENOSYS; |
5372 | } | ||
5373 | 5351 | ||
5374 | /* | 5352 | /* |
5375 | * These two scripts are odd: they don't seem to get run even when | 5353 | * These two scripts are odd: they don't seem to get run even when |
@@ -5809,6 +5787,20 @@ parse_dcb_gpio_table(struct nvbios *bios) | |||
5809 | gpio->line = tvdac_gpio[1] >> 4; | 5787 | gpio->line = tvdac_gpio[1] >> 4; |
5810 | gpio->invert = tvdac_gpio[0] & 2; | 5788 | gpio->invert = tvdac_gpio[0] & 2; |
5811 | } | 5789 | } |
5790 | } else { | ||
5791 | /* | ||
5792 | * No systematic way to store GPIO info on pre-v2.2 | ||
5793 | * DCBs, try to match the PCI device IDs. | ||
5794 | */ | ||
5795 | |||
5796 | /* Apple iMac G4 NV18 */ | ||
5797 | if (nv_match_device(dev, 0x0189, 0x10de, 0x0010)) { | ||
5798 | struct dcb_gpio_entry *gpio = new_gpio_entry(bios); | ||
5799 | |||
5800 | gpio->tag = DCB_GPIO_TVDAC0; | ||
5801 | gpio->line = 4; | ||
5802 | } | ||
5803 | |||
5812 | } | 5804 | } |
5813 | 5805 | ||
5814 | if (!gpio_table_ptr) | 5806 | if (!gpio_table_ptr) |
@@ -5884,9 +5876,7 @@ apply_dcb_connector_quirks(struct nvbios *bios, int idx) | |||
5884 | struct drm_device *dev = bios->dev; | 5876 | struct drm_device *dev = bios->dev; |
5885 | 5877 | ||
5886 | /* Gigabyte NX85T */ | 5878 | /* Gigabyte NX85T */ |
5887 | if ((dev->pdev->device == 0x0421) && | 5879 | if (nv_match_device(dev, 0x0421, 0x1458, 0x344c)) { |
5888 | (dev->pdev->subsystem_vendor == 0x1458) && | ||
5889 | (dev->pdev->subsystem_device == 0x344c)) { | ||
5890 | if (cte->type == DCB_CONNECTOR_HDMI_1) | 5880 | if (cte->type == DCB_CONNECTOR_HDMI_1) |
5891 | cte->type = DCB_CONNECTOR_DVI_I; | 5881 | cte->type = DCB_CONNECTOR_DVI_I; |
5892 | } | 5882 | } |
@@ -6139,7 +6129,7 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, | |||
6139 | entry->tmdsconf.slave_addr = (conf & 0x00000070) >> 4; | 6129 | entry->tmdsconf.slave_addr = (conf & 0x00000070) >> 4; |
6140 | 6130 | ||
6141 | break; | 6131 | break; |
6142 | case 0xe: | 6132 | case OUTPUT_EOL: |
6143 | /* weird g80 mobile type that "nv" treats as a terminator */ | 6133 | /* weird g80 mobile type that "nv" treats as a terminator */ |
6144 | dcb->entries--; | 6134 | dcb->entries--; |
6145 | return false; | 6135 | return false; |
@@ -6176,22 +6166,14 @@ parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb, | |||
6176 | entry->type = OUTPUT_TV; | 6166 | entry->type = OUTPUT_TV; |
6177 | break; | 6167 | break; |
6178 | case 2: | 6168 | case 2: |
6179 | case 3: | ||
6180 | entry->type = OUTPUT_LVDS; | ||
6181 | break; | ||
6182 | case 4: | 6169 | case 4: |
6183 | switch ((conn & 0x000000f0) >> 4) { | 6170 | if (conn & 0x10) |
6184 | case 0: | ||
6185 | entry->type = OUTPUT_TMDS; | ||
6186 | break; | ||
6187 | case 1: | ||
6188 | entry->type = OUTPUT_LVDS; | 6171 | entry->type = OUTPUT_LVDS; |
6189 | break; | 6172 | else |
6190 | default: | 6173 | entry->type = OUTPUT_TMDS; |
6191 | NV_ERROR(dev, "Unknown DCB subtype 4/%d\n", | 6174 | break; |
6192 | (conn & 0x000000f0) >> 4); | 6175 | case 3: |
6193 | return false; | 6176 | entry->type = OUTPUT_LVDS; |
6194 | } | ||
6195 | break; | 6177 | break; |
6196 | default: | 6178 | default: |
6197 | NV_ERROR(dev, "Unknown DCB type %d\n", conn & 0x0000000f); | 6179 | NV_ERROR(dev, "Unknown DCB type %d\n", conn & 0x0000000f); |
@@ -6307,9 +6289,7 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf) | |||
6307 | * nasty problems until this is sorted (assuming it's not a | 6289 | * nasty problems until this is sorted (assuming it's not a |
6308 | * VBIOS bug). | 6290 | * VBIOS bug). |
6309 | */ | 6291 | */ |
6310 | if ((dev->pdev->device == 0x040d) && | 6292 | if (nv_match_device(dev, 0x040d, 0x1028, 0x019b)) { |
6311 | (dev->pdev->subsystem_vendor == 0x1028) && | ||
6312 | (dev->pdev->subsystem_device == 0x019b)) { | ||
6313 | if (*conn == 0x02026312 && *conf == 0x00000020) | 6293 | if (*conn == 0x02026312 && *conf == 0x00000020) |
6314 | return false; | 6294 | return false; |
6315 | } | 6295 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index fd14dfd3d78..c1de2f3fcb0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h | |||
@@ -95,6 +95,7 @@ enum dcb_type { | |||
95 | OUTPUT_TMDS = 2, | 95 | OUTPUT_TMDS = 2, |
96 | OUTPUT_LVDS = 3, | 96 | OUTPUT_LVDS = 3, |
97 | OUTPUT_DP = 6, | 97 | OUTPUT_DP = 6, |
98 | OUTPUT_EOL = 14, /* DCB 4.0+, appears to be end-of-list */ | ||
98 | OUTPUT_ANY = -1 | 99 | OUTPUT_ANY = -1 |
99 | }; | 100 | }; |
100 | 101 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 84f85183d04..f6f44779d82 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -36,6 +36,21 @@ | |||
36 | #include <linux/log2.h> | 36 | #include <linux/log2.h> |
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | 38 | ||
39 | int | ||
40 | nouveau_bo_sync_gpu(struct nouveau_bo *nvbo, struct nouveau_channel *chan) | ||
41 | { | ||
42 | struct nouveau_fence *prev_fence = nvbo->bo.sync_obj; | ||
43 | int ret; | ||
44 | |||
45 | if (!prev_fence || nouveau_fence_channel(prev_fence) == chan) | ||
46 | return 0; | ||
47 | |||
48 | spin_lock(&nvbo->bo.lock); | ||
49 | ret = ttm_bo_wait(&nvbo->bo, false, false, false); | ||
50 | spin_unlock(&nvbo->bo.lock); | ||
51 | return ret; | ||
52 | } | ||
53 | |||
39 | static void | 54 | static void |
40 | nouveau_bo_del_ttm(struct ttm_buffer_object *bo) | 55 | nouveau_bo_del_ttm(struct ttm_buffer_object *bo) |
41 | { | 56 | { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 90fdcda332b..0480f064f2c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c | |||
@@ -426,18 +426,18 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, | |||
426 | ***********************************/ | 426 | ***********************************/ |
427 | 427 | ||
428 | struct drm_ioctl_desc nouveau_ioctls[] = { | 428 | struct drm_ioctl_desc nouveau_ioctls[] = { |
429 | DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH), | 429 | DRM_IOCTL_DEF_DRV(NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH), |
430 | DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 430 | DRM_IOCTL_DEF_DRV(NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
431 | DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH), | 431 | DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH), |
432 | DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH), | 432 | DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH), |
433 | DRM_IOCTL_DEF(DRM_NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH), | 433 | DRM_IOCTL_DEF_DRV(NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH), |
434 | DRM_IOCTL_DEF(DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH), | 434 | DRM_IOCTL_DEF_DRV(NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH), |
435 | DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH), | 435 | DRM_IOCTL_DEF_DRV(NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH), |
436 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH), | 436 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH), |
437 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH), | 437 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH), |
438 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH), | 438 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH), |
439 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH), | 439 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH), |
440 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH), | 440 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH), |
441 | }; | 441 | }; |
442 | 442 | ||
443 | int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); | 443 | int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index b1b22baf142..a1473fff06a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
@@ -104,7 +104,7 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, | |||
104 | int i; | 104 | int i; |
105 | 105 | ||
106 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { | 106 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { |
107 | struct nouveau_i2c_chan *i2c; | 107 | struct nouveau_i2c_chan *i2c = NULL; |
108 | struct nouveau_encoder *nv_encoder; | 108 | struct nouveau_encoder *nv_encoder; |
109 | struct drm_mode_object *obj; | 109 | struct drm_mode_object *obj; |
110 | int id; | 110 | int id; |
@@ -117,7 +117,9 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, | |||
117 | if (!obj) | 117 | if (!obj) |
118 | continue; | 118 | continue; |
119 | nv_encoder = nouveau_encoder(obj_to_encoder(obj)); | 119 | nv_encoder = nouveau_encoder(obj_to_encoder(obj)); |
120 | i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); | 120 | |
121 | if (nv_encoder->dcb->i2c_index < 0xf) | ||
122 | i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); | ||
121 | 123 | ||
122 | if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) { | 124 | if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) { |
123 | *pnv_encoder = nv_encoder; | 125 | *pnv_encoder = nv_encoder; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index e424bf74d70..b1be617373b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -1165,6 +1165,7 @@ extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index); | |||
1165 | extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); | 1165 | extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); |
1166 | extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); | 1166 | extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); |
1167 | extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val); | 1167 | extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val); |
1168 | extern int nouveau_bo_sync_gpu(struct nouveau_bo *, struct nouveau_channel *); | ||
1168 | 1169 | ||
1169 | /* nouveau_fence.c */ | 1170 | /* nouveau_fence.c */ |
1170 | struct nouveau_fence; | 1171 | struct nouveau_fence; |
@@ -1388,6 +1389,15 @@ nv_two_reg_pll(struct drm_device *dev) | |||
1388 | return false; | 1389 | return false; |
1389 | } | 1390 | } |
1390 | 1391 | ||
1392 | static inline bool | ||
1393 | nv_match_device(struct drm_device *dev, unsigned device, | ||
1394 | unsigned sub_vendor, unsigned sub_device) | ||
1395 | { | ||
1396 | return dev->pdev->device == device && | ||
1397 | dev->pdev->subsystem_vendor == sub_vendor && | ||
1398 | dev->pdev->subsystem_device == sub_device; | ||
1399 | } | ||
1400 | |||
1391 | #define NV_SW 0x0000506e | 1401 | #define NV_SW 0x0000506e |
1392 | #define NV_SW_DMA_SEMAPHORE 0x00000060 | 1402 | #define NV_SW_DMA_SEMAPHORE 0x00000060 |
1393 | #define NV_SW_SEMAPHORE_OFFSET 0x00000064 | 1403 | #define NV_SW_SEMAPHORE_OFFSET 0x00000064 |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 6b208ffafa8..87ac21ec23d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c | |||
@@ -64,16 +64,17 @@ nouveau_fence_update(struct nouveau_channel *chan) | |||
64 | struct nouveau_fence *fence; | 64 | struct nouveau_fence *fence; |
65 | uint32_t sequence; | 65 | uint32_t sequence; |
66 | 66 | ||
67 | spin_lock(&chan->fence.lock); | ||
68 | |||
67 | if (USE_REFCNT) | 69 | if (USE_REFCNT) |
68 | sequence = nvchan_rd32(chan, 0x48); | 70 | sequence = nvchan_rd32(chan, 0x48); |
69 | else | 71 | else |
70 | sequence = atomic_read(&chan->fence.last_sequence_irq); | 72 | sequence = atomic_read(&chan->fence.last_sequence_irq); |
71 | 73 | ||
72 | if (chan->fence.sequence_ack == sequence) | 74 | if (chan->fence.sequence_ack == sequence) |
73 | return; | 75 | goto out; |
74 | chan->fence.sequence_ack = sequence; | 76 | chan->fence.sequence_ack = sequence; |
75 | 77 | ||
76 | spin_lock(&chan->fence.lock); | ||
77 | list_for_each_safe(entry, tmp, &chan->fence.pending) { | 78 | list_for_each_safe(entry, tmp, &chan->fence.pending) { |
78 | fence = list_entry(entry, struct nouveau_fence, entry); | 79 | fence = list_entry(entry, struct nouveau_fence, entry); |
79 | 80 | ||
@@ -85,6 +86,7 @@ nouveau_fence_update(struct nouveau_channel *chan) | |||
85 | if (sequence == chan->fence.sequence_ack) | 86 | if (sequence == chan->fence.sequence_ack) |
86 | break; | 87 | break; |
87 | } | 88 | } |
89 | out: | ||
88 | spin_unlock(&chan->fence.lock); | 90 | spin_unlock(&chan->fence.lock); |
89 | } | 91 | } |
90 | 92 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 0f417ac1b69..ead7b8fc53f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
@@ -245,7 +245,7 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence) | |||
245 | list_del(&nvbo->entry); | 245 | list_del(&nvbo->entry); |
246 | nvbo->reserved_by = NULL; | 246 | nvbo->reserved_by = NULL; |
247 | ttm_bo_unreserve(&nvbo->bo); | 247 | ttm_bo_unreserve(&nvbo->bo); |
248 | drm_gem_object_unreference(nvbo->gem); | 248 | drm_gem_object_unreference_unlocked(nvbo->gem); |
249 | } | 249 | } |
250 | } | 250 | } |
251 | 251 | ||
@@ -300,7 +300,7 @@ retry: | |||
300 | validate_fini(op, NULL); | 300 | validate_fini(op, NULL); |
301 | if (ret == -EAGAIN) | 301 | if (ret == -EAGAIN) |
302 | ret = ttm_bo_wait_unreserved(&nvbo->bo, false); | 302 | ret = ttm_bo_wait_unreserved(&nvbo->bo, false); |
303 | drm_gem_object_unreference(gem); | 303 | drm_gem_object_unreference_unlocked(gem); |
304 | if (ret) { | 304 | if (ret) { |
305 | NV_ERROR(dev, "fail reserve\n"); | 305 | NV_ERROR(dev, "fail reserve\n"); |
306 | return ret; | 306 | return ret; |
@@ -337,7 +337,9 @@ retry: | |||
337 | return -EINVAL; | 337 | return -EINVAL; |
338 | } | 338 | } |
339 | 339 | ||
340 | mutex_unlock(&drm_global_mutex); | ||
340 | ret = ttm_bo_wait_cpu(&nvbo->bo, false); | 341 | ret = ttm_bo_wait_cpu(&nvbo->bo, false); |
342 | mutex_lock(&drm_global_mutex); | ||
341 | if (ret) { | 343 | if (ret) { |
342 | NV_ERROR(dev, "fail wait_cpu\n"); | 344 | NV_ERROR(dev, "fail wait_cpu\n"); |
343 | return ret; | 345 | return ret; |
@@ -361,16 +363,11 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
361 | 363 | ||
362 | list_for_each_entry(nvbo, list, entry) { | 364 | list_for_each_entry(nvbo, list, entry) { |
363 | struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; | 365 | struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; |
364 | struct nouveau_fence *prev_fence = nvbo->bo.sync_obj; | ||
365 | 366 | ||
366 | if (prev_fence && nouveau_fence_channel(prev_fence) != chan) { | 367 | ret = nouveau_bo_sync_gpu(nvbo, chan); |
367 | spin_lock(&nvbo->bo.lock); | 368 | if (unlikely(ret)) { |
368 | ret = ttm_bo_wait(&nvbo->bo, false, false, false); | 369 | NV_ERROR(dev, "fail pre-validate sync\n"); |
369 | spin_unlock(&nvbo->bo.lock); | 370 | return ret; |
370 | if (unlikely(ret)) { | ||
371 | NV_ERROR(dev, "fail wait other chan\n"); | ||
372 | return ret; | ||
373 | } | ||
374 | } | 371 | } |
375 | 372 | ||
376 | ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains, | 373 | ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains, |
@@ -381,7 +378,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
381 | return ret; | 378 | return ret; |
382 | } | 379 | } |
383 | 380 | ||
384 | nvbo->channel = chan; | 381 | nvbo->channel = (b->read_domains & (1 << 31)) ? NULL : chan; |
385 | ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement, | 382 | ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement, |
386 | false, false, false); | 383 | false, false, false); |
387 | nvbo->channel = NULL; | 384 | nvbo->channel = NULL; |
@@ -390,6 +387,12 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
390 | return ret; | 387 | return ret; |
391 | } | 388 | } |
392 | 389 | ||
390 | ret = nouveau_bo_sync_gpu(nvbo, chan); | ||
391 | if (unlikely(ret)) { | ||
392 | NV_ERROR(dev, "fail post-validate sync\n"); | ||
393 | return ret; | ||
394 | } | ||
395 | |||
393 | if (nvbo->bo.offset == b->presumed.offset && | 396 | if (nvbo->bo.offset == b->presumed.offset && |
394 | ((nvbo->bo.mem.mem_type == TTM_PL_VRAM && | 397 | ((nvbo->bo.mem.mem_type == TTM_PL_VRAM && |
395 | b->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM) || | 398 | b->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM) || |
@@ -613,7 +616,20 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, | |||
613 | return PTR_ERR(bo); | 616 | return PTR_ERR(bo); |
614 | } | 617 | } |
615 | 618 | ||
616 | mutex_lock(&dev->struct_mutex); | 619 | /* Mark push buffers as being used on PFIFO, the validation code |
620 | * will then make sure that if the pushbuf bo moves, that they | ||
621 | * happen on the kernel channel, which will in turn cause a sync | ||
622 | * to happen before we try and submit the push buffer. | ||
623 | */ | ||
624 | for (i = 0; i < req->nr_push; i++) { | ||
625 | if (push[i].bo_index >= req->nr_buffers) { | ||
626 | NV_ERROR(dev, "push %d buffer not in list\n", i); | ||
627 | ret = -EINVAL; | ||
628 | goto out; | ||
629 | } | ||
630 | |||
631 | bo[push[i].bo_index].read_domains |= (1 << 31); | ||
632 | } | ||
617 | 633 | ||
618 | /* Validate buffer list */ | 634 | /* Validate buffer list */ |
619 | ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers, | 635 | ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers, |
@@ -647,7 +663,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, | |||
647 | push[i].length); | 663 | push[i].length); |
648 | } | 664 | } |
649 | } else | 665 | } else |
650 | if (dev_priv->card_type >= NV_20) { | 666 | if (dev_priv->chipset >= 0x25) { |
651 | ret = RING_SPACE(chan, req->nr_push * 2); | 667 | ret = RING_SPACE(chan, req->nr_push * 2); |
652 | if (ret) { | 668 | if (ret) { |
653 | NV_ERROR(dev, "cal_space: %d\n", ret); | 669 | NV_ERROR(dev, "cal_space: %d\n", ret); |
@@ -713,7 +729,6 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, | |||
713 | out: | 729 | out: |
714 | validate_fini(&op, fence); | 730 | validate_fini(&op, fence); |
715 | nouveau_fence_unref((void**)&fence); | 731 | nouveau_fence_unref((void**)&fence); |
716 | mutex_unlock(&dev->struct_mutex); | ||
717 | kfree(bo); | 732 | kfree(bo); |
718 | kfree(push); | 733 | kfree(push); |
719 | 734 | ||
@@ -722,7 +737,7 @@ out_next: | |||
722 | req->suffix0 = 0x00000000; | 737 | req->suffix0 = 0x00000000; |
723 | req->suffix1 = 0x00000000; | 738 | req->suffix1 = 0x00000000; |
724 | } else | 739 | } else |
725 | if (dev_priv->card_type >= NV_20) { | 740 | if (dev_priv->chipset >= 0x25) { |
726 | req->suffix0 = 0x00020000; | 741 | req->suffix0 = 0x00020000; |
727 | req->suffix1 = 0x00000000; | 742 | req->suffix1 = 0x00000000; |
728 | } else { | 743 | } else { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index 0bd407ca3d4..84614858728 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c | |||
@@ -163,7 +163,7 @@ nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index) | |||
163 | if (entry->chan) | 163 | if (entry->chan) |
164 | return -EEXIST; | 164 | return -EEXIST; |
165 | 165 | ||
166 | if (dev_priv->card_type == NV_C0 && entry->read >= NV50_I2C_PORTS) { | 166 | if (dev_priv->card_type >= NV_50 && entry->read >= NV50_I2C_PORTS) { |
167 | NV_ERROR(dev, "unknown i2c port %d\n", entry->read); | 167 | NV_ERROR(dev, "unknown i2c port %d\n", entry->read); |
168 | return -EINVAL; | 168 | return -EINVAL; |
169 | } | 169 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 491767fe4fc..6b9187d7f67 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c | |||
@@ -214,6 +214,7 @@ int | |||
214 | nouveau_sgdma_init(struct drm_device *dev) | 214 | nouveau_sgdma_init(struct drm_device *dev) |
215 | { | 215 | { |
216 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 216 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
217 | struct pci_dev *pdev = dev->pdev; | ||
217 | struct nouveau_gpuobj *gpuobj = NULL; | 218 | struct nouveau_gpuobj *gpuobj = NULL; |
218 | uint32_t aper_size, obj_size; | 219 | uint32_t aper_size, obj_size; |
219 | int i, ret; | 220 | int i, ret; |
@@ -239,10 +240,19 @@ nouveau_sgdma_init(struct drm_device *dev) | |||
239 | 240 | ||
240 | dev_priv->gart_info.sg_dummy_page = | 241 | dev_priv->gart_info.sg_dummy_page = |
241 | alloc_page(GFP_KERNEL|__GFP_DMA32); | 242 | alloc_page(GFP_KERNEL|__GFP_DMA32); |
243 | if (!dev_priv->gart_info.sg_dummy_page) { | ||
244 | nouveau_gpuobj_del(dev, &gpuobj); | ||
245 | return -ENOMEM; | ||
246 | } | ||
247 | |||
242 | set_bit(PG_locked, &dev_priv->gart_info.sg_dummy_page->flags); | 248 | set_bit(PG_locked, &dev_priv->gart_info.sg_dummy_page->flags); |
243 | dev_priv->gart_info.sg_dummy_bus = | 249 | dev_priv->gart_info.sg_dummy_bus = |
244 | pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0, | 250 | pci_map_page(pdev, dev_priv->gart_info.sg_dummy_page, 0, |
245 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | 251 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
252 | if (pci_dma_mapping_error(pdev, dev_priv->gart_info.sg_dummy_bus)) { | ||
253 | nouveau_gpuobj_del(dev, &gpuobj); | ||
254 | return -EFAULT; | ||
255 | } | ||
246 | 256 | ||
247 | if (dev_priv->card_type < NV_50) { | 257 | if (dev_priv->card_type < NV_50) { |
248 | /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and | 258 | /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and |
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index a5dcf768580..0d3206a7046 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c | |||
@@ -444,6 +444,7 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) | |||
444 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 444 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
445 | struct dcb_entry *dcbe = nv_encoder->dcb; | 445 | struct dcb_entry *dcbe = nv_encoder->dcb; |
446 | int head = nouveau_crtc(encoder->crtc)->index; | 446 | int head = nouveau_crtc(encoder->crtc)->index; |
447 | struct drm_encoder *slave_encoder; | ||
447 | 448 | ||
448 | if (dcbe->type == OUTPUT_TMDS) | 449 | if (dcbe->type == OUTPUT_TMDS) |
449 | run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock); | 450 | run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock); |
@@ -462,9 +463,10 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) | |||
462 | NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000); | 463 | NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000); |
463 | 464 | ||
464 | /* Init external transmitters */ | 465 | /* Init external transmitters */ |
465 | if (get_tmds_slave(encoder)) | 466 | slave_encoder = get_tmds_slave(encoder); |
466 | get_slave_funcs(get_tmds_slave(encoder))->mode_set( | 467 | if (slave_encoder) |
467 | encoder, &nv_encoder->mode, &nv_encoder->mode); | 468 | get_slave_funcs(slave_encoder)->mode_set( |
469 | slave_encoder, &nv_encoder->mode, &nv_encoder->mode); | ||
468 | 470 | ||
469 | helper->dpms(encoder, DRM_MODE_DPMS_ON); | 471 | helper->dpms(encoder, DRM_MODE_DPMS_ON); |
470 | 472 | ||
@@ -473,6 +475,27 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) | |||
473 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); | 475 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); |
474 | } | 476 | } |
475 | 477 | ||
478 | static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode) | ||
479 | { | ||
480 | #ifdef __powerpc__ | ||
481 | struct drm_device *dev = encoder->dev; | ||
482 | |||
483 | /* BIOS scripts usually take care of the backlight, thanks | ||
484 | * Apple for your consistency. | ||
485 | */ | ||
486 | if (dev->pci_device == 0x0179 || dev->pci_device == 0x0189 || | ||
487 | dev->pci_device == 0x0329) { | ||
488 | if (mode == DRM_MODE_DPMS_ON) { | ||
489 | nv_mask(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, 0, 1 << 31); | ||
490 | nv_mask(dev, NV_PCRTC_GPIO_EXT, 3, 1); | ||
491 | } else { | ||
492 | nv_mask(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, 1 << 31, 0); | ||
493 | nv_mask(dev, NV_PCRTC_GPIO_EXT, 3, 0); | ||
494 | } | ||
495 | } | ||
496 | #endif | ||
497 | } | ||
498 | |||
476 | static inline bool is_powersaving_dpms(int mode) | 499 | static inline bool is_powersaving_dpms(int mode) |
477 | { | 500 | { |
478 | return (mode != DRM_MODE_DPMS_ON); | 501 | return (mode != DRM_MODE_DPMS_ON); |
@@ -520,6 +543,7 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
520 | LVDS_PANEL_OFF, 0); | 543 | LVDS_PANEL_OFF, 0); |
521 | } | 544 | } |
522 | 545 | ||
546 | nv04_dfp_update_backlight(encoder, mode); | ||
523 | nv04_dfp_update_fp_control(encoder, mode); | 547 | nv04_dfp_update_fp_control(encoder, mode); |
524 | 548 | ||
525 | if (mode == DRM_MODE_DPMS_ON) | 549 | if (mode == DRM_MODE_DPMS_ON) |
@@ -543,6 +567,7 @@ static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode) | |||
543 | NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n", | 567 | NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n", |
544 | mode, nv_encoder->dcb->index); | 568 | mode, nv_encoder->dcb->index); |
545 | 569 | ||
570 | nv04_dfp_update_backlight(encoder, mode); | ||
546 | nv04_dfp_update_fp_control(encoder, mode); | 571 | nv04_dfp_update_fp_control(encoder, mode); |
547 | } | 572 | } |
548 | 573 | ||
diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 44fefb0c708..13cdc05b7c2 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c | |||
@@ -121,10 +121,14 @@ static bool | |||
121 | get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask) | 121 | get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask) |
122 | { | 122 | { |
123 | /* Zotac FX5200 */ | 123 | /* Zotac FX5200 */ |
124 | if (dev->pdev->device == 0x0322 && | 124 | if (nv_match_device(dev, 0x0322, 0x19da, 0x1035) || |
125 | dev->pdev->subsystem_vendor == 0x19da && | 125 | nv_match_device(dev, 0x0322, 0x19da, 0x2035)) { |
126 | (dev->pdev->subsystem_device == 0x1035 || | 126 | *pin_mask = 0xc; |
127 | dev->pdev->subsystem_device == 0x2035)) { | 127 | return false; |
128 | } | ||
129 | |||
130 | /* MSI nForce2 IGP */ | ||
131 | if (nv_match_device(dev, 0x01f0, 0x1462, 0x5710)) { | ||
128 | *pin_mask = 0xc; | 132 | *pin_mask = 0xc; |
129 | return false; | 133 | return false; |
130 | } | 134 | } |
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index 37c7b48ab24..91ef93cf1f3 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c | |||
@@ -139,6 +139,8 @@ nv50_instmem_init(struct drm_device *dev) | |||
139 | chan->file_priv = (struct drm_file *)-2; | 139 | chan->file_priv = (struct drm_file *)-2; |
140 | dev_priv->fifos[0] = dev_priv->fifos[127] = chan; | 140 | dev_priv->fifos[0] = dev_priv->fifos[127] = chan; |
141 | 141 | ||
142 | INIT_LIST_HEAD(&chan->ramht_refs); | ||
143 | |||
142 | /* Channel's PRAMIN object + heap */ | 144 | /* Channel's PRAMIN object + heap */ |
143 | ret = nouveau_gpuobj_new_fake(dev, 0, c_offset, c_size, 0, | 145 | ret = nouveau_gpuobj_new_fake(dev, 0, c_offset, c_size, 0, |
144 | NULL, &chan->ramin); | 146 | NULL, &chan->ramin); |
@@ -278,7 +280,7 @@ nv50_instmem_init(struct drm_device *dev) | |||
278 | /*XXX: incorrect, but needed to make hash func "work" */ | 280 | /*XXX: incorrect, but needed to make hash func "work" */ |
279 | dev_priv->ramht_offset = 0x10000; | 281 | dev_priv->ramht_offset = 0x10000; |
280 | dev_priv->ramht_bits = 9; | 282 | dev_priv->ramht_bits = 9; |
281 | dev_priv->ramht_size = (1 << dev_priv->ramht_bits); | 283 | dev_priv->ramht_size = (1 << dev_priv->ramht_bits) * 8; |
282 | return 0; | 284 | return 0; |
283 | } | 285 | } |
284 | 286 | ||
diff --git a/drivers/gpu/drm/nouveau/nvc0_instmem.c b/drivers/gpu/drm/nouveau/nvc0_instmem.c index 3ab3cdc4217..6b451f86478 100644 --- a/drivers/gpu/drm/nouveau/nvc0_instmem.c +++ b/drivers/gpu/drm/nouveau/nvc0_instmem.c | |||
@@ -142,14 +142,16 @@ int | |||
142 | nvc0_instmem_suspend(struct drm_device *dev) | 142 | nvc0_instmem_suspend(struct drm_device *dev) |
143 | { | 143 | { |
144 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 144 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
145 | u32 *buf; | ||
145 | int i; | 146 | int i; |
146 | 147 | ||
147 | dev_priv->susres.ramin_copy = vmalloc(65536); | 148 | dev_priv->susres.ramin_copy = vmalloc(65536); |
148 | if (!dev_priv->susres.ramin_copy) | 149 | if (!dev_priv->susres.ramin_copy) |
149 | return -ENOMEM; | 150 | return -ENOMEM; |
151 | buf = dev_priv->susres.ramin_copy; | ||
150 | 152 | ||
151 | for (i = 0x700000; i < 0x710000; i += 4) | 153 | for (i = 0; i < 65536; i += 4) |
152 | dev_priv->susres.ramin_copy[i/4] = nv_rd32(dev, i); | 154 | buf[i/4] = nv_rd32(dev, NV04_PRAMIN + i); |
153 | return 0; | 155 | return 0; |
154 | } | 156 | } |
155 | 157 | ||
@@ -157,14 +159,15 @@ void | |||
157 | nvc0_instmem_resume(struct drm_device *dev) | 159 | nvc0_instmem_resume(struct drm_device *dev) |
158 | { | 160 | { |
159 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 161 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
162 | u32 *buf = dev_priv->susres.ramin_copy; | ||
160 | u64 chan; | 163 | u64 chan; |
161 | int i; | 164 | int i; |
162 | 165 | ||
163 | chan = dev_priv->vram_size - dev_priv->ramin_rsvd_vram; | 166 | chan = dev_priv->vram_size - dev_priv->ramin_rsvd_vram; |
164 | nv_wr32(dev, 0x001700, chan >> 16); | 167 | nv_wr32(dev, 0x001700, chan >> 16); |
165 | 168 | ||
166 | for (i = 0x700000; i < 0x710000; i += 4) | 169 | for (i = 0; i < 65536; i += 4) |
167 | nv_wr32(dev, i, dev_priv->susres.ramin_copy[i/4]); | 170 | nv_wr32(dev, NV04_PRAMIN + i, buf[i/4]); |
168 | vfree(dev_priv->susres.ramin_copy); | 171 | vfree(dev_priv->susres.ramin_copy); |
169 | dev_priv->susres.ramin_copy = NULL; | 172 | dev_priv->susres.ramin_copy = NULL; |
170 | 173 | ||
@@ -221,7 +224,7 @@ nvc0_instmem_init(struct drm_device *dev) | |||
221 | /*XXX: incorrect, but needed to make hash func "work" */ | 224 | /*XXX: incorrect, but needed to make hash func "work" */ |
222 | dev_priv->ramht_offset = 0x10000; | 225 | dev_priv->ramht_offset = 0x10000; |
223 | dev_priv->ramht_bits = 9; | 226 | dev_priv->ramht_bits = 9; |
224 | dev_priv->ramht_size = (1 << dev_priv->ramht_bits); | 227 | dev_priv->ramht_size = (1 << dev_priv->ramht_bits) * 8; |
225 | return 0; | 228 | return 0; |
226 | } | 229 | } |
227 | 230 | ||
diff --git a/drivers/gpu/drm/r128/r128_state.c b/drivers/gpu/drm/r128/r128_state.c index 077af1f2f9b..a9e33ce6591 100644 --- a/drivers/gpu/drm/r128/r128_state.c +++ b/drivers/gpu/drm/r128/r128_state.c | |||
@@ -1639,30 +1639,29 @@ void r128_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) | |||
1639 | r128_do_cleanup_pageflip(dev); | 1639 | r128_do_cleanup_pageflip(dev); |
1640 | } | 1640 | } |
1641 | } | 1641 | } |
1642 | |||
1643 | void r128_driver_lastclose(struct drm_device *dev) | 1642 | void r128_driver_lastclose(struct drm_device *dev) |
1644 | { | 1643 | { |
1645 | r128_do_cleanup_cce(dev); | 1644 | r128_do_cleanup_cce(dev); |
1646 | } | 1645 | } |
1647 | 1646 | ||
1648 | struct drm_ioctl_desc r128_ioctls[] = { | 1647 | struct drm_ioctl_desc r128_ioctls[] = { |
1649 | DRM_IOCTL_DEF(DRM_R128_INIT, r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1648 | DRM_IOCTL_DEF_DRV(R128_INIT, r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1650 | DRM_IOCTL_DEF(DRM_R128_CCE_START, r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1649 | DRM_IOCTL_DEF_DRV(R128_CCE_START, r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1651 | DRM_IOCTL_DEF(DRM_R128_CCE_STOP, r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1650 | DRM_IOCTL_DEF_DRV(R128_CCE_STOP, r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1652 | DRM_IOCTL_DEF(DRM_R128_CCE_RESET, r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1651 | DRM_IOCTL_DEF_DRV(R128_CCE_RESET, r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1653 | DRM_IOCTL_DEF(DRM_R128_CCE_IDLE, r128_cce_idle, DRM_AUTH), | 1652 | DRM_IOCTL_DEF_DRV(R128_CCE_IDLE, r128_cce_idle, DRM_AUTH), |
1654 | DRM_IOCTL_DEF(DRM_R128_RESET, r128_engine_reset, DRM_AUTH), | 1653 | DRM_IOCTL_DEF_DRV(R128_RESET, r128_engine_reset, DRM_AUTH), |
1655 | DRM_IOCTL_DEF(DRM_R128_FULLSCREEN, r128_fullscreen, DRM_AUTH), | 1654 | DRM_IOCTL_DEF_DRV(R128_FULLSCREEN, r128_fullscreen, DRM_AUTH), |
1656 | DRM_IOCTL_DEF(DRM_R128_SWAP, r128_cce_swap, DRM_AUTH), | 1655 | DRM_IOCTL_DEF_DRV(R128_SWAP, r128_cce_swap, DRM_AUTH), |
1657 | DRM_IOCTL_DEF(DRM_R128_FLIP, r128_cce_flip, DRM_AUTH), | 1656 | DRM_IOCTL_DEF_DRV(R128_FLIP, r128_cce_flip, DRM_AUTH), |
1658 | DRM_IOCTL_DEF(DRM_R128_CLEAR, r128_cce_clear, DRM_AUTH), | 1657 | DRM_IOCTL_DEF_DRV(R128_CLEAR, r128_cce_clear, DRM_AUTH), |
1659 | DRM_IOCTL_DEF(DRM_R128_VERTEX, r128_cce_vertex, DRM_AUTH), | 1658 | DRM_IOCTL_DEF_DRV(R128_VERTEX, r128_cce_vertex, DRM_AUTH), |
1660 | DRM_IOCTL_DEF(DRM_R128_INDICES, r128_cce_indices, DRM_AUTH), | 1659 | DRM_IOCTL_DEF_DRV(R128_INDICES, r128_cce_indices, DRM_AUTH), |
1661 | DRM_IOCTL_DEF(DRM_R128_BLIT, r128_cce_blit, DRM_AUTH), | 1660 | DRM_IOCTL_DEF_DRV(R128_BLIT, r128_cce_blit, DRM_AUTH), |
1662 | DRM_IOCTL_DEF(DRM_R128_DEPTH, r128_cce_depth, DRM_AUTH), | 1661 | DRM_IOCTL_DEF_DRV(R128_DEPTH, r128_cce_depth, DRM_AUTH), |
1663 | DRM_IOCTL_DEF(DRM_R128_STIPPLE, r128_cce_stipple, DRM_AUTH), | 1662 | DRM_IOCTL_DEF_DRV(R128_STIPPLE, r128_cce_stipple, DRM_AUTH), |
1664 | DRM_IOCTL_DEF(DRM_R128_INDIRECT, r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1663 | DRM_IOCTL_DEF_DRV(R128_INDIRECT, r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1665 | DRM_IOCTL_DEF(DRM_R128_GETPARAM, r128_getparam, DRM_AUTH), | 1664 | DRM_IOCTL_DEF_DRV(R128_GETPARAM, r128_getparam, DRM_AUTH), |
1666 | }; | 1665 | }; |
1667 | 1666 | ||
1668 | int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls); | 1667 | int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls); |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 12ad512bd3d..464a81a1990 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -332,6 +332,11 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc, | |||
332 | args.usV_SyncWidth = | 332 | args.usV_SyncWidth = |
333 | cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); | 333 | cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); |
334 | 334 | ||
335 | args.ucOverscanRight = radeon_crtc->h_border; | ||
336 | args.ucOverscanLeft = radeon_crtc->h_border; | ||
337 | args.ucOverscanBottom = radeon_crtc->v_border; | ||
338 | args.ucOverscanTop = radeon_crtc->v_border; | ||
339 | |||
335 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) | 340 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) |
336 | misc |= ATOM_VSYNC_POLARITY; | 341 | misc |= ATOM_VSYNC_POLARITY; |
337 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) | 342 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) |
@@ -471,6 +476,8 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
471 | struct radeon_encoder *radeon_encoder = NULL; | 476 | struct radeon_encoder *radeon_encoder = NULL; |
472 | u32 adjusted_clock = mode->clock; | 477 | u32 adjusted_clock = mode->clock; |
473 | int encoder_mode = 0; | 478 | int encoder_mode = 0; |
479 | u32 dp_clock = mode->clock; | ||
480 | int bpc = 8; | ||
474 | 481 | ||
475 | /* reset the pll flags */ | 482 | /* reset the pll flags */ |
476 | pll->flags = 0; | 483 | pll->flags = 0; |
@@ -513,6 +520,17 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
513 | if (encoder->crtc == crtc) { | 520 | if (encoder->crtc == crtc) { |
514 | radeon_encoder = to_radeon_encoder(encoder); | 521 | radeon_encoder = to_radeon_encoder(encoder); |
515 | encoder_mode = atombios_get_encoder_mode(encoder); | 522 | encoder_mode = atombios_get_encoder_mode(encoder); |
523 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) { | ||
524 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
525 | if (connector) { | ||
526 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
527 | struct radeon_connector_atom_dig *dig_connector = | ||
528 | radeon_connector->con_priv; | ||
529 | |||
530 | dp_clock = dig_connector->dp_clock; | ||
531 | } | ||
532 | } | ||
533 | |||
516 | if (ASIC_IS_AVIVO(rdev)) { | 534 | if (ASIC_IS_AVIVO(rdev)) { |
517 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ | 535 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ |
518 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) | 536 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) |
@@ -521,6 +539,20 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
521 | pll->algo = PLL_ALGO_LEGACY; | 539 | pll->algo = PLL_ALGO_LEGACY; |
522 | pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; | 540 | pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; |
523 | } | 541 | } |
542 | /* There is some evidence (often anecdotal) that RV515 LVDS | ||
543 | * (on some boards at least) prefers the legacy algo. I'm not | ||
544 | * sure whether this should handled generically or on a | ||
545 | * case-by-case quirk basis. Both algos should work fine in the | ||
546 | * majority of cases. | ||
547 | */ | ||
548 | if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) && | ||
549 | (rdev->family == CHIP_RV515)) { | ||
550 | /* allow the user to overrride just in case */ | ||
551 | if (radeon_new_pll == 1) | ||
552 | pll->algo = PLL_ALGO_NEW; | ||
553 | else | ||
554 | pll->algo = PLL_ALGO_LEGACY; | ||
555 | } | ||
524 | } else { | 556 | } else { |
525 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) | 557 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) |
526 | pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; | 558 | pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; |
@@ -555,6 +587,14 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
555 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); | 587 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); |
556 | args.v1.ucTransmitterID = radeon_encoder->encoder_id; | 588 | args.v1.ucTransmitterID = radeon_encoder->encoder_id; |
557 | args.v1.ucEncodeMode = encoder_mode; | 589 | args.v1.ucEncodeMode = encoder_mode; |
590 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { | ||
591 | /* may want to enable SS on DP eventually */ | ||
592 | /* args.v1.ucConfig |= | ||
593 | ADJUST_DISPLAY_CONFIG_SS_ENABLE;*/ | ||
594 | } else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) { | ||
595 | args.v1.ucConfig |= | ||
596 | ADJUST_DISPLAY_CONFIG_SS_ENABLE; | ||
597 | } | ||
558 | 598 | ||
559 | atom_execute_table(rdev->mode_info.atom_context, | 599 | atom_execute_table(rdev->mode_info.atom_context, |
560 | index, (uint32_t *)&args); | 600 | index, (uint32_t *)&args); |
@@ -568,10 +608,20 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
568 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 608 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
569 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 609 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
570 | 610 | ||
571 | if (encoder_mode == ATOM_ENCODER_MODE_DP) | 611 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { |
612 | /* may want to enable SS on DP/eDP eventually */ | ||
613 | /*args.v3.sInput.ucDispPllConfig |= | ||
614 | DISPPLL_CONFIG_SS_ENABLE;*/ | ||
572 | args.v3.sInput.ucDispPllConfig |= | 615 | args.v3.sInput.ucDispPllConfig |= |
573 | DISPPLL_CONFIG_COHERENT_MODE; | 616 | DISPPLL_CONFIG_COHERENT_MODE; |
574 | else { | 617 | /* 16200 or 27000 */ |
618 | args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); | ||
619 | } else { | ||
620 | if (encoder_mode == ATOM_ENCODER_MODE_HDMI) { | ||
621 | /* deep color support */ | ||
622 | args.v3.sInput.usPixelClock = | ||
623 | cpu_to_le16((mode->clock * bpc / 8) / 10); | ||
624 | } | ||
575 | if (dig->coherent_mode) | 625 | if (dig->coherent_mode) |
576 | args.v3.sInput.ucDispPllConfig |= | 626 | args.v3.sInput.ucDispPllConfig |= |
577 | DISPPLL_CONFIG_COHERENT_MODE; | 627 | DISPPLL_CONFIG_COHERENT_MODE; |
@@ -580,13 +630,19 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
580 | DISPPLL_CONFIG_DUAL_LINK; | 630 | DISPPLL_CONFIG_DUAL_LINK; |
581 | } | 631 | } |
582 | } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 632 | } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
583 | /* may want to enable SS on DP/eDP eventually */ | 633 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { |
584 | /*args.v3.sInput.ucDispPllConfig |= | 634 | /* may want to enable SS on DP/eDP eventually */ |
585 | DISPPLL_CONFIG_SS_ENABLE;*/ | 635 | /*args.v3.sInput.ucDispPllConfig |= |
586 | if (encoder_mode == ATOM_ENCODER_MODE_DP) | 636 | DISPPLL_CONFIG_SS_ENABLE;*/ |
587 | args.v3.sInput.ucDispPllConfig |= | 637 | args.v3.sInput.ucDispPllConfig |= |
588 | DISPPLL_CONFIG_COHERENT_MODE; | 638 | DISPPLL_CONFIG_COHERENT_MODE; |
589 | else { | 639 | /* 16200 or 27000 */ |
640 | args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); | ||
641 | } else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) { | ||
642 | /* want to enable SS on LVDS eventually */ | ||
643 | /*args.v3.sInput.ucDispPllConfig |= | ||
644 | DISPPLL_CONFIG_SS_ENABLE;*/ | ||
645 | } else { | ||
590 | if (mode->clock > 165000) | 646 | if (mode->clock > 165000) |
591 | args.v3.sInput.ucDispPllConfig |= | 647 | args.v3.sInput.ucDispPllConfig |= |
592 | DISPPLL_CONFIG_DUAL_LINK; | 648 | DISPPLL_CONFIG_DUAL_LINK; |
@@ -1019,11 +1075,11 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
1019 | 1075 | ||
1020 | if (rdev->family >= CHIP_RV770) { | 1076 | if (rdev->family >= CHIP_RV770) { |
1021 | if (radeon_crtc->crtc_id) { | 1077 | if (radeon_crtc->crtc_id) { |
1022 | WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0); | 1078 | WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); |
1023 | WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0); | 1079 | WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); |
1024 | } else { | 1080 | } else { |
1025 | WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0); | 1081 | WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); |
1026 | WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0); | 1082 | WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); |
1027 | } | 1083 | } |
1028 | } | 1084 | } |
1029 | WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | 1085 | WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, |
@@ -1160,8 +1216,18 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
1160 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 1216 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1161 | struct drm_device *dev = crtc->dev; | 1217 | struct drm_device *dev = crtc->dev; |
1162 | struct radeon_device *rdev = dev->dev_private; | 1218 | struct radeon_device *rdev = dev->dev_private; |
1219 | struct drm_encoder *encoder; | ||
1220 | bool is_tvcv = false; | ||
1163 | 1221 | ||
1164 | /* TODO color tiling */ | 1222 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
1223 | /* find tv std */ | ||
1224 | if (encoder->crtc == crtc) { | ||
1225 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1226 | if (radeon_encoder->active_device & | ||
1227 | (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | ||
1228 | is_tvcv = true; | ||
1229 | } | ||
1230 | } | ||
1165 | 1231 | ||
1166 | atombios_disable_ss(crtc); | 1232 | atombios_disable_ss(crtc); |
1167 | /* always set DCPLL */ | 1233 | /* always set DCPLL */ |
@@ -1170,9 +1236,14 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
1170 | atombios_crtc_set_pll(crtc, adjusted_mode); | 1236 | atombios_crtc_set_pll(crtc, adjusted_mode); |
1171 | atombios_enable_ss(crtc); | 1237 | atombios_enable_ss(crtc); |
1172 | 1238 | ||
1173 | if (ASIC_IS_AVIVO(rdev)) | 1239 | if (ASIC_IS_DCE4(rdev)) |
1174 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); | 1240 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); |
1175 | else { | 1241 | else if (ASIC_IS_AVIVO(rdev)) { |
1242 | if (is_tvcv) | ||
1243 | atombios_crtc_set_timing(crtc, adjusted_mode); | ||
1244 | else | ||
1245 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); | ||
1246 | } else { | ||
1176 | atombios_crtc_set_timing(crtc, adjusted_mode); | 1247 | atombios_crtc_set_timing(crtc, adjusted_mode); |
1177 | if (radeon_crtc->crtc_id == 0) | 1248 | if (radeon_crtc->crtc_id == 0) |
1178 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); | 1249 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 36e0d4b545e..4e7778d44b8 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -610,7 +610,7 @@ void dp_link_train(struct drm_encoder *encoder, | |||
610 | enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; | 610 | enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; |
611 | else | 611 | else |
612 | enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER; | 612 | enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER; |
613 | if (dig_connector->linkb) | 613 | if (dig->linkb) |
614 | enc_id |= ATOM_DP_CONFIG_LINK_B; | 614 | enc_id |= ATOM_DP_CONFIG_LINK_B; |
615 | else | 615 | else |
616 | enc_id |= ATOM_DP_CONFIG_LINK_A; | 616 | enc_id |= ATOM_DP_CONFIG_LINK_A; |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 957d5067ad9..b8b7f010b25 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -675,6 +675,43 @@ static int evergreen_cp_load_microcode(struct radeon_device *rdev) | |||
675 | return 0; | 675 | return 0; |
676 | } | 676 | } |
677 | 677 | ||
678 | static int evergreen_cp_start(struct radeon_device *rdev) | ||
679 | { | ||
680 | int r; | ||
681 | uint32_t cp_me; | ||
682 | |||
683 | r = radeon_ring_lock(rdev, 7); | ||
684 | if (r) { | ||
685 | DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); | ||
686 | return r; | ||
687 | } | ||
688 | radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5)); | ||
689 | radeon_ring_write(rdev, 0x1); | ||
690 | radeon_ring_write(rdev, 0x0); | ||
691 | radeon_ring_write(rdev, rdev->config.evergreen.max_hw_contexts - 1); | ||
692 | radeon_ring_write(rdev, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); | ||
693 | radeon_ring_write(rdev, 0); | ||
694 | radeon_ring_write(rdev, 0); | ||
695 | radeon_ring_unlock_commit(rdev); | ||
696 | |||
697 | cp_me = 0xff; | ||
698 | WREG32(CP_ME_CNTL, cp_me); | ||
699 | |||
700 | r = radeon_ring_lock(rdev, 4); | ||
701 | if (r) { | ||
702 | DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); | ||
703 | return r; | ||
704 | } | ||
705 | /* init some VGT regs */ | ||
706 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); | ||
707 | radeon_ring_write(rdev, (VGT_VERTEX_REUSE_BLOCK_CNTL - PACKET3_SET_CONTEXT_REG_START) >> 2); | ||
708 | radeon_ring_write(rdev, 0xe); | ||
709 | radeon_ring_write(rdev, 0x10); | ||
710 | radeon_ring_unlock_commit(rdev); | ||
711 | |||
712 | return 0; | ||
713 | } | ||
714 | |||
678 | int evergreen_cp_resume(struct radeon_device *rdev) | 715 | int evergreen_cp_resume(struct radeon_device *rdev) |
679 | { | 716 | { |
680 | u32 tmp; | 717 | u32 tmp; |
@@ -719,7 +756,7 @@ int evergreen_cp_resume(struct radeon_device *rdev) | |||
719 | rdev->cp.rptr = RREG32(CP_RB_RPTR); | 756 | rdev->cp.rptr = RREG32(CP_RB_RPTR); |
720 | rdev->cp.wptr = RREG32(CP_RB_WPTR); | 757 | rdev->cp.wptr = RREG32(CP_RB_WPTR); |
721 | 758 | ||
722 | r600_cp_start(rdev); | 759 | evergreen_cp_start(rdev); |
723 | rdev->cp.ready = true; | 760 | rdev->cp.ready = true; |
724 | r = radeon_ring_test(rdev); | 761 | r = radeon_ring_test(rdev); |
725 | if (r) { | 762 | if (r) { |
@@ -2054,11 +2091,6 @@ int evergreen_resume(struct radeon_device *rdev) | |||
2054 | */ | 2091 | */ |
2055 | /* post card */ | 2092 | /* post card */ |
2056 | atom_asic_init(rdev->mode_info.atom_context); | 2093 | atom_asic_init(rdev->mode_info.atom_context); |
2057 | /* Initialize clocks */ | ||
2058 | r = radeon_clocks_init(rdev); | ||
2059 | if (r) { | ||
2060 | return r; | ||
2061 | } | ||
2062 | 2094 | ||
2063 | r = evergreen_startup(rdev); | 2095 | r = evergreen_startup(rdev); |
2064 | if (r) { | 2096 | if (r) { |
@@ -2164,9 +2196,6 @@ int evergreen_init(struct radeon_device *rdev) | |||
2164 | radeon_surface_init(rdev); | 2196 | radeon_surface_init(rdev); |
2165 | /* Initialize clocks */ | 2197 | /* Initialize clocks */ |
2166 | radeon_get_clock_info(rdev->ddev); | 2198 | radeon_get_clock_info(rdev->ddev); |
2167 | r = radeon_clocks_init(rdev); | ||
2168 | if (r) | ||
2169 | return r; | ||
2170 | /* Fence driver */ | 2199 | /* Fence driver */ |
2171 | r = radeon_fence_driver_init(rdev); | 2200 | r = radeon_fence_driver_init(rdev); |
2172 | if (r) | 2201 | if (r) |
@@ -2236,7 +2265,6 @@ void evergreen_fini(struct radeon_device *rdev) | |||
2236 | evergreen_pcie_gart_fini(rdev); | 2265 | evergreen_pcie_gart_fini(rdev); |
2237 | radeon_gem_fini(rdev); | 2266 | radeon_gem_fini(rdev); |
2238 | radeon_fence_driver_fini(rdev); | 2267 | radeon_fence_driver_fini(rdev); |
2239 | radeon_clocks_fini(rdev); | ||
2240 | radeon_agp_fini(rdev); | 2268 | radeon_agp_fini(rdev); |
2241 | radeon_bo_fini(rdev); | 2269 | radeon_bo_fini(rdev); |
2242 | radeon_atombios_fini(rdev); | 2270 | radeon_atombios_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index d0ebae9dde2..afc18d87fdc 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -2119,10 +2119,7 @@ int r600_cp_start(struct radeon_device *rdev) | |||
2119 | } | 2119 | } |
2120 | radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5)); | 2120 | radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5)); |
2121 | radeon_ring_write(rdev, 0x1); | 2121 | radeon_ring_write(rdev, 0x1); |
2122 | if (rdev->family >= CHIP_CEDAR) { | 2122 | if (rdev->family >= CHIP_RV770) { |
2123 | radeon_ring_write(rdev, 0x0); | ||
2124 | radeon_ring_write(rdev, rdev->config.evergreen.max_hw_contexts - 1); | ||
2125 | } else if (rdev->family >= CHIP_RV770) { | ||
2126 | radeon_ring_write(rdev, 0x0); | 2123 | radeon_ring_write(rdev, 0x0); |
2127 | radeon_ring_write(rdev, rdev->config.rv770.max_hw_contexts - 1); | 2124 | radeon_ring_write(rdev, rdev->config.rv770.max_hw_contexts - 1); |
2128 | } else { | 2125 | } else { |
@@ -2489,11 +2486,6 @@ int r600_resume(struct radeon_device *rdev) | |||
2489 | */ | 2486 | */ |
2490 | /* post card */ | 2487 | /* post card */ |
2491 | atom_asic_init(rdev->mode_info.atom_context); | 2488 | atom_asic_init(rdev->mode_info.atom_context); |
2492 | /* Initialize clocks */ | ||
2493 | r = radeon_clocks_init(rdev); | ||
2494 | if (r) { | ||
2495 | return r; | ||
2496 | } | ||
2497 | 2489 | ||
2498 | r = r600_startup(rdev); | 2490 | r = r600_startup(rdev); |
2499 | if (r) { | 2491 | if (r) { |
@@ -2586,9 +2578,6 @@ int r600_init(struct radeon_device *rdev) | |||
2586 | radeon_surface_init(rdev); | 2578 | radeon_surface_init(rdev); |
2587 | /* Initialize clocks */ | 2579 | /* Initialize clocks */ |
2588 | radeon_get_clock_info(rdev->ddev); | 2580 | radeon_get_clock_info(rdev->ddev); |
2589 | r = radeon_clocks_init(rdev); | ||
2590 | if (r) | ||
2591 | return r; | ||
2592 | /* Fence driver */ | 2581 | /* Fence driver */ |
2593 | r = radeon_fence_driver_init(rdev); | 2582 | r = radeon_fence_driver_init(rdev); |
2594 | if (r) | 2583 | if (r) |
@@ -2663,7 +2652,6 @@ void r600_fini(struct radeon_device *rdev) | |||
2663 | radeon_agp_fini(rdev); | 2652 | radeon_agp_fini(rdev); |
2664 | radeon_gem_fini(rdev); | 2653 | radeon_gem_fini(rdev); |
2665 | radeon_fence_driver_fini(rdev); | 2654 | radeon_fence_driver_fini(rdev); |
2666 | radeon_clocks_fini(rdev); | ||
2667 | radeon_bo_fini(rdev); | 2655 | radeon_bo_fini(rdev); |
2668 | radeon_atombios_fini(rdev); | 2656 | radeon_atombios_fini(rdev); |
2669 | kfree(rdev->bios); | 2657 | kfree(rdev->bios); |
@@ -3541,7 +3529,7 @@ void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) | |||
3541 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL | 3529 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL |
3542 | */ | 3530 | */ |
3543 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { | 3531 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { |
3544 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; | 3532 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; |
3545 | u32 tmp; | 3533 | u32 tmp; |
3546 | 3534 | ||
3547 | WREG32(HDP_DEBUG1, 0); | 3535 | WREG32(HDP_DEBUG1, 0); |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 3dfcfa3ca42..a168d644bf9 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -1013,6 +1013,11 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, | |||
1013 | int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, | 1013 | int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, |
1014 | struct drm_file *filp); | 1014 | struct drm_file *filp); |
1015 | 1015 | ||
1016 | /* VRAM scratch page for HDP bug */ | ||
1017 | struct r700_vram_scratch { | ||
1018 | struct radeon_bo *robj; | ||
1019 | volatile uint32_t *ptr; | ||
1020 | }; | ||
1016 | 1021 | ||
1017 | /* | 1022 | /* |
1018 | * Core structure, functions and helpers. | 1023 | * Core structure, functions and helpers. |
@@ -1079,6 +1084,7 @@ struct radeon_device { | |||
1079 | const struct firmware *pfp_fw; /* r6/700 PFP firmware */ | 1084 | const struct firmware *pfp_fw; /* r6/700 PFP firmware */ |
1080 | const struct firmware *rlc_fw; /* r6/700 RLC firmware */ | 1085 | const struct firmware *rlc_fw; /* r6/700 RLC firmware */ |
1081 | struct r600_blit r600_blit; | 1086 | struct r600_blit r600_blit; |
1087 | struct r700_vram_scratch vram_scratch; | ||
1082 | int msi_enabled; /* msi enabled */ | 1088 | int msi_enabled; /* msi enabled */ |
1083 | struct r600_ih ih; /* r6/700 interrupt ring */ | 1089 | struct r600_ih ih; /* r6/700 interrupt ring */ |
1084 | struct workqueue_struct *wq; | 1090 | struct workqueue_struct *wq; |
@@ -1333,8 +1339,6 @@ extern bool radeon_card_posted(struct radeon_device *rdev); | |||
1333 | extern void radeon_update_bandwidth_info(struct radeon_device *rdev); | 1339 | extern void radeon_update_bandwidth_info(struct radeon_device *rdev); |
1334 | extern void radeon_update_display_priority(struct radeon_device *rdev); | 1340 | extern void radeon_update_display_priority(struct radeon_device *rdev); |
1335 | extern bool radeon_boot_test_post_card(struct radeon_device *rdev); | 1341 | extern bool radeon_boot_test_post_card(struct radeon_device *rdev); |
1336 | extern int radeon_clocks_init(struct radeon_device *rdev); | ||
1337 | extern void radeon_clocks_fini(struct radeon_device *rdev); | ||
1338 | extern void radeon_scratch_init(struct radeon_device *rdev); | 1342 | extern void radeon_scratch_init(struct radeon_device *rdev); |
1339 | extern void radeon_surface_init(struct radeon_device *rdev); | 1343 | extern void radeon_surface_init(struct radeon_device *rdev); |
1340 | extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data); | 1344 | extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data); |
diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index f40dfb77f9b..bd2f33e5c91 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c | |||
@@ -156,7 +156,13 @@ int radeon_agp_init(struct radeon_device *rdev) | |||
156 | } | 156 | } |
157 | 157 | ||
158 | mode.mode = info.mode; | 158 | mode.mode = info.mode; |
159 | agp_status = (RREG32(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode; | 159 | /* chips with the agp to pcie bridge don't have the AGP_STATUS register |
160 | * Just use the whatever mode the host sets up. | ||
161 | */ | ||
162 | if (rdev->family <= CHIP_RV350) | ||
163 | agp_status = (RREG32(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode; | ||
164 | else | ||
165 | agp_status = mode.mode; | ||
160 | is_v3 = !!(agp_status & RADEON_AGPv3_MODE); | 166 | is_v3 = !!(agp_status & RADEON_AGPv3_MODE); |
161 | 167 | ||
162 | if (is_v3) { | 168 | if (is_v3) { |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 646f96f97c7..25e1dd19779 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -733,6 +733,7 @@ static struct radeon_asic evergreen_asic = { | |||
733 | .set_engine_clock = &radeon_atom_set_engine_clock, | 733 | .set_engine_clock = &radeon_atom_set_engine_clock, |
734 | .get_memory_clock = &radeon_atom_get_memory_clock, | 734 | .get_memory_clock = &radeon_atom_get_memory_clock, |
735 | .set_memory_clock = &radeon_atom_set_memory_clock, | 735 | .set_memory_clock = &radeon_atom_set_memory_clock, |
736 | .get_pcie_lanes = NULL, | ||
736 | .set_pcie_lanes = NULL, | 737 | .set_pcie_lanes = NULL, |
737 | .set_clock_gating = NULL, | 738 | .set_clock_gating = NULL, |
738 | .set_surface_reg = r600_set_surface_reg, | 739 | .set_surface_reg = r600_set_surface_reg, |
@@ -857,21 +858,3 @@ int radeon_asic_init(struct radeon_device *rdev) | |||
857 | return 0; | 858 | return 0; |
858 | } | 859 | } |
859 | 860 | ||
860 | /* | ||
861 | * Wrapper around modesetting bits. Move to radeon_clocks.c? | ||
862 | */ | ||
863 | int radeon_clocks_init(struct radeon_device *rdev) | ||
864 | { | ||
865 | int r; | ||
866 | |||
867 | r = radeon_static_clocks_init(rdev->ddev); | ||
868 | if (r) { | ||
869 | return r; | ||
870 | } | ||
871 | DRM_INFO("Clocks initialized !\n"); | ||
872 | return 0; | ||
873 | } | ||
874 | |||
875 | void radeon_clocks_fini(struct radeon_device *rdev) | ||
876 | { | ||
877 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 6d30868744e..ebae14c4b76 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -32,11 +32,11 @@ | |||
32 | 32 | ||
33 | /* from radeon_encoder.c */ | 33 | /* from radeon_encoder.c */ |
34 | extern uint32_t | 34 | extern uint32_t |
35 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, | 35 | radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, |
36 | uint8_t dac); | 36 | uint8_t dac); |
37 | extern void radeon_link_encoder_connector(struct drm_device *dev); | 37 | extern void radeon_link_encoder_connector(struct drm_device *dev); |
38 | extern void | 38 | extern void |
39 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, | 39 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, |
40 | uint32_t supported_device); | 40 | uint32_t supported_device); |
41 | 41 | ||
42 | /* from radeon_connector.c */ | 42 | /* from radeon_connector.c */ |
@@ -46,14 +46,14 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
46 | uint32_t supported_device, | 46 | uint32_t supported_device, |
47 | int connector_type, | 47 | int connector_type, |
48 | struct radeon_i2c_bus_rec *i2c_bus, | 48 | struct radeon_i2c_bus_rec *i2c_bus, |
49 | bool linkb, uint32_t igp_lane_info, | 49 | uint32_t igp_lane_info, |
50 | uint16_t connector_object_id, | 50 | uint16_t connector_object_id, |
51 | struct radeon_hpd *hpd, | 51 | struct radeon_hpd *hpd, |
52 | struct radeon_router *router); | 52 | struct radeon_router *router); |
53 | 53 | ||
54 | /* from radeon_legacy_encoder.c */ | 54 | /* from radeon_legacy_encoder.c */ |
55 | extern void | 55 | extern void |
56 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, | 56 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, |
57 | uint32_t supported_device); | 57 | uint32_t supported_device); |
58 | 58 | ||
59 | union atom_supported_devices { | 59 | union atom_supported_devices { |
@@ -85,6 +85,19 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev | |||
85 | for (i = 0; i < num_indices; i++) { | 85 | for (i = 0; i < num_indices; i++) { |
86 | gpio = &i2c_info->asGPIO_Info[i]; | 86 | gpio = &i2c_info->asGPIO_Info[i]; |
87 | 87 | ||
88 | /* some evergreen boards have bad data for this entry */ | ||
89 | if (ASIC_IS_DCE4(rdev)) { | ||
90 | if ((i == 7) && | ||
91 | (gpio->usClkMaskRegisterIndex == 0x1936) && | ||
92 | (gpio->sucI2cId.ucAccess == 0)) { | ||
93 | gpio->sucI2cId.ucAccess = 0x97; | ||
94 | gpio->ucDataMaskShift = 8; | ||
95 | gpio->ucDataEnShift = 8; | ||
96 | gpio->ucDataY_Shift = 8; | ||
97 | gpio->ucDataA_Shift = 8; | ||
98 | } | ||
99 | } | ||
100 | |||
88 | if (gpio->sucI2cId.ucAccess == id) { | 101 | if (gpio->sucI2cId.ucAccess == id) { |
89 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; | 102 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; |
90 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; | 103 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; |
@@ -147,6 +160,20 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) | |||
147 | for (i = 0; i < num_indices; i++) { | 160 | for (i = 0; i < num_indices; i++) { |
148 | gpio = &i2c_info->asGPIO_Info[i]; | 161 | gpio = &i2c_info->asGPIO_Info[i]; |
149 | i2c.valid = false; | 162 | i2c.valid = false; |
163 | |||
164 | /* some evergreen boards have bad data for this entry */ | ||
165 | if (ASIC_IS_DCE4(rdev)) { | ||
166 | if ((i == 7) && | ||
167 | (gpio->usClkMaskRegisterIndex == 0x1936) && | ||
168 | (gpio->sucI2cId.ucAccess == 0)) { | ||
169 | gpio->sucI2cId.ucAccess = 0x97; | ||
170 | gpio->ucDataMaskShift = 8; | ||
171 | gpio->ucDataEnShift = 8; | ||
172 | gpio->ucDataY_Shift = 8; | ||
173 | gpio->ucDataA_Shift = 8; | ||
174 | } | ||
175 | } | ||
176 | |||
150 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; | 177 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; |
151 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; | 178 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; |
152 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; | 179 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; |
@@ -226,6 +253,8 @@ static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device | |||
226 | struct radeon_hpd hpd; | 253 | struct radeon_hpd hpd; |
227 | u32 reg; | 254 | u32 reg; |
228 | 255 | ||
256 | memset(&hpd, 0, sizeof(struct radeon_hpd)); | ||
257 | |||
229 | if (ASIC_IS_DCE4(rdev)) | 258 | if (ASIC_IS_DCE4(rdev)) |
230 | reg = EVERGREEN_DC_GPIO_HPD_A; | 259 | reg = EVERGREEN_DC_GPIO_HPD_A; |
231 | else | 260 | else |
@@ -477,7 +506,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
477 | int i, j, k, path_size, device_support; | 506 | int i, j, k, path_size, device_support; |
478 | int connector_type; | 507 | int connector_type; |
479 | u16 igp_lane_info, conn_id, connector_object_id; | 508 | u16 igp_lane_info, conn_id, connector_object_id; |
480 | bool linkb; | ||
481 | struct radeon_i2c_bus_rec ddc_bus; | 509 | struct radeon_i2c_bus_rec ddc_bus; |
482 | struct radeon_router router; | 510 | struct radeon_router router; |
483 | struct radeon_gpio_rec gpio; | 511 | struct radeon_gpio_rec gpio; |
@@ -510,7 +538,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
510 | addr += path_size; | 538 | addr += path_size; |
511 | path = (ATOM_DISPLAY_OBJECT_PATH *) addr; | 539 | path = (ATOM_DISPLAY_OBJECT_PATH *) addr; |
512 | path_size += le16_to_cpu(path->usSize); | 540 | path_size += le16_to_cpu(path->usSize); |
513 | linkb = false; | 541 | |
514 | if (device_support & le16_to_cpu(path->usDeviceTag)) { | 542 | if (device_support & le16_to_cpu(path->usDeviceTag)) { |
515 | uint8_t con_obj_id, con_obj_num, con_obj_type; | 543 | uint8_t con_obj_id, con_obj_num, con_obj_type; |
516 | 544 | ||
@@ -601,13 +629,10 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
601 | OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; | 629 | OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; |
602 | 630 | ||
603 | if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) { | 631 | if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) { |
604 | if (grph_obj_num == 2) | 632 | u16 encoder_obj = le16_to_cpu(path->usGraphicObjIds[j]); |
605 | linkb = true; | ||
606 | else | ||
607 | linkb = false; | ||
608 | 633 | ||
609 | radeon_add_atom_encoder(dev, | 634 | radeon_add_atom_encoder(dev, |
610 | grph_obj_id, | 635 | encoder_obj, |
611 | le16_to_cpu | 636 | le16_to_cpu |
612 | (path-> | 637 | (path-> |
613 | usDeviceTag)); | 638 | usDeviceTag)); |
@@ -744,7 +769,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
744 | le16_to_cpu(path-> | 769 | le16_to_cpu(path-> |
745 | usDeviceTag), | 770 | usDeviceTag), |
746 | connector_type, &ddc_bus, | 771 | connector_type, &ddc_bus, |
747 | linkb, igp_lane_info, | 772 | igp_lane_info, |
748 | connector_object_id, | 773 | connector_object_id, |
749 | &hpd, | 774 | &hpd, |
750 | &router); | 775 | &router); |
@@ -933,13 +958,13 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
933 | 958 | ||
934 | if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom) | 959 | if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom) |
935 | radeon_add_atom_encoder(dev, | 960 | radeon_add_atom_encoder(dev, |
936 | radeon_get_encoder_id(dev, | 961 | radeon_get_encoder_enum(dev, |
937 | (1 << i), | 962 | (1 << i), |
938 | dac), | 963 | dac), |
939 | (1 << i)); | 964 | (1 << i)); |
940 | else | 965 | else |
941 | radeon_add_legacy_encoder(dev, | 966 | radeon_add_legacy_encoder(dev, |
942 | radeon_get_encoder_id(dev, | 967 | radeon_get_encoder_enum(dev, |
943 | (1 << i), | 968 | (1 << i), |
944 | dac), | 969 | dac), |
945 | (1 << i)); | 970 | (1 << i)); |
@@ -996,7 +1021,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
996 | bios_connectors[i]. | 1021 | bios_connectors[i]. |
997 | connector_type, | 1022 | connector_type, |
998 | &bios_connectors[i].ddc_bus, | 1023 | &bios_connectors[i].ddc_bus, |
999 | false, 0, | 1024 | 0, |
1000 | connector_object_id, | 1025 | connector_object_id, |
1001 | &bios_connectors[i].hpd, | 1026 | &bios_connectors[i].hpd, |
1002 | &router); | 1027 | &router); |
@@ -1183,7 +1208,7 @@ bool radeon_atombios_sideport_present(struct radeon_device *rdev) | |||
1183 | return true; | 1208 | return true; |
1184 | break; | 1209 | break; |
1185 | case 2: | 1210 | case 2: |
1186 | if (igp_info->info_2.ucMemoryType & 0x0f) | 1211 | if (igp_info->info_2.ulBootUpSidePortClock) |
1187 | return true; | 1212 | return true; |
1188 | break; | 1213 | break; |
1189 | default: | 1214 | default: |
@@ -1305,6 +1330,7 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
1305 | union lvds_info *lvds_info; | 1330 | union lvds_info *lvds_info; |
1306 | uint8_t frev, crev; | 1331 | uint8_t frev, crev; |
1307 | struct radeon_encoder_atom_dig *lvds = NULL; | 1332 | struct radeon_encoder_atom_dig *lvds = NULL; |
1333 | int encoder_enum = (encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | ||
1308 | 1334 | ||
1309 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, | 1335 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
1310 | &frev, &crev, &data_offset)) { | 1336 | &frev, &crev, &data_offset)) { |
@@ -1368,6 +1394,12 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
1368 | } | 1394 | } |
1369 | 1395 | ||
1370 | encoder->native_mode = lvds->native_mode; | 1396 | encoder->native_mode = lvds->native_mode; |
1397 | |||
1398 | if (encoder_enum == 2) | ||
1399 | lvds->linkb = true; | ||
1400 | else | ||
1401 | lvds->linkb = false; | ||
1402 | |||
1371 | } | 1403 | } |
1372 | return lvds; | 1404 | return lvds; |
1373 | } | 1405 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c index 14448a740ba..5249af8931e 100644 --- a/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/drivers/gpu/drm/radeon/radeon_clocks.c | |||
@@ -327,6 +327,14 @@ void radeon_get_clock_info(struct drm_device *dev) | |||
327 | mpll->max_feedback_div = 0xff; | 327 | mpll->max_feedback_div = 0xff; |
328 | mpll->best_vco = 0; | 328 | mpll->best_vco = 0; |
329 | 329 | ||
330 | if (!rdev->clock.default_sclk) | ||
331 | rdev->clock.default_sclk = radeon_get_engine_clock(rdev); | ||
332 | if ((!rdev->clock.default_mclk) && rdev->asic->get_memory_clock) | ||
333 | rdev->clock.default_mclk = radeon_get_memory_clock(rdev); | ||
334 | |||
335 | rdev->pm.current_sclk = rdev->clock.default_sclk; | ||
336 | rdev->pm.current_mclk = rdev->clock.default_mclk; | ||
337 | |||
330 | } | 338 | } |
331 | 339 | ||
332 | /* 10 khz */ | 340 | /* 10 khz */ |
@@ -897,53 +905,3 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
897 | } | 905 | } |
898 | } | 906 | } |
899 | 907 | ||
900 | static void radeon_apply_clock_quirks(struct radeon_device *rdev) | ||
901 | { | ||
902 | uint32_t tmp; | ||
903 | |||
904 | /* XXX make sure engine is idle */ | ||
905 | |||
906 | if (rdev->family < CHIP_RS600) { | ||
907 | tmp = RREG32_PLL(RADEON_SCLK_CNTL); | ||
908 | if (ASIC_IS_R300(rdev) || ASIC_IS_RV100(rdev)) | ||
909 | tmp |= RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_VIP; | ||
910 | if ((rdev->family == CHIP_RV250) | ||
911 | || (rdev->family == CHIP_RV280)) | ||
912 | tmp |= | ||
913 | RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_DISP2; | ||
914 | if ((rdev->family == CHIP_RV350) | ||
915 | || (rdev->family == CHIP_RV380)) | ||
916 | tmp |= R300_SCLK_FORCE_VAP; | ||
917 | if (rdev->family == CHIP_R420) | ||
918 | tmp |= R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX; | ||
919 | WREG32_PLL(RADEON_SCLK_CNTL, tmp); | ||
920 | } else if (rdev->family < CHIP_R600) { | ||
921 | tmp = RREG32_PLL(AVIVO_CP_DYN_CNTL); | ||
922 | tmp |= AVIVO_CP_FORCEON; | ||
923 | WREG32_PLL(AVIVO_CP_DYN_CNTL, tmp); | ||
924 | |||
925 | tmp = RREG32_PLL(AVIVO_E2_DYN_CNTL); | ||
926 | tmp |= AVIVO_E2_FORCEON; | ||
927 | WREG32_PLL(AVIVO_E2_DYN_CNTL, tmp); | ||
928 | |||
929 | tmp = RREG32_PLL(AVIVO_IDCT_DYN_CNTL); | ||
930 | tmp |= AVIVO_IDCT_FORCEON; | ||
931 | WREG32_PLL(AVIVO_IDCT_DYN_CNTL, tmp); | ||
932 | } | ||
933 | } | ||
934 | |||
935 | int radeon_static_clocks_init(struct drm_device *dev) | ||
936 | { | ||
937 | struct radeon_device *rdev = dev->dev_private; | ||
938 | |||
939 | /* XXX make sure engine is idle */ | ||
940 | |||
941 | if (radeon_dynclks != -1) { | ||
942 | if (radeon_dynclks) { | ||
943 | if (rdev->asic->set_clock_gating) | ||
944 | radeon_set_clock_gating(rdev, 1); | ||
945 | } | ||
946 | } | ||
947 | radeon_apply_clock_quirks(rdev); | ||
948 | return 0; | ||
949 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 885dcfac183..bd74e428bd1 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -39,8 +39,8 @@ | |||
39 | 39 | ||
40 | /* from radeon_encoder.c */ | 40 | /* from radeon_encoder.c */ |
41 | extern uint32_t | 41 | extern uint32_t |
42 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, | 42 | radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, |
43 | uint8_t dac); | 43 | uint8_t dac); |
44 | extern void radeon_link_encoder_connector(struct drm_device *dev); | 44 | extern void radeon_link_encoder_connector(struct drm_device *dev); |
45 | 45 | ||
46 | /* from radeon_connector.c */ | 46 | /* from radeon_connector.c */ |
@@ -55,7 +55,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
55 | 55 | ||
56 | /* from radeon_legacy_encoder.c */ | 56 | /* from radeon_legacy_encoder.c */ |
57 | extern void | 57 | extern void |
58 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, | 58 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, |
59 | uint32_t supported_device); | 59 | uint32_t supported_device); |
60 | 60 | ||
61 | /* old legacy ATI BIOS routines */ | 61 | /* old legacy ATI BIOS routines */ |
@@ -1505,7 +1505,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1505 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1505 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1506 | hpd.hpd = RADEON_HPD_NONE; | 1506 | hpd.hpd = RADEON_HPD_NONE; |
1507 | radeon_add_legacy_encoder(dev, | 1507 | radeon_add_legacy_encoder(dev, |
1508 | radeon_get_encoder_id(dev, | 1508 | radeon_get_encoder_enum(dev, |
1509 | ATOM_DEVICE_CRT1_SUPPORT, | 1509 | ATOM_DEVICE_CRT1_SUPPORT, |
1510 | 1), | 1510 | 1), |
1511 | ATOM_DEVICE_CRT1_SUPPORT); | 1511 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1520,7 +1520,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1520 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0); | 1520 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0); |
1521 | hpd.hpd = RADEON_HPD_NONE; | 1521 | hpd.hpd = RADEON_HPD_NONE; |
1522 | radeon_add_legacy_encoder(dev, | 1522 | radeon_add_legacy_encoder(dev, |
1523 | radeon_get_encoder_id(dev, | 1523 | radeon_get_encoder_enum(dev, |
1524 | ATOM_DEVICE_LCD1_SUPPORT, | 1524 | ATOM_DEVICE_LCD1_SUPPORT, |
1525 | 0), | 1525 | 0), |
1526 | ATOM_DEVICE_LCD1_SUPPORT); | 1526 | ATOM_DEVICE_LCD1_SUPPORT); |
@@ -1535,7 +1535,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1535 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1535 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1536 | hpd.hpd = RADEON_HPD_NONE; | 1536 | hpd.hpd = RADEON_HPD_NONE; |
1537 | radeon_add_legacy_encoder(dev, | 1537 | radeon_add_legacy_encoder(dev, |
1538 | radeon_get_encoder_id(dev, | 1538 | radeon_get_encoder_enum(dev, |
1539 | ATOM_DEVICE_CRT1_SUPPORT, | 1539 | ATOM_DEVICE_CRT1_SUPPORT, |
1540 | 1), | 1540 | 1), |
1541 | ATOM_DEVICE_CRT1_SUPPORT); | 1541 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1550,12 +1550,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1550 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1550 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
1551 | hpd.hpd = RADEON_HPD_1; | 1551 | hpd.hpd = RADEON_HPD_1; |
1552 | radeon_add_legacy_encoder(dev, | 1552 | radeon_add_legacy_encoder(dev, |
1553 | radeon_get_encoder_id(dev, | 1553 | radeon_get_encoder_enum(dev, |
1554 | ATOM_DEVICE_DFP1_SUPPORT, | 1554 | ATOM_DEVICE_DFP1_SUPPORT, |
1555 | 0), | 1555 | 0), |
1556 | ATOM_DEVICE_DFP1_SUPPORT); | 1556 | ATOM_DEVICE_DFP1_SUPPORT); |
1557 | radeon_add_legacy_encoder(dev, | 1557 | radeon_add_legacy_encoder(dev, |
1558 | radeon_get_encoder_id(dev, | 1558 | radeon_get_encoder_enum(dev, |
1559 | ATOM_DEVICE_CRT2_SUPPORT, | 1559 | ATOM_DEVICE_CRT2_SUPPORT, |
1560 | 2), | 1560 | 2), |
1561 | ATOM_DEVICE_CRT2_SUPPORT); | 1561 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -1571,7 +1571,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1571 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1571 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1572 | hpd.hpd = RADEON_HPD_NONE; | 1572 | hpd.hpd = RADEON_HPD_NONE; |
1573 | radeon_add_legacy_encoder(dev, | 1573 | radeon_add_legacy_encoder(dev, |
1574 | radeon_get_encoder_id(dev, | 1574 | radeon_get_encoder_enum(dev, |
1575 | ATOM_DEVICE_CRT1_SUPPORT, | 1575 | ATOM_DEVICE_CRT1_SUPPORT, |
1576 | 1), | 1576 | 1), |
1577 | ATOM_DEVICE_CRT1_SUPPORT); | 1577 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1588,7 +1588,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1588 | ddc_i2c.valid = false; | 1588 | ddc_i2c.valid = false; |
1589 | hpd.hpd = RADEON_HPD_NONE; | 1589 | hpd.hpd = RADEON_HPD_NONE; |
1590 | radeon_add_legacy_encoder(dev, | 1590 | radeon_add_legacy_encoder(dev, |
1591 | radeon_get_encoder_id(dev, | 1591 | radeon_get_encoder_enum(dev, |
1592 | ATOM_DEVICE_TV1_SUPPORT, | 1592 | ATOM_DEVICE_TV1_SUPPORT, |
1593 | 2), | 1593 | 2), |
1594 | ATOM_DEVICE_TV1_SUPPORT); | 1594 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1607,7 +1607,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1607 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1607 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
1608 | hpd.hpd = RADEON_HPD_NONE; | 1608 | hpd.hpd = RADEON_HPD_NONE; |
1609 | radeon_add_legacy_encoder(dev, | 1609 | radeon_add_legacy_encoder(dev, |
1610 | radeon_get_encoder_id(dev, | 1610 | radeon_get_encoder_enum(dev, |
1611 | ATOM_DEVICE_LCD1_SUPPORT, | 1611 | ATOM_DEVICE_LCD1_SUPPORT, |
1612 | 0), | 1612 | 0), |
1613 | ATOM_DEVICE_LCD1_SUPPORT); | 1613 | ATOM_DEVICE_LCD1_SUPPORT); |
@@ -1619,7 +1619,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1619 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1619 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1620 | hpd.hpd = RADEON_HPD_NONE; | 1620 | hpd.hpd = RADEON_HPD_NONE; |
1621 | radeon_add_legacy_encoder(dev, | 1621 | radeon_add_legacy_encoder(dev, |
1622 | radeon_get_encoder_id(dev, | 1622 | radeon_get_encoder_enum(dev, |
1623 | ATOM_DEVICE_CRT2_SUPPORT, | 1623 | ATOM_DEVICE_CRT2_SUPPORT, |
1624 | 2), | 1624 | 2), |
1625 | ATOM_DEVICE_CRT2_SUPPORT); | 1625 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -1631,7 +1631,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1631 | ddc_i2c.valid = false; | 1631 | ddc_i2c.valid = false; |
1632 | hpd.hpd = RADEON_HPD_NONE; | 1632 | hpd.hpd = RADEON_HPD_NONE; |
1633 | radeon_add_legacy_encoder(dev, | 1633 | radeon_add_legacy_encoder(dev, |
1634 | radeon_get_encoder_id(dev, | 1634 | radeon_get_encoder_enum(dev, |
1635 | ATOM_DEVICE_TV1_SUPPORT, | 1635 | ATOM_DEVICE_TV1_SUPPORT, |
1636 | 2), | 1636 | 2), |
1637 | ATOM_DEVICE_TV1_SUPPORT); | 1637 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1648,7 +1648,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1648 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1648 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
1649 | hpd.hpd = RADEON_HPD_NONE; | 1649 | hpd.hpd = RADEON_HPD_NONE; |
1650 | radeon_add_legacy_encoder(dev, | 1650 | radeon_add_legacy_encoder(dev, |
1651 | radeon_get_encoder_id(dev, | 1651 | radeon_get_encoder_enum(dev, |
1652 | ATOM_DEVICE_LCD1_SUPPORT, | 1652 | ATOM_DEVICE_LCD1_SUPPORT, |
1653 | 0), | 1653 | 0), |
1654 | ATOM_DEVICE_LCD1_SUPPORT); | 1654 | ATOM_DEVICE_LCD1_SUPPORT); |
@@ -1660,12 +1660,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1660 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1660 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1661 | hpd.hpd = RADEON_HPD_2; /* ??? */ | 1661 | hpd.hpd = RADEON_HPD_2; /* ??? */ |
1662 | radeon_add_legacy_encoder(dev, | 1662 | radeon_add_legacy_encoder(dev, |
1663 | radeon_get_encoder_id(dev, | 1663 | radeon_get_encoder_enum(dev, |
1664 | ATOM_DEVICE_DFP2_SUPPORT, | 1664 | ATOM_DEVICE_DFP2_SUPPORT, |
1665 | 0), | 1665 | 0), |
1666 | ATOM_DEVICE_DFP2_SUPPORT); | 1666 | ATOM_DEVICE_DFP2_SUPPORT); |
1667 | radeon_add_legacy_encoder(dev, | 1667 | radeon_add_legacy_encoder(dev, |
1668 | radeon_get_encoder_id(dev, | 1668 | radeon_get_encoder_enum(dev, |
1669 | ATOM_DEVICE_CRT1_SUPPORT, | 1669 | ATOM_DEVICE_CRT1_SUPPORT, |
1670 | 1), | 1670 | 1), |
1671 | ATOM_DEVICE_CRT1_SUPPORT); | 1671 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1680,7 +1680,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1680 | ddc_i2c.valid = false; | 1680 | ddc_i2c.valid = false; |
1681 | hpd.hpd = RADEON_HPD_NONE; | 1681 | hpd.hpd = RADEON_HPD_NONE; |
1682 | radeon_add_legacy_encoder(dev, | 1682 | radeon_add_legacy_encoder(dev, |
1683 | radeon_get_encoder_id(dev, | 1683 | radeon_get_encoder_enum(dev, |
1684 | ATOM_DEVICE_TV1_SUPPORT, | 1684 | ATOM_DEVICE_TV1_SUPPORT, |
1685 | 2), | 1685 | 2), |
1686 | ATOM_DEVICE_TV1_SUPPORT); | 1686 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1697,7 +1697,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1697 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1697 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
1698 | hpd.hpd = RADEON_HPD_NONE; | 1698 | hpd.hpd = RADEON_HPD_NONE; |
1699 | radeon_add_legacy_encoder(dev, | 1699 | radeon_add_legacy_encoder(dev, |
1700 | radeon_get_encoder_id(dev, | 1700 | radeon_get_encoder_enum(dev, |
1701 | ATOM_DEVICE_LCD1_SUPPORT, | 1701 | ATOM_DEVICE_LCD1_SUPPORT, |
1702 | 0), | 1702 | 0), |
1703 | ATOM_DEVICE_LCD1_SUPPORT); | 1703 | ATOM_DEVICE_LCD1_SUPPORT); |
@@ -1709,12 +1709,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1709 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1709 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1710 | hpd.hpd = RADEON_HPD_1; /* ??? */ | 1710 | hpd.hpd = RADEON_HPD_1; /* ??? */ |
1711 | radeon_add_legacy_encoder(dev, | 1711 | radeon_add_legacy_encoder(dev, |
1712 | radeon_get_encoder_id(dev, | 1712 | radeon_get_encoder_enum(dev, |
1713 | ATOM_DEVICE_DFP1_SUPPORT, | 1713 | ATOM_DEVICE_DFP1_SUPPORT, |
1714 | 0), | 1714 | 0), |
1715 | ATOM_DEVICE_DFP1_SUPPORT); | 1715 | ATOM_DEVICE_DFP1_SUPPORT); |
1716 | radeon_add_legacy_encoder(dev, | 1716 | radeon_add_legacy_encoder(dev, |
1717 | radeon_get_encoder_id(dev, | 1717 | radeon_get_encoder_enum(dev, |
1718 | ATOM_DEVICE_CRT1_SUPPORT, | 1718 | ATOM_DEVICE_CRT1_SUPPORT, |
1719 | 1), | 1719 | 1), |
1720 | ATOM_DEVICE_CRT1_SUPPORT); | 1720 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1728,7 +1728,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1728 | ddc_i2c.valid = false; | 1728 | ddc_i2c.valid = false; |
1729 | hpd.hpd = RADEON_HPD_NONE; | 1729 | hpd.hpd = RADEON_HPD_NONE; |
1730 | radeon_add_legacy_encoder(dev, | 1730 | radeon_add_legacy_encoder(dev, |
1731 | radeon_get_encoder_id(dev, | 1731 | radeon_get_encoder_enum(dev, |
1732 | ATOM_DEVICE_TV1_SUPPORT, | 1732 | ATOM_DEVICE_TV1_SUPPORT, |
1733 | 2), | 1733 | 2), |
1734 | ATOM_DEVICE_TV1_SUPPORT); | 1734 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1745,7 +1745,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1745 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1745 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
1746 | hpd.hpd = RADEON_HPD_NONE; | 1746 | hpd.hpd = RADEON_HPD_NONE; |
1747 | radeon_add_legacy_encoder(dev, | 1747 | radeon_add_legacy_encoder(dev, |
1748 | radeon_get_encoder_id(dev, | 1748 | radeon_get_encoder_enum(dev, |
1749 | ATOM_DEVICE_LCD1_SUPPORT, | 1749 | ATOM_DEVICE_LCD1_SUPPORT, |
1750 | 0), | 1750 | 0), |
1751 | ATOM_DEVICE_LCD1_SUPPORT); | 1751 | ATOM_DEVICE_LCD1_SUPPORT); |
@@ -1757,7 +1757,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1757 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1757 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1758 | hpd.hpd = RADEON_HPD_NONE; | 1758 | hpd.hpd = RADEON_HPD_NONE; |
1759 | radeon_add_legacy_encoder(dev, | 1759 | radeon_add_legacy_encoder(dev, |
1760 | radeon_get_encoder_id(dev, | 1760 | radeon_get_encoder_enum(dev, |
1761 | ATOM_DEVICE_CRT1_SUPPORT, | 1761 | ATOM_DEVICE_CRT1_SUPPORT, |
1762 | 1), | 1762 | 1), |
1763 | ATOM_DEVICE_CRT1_SUPPORT); | 1763 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1769,7 +1769,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1769 | ddc_i2c.valid = false; | 1769 | ddc_i2c.valid = false; |
1770 | hpd.hpd = RADEON_HPD_NONE; | 1770 | hpd.hpd = RADEON_HPD_NONE; |
1771 | radeon_add_legacy_encoder(dev, | 1771 | radeon_add_legacy_encoder(dev, |
1772 | radeon_get_encoder_id(dev, | 1772 | radeon_get_encoder_enum(dev, |
1773 | ATOM_DEVICE_TV1_SUPPORT, | 1773 | ATOM_DEVICE_TV1_SUPPORT, |
1774 | 2), | 1774 | 2), |
1775 | ATOM_DEVICE_TV1_SUPPORT); | 1775 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1786,12 +1786,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1786 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 1786 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
1787 | hpd.hpd = RADEON_HPD_2; /* ??? */ | 1787 | hpd.hpd = RADEON_HPD_2; /* ??? */ |
1788 | radeon_add_legacy_encoder(dev, | 1788 | radeon_add_legacy_encoder(dev, |
1789 | radeon_get_encoder_id(dev, | 1789 | radeon_get_encoder_enum(dev, |
1790 | ATOM_DEVICE_DFP2_SUPPORT, | 1790 | ATOM_DEVICE_DFP2_SUPPORT, |
1791 | 0), | 1791 | 0), |
1792 | ATOM_DEVICE_DFP2_SUPPORT); | 1792 | ATOM_DEVICE_DFP2_SUPPORT); |
1793 | radeon_add_legacy_encoder(dev, | 1793 | radeon_add_legacy_encoder(dev, |
1794 | radeon_get_encoder_id(dev, | 1794 | radeon_get_encoder_enum(dev, |
1795 | ATOM_DEVICE_CRT2_SUPPORT, | 1795 | ATOM_DEVICE_CRT2_SUPPORT, |
1796 | 2), | 1796 | 2), |
1797 | ATOM_DEVICE_CRT2_SUPPORT); | 1797 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -1806,7 +1806,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1806 | ddc_i2c.valid = false; | 1806 | ddc_i2c.valid = false; |
1807 | hpd.hpd = RADEON_HPD_NONE; | 1807 | hpd.hpd = RADEON_HPD_NONE; |
1808 | radeon_add_legacy_encoder(dev, | 1808 | radeon_add_legacy_encoder(dev, |
1809 | radeon_get_encoder_id(dev, | 1809 | radeon_get_encoder_enum(dev, |
1810 | ATOM_DEVICE_TV1_SUPPORT, | 1810 | ATOM_DEVICE_TV1_SUPPORT, |
1811 | 2), | 1811 | 2), |
1812 | ATOM_DEVICE_TV1_SUPPORT); | 1812 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1823,12 +1823,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1823 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 1823 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
1824 | hpd.hpd = RADEON_HPD_1; /* ??? */ | 1824 | hpd.hpd = RADEON_HPD_1; /* ??? */ |
1825 | radeon_add_legacy_encoder(dev, | 1825 | radeon_add_legacy_encoder(dev, |
1826 | radeon_get_encoder_id(dev, | 1826 | radeon_get_encoder_enum(dev, |
1827 | ATOM_DEVICE_DFP1_SUPPORT, | 1827 | ATOM_DEVICE_DFP1_SUPPORT, |
1828 | 0), | 1828 | 0), |
1829 | ATOM_DEVICE_DFP1_SUPPORT); | 1829 | ATOM_DEVICE_DFP1_SUPPORT); |
1830 | radeon_add_legacy_encoder(dev, | 1830 | radeon_add_legacy_encoder(dev, |
1831 | radeon_get_encoder_id(dev, | 1831 | radeon_get_encoder_enum(dev, |
1832 | ATOM_DEVICE_CRT2_SUPPORT, | 1832 | ATOM_DEVICE_CRT2_SUPPORT, |
1833 | 2), | 1833 | 2), |
1834 | ATOM_DEVICE_CRT2_SUPPORT); | 1834 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -1842,7 +1842,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1842 | ddc_i2c.valid = false; | 1842 | ddc_i2c.valid = false; |
1843 | hpd.hpd = RADEON_HPD_NONE; | 1843 | hpd.hpd = RADEON_HPD_NONE; |
1844 | radeon_add_legacy_encoder(dev, | 1844 | radeon_add_legacy_encoder(dev, |
1845 | radeon_get_encoder_id(dev, | 1845 | radeon_get_encoder_enum(dev, |
1846 | ATOM_DEVICE_TV1_SUPPORT, | 1846 | ATOM_DEVICE_TV1_SUPPORT, |
1847 | 2), | 1847 | 2), |
1848 | ATOM_DEVICE_TV1_SUPPORT); | 1848 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1859,7 +1859,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1859 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); | 1859 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); |
1860 | hpd.hpd = RADEON_HPD_1; /* ??? */ | 1860 | hpd.hpd = RADEON_HPD_1; /* ??? */ |
1861 | radeon_add_legacy_encoder(dev, | 1861 | radeon_add_legacy_encoder(dev, |
1862 | radeon_get_encoder_id(dev, | 1862 | radeon_get_encoder_enum(dev, |
1863 | ATOM_DEVICE_DFP1_SUPPORT, | 1863 | ATOM_DEVICE_DFP1_SUPPORT, |
1864 | 0), | 1864 | 0), |
1865 | ATOM_DEVICE_DFP1_SUPPORT); | 1865 | ATOM_DEVICE_DFP1_SUPPORT); |
@@ -1871,7 +1871,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1871 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1871 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
1872 | hpd.hpd = RADEON_HPD_NONE; | 1872 | hpd.hpd = RADEON_HPD_NONE; |
1873 | radeon_add_legacy_encoder(dev, | 1873 | radeon_add_legacy_encoder(dev, |
1874 | radeon_get_encoder_id(dev, | 1874 | radeon_get_encoder_enum(dev, |
1875 | ATOM_DEVICE_CRT2_SUPPORT, | 1875 | ATOM_DEVICE_CRT2_SUPPORT, |
1876 | 2), | 1876 | 2), |
1877 | ATOM_DEVICE_CRT2_SUPPORT); | 1877 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -1883,7 +1883,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1883 | ddc_i2c.valid = false; | 1883 | ddc_i2c.valid = false; |
1884 | hpd.hpd = RADEON_HPD_NONE; | 1884 | hpd.hpd = RADEON_HPD_NONE; |
1885 | radeon_add_legacy_encoder(dev, | 1885 | radeon_add_legacy_encoder(dev, |
1886 | radeon_get_encoder_id(dev, | 1886 | radeon_get_encoder_enum(dev, |
1887 | ATOM_DEVICE_TV1_SUPPORT, | 1887 | ATOM_DEVICE_TV1_SUPPORT, |
1888 | 2), | 1888 | 2), |
1889 | ATOM_DEVICE_TV1_SUPPORT); | 1889 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1900,7 +1900,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1900 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1900 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1901 | hpd.hpd = RADEON_HPD_NONE; | 1901 | hpd.hpd = RADEON_HPD_NONE; |
1902 | radeon_add_legacy_encoder(dev, | 1902 | radeon_add_legacy_encoder(dev, |
1903 | radeon_get_encoder_id(dev, | 1903 | radeon_get_encoder_enum(dev, |
1904 | ATOM_DEVICE_CRT1_SUPPORT, | 1904 | ATOM_DEVICE_CRT1_SUPPORT, |
1905 | 1), | 1905 | 1), |
1906 | ATOM_DEVICE_CRT1_SUPPORT); | 1906 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1912,7 +1912,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1912 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 1912 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
1913 | hpd.hpd = RADEON_HPD_NONE; | 1913 | hpd.hpd = RADEON_HPD_NONE; |
1914 | radeon_add_legacy_encoder(dev, | 1914 | radeon_add_legacy_encoder(dev, |
1915 | radeon_get_encoder_id(dev, | 1915 | radeon_get_encoder_enum(dev, |
1916 | ATOM_DEVICE_CRT2_SUPPORT, | 1916 | ATOM_DEVICE_CRT2_SUPPORT, |
1917 | 2), | 1917 | 2), |
1918 | ATOM_DEVICE_CRT2_SUPPORT); | 1918 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -1924,7 +1924,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1924 | ddc_i2c.valid = false; | 1924 | ddc_i2c.valid = false; |
1925 | hpd.hpd = RADEON_HPD_NONE; | 1925 | hpd.hpd = RADEON_HPD_NONE; |
1926 | radeon_add_legacy_encoder(dev, | 1926 | radeon_add_legacy_encoder(dev, |
1927 | radeon_get_encoder_id(dev, | 1927 | radeon_get_encoder_enum(dev, |
1928 | ATOM_DEVICE_TV1_SUPPORT, | 1928 | ATOM_DEVICE_TV1_SUPPORT, |
1929 | 2), | 1929 | 2), |
1930 | ATOM_DEVICE_TV1_SUPPORT); | 1930 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1941,7 +1941,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1941 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1941 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1942 | hpd.hpd = RADEON_HPD_NONE; | 1942 | hpd.hpd = RADEON_HPD_NONE; |
1943 | radeon_add_legacy_encoder(dev, | 1943 | radeon_add_legacy_encoder(dev, |
1944 | radeon_get_encoder_id(dev, | 1944 | radeon_get_encoder_enum(dev, |
1945 | ATOM_DEVICE_CRT1_SUPPORT, | 1945 | ATOM_DEVICE_CRT1_SUPPORT, |
1946 | 1), | 1946 | 1), |
1947 | ATOM_DEVICE_CRT1_SUPPORT); | 1947 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1952,7 +1952,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1952 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 1952 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
1953 | hpd.hpd = RADEON_HPD_NONE; | 1953 | hpd.hpd = RADEON_HPD_NONE; |
1954 | radeon_add_legacy_encoder(dev, | 1954 | radeon_add_legacy_encoder(dev, |
1955 | radeon_get_encoder_id(dev, | 1955 | radeon_get_encoder_enum(dev, |
1956 | ATOM_DEVICE_CRT2_SUPPORT, | 1956 | ATOM_DEVICE_CRT2_SUPPORT, |
1957 | 2), | 1957 | 2), |
1958 | ATOM_DEVICE_CRT2_SUPPORT); | 1958 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -2109,7 +2109,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2109 | else | 2109 | else |
2110 | devices = ATOM_DEVICE_DFP1_SUPPORT; | 2110 | devices = ATOM_DEVICE_DFP1_SUPPORT; |
2111 | radeon_add_legacy_encoder(dev, | 2111 | radeon_add_legacy_encoder(dev, |
2112 | radeon_get_encoder_id | 2112 | radeon_get_encoder_enum |
2113 | (dev, devices, 0), | 2113 | (dev, devices, 0), |
2114 | devices); | 2114 | devices); |
2115 | radeon_add_legacy_connector(dev, i, devices, | 2115 | radeon_add_legacy_connector(dev, i, devices, |
@@ -2123,7 +2123,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2123 | if (tmp & 0x1) { | 2123 | if (tmp & 0x1) { |
2124 | devices = ATOM_DEVICE_CRT2_SUPPORT; | 2124 | devices = ATOM_DEVICE_CRT2_SUPPORT; |
2125 | radeon_add_legacy_encoder(dev, | 2125 | radeon_add_legacy_encoder(dev, |
2126 | radeon_get_encoder_id | 2126 | radeon_get_encoder_enum |
2127 | (dev, | 2127 | (dev, |
2128 | ATOM_DEVICE_CRT2_SUPPORT, | 2128 | ATOM_DEVICE_CRT2_SUPPORT, |
2129 | 2), | 2129 | 2), |
@@ -2131,7 +2131,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2131 | } else { | 2131 | } else { |
2132 | devices = ATOM_DEVICE_CRT1_SUPPORT; | 2132 | devices = ATOM_DEVICE_CRT1_SUPPORT; |
2133 | radeon_add_legacy_encoder(dev, | 2133 | radeon_add_legacy_encoder(dev, |
2134 | radeon_get_encoder_id | 2134 | radeon_get_encoder_enum |
2135 | (dev, | 2135 | (dev, |
2136 | ATOM_DEVICE_CRT1_SUPPORT, | 2136 | ATOM_DEVICE_CRT1_SUPPORT, |
2137 | 1), | 2137 | 1), |
@@ -2151,7 +2151,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2151 | if (tmp & 0x1) { | 2151 | if (tmp & 0x1) { |
2152 | devices |= ATOM_DEVICE_CRT2_SUPPORT; | 2152 | devices |= ATOM_DEVICE_CRT2_SUPPORT; |
2153 | radeon_add_legacy_encoder(dev, | 2153 | radeon_add_legacy_encoder(dev, |
2154 | radeon_get_encoder_id | 2154 | radeon_get_encoder_enum |
2155 | (dev, | 2155 | (dev, |
2156 | ATOM_DEVICE_CRT2_SUPPORT, | 2156 | ATOM_DEVICE_CRT2_SUPPORT, |
2157 | 2), | 2157 | 2), |
@@ -2159,7 +2159,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2159 | } else { | 2159 | } else { |
2160 | devices |= ATOM_DEVICE_CRT1_SUPPORT; | 2160 | devices |= ATOM_DEVICE_CRT1_SUPPORT; |
2161 | radeon_add_legacy_encoder(dev, | 2161 | radeon_add_legacy_encoder(dev, |
2162 | radeon_get_encoder_id | 2162 | radeon_get_encoder_enum |
2163 | (dev, | 2163 | (dev, |
2164 | ATOM_DEVICE_CRT1_SUPPORT, | 2164 | ATOM_DEVICE_CRT1_SUPPORT, |
2165 | 1), | 2165 | 1), |
@@ -2168,7 +2168,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2168 | if ((tmp >> 4) & 0x1) { | 2168 | if ((tmp >> 4) & 0x1) { |
2169 | devices |= ATOM_DEVICE_DFP2_SUPPORT; | 2169 | devices |= ATOM_DEVICE_DFP2_SUPPORT; |
2170 | radeon_add_legacy_encoder(dev, | 2170 | radeon_add_legacy_encoder(dev, |
2171 | radeon_get_encoder_id | 2171 | radeon_get_encoder_enum |
2172 | (dev, | 2172 | (dev, |
2173 | ATOM_DEVICE_DFP2_SUPPORT, | 2173 | ATOM_DEVICE_DFP2_SUPPORT, |
2174 | 0), | 2174 | 0), |
@@ -2177,7 +2177,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2177 | } else { | 2177 | } else { |
2178 | devices |= ATOM_DEVICE_DFP1_SUPPORT; | 2178 | devices |= ATOM_DEVICE_DFP1_SUPPORT; |
2179 | radeon_add_legacy_encoder(dev, | 2179 | radeon_add_legacy_encoder(dev, |
2180 | radeon_get_encoder_id | 2180 | radeon_get_encoder_enum |
2181 | (dev, | 2181 | (dev, |
2182 | ATOM_DEVICE_DFP1_SUPPORT, | 2182 | ATOM_DEVICE_DFP1_SUPPORT, |
2183 | 0), | 2183 | 0), |
@@ -2202,7 +2202,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2202 | connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; | 2202 | connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; |
2203 | } | 2203 | } |
2204 | radeon_add_legacy_encoder(dev, | 2204 | radeon_add_legacy_encoder(dev, |
2205 | radeon_get_encoder_id | 2205 | radeon_get_encoder_enum |
2206 | (dev, devices, 0), | 2206 | (dev, devices, 0), |
2207 | devices); | 2207 | devices); |
2208 | radeon_add_legacy_connector(dev, i, devices, | 2208 | radeon_add_legacy_connector(dev, i, devices, |
@@ -2215,7 +2215,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2215 | case CONNECTOR_CTV_LEGACY: | 2215 | case CONNECTOR_CTV_LEGACY: |
2216 | case CONNECTOR_STV_LEGACY: | 2216 | case CONNECTOR_STV_LEGACY: |
2217 | radeon_add_legacy_encoder(dev, | 2217 | radeon_add_legacy_encoder(dev, |
2218 | radeon_get_encoder_id | 2218 | radeon_get_encoder_enum |
2219 | (dev, | 2219 | (dev, |
2220 | ATOM_DEVICE_TV1_SUPPORT, | 2220 | ATOM_DEVICE_TV1_SUPPORT, |
2221 | 2), | 2221 | 2), |
@@ -2242,12 +2242,12 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2242 | DRM_DEBUG_KMS("Found DFP table, assuming DVI connector\n"); | 2242 | DRM_DEBUG_KMS("Found DFP table, assuming DVI connector\n"); |
2243 | 2243 | ||
2244 | radeon_add_legacy_encoder(dev, | 2244 | radeon_add_legacy_encoder(dev, |
2245 | radeon_get_encoder_id(dev, | 2245 | radeon_get_encoder_enum(dev, |
2246 | ATOM_DEVICE_CRT1_SUPPORT, | 2246 | ATOM_DEVICE_CRT1_SUPPORT, |
2247 | 1), | 2247 | 1), |
2248 | ATOM_DEVICE_CRT1_SUPPORT); | 2248 | ATOM_DEVICE_CRT1_SUPPORT); |
2249 | radeon_add_legacy_encoder(dev, | 2249 | radeon_add_legacy_encoder(dev, |
2250 | radeon_get_encoder_id(dev, | 2250 | radeon_get_encoder_enum(dev, |
2251 | ATOM_DEVICE_DFP1_SUPPORT, | 2251 | ATOM_DEVICE_DFP1_SUPPORT, |
2252 | 0), | 2252 | 0), |
2253 | ATOM_DEVICE_DFP1_SUPPORT); | 2253 | ATOM_DEVICE_DFP1_SUPPORT); |
@@ -2268,7 +2268,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2268 | DRM_DEBUG_KMS("Found CRT table, assuming VGA connector\n"); | 2268 | DRM_DEBUG_KMS("Found CRT table, assuming VGA connector\n"); |
2269 | if (crt_info) { | 2269 | if (crt_info) { |
2270 | radeon_add_legacy_encoder(dev, | 2270 | radeon_add_legacy_encoder(dev, |
2271 | radeon_get_encoder_id(dev, | 2271 | radeon_get_encoder_enum(dev, |
2272 | ATOM_DEVICE_CRT1_SUPPORT, | 2272 | ATOM_DEVICE_CRT1_SUPPORT, |
2273 | 1), | 2273 | 1), |
2274 | ATOM_DEVICE_CRT1_SUPPORT); | 2274 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -2297,7 +2297,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2297 | COMBIOS_LCD_DDC_INFO_TABLE); | 2297 | COMBIOS_LCD_DDC_INFO_TABLE); |
2298 | 2298 | ||
2299 | radeon_add_legacy_encoder(dev, | 2299 | radeon_add_legacy_encoder(dev, |
2300 | radeon_get_encoder_id(dev, | 2300 | radeon_get_encoder_enum(dev, |
2301 | ATOM_DEVICE_LCD1_SUPPORT, | 2301 | ATOM_DEVICE_LCD1_SUPPORT, |
2302 | 0), | 2302 | 0), |
2303 | ATOM_DEVICE_LCD1_SUPPORT); | 2303 | ATOM_DEVICE_LCD1_SUPPORT); |
@@ -2351,7 +2351,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2351 | hpd.hpd = RADEON_HPD_NONE; | 2351 | hpd.hpd = RADEON_HPD_NONE; |
2352 | ddc_i2c.valid = false; | 2352 | ddc_i2c.valid = false; |
2353 | radeon_add_legacy_encoder(dev, | 2353 | radeon_add_legacy_encoder(dev, |
2354 | radeon_get_encoder_id | 2354 | radeon_get_encoder_enum |
2355 | (dev, | 2355 | (dev, |
2356 | ATOM_DEVICE_TV1_SUPPORT, | 2356 | ATOM_DEVICE_TV1_SUPPORT, |
2357 | 2), | 2357 | 2), |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 47c4b276d30..a9dd7847d96 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -977,27 +977,29 @@ static enum drm_connector_status radeon_dp_detect(struct drm_connector *connecto | |||
977 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 977 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
978 | enum drm_connector_status ret = connector_status_disconnected; | 978 | enum drm_connector_status ret = connector_status_disconnected; |
979 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; | 979 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; |
980 | u8 sink_type; | ||
981 | 980 | ||
982 | if (radeon_connector->edid) { | 981 | if (radeon_connector->edid) { |
983 | kfree(radeon_connector->edid); | 982 | kfree(radeon_connector->edid); |
984 | radeon_connector->edid = NULL; | 983 | radeon_connector->edid = NULL; |
985 | } | 984 | } |
986 | 985 | ||
987 | sink_type = radeon_dp_getsinktype(radeon_connector); | 986 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
988 | if ((sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | 987 | /* eDP is always DP */ |
989 | (sink_type == CONNECTOR_OBJECT_ID_eDP)) { | 988 | radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; |
990 | if (radeon_dp_getdpcd(radeon_connector)) { | 989 | if (radeon_dp_getdpcd(radeon_connector)) |
991 | radeon_dig_connector->dp_sink_type = sink_type; | ||
992 | ret = connector_status_connected; | 990 | ret = connector_status_connected; |
993 | } | ||
994 | } else { | 991 | } else { |
995 | if (radeon_ddc_probe(radeon_connector)) { | 992 | radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); |
996 | radeon_dig_connector->dp_sink_type = sink_type; | 993 | if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { |
997 | ret = connector_status_connected; | 994 | if (radeon_dp_getdpcd(radeon_connector)) |
995 | ret = connector_status_connected; | ||
996 | } else { | ||
997 | if (radeon_ddc_probe(radeon_connector)) | ||
998 | ret = connector_status_connected; | ||
998 | } | 999 | } |
999 | } | 1000 | } |
1000 | 1001 | ||
1002 | radeon_connector_update_scratch_regs(connector, ret); | ||
1001 | return ret; | 1003 | return ret; |
1002 | } | 1004 | } |
1003 | 1005 | ||
@@ -1037,7 +1039,6 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1037 | uint32_t supported_device, | 1039 | uint32_t supported_device, |
1038 | int connector_type, | 1040 | int connector_type, |
1039 | struct radeon_i2c_bus_rec *i2c_bus, | 1041 | struct radeon_i2c_bus_rec *i2c_bus, |
1040 | bool linkb, | ||
1041 | uint32_t igp_lane_info, | 1042 | uint32_t igp_lane_info, |
1042 | uint16_t connector_object_id, | 1043 | uint16_t connector_object_id, |
1043 | struct radeon_hpd *hpd, | 1044 | struct radeon_hpd *hpd, |
@@ -1050,10 +1051,16 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1050 | uint32_t subpixel_order = SubPixelNone; | 1051 | uint32_t subpixel_order = SubPixelNone; |
1051 | bool shared_ddc = false; | 1052 | bool shared_ddc = false; |
1052 | 1053 | ||
1053 | /* fixme - tv/cv/din */ | ||
1054 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) | 1054 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) |
1055 | return; | 1055 | return; |
1056 | 1056 | ||
1057 | /* if the user selected tv=0 don't try and add the connector */ | ||
1058 | if (((connector_type == DRM_MODE_CONNECTOR_SVIDEO) || | ||
1059 | (connector_type == DRM_MODE_CONNECTOR_Composite) || | ||
1060 | (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) && | ||
1061 | (radeon_tv == 0)) | ||
1062 | return; | ||
1063 | |||
1057 | /* see if we already added it */ | 1064 | /* see if we already added it */ |
1058 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1065 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
1059 | radeon_connector = to_radeon_connector(connector); | 1066 | radeon_connector = to_radeon_connector(connector); |
@@ -1128,7 +1135,6 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1128 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 1135 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
1129 | if (!radeon_dig_connector) | 1136 | if (!radeon_dig_connector) |
1130 | goto failed; | 1137 | goto failed; |
1131 | radeon_dig_connector->linkb = linkb; | ||
1132 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 1138 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
1133 | radeon_connector->con_priv = radeon_dig_connector; | 1139 | radeon_connector->con_priv = radeon_dig_connector; |
1134 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); | 1140 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
@@ -1158,7 +1164,6 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1158 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 1164 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
1159 | if (!radeon_dig_connector) | 1165 | if (!radeon_dig_connector) |
1160 | goto failed; | 1166 | goto failed; |
1161 | radeon_dig_connector->linkb = linkb; | ||
1162 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 1167 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
1163 | radeon_connector->con_priv = radeon_dig_connector; | 1168 | radeon_connector->con_priv = radeon_dig_connector; |
1164 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); | 1169 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
@@ -1182,7 +1187,6 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1182 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 1187 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
1183 | if (!radeon_dig_connector) | 1188 | if (!radeon_dig_connector) |
1184 | goto failed; | 1189 | goto failed; |
1185 | radeon_dig_connector->linkb = linkb; | ||
1186 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 1190 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
1187 | radeon_connector->con_priv = radeon_dig_connector; | 1191 | radeon_connector->con_priv = radeon_dig_connector; |
1188 | drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); | 1192 | drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); |
@@ -1211,25 +1215,22 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1211 | case DRM_MODE_CONNECTOR_SVIDEO: | 1215 | case DRM_MODE_CONNECTOR_SVIDEO: |
1212 | case DRM_MODE_CONNECTOR_Composite: | 1216 | case DRM_MODE_CONNECTOR_Composite: |
1213 | case DRM_MODE_CONNECTOR_9PinDIN: | 1217 | case DRM_MODE_CONNECTOR_9PinDIN: |
1214 | if (radeon_tv == 1) { | 1218 | drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); |
1215 | drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); | 1219 | drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); |
1216 | drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); | 1220 | radeon_connector->dac_load_detect = true; |
1217 | radeon_connector->dac_load_detect = true; | 1221 | drm_connector_attach_property(&radeon_connector->base, |
1218 | drm_connector_attach_property(&radeon_connector->base, | 1222 | rdev->mode_info.load_detect_property, |
1219 | rdev->mode_info.load_detect_property, | 1223 | 1); |
1220 | 1); | 1224 | drm_connector_attach_property(&radeon_connector->base, |
1221 | drm_connector_attach_property(&radeon_connector->base, | 1225 | rdev->mode_info.tv_std_property, |
1222 | rdev->mode_info.tv_std_property, | 1226 | radeon_atombios_get_tv_info(rdev)); |
1223 | radeon_atombios_get_tv_info(rdev)); | 1227 | /* no HPD on analog connectors */ |
1224 | /* no HPD on analog connectors */ | 1228 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; |
1225 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | ||
1226 | } | ||
1227 | break; | 1229 | break; |
1228 | case DRM_MODE_CONNECTOR_LVDS: | 1230 | case DRM_MODE_CONNECTOR_LVDS: |
1229 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 1231 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
1230 | if (!radeon_dig_connector) | 1232 | if (!radeon_dig_connector) |
1231 | goto failed; | 1233 | goto failed; |
1232 | radeon_dig_connector->linkb = linkb; | ||
1233 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 1234 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
1234 | radeon_connector->con_priv = radeon_dig_connector; | 1235 | radeon_connector->con_priv = radeon_dig_connector; |
1235 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); | 1236 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); |
@@ -1275,10 +1276,16 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1275 | struct radeon_connector *radeon_connector; | 1276 | struct radeon_connector *radeon_connector; |
1276 | uint32_t subpixel_order = SubPixelNone; | 1277 | uint32_t subpixel_order = SubPixelNone; |
1277 | 1278 | ||
1278 | /* fixme - tv/cv/din */ | ||
1279 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) | 1279 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) |
1280 | return; | 1280 | return; |
1281 | 1281 | ||
1282 | /* if the user selected tv=0 don't try and add the connector */ | ||
1283 | if (((connector_type == DRM_MODE_CONNECTOR_SVIDEO) || | ||
1284 | (connector_type == DRM_MODE_CONNECTOR_Composite) || | ||
1285 | (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) && | ||
1286 | (radeon_tv == 0)) | ||
1287 | return; | ||
1288 | |||
1282 | /* see if we already added it */ | 1289 | /* see if we already added it */ |
1283 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1290 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
1284 | radeon_connector = to_radeon_connector(connector); | 1291 | radeon_connector = to_radeon_connector(connector); |
@@ -1350,26 +1357,24 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1350 | case DRM_MODE_CONNECTOR_SVIDEO: | 1357 | case DRM_MODE_CONNECTOR_SVIDEO: |
1351 | case DRM_MODE_CONNECTOR_Composite: | 1358 | case DRM_MODE_CONNECTOR_Composite: |
1352 | case DRM_MODE_CONNECTOR_9PinDIN: | 1359 | case DRM_MODE_CONNECTOR_9PinDIN: |
1353 | if (radeon_tv == 1) { | 1360 | drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); |
1354 | drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); | 1361 | drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); |
1355 | drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); | 1362 | radeon_connector->dac_load_detect = true; |
1356 | radeon_connector->dac_load_detect = true; | 1363 | /* RS400,RC410,RS480 chipset seems to report a lot |
1357 | /* RS400,RC410,RS480 chipset seems to report a lot | 1364 | * of false positive on load detect, we haven't yet |
1358 | * of false positive on load detect, we haven't yet | 1365 | * found a way to make load detect reliable on those |
1359 | * found a way to make load detect reliable on those | 1366 | * chipset, thus just disable it for TV. |
1360 | * chipset, thus just disable it for TV. | 1367 | */ |
1361 | */ | 1368 | if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) |
1362 | if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) | 1369 | radeon_connector->dac_load_detect = false; |
1363 | radeon_connector->dac_load_detect = false; | 1370 | drm_connector_attach_property(&radeon_connector->base, |
1364 | drm_connector_attach_property(&radeon_connector->base, | 1371 | rdev->mode_info.load_detect_property, |
1365 | rdev->mode_info.load_detect_property, | 1372 | radeon_connector->dac_load_detect); |
1366 | radeon_connector->dac_load_detect); | 1373 | drm_connector_attach_property(&radeon_connector->base, |
1367 | drm_connector_attach_property(&radeon_connector->base, | 1374 | rdev->mode_info.tv_std_property, |
1368 | rdev->mode_info.tv_std_property, | 1375 | radeon_combios_get_tv_info(rdev)); |
1369 | radeon_combios_get_tv_info(rdev)); | 1376 | /* no HPD on analog connectors */ |
1370 | /* no HPD on analog connectors */ | 1377 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; |
1371 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | ||
1372 | } | ||
1373 | break; | 1378 | break; |
1374 | case DRM_MODE_CONNECTOR_LVDS: | 1379 | case DRM_MODE_CONNECTOR_LVDS: |
1375 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); | 1380 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 4f7a170d156..256d204a6d2 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -199,7 +199,7 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 | |||
199 | mc->mc_vram_size = mc->aper_size; | 199 | mc->mc_vram_size = mc->aper_size; |
200 | } | 200 | } |
201 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; | 201 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; |
202 | if (rdev->flags & RADEON_IS_AGP && mc->vram_end > mc->gtt_start && mc->vram_end <= mc->gtt_end) { | 202 | if (rdev->flags & RADEON_IS_AGP && mc->vram_end > mc->gtt_start && mc->vram_start <= mc->gtt_end) { |
203 | dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); | 203 | dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); |
204 | mc->real_vram_size = mc->aper_size; | 204 | mc->real_vram_size = mc->aper_size; |
205 | mc->mc_vram_size = mc->aper_size; | 205 | mc->mc_vram_size = mc->aper_size; |
@@ -293,30 +293,20 @@ bool radeon_card_posted(struct radeon_device *rdev) | |||
293 | void radeon_update_bandwidth_info(struct radeon_device *rdev) | 293 | void radeon_update_bandwidth_info(struct radeon_device *rdev) |
294 | { | 294 | { |
295 | fixed20_12 a; | 295 | fixed20_12 a; |
296 | u32 sclk, mclk; | 296 | u32 sclk = rdev->pm.current_sclk; |
297 | u32 mclk = rdev->pm.current_mclk; | ||
297 | 298 | ||
298 | if (rdev->flags & RADEON_IS_IGP) { | 299 | /* sclk/mclk in Mhz */ |
299 | sclk = radeon_get_engine_clock(rdev); | 300 | a.full = dfixed_const(100); |
300 | mclk = rdev->clock.default_mclk; | 301 | rdev->pm.sclk.full = dfixed_const(sclk); |
301 | 302 | rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a); | |
302 | a.full = dfixed_const(100); | 303 | rdev->pm.mclk.full = dfixed_const(mclk); |
303 | rdev->pm.sclk.full = dfixed_const(sclk); | 304 | rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a); |
304 | rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a); | ||
305 | rdev->pm.mclk.full = dfixed_const(mclk); | ||
306 | rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a); | ||
307 | 305 | ||
306 | if (rdev->flags & RADEON_IS_IGP) { | ||
308 | a.full = dfixed_const(16); | 307 | a.full = dfixed_const(16); |
309 | /* core_bandwidth = sclk(Mhz) * 16 */ | 308 | /* core_bandwidth = sclk(Mhz) * 16 */ |
310 | rdev->pm.core_bandwidth.full = dfixed_div(rdev->pm.sclk, a); | 309 | rdev->pm.core_bandwidth.full = dfixed_div(rdev->pm.sclk, a); |
311 | } else { | ||
312 | sclk = radeon_get_engine_clock(rdev); | ||
313 | mclk = radeon_get_memory_clock(rdev); | ||
314 | |||
315 | a.full = dfixed_const(100); | ||
316 | rdev->pm.sclk.full = dfixed_const(sclk); | ||
317 | rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a); | ||
318 | rdev->pm.mclk.full = dfixed_const(mclk); | ||
319 | rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a); | ||
320 | } | 310 | } |
321 | } | 311 | } |
322 | 312 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 5764f4d3b4f..6dd434ad242 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -1094,6 +1094,18 @@ void radeon_modeset_fini(struct radeon_device *rdev) | |||
1094 | radeon_i2c_fini(rdev); | 1094 | radeon_i2c_fini(rdev); |
1095 | } | 1095 | } |
1096 | 1096 | ||
1097 | static bool is_hdtv_mode(struct drm_display_mode *mode) | ||
1098 | { | ||
1099 | /* try and guess if this is a tv or a monitor */ | ||
1100 | if ((mode->vdisplay == 480 && mode->hdisplay == 720) || /* 480p */ | ||
1101 | (mode->vdisplay == 576) || /* 576p */ | ||
1102 | (mode->vdisplay == 720) || /* 720p */ | ||
1103 | (mode->vdisplay == 1080)) /* 1080p */ | ||
1104 | return true; | ||
1105 | else | ||
1106 | return false; | ||
1107 | } | ||
1108 | |||
1097 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | 1109 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, |
1098 | struct drm_display_mode *mode, | 1110 | struct drm_display_mode *mode, |
1099 | struct drm_display_mode *adjusted_mode) | 1111 | struct drm_display_mode *adjusted_mode) |
@@ -1141,7 +1153,8 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
1141 | if (ASIC_IS_AVIVO(rdev) && | 1153 | if (ASIC_IS_AVIVO(rdev) && |
1142 | ((radeon_encoder->underscan_type == UNDERSCAN_ON) || | 1154 | ((radeon_encoder->underscan_type == UNDERSCAN_ON) || |
1143 | ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) && | 1155 | ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) && |
1144 | drm_detect_hdmi_monitor(radeon_connector->edid)))) { | 1156 | drm_detect_hdmi_monitor(radeon_connector->edid) && |
1157 | is_hdtv_mode(mode)))) { | ||
1145 | radeon_crtc->h_border = (mode->hdisplay >> 5) + 16; | 1158 | radeon_crtc->h_border = (mode->hdisplay >> 5) + 16; |
1146 | radeon_crtc->v_border = (mode->vdisplay >> 5) + 16; | 1159 | radeon_crtc->v_border = (mode->vdisplay >> 5) + 16; |
1147 | radeon_crtc->rmx_type = RMX_FULL; | 1160 | radeon_crtc->rmx_type = RMX_FULL; |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 263c8098d7d..2c293e8304d 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -81,7 +81,7 @@ void radeon_setup_encoder_clones(struct drm_device *dev) | |||
81 | } | 81 | } |
82 | 82 | ||
83 | uint32_t | 83 | uint32_t |
84 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac) | 84 | radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8_t dac) |
85 | { | 85 | { |
86 | struct radeon_device *rdev = dev->dev_private; | 86 | struct radeon_device *rdev = dev->dev_private; |
87 | uint32_t ret = 0; | 87 | uint32_t ret = 0; |
@@ -97,59 +97,59 @@ radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t | |||
97 | if ((rdev->family == CHIP_RS300) || | 97 | if ((rdev->family == CHIP_RS300) || |
98 | (rdev->family == CHIP_RS400) || | 98 | (rdev->family == CHIP_RS400) || |
99 | (rdev->family == CHIP_RS480)) | 99 | (rdev->family == CHIP_RS480)) |
100 | ret = ENCODER_OBJECT_ID_INTERNAL_DAC2; | 100 | ret = ENCODER_INTERNAL_DAC2_ENUM_ID1; |
101 | else if (ASIC_IS_AVIVO(rdev)) | 101 | else if (ASIC_IS_AVIVO(rdev)) |
102 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1; | 102 | ret = ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1; |
103 | else | 103 | else |
104 | ret = ENCODER_OBJECT_ID_INTERNAL_DAC1; | 104 | ret = ENCODER_INTERNAL_DAC1_ENUM_ID1; |
105 | break; | 105 | break; |
106 | case 2: /* dac b */ | 106 | case 2: /* dac b */ |
107 | if (ASIC_IS_AVIVO(rdev)) | 107 | if (ASIC_IS_AVIVO(rdev)) |
108 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2; | 108 | ret = ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1; |
109 | else { | 109 | else { |
110 | /*if (rdev->family == CHIP_R200) | 110 | /*if (rdev->family == CHIP_R200) |
111 | ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; | 111 | ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; |
112 | else*/ | 112 | else*/ |
113 | ret = ENCODER_OBJECT_ID_INTERNAL_DAC2; | 113 | ret = ENCODER_INTERNAL_DAC2_ENUM_ID1; |
114 | } | 114 | } |
115 | break; | 115 | break; |
116 | case 3: /* external dac */ | 116 | case 3: /* external dac */ |
117 | if (ASIC_IS_AVIVO(rdev)) | 117 | if (ASIC_IS_AVIVO(rdev)) |
118 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1; | 118 | ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1; |
119 | else | 119 | else |
120 | ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; | 120 | ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; |
121 | break; | 121 | break; |
122 | } | 122 | } |
123 | break; | 123 | break; |
124 | case ATOM_DEVICE_LCD1_SUPPORT: | 124 | case ATOM_DEVICE_LCD1_SUPPORT: |
125 | if (ASIC_IS_AVIVO(rdev)) | 125 | if (ASIC_IS_AVIVO(rdev)) |
126 | ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1; | 126 | ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1; |
127 | else | 127 | else |
128 | ret = ENCODER_OBJECT_ID_INTERNAL_LVDS; | 128 | ret = ENCODER_INTERNAL_LVDS_ENUM_ID1; |
129 | break; | 129 | break; |
130 | case ATOM_DEVICE_DFP1_SUPPORT: | 130 | case ATOM_DEVICE_DFP1_SUPPORT: |
131 | if ((rdev->family == CHIP_RS300) || | 131 | if ((rdev->family == CHIP_RS300) || |
132 | (rdev->family == CHIP_RS400) || | 132 | (rdev->family == CHIP_RS400) || |
133 | (rdev->family == CHIP_RS480)) | 133 | (rdev->family == CHIP_RS480)) |
134 | ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; | 134 | ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; |
135 | else if (ASIC_IS_AVIVO(rdev)) | 135 | else if (ASIC_IS_AVIVO(rdev)) |
136 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1; | 136 | ret = ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1; |
137 | else | 137 | else |
138 | ret = ENCODER_OBJECT_ID_INTERNAL_TMDS1; | 138 | ret = ENCODER_INTERNAL_TMDS1_ENUM_ID1; |
139 | break; | 139 | break; |
140 | case ATOM_DEVICE_LCD2_SUPPORT: | 140 | case ATOM_DEVICE_LCD2_SUPPORT: |
141 | case ATOM_DEVICE_DFP2_SUPPORT: | 141 | case ATOM_DEVICE_DFP2_SUPPORT: |
142 | if ((rdev->family == CHIP_RS600) || | 142 | if ((rdev->family == CHIP_RS600) || |
143 | (rdev->family == CHIP_RS690) || | 143 | (rdev->family == CHIP_RS690) || |
144 | (rdev->family == CHIP_RS740)) | 144 | (rdev->family == CHIP_RS740)) |
145 | ret = ENCODER_OBJECT_ID_INTERNAL_DDI; | 145 | ret = ENCODER_INTERNAL_DDI_ENUM_ID1; |
146 | else if (ASIC_IS_AVIVO(rdev)) | 146 | else if (ASIC_IS_AVIVO(rdev)) |
147 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1; | 147 | ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1; |
148 | else | 148 | else |
149 | ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; | 149 | ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; |
150 | break; | 150 | break; |
151 | case ATOM_DEVICE_DFP3_SUPPORT: | 151 | case ATOM_DEVICE_DFP3_SUPPORT: |
152 | ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1; | 152 | ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1; |
153 | break; | 153 | break; |
154 | } | 154 | } |
155 | 155 | ||
@@ -228,32 +228,6 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder) | |||
228 | return NULL; | 228 | return NULL; |
229 | } | 229 | } |
230 | 230 | ||
231 | static struct radeon_connector_atom_dig * | ||
232 | radeon_get_atom_connector_priv_from_encoder(struct drm_encoder *encoder) | ||
233 | { | ||
234 | struct drm_device *dev = encoder->dev; | ||
235 | struct radeon_device *rdev = dev->dev_private; | ||
236 | struct drm_connector *connector; | ||
237 | struct radeon_connector *radeon_connector; | ||
238 | struct radeon_connector_atom_dig *dig_connector; | ||
239 | |||
240 | if (!rdev->is_atom_bios) | ||
241 | return NULL; | ||
242 | |||
243 | connector = radeon_get_connector_for_encoder(encoder); | ||
244 | if (!connector) | ||
245 | return NULL; | ||
246 | |||
247 | radeon_connector = to_radeon_connector(connector); | ||
248 | |||
249 | if (!radeon_connector->con_priv) | ||
250 | return NULL; | ||
251 | |||
252 | dig_connector = radeon_connector->con_priv; | ||
253 | |||
254 | return dig_connector; | ||
255 | } | ||
256 | |||
257 | void radeon_panel_mode_fixup(struct drm_encoder *encoder, | 231 | void radeon_panel_mode_fixup(struct drm_encoder *encoder, |
258 | struct drm_display_mode *adjusted_mode) | 232 | struct drm_display_mode *adjusted_mode) |
259 | { | 233 | { |
@@ -512,14 +486,12 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
512 | struct radeon_device *rdev = dev->dev_private; | 486 | struct radeon_device *rdev = dev->dev_private; |
513 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 487 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
514 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 488 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
515 | struct radeon_connector_atom_dig *dig_connector = | ||
516 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
517 | union lvds_encoder_control args; | 489 | union lvds_encoder_control args; |
518 | int index = 0; | 490 | int index = 0; |
519 | int hdmi_detected = 0; | 491 | int hdmi_detected = 0; |
520 | uint8_t frev, crev; | 492 | uint8_t frev, crev; |
521 | 493 | ||
522 | if (!dig || !dig_connector) | 494 | if (!dig) |
523 | return; | 495 | return; |
524 | 496 | ||
525 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) | 497 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) |
@@ -562,7 +534,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
562 | if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB) | 534 | if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB) |
563 | args.v1.ucMisc |= (1 << 1); | 535 | args.v1.ucMisc |= (1 << 1); |
564 | } else { | 536 | } else { |
565 | if (dig_connector->linkb) | 537 | if (dig->linkb) |
566 | args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | 538 | args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; |
567 | if (radeon_encoder->pixel_clock > 165000) | 539 | if (radeon_encoder->pixel_clock > 165000) |
568 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 540 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
@@ -601,7 +573,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
601 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; | 573 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; |
602 | } | 574 | } |
603 | } else { | 575 | } else { |
604 | if (dig_connector->linkb) | 576 | if (dig->linkb) |
605 | args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | 577 | args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; |
606 | if (radeon_encoder->pixel_clock > 165000) | 578 | if (radeon_encoder->pixel_clock > 165000) |
607 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 579 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
@@ -623,6 +595,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
623 | int | 595 | int |
624 | atombios_get_encoder_mode(struct drm_encoder *encoder) | 596 | atombios_get_encoder_mode(struct drm_encoder *encoder) |
625 | { | 597 | { |
598 | struct drm_device *dev = encoder->dev; | ||
599 | struct radeon_device *rdev = dev->dev_private; | ||
626 | struct drm_connector *connector; | 600 | struct drm_connector *connector; |
627 | struct radeon_connector *radeon_connector; | 601 | struct radeon_connector *radeon_connector; |
628 | struct radeon_connector_atom_dig *dig_connector; | 602 | struct radeon_connector_atom_dig *dig_connector; |
@@ -636,9 +610,13 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
636 | switch (connector->connector_type) { | 610 | switch (connector->connector_type) { |
637 | case DRM_MODE_CONNECTOR_DVII: | 611 | case DRM_MODE_CONNECTOR_DVII: |
638 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ | 612 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ |
639 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) | 613 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) { |
640 | return ATOM_ENCODER_MODE_HDMI; | 614 | /* fix me */ |
641 | else if (radeon_connector->use_digital) | 615 | if (ASIC_IS_DCE4(rdev)) |
616 | return ATOM_ENCODER_MODE_DVI; | ||
617 | else | ||
618 | return ATOM_ENCODER_MODE_HDMI; | ||
619 | } else if (radeon_connector->use_digital) | ||
642 | return ATOM_ENCODER_MODE_DVI; | 620 | return ATOM_ENCODER_MODE_DVI; |
643 | else | 621 | else |
644 | return ATOM_ENCODER_MODE_CRT; | 622 | return ATOM_ENCODER_MODE_CRT; |
@@ -646,9 +624,13 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
646 | case DRM_MODE_CONNECTOR_DVID: | 624 | case DRM_MODE_CONNECTOR_DVID: |
647 | case DRM_MODE_CONNECTOR_HDMIA: | 625 | case DRM_MODE_CONNECTOR_HDMIA: |
648 | default: | 626 | default: |
649 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) | 627 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) { |
650 | return ATOM_ENCODER_MODE_HDMI; | 628 | /* fix me */ |
651 | else | 629 | if (ASIC_IS_DCE4(rdev)) |
630 | return ATOM_ENCODER_MODE_DVI; | ||
631 | else | ||
632 | return ATOM_ENCODER_MODE_HDMI; | ||
633 | } else | ||
652 | return ATOM_ENCODER_MODE_DVI; | 634 | return ATOM_ENCODER_MODE_DVI; |
653 | break; | 635 | break; |
654 | case DRM_MODE_CONNECTOR_LVDS: | 636 | case DRM_MODE_CONNECTOR_LVDS: |
@@ -660,9 +642,13 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
660 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | 642 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
661 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) | 643 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) |
662 | return ATOM_ENCODER_MODE_DP; | 644 | return ATOM_ENCODER_MODE_DP; |
663 | else if (drm_detect_hdmi_monitor(radeon_connector->edid)) | 645 | else if (drm_detect_hdmi_monitor(radeon_connector->edid)) { |
664 | return ATOM_ENCODER_MODE_HDMI; | 646 | /* fix me */ |
665 | else | 647 | if (ASIC_IS_DCE4(rdev)) |
648 | return ATOM_ENCODER_MODE_DVI; | ||
649 | else | ||
650 | return ATOM_ENCODER_MODE_HDMI; | ||
651 | } else | ||
666 | return ATOM_ENCODER_MODE_DVI; | 652 | return ATOM_ENCODER_MODE_DVI; |
667 | break; | 653 | break; |
668 | case DRM_MODE_CONNECTOR_DVIA: | 654 | case DRM_MODE_CONNECTOR_DVIA: |
@@ -729,13 +715,24 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
729 | struct radeon_device *rdev = dev->dev_private; | 715 | struct radeon_device *rdev = dev->dev_private; |
730 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 716 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
731 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 717 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
732 | struct radeon_connector_atom_dig *dig_connector = | 718 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
733 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
734 | union dig_encoder_control args; | 719 | union dig_encoder_control args; |
735 | int index = 0; | 720 | int index = 0; |
736 | uint8_t frev, crev; | 721 | uint8_t frev, crev; |
722 | int dp_clock = 0; | ||
723 | int dp_lane_count = 0; | ||
724 | |||
725 | if (connector) { | ||
726 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
727 | struct radeon_connector_atom_dig *dig_connector = | ||
728 | radeon_connector->con_priv; | ||
737 | 729 | ||
738 | if (!dig || !dig_connector) | 730 | dp_clock = dig_connector->dp_clock; |
731 | dp_lane_count = dig_connector->dp_lane_count; | ||
732 | } | ||
733 | |||
734 | /* no dig encoder assigned */ | ||
735 | if (dig->dig_encoder == -1) | ||
739 | return; | 736 | return; |
740 | 737 | ||
741 | memset(&args, 0, sizeof(args)); | 738 | memset(&args, 0, sizeof(args)); |
@@ -757,9 +754,9 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
757 | args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); | 754 | args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); |
758 | 755 | ||
759 | if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) { | 756 | if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) { |
760 | if (dig_connector->dp_clock == 270000) | 757 | if (dp_clock == 270000) |
761 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | 758 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; |
762 | args.v1.ucLaneNum = dig_connector->dp_lane_count; | 759 | args.v1.ucLaneNum = dp_lane_count; |
763 | } else if (radeon_encoder->pixel_clock > 165000) | 760 | } else if (radeon_encoder->pixel_clock > 165000) |
764 | args.v1.ucLaneNum = 8; | 761 | args.v1.ucLaneNum = 8; |
765 | else | 762 | else |
@@ -781,7 +778,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
781 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; | 778 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; |
782 | break; | 779 | break; |
783 | } | 780 | } |
784 | if (dig_connector->linkb) | 781 | if (dig->linkb) |
785 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; | 782 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; |
786 | else | 783 | else |
787 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; | 784 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; |
@@ -804,38 +801,47 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
804 | struct radeon_device *rdev = dev->dev_private; | 801 | struct radeon_device *rdev = dev->dev_private; |
805 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 802 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
806 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 803 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
807 | struct radeon_connector_atom_dig *dig_connector = | 804 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
808 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
809 | struct drm_connector *connector; | ||
810 | struct radeon_connector *radeon_connector; | ||
811 | union dig_transmitter_control args; | 805 | union dig_transmitter_control args; |
812 | int index = 0; | 806 | int index = 0; |
813 | uint8_t frev, crev; | 807 | uint8_t frev, crev; |
814 | bool is_dp = false; | 808 | bool is_dp = false; |
815 | int pll_id = 0; | 809 | int pll_id = 0; |
810 | int dp_clock = 0; | ||
811 | int dp_lane_count = 0; | ||
812 | int connector_object_id = 0; | ||
813 | int igp_lane_info = 0; | ||
816 | 814 | ||
817 | if (!dig || !dig_connector) | 815 | if (connector) { |
818 | return; | 816 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
817 | struct radeon_connector_atom_dig *dig_connector = | ||
818 | radeon_connector->con_priv; | ||
819 | 819 | ||
820 | connector = radeon_get_connector_for_encoder(encoder); | 820 | dp_clock = dig_connector->dp_clock; |
821 | radeon_connector = to_radeon_connector(connector); | 821 | dp_lane_count = dig_connector->dp_lane_count; |
822 | connector_object_id = | ||
823 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
824 | igp_lane_info = dig_connector->igp_lane_info; | ||
825 | } | ||
826 | |||
827 | /* no dig encoder assigned */ | ||
828 | if (dig->dig_encoder == -1) | ||
829 | return; | ||
822 | 830 | ||
823 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) | 831 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) |
824 | is_dp = true; | 832 | is_dp = true; |
825 | 833 | ||
826 | memset(&args, 0, sizeof(args)); | 834 | memset(&args, 0, sizeof(args)); |
827 | 835 | ||
828 | if (ASIC_IS_DCE32(rdev) || ASIC_IS_DCE4(rdev)) | 836 | switch (radeon_encoder->encoder_id) { |
837 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
838 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
839 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
829 | index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); | 840 | index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); |
830 | else { | 841 | break; |
831 | switch (radeon_encoder->encoder_id) { | 842 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
832 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 843 | index = GetIndexIntoMasterTable(COMMAND, LVTMATransmitterControl); |
833 | index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl); | 844 | break; |
834 | break; | ||
835 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
836 | index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl); | ||
837 | break; | ||
838 | } | ||
839 | } | 845 | } |
840 | 846 | ||
841 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | 847 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) |
@@ -843,14 +849,14 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
843 | 849 | ||
844 | args.v1.ucAction = action; | 850 | args.v1.ucAction = action; |
845 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | 851 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { |
846 | args.v1.usInitInfo = radeon_connector->connector_object_id; | 852 | args.v1.usInitInfo = connector_object_id; |
847 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { | 853 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { |
848 | args.v1.asMode.ucLaneSel = lane_num; | 854 | args.v1.asMode.ucLaneSel = lane_num; |
849 | args.v1.asMode.ucLaneSet = lane_set; | 855 | args.v1.asMode.ucLaneSet = lane_set; |
850 | } else { | 856 | } else { |
851 | if (is_dp) | 857 | if (is_dp) |
852 | args.v1.usPixelClock = | 858 | args.v1.usPixelClock = |
853 | cpu_to_le16(dig_connector->dp_clock / 10); | 859 | cpu_to_le16(dp_clock / 10); |
854 | else if (radeon_encoder->pixel_clock > 165000) | 860 | else if (radeon_encoder->pixel_clock > 165000) |
855 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 861 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
856 | else | 862 | else |
@@ -858,13 +864,13 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
858 | } | 864 | } |
859 | if (ASIC_IS_DCE4(rdev)) { | 865 | if (ASIC_IS_DCE4(rdev)) { |
860 | if (is_dp) | 866 | if (is_dp) |
861 | args.v3.ucLaneNum = dig_connector->dp_lane_count; | 867 | args.v3.ucLaneNum = dp_lane_count; |
862 | else if (radeon_encoder->pixel_clock > 165000) | 868 | else if (radeon_encoder->pixel_clock > 165000) |
863 | args.v3.ucLaneNum = 8; | 869 | args.v3.ucLaneNum = 8; |
864 | else | 870 | else |
865 | args.v3.ucLaneNum = 4; | 871 | args.v3.ucLaneNum = 4; |
866 | 872 | ||
867 | if (dig_connector->linkb) { | 873 | if (dig->linkb) { |
868 | args.v3.acConfig.ucLinkSel = 1; | 874 | args.v3.acConfig.ucLinkSel = 1; |
869 | args.v3.acConfig.ucEncoderSel = 1; | 875 | args.v3.acConfig.ucEncoderSel = 1; |
870 | } | 876 | } |
@@ -904,7 +910,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
904 | } | 910 | } |
905 | } else if (ASIC_IS_DCE32(rdev)) { | 911 | } else if (ASIC_IS_DCE32(rdev)) { |
906 | args.v2.acConfig.ucEncoderSel = dig->dig_encoder; | 912 | args.v2.acConfig.ucEncoderSel = dig->dig_encoder; |
907 | if (dig_connector->linkb) | 913 | if (dig->linkb) |
908 | args.v2.acConfig.ucLinkSel = 1; | 914 | args.v2.acConfig.ucLinkSel = 1; |
909 | 915 | ||
910 | switch (radeon_encoder->encoder_id) { | 916 | switch (radeon_encoder->encoder_id) { |
@@ -938,23 +944,23 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
938 | if ((rdev->flags & RADEON_IS_IGP) && | 944 | if ((rdev->flags & RADEON_IS_IGP) && |
939 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { | 945 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { |
940 | if (is_dp || (radeon_encoder->pixel_clock <= 165000)) { | 946 | if (is_dp || (radeon_encoder->pixel_clock <= 165000)) { |
941 | if (dig_connector->igp_lane_info & 0x1) | 947 | if (igp_lane_info & 0x1) |
942 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; | 948 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; |
943 | else if (dig_connector->igp_lane_info & 0x2) | 949 | else if (igp_lane_info & 0x2) |
944 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; | 950 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; |
945 | else if (dig_connector->igp_lane_info & 0x4) | 951 | else if (igp_lane_info & 0x4) |
946 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; | 952 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; |
947 | else if (dig_connector->igp_lane_info & 0x8) | 953 | else if (igp_lane_info & 0x8) |
948 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; | 954 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; |
949 | } else { | 955 | } else { |
950 | if (dig_connector->igp_lane_info & 0x3) | 956 | if (igp_lane_info & 0x3) |
951 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; | 957 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; |
952 | else if (dig_connector->igp_lane_info & 0xc) | 958 | else if (igp_lane_info & 0xc) |
953 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; | 959 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; |
954 | } | 960 | } |
955 | } | 961 | } |
956 | 962 | ||
957 | if (dig_connector->linkb) | 963 | if (dig->linkb) |
958 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB; | 964 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB; |
959 | else | 965 | else |
960 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; | 966 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; |
@@ -1072,8 +1078,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
1072 | if (is_dig) { | 1078 | if (is_dig) { |
1073 | switch (mode) { | 1079 | switch (mode) { |
1074 | case DRM_MODE_DPMS_ON: | 1080 | case DRM_MODE_DPMS_ON: |
1075 | if (!ASIC_IS_DCE4(rdev)) | 1081 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); |
1076 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | ||
1077 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { | 1082 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { |
1078 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | 1083 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
1079 | 1084 | ||
@@ -1085,8 +1090,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
1085 | case DRM_MODE_DPMS_STANDBY: | 1090 | case DRM_MODE_DPMS_STANDBY: |
1086 | case DRM_MODE_DPMS_SUSPEND: | 1091 | case DRM_MODE_DPMS_SUSPEND: |
1087 | case DRM_MODE_DPMS_OFF: | 1092 | case DRM_MODE_DPMS_OFF: |
1088 | if (!ASIC_IS_DCE4(rdev)) | 1093 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); |
1089 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | ||
1090 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { | 1094 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { |
1091 | if (ASIC_IS_DCE4(rdev)) | 1095 | if (ASIC_IS_DCE4(rdev)) |
1092 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF); | 1096 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF); |
@@ -1290,24 +1294,22 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) | |||
1290 | uint32_t dig_enc_in_use = 0; | 1294 | uint32_t dig_enc_in_use = 0; |
1291 | 1295 | ||
1292 | if (ASIC_IS_DCE4(rdev)) { | 1296 | if (ASIC_IS_DCE4(rdev)) { |
1293 | struct radeon_connector_atom_dig *dig_connector = | 1297 | dig = radeon_encoder->enc_priv; |
1294 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
1295 | |||
1296 | switch (radeon_encoder->encoder_id) { | 1298 | switch (radeon_encoder->encoder_id) { |
1297 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 1299 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
1298 | if (dig_connector->linkb) | 1300 | if (dig->linkb) |
1299 | return 1; | 1301 | return 1; |
1300 | else | 1302 | else |
1301 | return 0; | 1303 | return 0; |
1302 | break; | 1304 | break; |
1303 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 1305 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
1304 | if (dig_connector->linkb) | 1306 | if (dig->linkb) |
1305 | return 3; | 1307 | return 3; |
1306 | else | 1308 | else |
1307 | return 2; | 1309 | return 2; |
1308 | break; | 1310 | break; |
1309 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1311 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
1310 | if (dig_connector->linkb) | 1312 | if (dig->linkb) |
1311 | return 5; | 1313 | return 5; |
1312 | else | 1314 | else |
1313 | return 4; | 1315 | return 4; |
@@ -1641,6 +1643,7 @@ radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) | |||
1641 | struct radeon_encoder_atom_dig * | 1643 | struct radeon_encoder_atom_dig * |
1642 | radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) | 1644 | radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) |
1643 | { | 1645 | { |
1646 | int encoder_enum = (radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | ||
1644 | struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); | 1647 | struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); |
1645 | 1648 | ||
1646 | if (!dig) | 1649 | if (!dig) |
@@ -1650,11 +1653,16 @@ radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) | |||
1650 | dig->coherent_mode = true; | 1653 | dig->coherent_mode = true; |
1651 | dig->dig_encoder = -1; | 1654 | dig->dig_encoder = -1; |
1652 | 1655 | ||
1656 | if (encoder_enum == 2) | ||
1657 | dig->linkb = true; | ||
1658 | else | ||
1659 | dig->linkb = false; | ||
1660 | |||
1653 | return dig; | 1661 | return dig; |
1654 | } | 1662 | } |
1655 | 1663 | ||
1656 | void | 1664 | void |
1657 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device) | 1665 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t supported_device) |
1658 | { | 1666 | { |
1659 | struct radeon_device *rdev = dev->dev_private; | 1667 | struct radeon_device *rdev = dev->dev_private; |
1660 | struct drm_encoder *encoder; | 1668 | struct drm_encoder *encoder; |
@@ -1663,7 +1671,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su | |||
1663 | /* see if we already added it */ | 1671 | /* see if we already added it */ |
1664 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 1672 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
1665 | radeon_encoder = to_radeon_encoder(encoder); | 1673 | radeon_encoder = to_radeon_encoder(encoder); |
1666 | if (radeon_encoder->encoder_id == encoder_id) { | 1674 | if (radeon_encoder->encoder_enum == encoder_enum) { |
1667 | radeon_encoder->devices |= supported_device; | 1675 | radeon_encoder->devices |= supported_device; |
1668 | return; | 1676 | return; |
1669 | } | 1677 | } |
@@ -1691,7 +1699,8 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su | |||
1691 | 1699 | ||
1692 | radeon_encoder->enc_priv = NULL; | 1700 | radeon_encoder->enc_priv = NULL; |
1693 | 1701 | ||
1694 | radeon_encoder->encoder_id = encoder_id; | 1702 | radeon_encoder->encoder_enum = encoder_enum; |
1703 | radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
1695 | radeon_encoder->devices = supported_device; | 1704 | radeon_encoder->devices = supported_device; |
1696 | radeon_encoder->rmx_type = RMX_OFF; | 1705 | radeon_encoder->rmx_type = RMX_OFF; |
1697 | radeon_encoder->underscan_type = UNDERSCAN_OFF; | 1706 | radeon_encoder->underscan_type = UNDERSCAN_OFF; |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index dbf86962bdd..c74a8b20d94 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -118,7 +118,7 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev, | |||
118 | aligned_size = ALIGN(size, PAGE_SIZE); | 118 | aligned_size = ALIGN(size, PAGE_SIZE); |
119 | ret = radeon_gem_object_create(rdev, aligned_size, 0, | 119 | ret = radeon_gem_object_create(rdev, aligned_size, 0, |
120 | RADEON_GEM_DOMAIN_VRAM, | 120 | RADEON_GEM_DOMAIN_VRAM, |
121 | false, ttm_bo_type_kernel, | 121 | false, true, |
122 | &gobj); | 122 | &gobj); |
123 | if (ret) { | 123 | if (ret) { |
124 | printk(KERN_ERR "failed to allocate framebuffer (%d)\n", | 124 | printk(KERN_ERR "failed to allocate framebuffer (%d)\n", |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index bfd2ce5f537..6a13ee38a5b 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
@@ -99,6 +99,13 @@ static void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state) | |||
99 | } | 99 | } |
100 | } | 100 | } |
101 | 101 | ||
102 | /* switch the pads to ddc mode */ | ||
103 | if (ASIC_IS_DCE3(rdev) && rec->hw_capable) { | ||
104 | temp = RREG32(rec->mask_clk_reg); | ||
105 | temp &= ~(1 << 16); | ||
106 | WREG32(rec->mask_clk_reg, temp); | ||
107 | } | ||
108 | |||
102 | /* clear the output pin values */ | 109 | /* clear the output pin values */ |
103 | temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask; | 110 | temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask; |
104 | WREG32(rec->a_clk_reg, temp); | 111 | WREG32(rec->a_clk_reg, temp); |
@@ -206,7 +213,7 @@ static void post_xfer(struct i2c_adapter *i2c_adap) | |||
206 | 213 | ||
207 | static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) | 214 | static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) |
208 | { | 215 | { |
209 | u32 sclk = radeon_get_engine_clock(rdev); | 216 | u32 sclk = rdev->pm.current_sclk; |
210 | u32 prescale = 0; | 217 | u32 prescale = 0; |
211 | u32 nm; | 218 | u32 nm; |
212 | u8 n, m, loop; | 219 | u8 n, m, loop; |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 059bfa4098d..a108c7ed14f 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -121,11 +121,12 @@ int radeon_irq_kms_init(struct radeon_device *rdev) | |||
121 | * chips. Disable MSI on them for now. | 121 | * chips. Disable MSI on them for now. |
122 | */ | 122 | */ |
123 | if ((rdev->family >= CHIP_RV380) && | 123 | if ((rdev->family >= CHIP_RV380) && |
124 | (!(rdev->flags & RADEON_IS_IGP))) { | 124 | (!(rdev->flags & RADEON_IS_IGP)) && |
125 | (!(rdev->flags & RADEON_IS_AGP))) { | ||
125 | int ret = pci_enable_msi(rdev->pdev); | 126 | int ret = pci_enable_msi(rdev->pdev); |
126 | if (!ret) { | 127 | if (!ret) { |
127 | rdev->msi_enabled = 1; | 128 | rdev->msi_enabled = 1; |
128 | DRM_INFO("radeon: using MSI.\n"); | 129 | dev_info(rdev->dev, "radeon: using MSI.\n"); |
129 | } | 130 | } |
130 | } | 131 | } |
131 | rdev->irq.installed = true; | 132 | rdev->irq.installed = true; |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index b1c8ace5f08..5eee3c41d12 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -161,6 +161,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
161 | DRM_DEBUG_KMS("tiling config is r6xx+ only!\n"); | 161 | DRM_DEBUG_KMS("tiling config is r6xx+ only!\n"); |
162 | return -EINVAL; | 162 | return -EINVAL; |
163 | } | 163 | } |
164 | break; | ||
164 | case RADEON_INFO_WANT_HYPERZ: | 165 | case RADEON_INFO_WANT_HYPERZ: |
165 | /* The "value" here is both an input and output parameter. | 166 | /* The "value" here is both an input and output parameter. |
166 | * If the input value is 1, filp requests hyper-z access. | 167 | * If the input value is 1, filp requests hyper-z access. |
@@ -323,45 +324,45 @@ KMS_INVALID_IOCTL(radeon_surface_free_kms) | |||
323 | 324 | ||
324 | 325 | ||
325 | struct drm_ioctl_desc radeon_ioctls_kms[] = { | 326 | struct drm_ioctl_desc radeon_ioctls_kms[] = { |
326 | DRM_IOCTL_DEF(DRM_RADEON_CP_INIT, radeon_cp_init_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 327 | DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, radeon_cp_init_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
327 | DRM_IOCTL_DEF(DRM_RADEON_CP_START, radeon_cp_start_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 328 | DRM_IOCTL_DEF_DRV(RADEON_CP_START, radeon_cp_start_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
328 | DRM_IOCTL_DEF(DRM_RADEON_CP_STOP, radeon_cp_stop_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 329 | DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, radeon_cp_stop_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
329 | DRM_IOCTL_DEF(DRM_RADEON_CP_RESET, radeon_cp_reset_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 330 | DRM_IOCTL_DEF_DRV(RADEON_CP_RESET, radeon_cp_reset_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
330 | DRM_IOCTL_DEF(DRM_RADEON_CP_IDLE, radeon_cp_idle_kms, DRM_AUTH), | 331 | DRM_IOCTL_DEF_DRV(RADEON_CP_IDLE, radeon_cp_idle_kms, DRM_AUTH), |
331 | DRM_IOCTL_DEF(DRM_RADEON_CP_RESUME, radeon_cp_resume_kms, DRM_AUTH), | 332 | DRM_IOCTL_DEF_DRV(RADEON_CP_RESUME, radeon_cp_resume_kms, DRM_AUTH), |
332 | DRM_IOCTL_DEF(DRM_RADEON_RESET, radeon_engine_reset_kms, DRM_AUTH), | 333 | DRM_IOCTL_DEF_DRV(RADEON_RESET, radeon_engine_reset_kms, DRM_AUTH), |
333 | DRM_IOCTL_DEF(DRM_RADEON_FULLSCREEN, radeon_fullscreen_kms, DRM_AUTH), | 334 | DRM_IOCTL_DEF_DRV(RADEON_FULLSCREEN, radeon_fullscreen_kms, DRM_AUTH), |
334 | DRM_IOCTL_DEF(DRM_RADEON_SWAP, radeon_cp_swap_kms, DRM_AUTH), | 335 | DRM_IOCTL_DEF_DRV(RADEON_SWAP, radeon_cp_swap_kms, DRM_AUTH), |
335 | DRM_IOCTL_DEF(DRM_RADEON_CLEAR, radeon_cp_clear_kms, DRM_AUTH), | 336 | DRM_IOCTL_DEF_DRV(RADEON_CLEAR, radeon_cp_clear_kms, DRM_AUTH), |
336 | DRM_IOCTL_DEF(DRM_RADEON_VERTEX, radeon_cp_vertex_kms, DRM_AUTH), | 337 | DRM_IOCTL_DEF_DRV(RADEON_VERTEX, radeon_cp_vertex_kms, DRM_AUTH), |
337 | DRM_IOCTL_DEF(DRM_RADEON_INDICES, radeon_cp_indices_kms, DRM_AUTH), | 338 | DRM_IOCTL_DEF_DRV(RADEON_INDICES, radeon_cp_indices_kms, DRM_AUTH), |
338 | DRM_IOCTL_DEF(DRM_RADEON_TEXTURE, radeon_cp_texture_kms, DRM_AUTH), | 339 | DRM_IOCTL_DEF_DRV(RADEON_TEXTURE, radeon_cp_texture_kms, DRM_AUTH), |
339 | DRM_IOCTL_DEF(DRM_RADEON_STIPPLE, radeon_cp_stipple_kms, DRM_AUTH), | 340 | DRM_IOCTL_DEF_DRV(RADEON_STIPPLE, radeon_cp_stipple_kms, DRM_AUTH), |
340 | DRM_IOCTL_DEF(DRM_RADEON_INDIRECT, radeon_cp_indirect_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 341 | DRM_IOCTL_DEF_DRV(RADEON_INDIRECT, radeon_cp_indirect_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
341 | DRM_IOCTL_DEF(DRM_RADEON_VERTEX2, radeon_cp_vertex2_kms, DRM_AUTH), | 342 | DRM_IOCTL_DEF_DRV(RADEON_VERTEX2, radeon_cp_vertex2_kms, DRM_AUTH), |
342 | DRM_IOCTL_DEF(DRM_RADEON_CMDBUF, radeon_cp_cmdbuf_kms, DRM_AUTH), | 343 | DRM_IOCTL_DEF_DRV(RADEON_CMDBUF, radeon_cp_cmdbuf_kms, DRM_AUTH), |
343 | DRM_IOCTL_DEF(DRM_RADEON_GETPARAM, radeon_cp_getparam_kms, DRM_AUTH), | 344 | DRM_IOCTL_DEF_DRV(RADEON_GETPARAM, radeon_cp_getparam_kms, DRM_AUTH), |
344 | DRM_IOCTL_DEF(DRM_RADEON_FLIP, radeon_cp_flip_kms, DRM_AUTH), | 345 | DRM_IOCTL_DEF_DRV(RADEON_FLIP, radeon_cp_flip_kms, DRM_AUTH), |
345 | DRM_IOCTL_DEF(DRM_RADEON_ALLOC, radeon_mem_alloc_kms, DRM_AUTH), | 346 | DRM_IOCTL_DEF_DRV(RADEON_ALLOC, radeon_mem_alloc_kms, DRM_AUTH), |
346 | DRM_IOCTL_DEF(DRM_RADEON_FREE, radeon_mem_free_kms, DRM_AUTH), | 347 | DRM_IOCTL_DEF_DRV(RADEON_FREE, radeon_mem_free_kms, DRM_AUTH), |
347 | DRM_IOCTL_DEF(DRM_RADEON_INIT_HEAP, radeon_mem_init_heap_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 348 | DRM_IOCTL_DEF_DRV(RADEON_INIT_HEAP, radeon_mem_init_heap_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
348 | DRM_IOCTL_DEF(DRM_RADEON_IRQ_EMIT, radeon_irq_emit_kms, DRM_AUTH), | 349 | DRM_IOCTL_DEF_DRV(RADEON_IRQ_EMIT, radeon_irq_emit_kms, DRM_AUTH), |
349 | DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait_kms, DRM_AUTH), | 350 | DRM_IOCTL_DEF_DRV(RADEON_IRQ_WAIT, radeon_irq_wait_kms, DRM_AUTH), |
350 | DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam_kms, DRM_AUTH), | 351 | DRM_IOCTL_DEF_DRV(RADEON_SETPARAM, radeon_cp_setparam_kms, DRM_AUTH), |
351 | DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc_kms, DRM_AUTH), | 352 | DRM_IOCTL_DEF_DRV(RADEON_SURF_ALLOC, radeon_surface_alloc_kms, DRM_AUTH), |
352 | DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free_kms, DRM_AUTH), | 353 | DRM_IOCTL_DEF_DRV(RADEON_SURF_FREE, radeon_surface_free_kms, DRM_AUTH), |
353 | /* KMS */ | 354 | /* KMS */ |
354 | DRM_IOCTL_DEF(DRM_RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH|DRM_UNLOCKED), | 355 | DRM_IOCTL_DEF_DRV(RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH|DRM_UNLOCKED), |
355 | DRM_IOCTL_DEF(DRM_RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH|DRM_UNLOCKED), | 356 | DRM_IOCTL_DEF_DRV(RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH|DRM_UNLOCKED), |
356 | DRM_IOCTL_DEF(DRM_RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH|DRM_UNLOCKED), | 357 | DRM_IOCTL_DEF_DRV(RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH|DRM_UNLOCKED), |
357 | DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH|DRM_UNLOCKED), | 358 | DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH|DRM_UNLOCKED), |
358 | DRM_IOCTL_DEF(DRM_RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH|DRM_UNLOCKED), | 359 | DRM_IOCTL_DEF_DRV(RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH|DRM_UNLOCKED), |
359 | DRM_IOCTL_DEF(DRM_RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH|DRM_UNLOCKED), | 360 | DRM_IOCTL_DEF_DRV(RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH|DRM_UNLOCKED), |
360 | DRM_IOCTL_DEF(DRM_RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH|DRM_UNLOCKED), | 361 | DRM_IOCTL_DEF_DRV(RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH|DRM_UNLOCKED), |
361 | DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH|DRM_UNLOCKED), | 362 | DRM_IOCTL_DEF_DRV(RADEON_CS, radeon_cs_ioctl, DRM_AUTH|DRM_UNLOCKED), |
362 | DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH|DRM_UNLOCKED), | 363 | DRM_IOCTL_DEF_DRV(RADEON_INFO, radeon_info_ioctl, DRM_AUTH|DRM_UNLOCKED), |
363 | DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), | 364 | DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), |
364 | DRM_IOCTL_DEF(DRM_RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), | 365 | DRM_IOCTL_DEF_DRV(RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), |
365 | DRM_IOCTL_DEF(DRM_RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), | 366 | DRM_IOCTL_DEF_DRV(RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), |
366 | }; | 367 | }; |
367 | int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms); | 368 | int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms); |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 989df519a1e..305049afde1 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -272,7 +272,7 @@ static uint8_t radeon_compute_pll_gain(uint16_t ref_freq, uint16_t ref_div, | |||
272 | if (!ref_div) | 272 | if (!ref_div) |
273 | return 1; | 273 | return 1; |
274 | 274 | ||
275 | vcoFreq = ((unsigned)ref_freq & fb_div) / ref_div; | 275 | vcoFreq = ((unsigned)ref_freq * fb_div) / ref_div; |
276 | 276 | ||
277 | /* | 277 | /* |
278 | * This is horribly crude: the VCO frequency range is divided into | 278 | * This is horribly crude: the VCO frequency range is divided into |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index b8149cbc0c7..0b8397000f4 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
@@ -1345,7 +1345,7 @@ static struct radeon_encoder_ext_tmds *radeon_legacy_get_ext_tmds_info(struct ra | |||
1345 | } | 1345 | } |
1346 | 1346 | ||
1347 | void | 1347 | void |
1348 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device) | 1348 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t supported_device) |
1349 | { | 1349 | { |
1350 | struct radeon_device *rdev = dev->dev_private; | 1350 | struct radeon_device *rdev = dev->dev_private; |
1351 | struct drm_encoder *encoder; | 1351 | struct drm_encoder *encoder; |
@@ -1354,7 +1354,7 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t | |||
1354 | /* see if we already added it */ | 1354 | /* see if we already added it */ |
1355 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 1355 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
1356 | radeon_encoder = to_radeon_encoder(encoder); | 1356 | radeon_encoder = to_radeon_encoder(encoder); |
1357 | if (radeon_encoder->encoder_id == encoder_id) { | 1357 | if (radeon_encoder->encoder_enum == encoder_enum) { |
1358 | radeon_encoder->devices |= supported_device; | 1358 | radeon_encoder->devices |= supported_device; |
1359 | return; | 1359 | return; |
1360 | } | 1360 | } |
@@ -1374,7 +1374,8 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t | |||
1374 | 1374 | ||
1375 | radeon_encoder->enc_priv = NULL; | 1375 | radeon_encoder->enc_priv = NULL; |
1376 | 1376 | ||
1377 | radeon_encoder->encoder_id = encoder_id; | 1377 | radeon_encoder->encoder_enum = encoder_enum; |
1378 | radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
1378 | radeon_encoder->devices = supported_device; | 1379 | radeon_encoder->devices = supported_device; |
1379 | radeon_encoder->rmx_type = RMX_OFF; | 1380 | radeon_encoder->rmx_type = RMX_OFF; |
1380 | 1381 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 5bbc086b926..efbe975312d 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -342,6 +342,7 @@ struct radeon_atom_ss { | |||
342 | }; | 342 | }; |
343 | 343 | ||
344 | struct radeon_encoder_atom_dig { | 344 | struct radeon_encoder_atom_dig { |
345 | bool linkb; | ||
345 | /* atom dig */ | 346 | /* atom dig */ |
346 | bool coherent_mode; | 347 | bool coherent_mode; |
347 | int dig_encoder; /* -1 disabled, 0 DIGA, 1 DIGB */ | 348 | int dig_encoder; /* -1 disabled, 0 DIGA, 1 DIGB */ |
@@ -360,6 +361,7 @@ struct radeon_encoder_atom_dac { | |||
360 | 361 | ||
361 | struct radeon_encoder { | 362 | struct radeon_encoder { |
362 | struct drm_encoder base; | 363 | struct drm_encoder base; |
364 | uint32_t encoder_enum; | ||
363 | uint32_t encoder_id; | 365 | uint32_t encoder_id; |
364 | uint32_t devices; | 366 | uint32_t devices; |
365 | uint32_t active_device; | 367 | uint32_t active_device; |
@@ -378,7 +380,6 @@ struct radeon_encoder { | |||
378 | 380 | ||
379 | struct radeon_connector_atom_dig { | 381 | struct radeon_connector_atom_dig { |
380 | uint32_t igp_lane_info; | 382 | uint32_t igp_lane_info; |
381 | bool linkb; | ||
382 | /* displayport */ | 383 | /* displayport */ |
383 | struct radeon_i2c_chan *dp_i2c_bus; | 384 | struct radeon_i2c_chan *dp_i2c_bus; |
384 | u8 dpcd[8]; | 385 | u8 dpcd[8]; |
@@ -599,7 +600,6 @@ extern bool radeon_get_atom_connector_info_from_supported_devices_table(struct d | |||
599 | void radeon_enc_destroy(struct drm_encoder *encoder); | 600 | void radeon_enc_destroy(struct drm_encoder *encoder); |
600 | void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj); | 601 | void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj); |
601 | void radeon_combios_asic_init(struct drm_device *dev); | 602 | void radeon_combios_asic_init(struct drm_device *dev); |
602 | extern int radeon_static_clocks_init(struct drm_device *dev); | ||
603 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | 603 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, |
604 | struct drm_display_mode *mode, | 604 | struct drm_display_mode *mode, |
605 | struct drm_display_mode *adjusted_mode); | 605 | struct drm_display_mode *adjusted_mode); |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 58038f5cab3..f87efec7623 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -226,6 +226,11 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) | |||
226 | { | 226 | { |
227 | int i; | 227 | int i; |
228 | 228 | ||
229 | /* no need to take locks, etc. if nothing's going to change */ | ||
230 | if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) && | ||
231 | (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index)) | ||
232 | return; | ||
233 | |||
229 | mutex_lock(&rdev->ddev->struct_mutex); | 234 | mutex_lock(&rdev->ddev->struct_mutex); |
230 | mutex_lock(&rdev->vram_mutex); | 235 | mutex_lock(&rdev->vram_mutex); |
231 | mutex_lock(&rdev->cp.mutex); | 236 | mutex_lock(&rdev->cp.mutex); |
@@ -632,8 +637,6 @@ void radeon_pm_fini(struct radeon_device *rdev) | |||
632 | } | 637 | } |
633 | 638 | ||
634 | radeon_hwmon_fini(rdev); | 639 | radeon_hwmon_fini(rdev); |
635 | if (rdev->pm.i2c_bus) | ||
636 | radeon_i2c_destroy(rdev->pm.i2c_bus); | ||
637 | } | 640 | } |
638 | 641 | ||
639 | void radeon_pm_compute_clocks(struct radeon_device *rdev) | 642 | void radeon_pm_compute_clocks(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index b3ba44c0a81..4ae5a3d1074 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c | |||
@@ -3228,34 +3228,34 @@ void radeon_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) | |||
3228 | } | 3228 | } |
3229 | 3229 | ||
3230 | struct drm_ioctl_desc radeon_ioctls[] = { | 3230 | struct drm_ioctl_desc radeon_ioctls[] = { |
3231 | DRM_IOCTL_DEF(DRM_RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3231 | DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
3232 | DRM_IOCTL_DEF(DRM_RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3232 | DRM_IOCTL_DEF_DRV(RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
3233 | DRM_IOCTL_DEF(DRM_RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3233 | DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
3234 | DRM_IOCTL_DEF(DRM_RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3234 | DRM_IOCTL_DEF_DRV(RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
3235 | DRM_IOCTL_DEF(DRM_RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH), | 3235 | DRM_IOCTL_DEF_DRV(RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH), |
3236 | DRM_IOCTL_DEF(DRM_RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH), | 3236 | DRM_IOCTL_DEF_DRV(RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH), |
3237 | DRM_IOCTL_DEF(DRM_RADEON_RESET, radeon_engine_reset, DRM_AUTH), | 3237 | DRM_IOCTL_DEF_DRV(RADEON_RESET, radeon_engine_reset, DRM_AUTH), |
3238 | DRM_IOCTL_DEF(DRM_RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH), | 3238 | DRM_IOCTL_DEF_DRV(RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH), |
3239 | DRM_IOCTL_DEF(DRM_RADEON_SWAP, radeon_cp_swap, DRM_AUTH), | 3239 | DRM_IOCTL_DEF_DRV(RADEON_SWAP, radeon_cp_swap, DRM_AUTH), |
3240 | DRM_IOCTL_DEF(DRM_RADEON_CLEAR, radeon_cp_clear, DRM_AUTH), | 3240 | DRM_IOCTL_DEF_DRV(RADEON_CLEAR, radeon_cp_clear, DRM_AUTH), |
3241 | DRM_IOCTL_DEF(DRM_RADEON_VERTEX, radeon_cp_vertex, DRM_AUTH), | 3241 | DRM_IOCTL_DEF_DRV(RADEON_VERTEX, radeon_cp_vertex, DRM_AUTH), |
3242 | DRM_IOCTL_DEF(DRM_RADEON_INDICES, radeon_cp_indices, DRM_AUTH), | 3242 | DRM_IOCTL_DEF_DRV(RADEON_INDICES, radeon_cp_indices, DRM_AUTH), |
3243 | DRM_IOCTL_DEF(DRM_RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH), | 3243 | DRM_IOCTL_DEF_DRV(RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH), |
3244 | DRM_IOCTL_DEF(DRM_RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH), | 3244 | DRM_IOCTL_DEF_DRV(RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH), |
3245 | DRM_IOCTL_DEF(DRM_RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3245 | DRM_IOCTL_DEF_DRV(RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
3246 | DRM_IOCTL_DEF(DRM_RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH), | 3246 | DRM_IOCTL_DEF_DRV(RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH), |
3247 | DRM_IOCTL_DEF(DRM_RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH), | 3247 | DRM_IOCTL_DEF_DRV(RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH), |
3248 | DRM_IOCTL_DEF(DRM_RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH), | 3248 | DRM_IOCTL_DEF_DRV(RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH), |
3249 | DRM_IOCTL_DEF(DRM_RADEON_FLIP, radeon_cp_flip, DRM_AUTH), | 3249 | DRM_IOCTL_DEF_DRV(RADEON_FLIP, radeon_cp_flip, DRM_AUTH), |
3250 | DRM_IOCTL_DEF(DRM_RADEON_ALLOC, radeon_mem_alloc, DRM_AUTH), | 3250 | DRM_IOCTL_DEF_DRV(RADEON_ALLOC, radeon_mem_alloc, DRM_AUTH), |
3251 | DRM_IOCTL_DEF(DRM_RADEON_FREE, radeon_mem_free, DRM_AUTH), | 3251 | DRM_IOCTL_DEF_DRV(RADEON_FREE, radeon_mem_free, DRM_AUTH), |
3252 | DRM_IOCTL_DEF(DRM_RADEON_INIT_HEAP, radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3252 | DRM_IOCTL_DEF_DRV(RADEON_INIT_HEAP, radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
3253 | DRM_IOCTL_DEF(DRM_RADEON_IRQ_EMIT, radeon_irq_emit, DRM_AUTH), | 3253 | DRM_IOCTL_DEF_DRV(RADEON_IRQ_EMIT, radeon_irq_emit, DRM_AUTH), |
3254 | DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH), | 3254 | DRM_IOCTL_DEF_DRV(RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH), |
3255 | DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH), | 3255 | DRM_IOCTL_DEF_DRV(RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH), |
3256 | DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH), | 3256 | DRM_IOCTL_DEF_DRV(RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH), |
3257 | DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH), | 3257 | DRM_IOCTL_DEF_DRV(RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH), |
3258 | DRM_IOCTL_DEF(DRM_RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH) | 3258 | DRM_IOCTL_DEF_DRV(RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH) |
3259 | }; | 3259 | }; |
3260 | 3260 | ||
3261 | int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); | 3261 | int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index f1c79681011..bfa59db374d 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -905,6 +905,54 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
905 | 905 | ||
906 | } | 906 | } |
907 | 907 | ||
908 | static int rv770_vram_scratch_init(struct radeon_device *rdev) | ||
909 | { | ||
910 | int r; | ||
911 | u64 gpu_addr; | ||
912 | |||
913 | if (rdev->vram_scratch.robj == NULL) { | ||
914 | r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, | ||
915 | true, RADEON_GEM_DOMAIN_VRAM, | ||
916 | &rdev->vram_scratch.robj); | ||
917 | if (r) { | ||
918 | return r; | ||
919 | } | ||
920 | } | ||
921 | |||
922 | r = radeon_bo_reserve(rdev->vram_scratch.robj, false); | ||
923 | if (unlikely(r != 0)) | ||
924 | return r; | ||
925 | r = radeon_bo_pin(rdev->vram_scratch.robj, | ||
926 | RADEON_GEM_DOMAIN_VRAM, &gpu_addr); | ||
927 | if (r) { | ||
928 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
929 | return r; | ||
930 | } | ||
931 | r = radeon_bo_kmap(rdev->vram_scratch.robj, | ||
932 | (void **)&rdev->vram_scratch.ptr); | ||
933 | if (r) | ||
934 | radeon_bo_unpin(rdev->vram_scratch.robj); | ||
935 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
936 | |||
937 | return r; | ||
938 | } | ||
939 | |||
940 | static void rv770_vram_scratch_fini(struct radeon_device *rdev) | ||
941 | { | ||
942 | int r; | ||
943 | |||
944 | if (rdev->vram_scratch.robj == NULL) { | ||
945 | return; | ||
946 | } | ||
947 | r = radeon_bo_reserve(rdev->vram_scratch.robj, false); | ||
948 | if (likely(r == 0)) { | ||
949 | radeon_bo_kunmap(rdev->vram_scratch.robj); | ||
950 | radeon_bo_unpin(rdev->vram_scratch.robj); | ||
951 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
952 | } | ||
953 | radeon_bo_unref(&rdev->vram_scratch.robj); | ||
954 | } | ||
955 | |||
908 | int rv770_mc_init(struct radeon_device *rdev) | 956 | int rv770_mc_init(struct radeon_device *rdev) |
909 | { | 957 | { |
910 | u32 tmp; | 958 | u32 tmp; |
@@ -970,6 +1018,9 @@ static int rv770_startup(struct radeon_device *rdev) | |||
970 | if (r) | 1018 | if (r) |
971 | return r; | 1019 | return r; |
972 | } | 1020 | } |
1021 | r = rv770_vram_scratch_init(rdev); | ||
1022 | if (r) | ||
1023 | return r; | ||
973 | rv770_gpu_init(rdev); | 1024 | rv770_gpu_init(rdev); |
974 | r = r600_blit_init(rdev); | 1025 | r = r600_blit_init(rdev); |
975 | if (r) { | 1026 | if (r) { |
@@ -1023,11 +1074,6 @@ int rv770_resume(struct radeon_device *rdev) | |||
1023 | */ | 1074 | */ |
1024 | /* post card */ | 1075 | /* post card */ |
1025 | atom_asic_init(rdev->mode_info.atom_context); | 1076 | atom_asic_init(rdev->mode_info.atom_context); |
1026 | /* Initialize clocks */ | ||
1027 | r = radeon_clocks_init(rdev); | ||
1028 | if (r) { | ||
1029 | return r; | ||
1030 | } | ||
1031 | 1077 | ||
1032 | r = rv770_startup(rdev); | 1078 | r = rv770_startup(rdev); |
1033 | if (r) { | 1079 | if (r) { |
@@ -1118,9 +1164,6 @@ int rv770_init(struct radeon_device *rdev) | |||
1118 | radeon_surface_init(rdev); | 1164 | radeon_surface_init(rdev); |
1119 | /* Initialize clocks */ | 1165 | /* Initialize clocks */ |
1120 | radeon_get_clock_info(rdev->ddev); | 1166 | radeon_get_clock_info(rdev->ddev); |
1121 | r = radeon_clocks_init(rdev); | ||
1122 | if (r) | ||
1123 | return r; | ||
1124 | /* Fence driver */ | 1167 | /* Fence driver */ |
1125 | r = radeon_fence_driver_init(rdev); | 1168 | r = radeon_fence_driver_init(rdev); |
1126 | if (r) | 1169 | if (r) |
@@ -1195,9 +1238,9 @@ void rv770_fini(struct radeon_device *rdev) | |||
1195 | r600_irq_fini(rdev); | 1238 | r600_irq_fini(rdev); |
1196 | radeon_irq_kms_fini(rdev); | 1239 | radeon_irq_kms_fini(rdev); |
1197 | rv770_pcie_gart_fini(rdev); | 1240 | rv770_pcie_gart_fini(rdev); |
1241 | rv770_vram_scratch_fini(rdev); | ||
1198 | radeon_gem_fini(rdev); | 1242 | radeon_gem_fini(rdev); |
1199 | radeon_fence_driver_fini(rdev); | 1243 | radeon_fence_driver_fini(rdev); |
1200 | radeon_clocks_fini(rdev); | ||
1201 | radeon_agp_fini(rdev); | 1244 | radeon_agp_fini(rdev); |
1202 | radeon_bo_fini(rdev); | 1245 | radeon_bo_fini(rdev); |
1203 | radeon_atombios_fini(rdev); | 1246 | radeon_atombios_fini(rdev); |
diff --git a/drivers/gpu/drm/savage/savage_bci.c b/drivers/gpu/drm/savage/savage_bci.c index 976dc8d2528..bf5f83ea14f 100644 --- a/drivers/gpu/drm/savage/savage_bci.c +++ b/drivers/gpu/drm/savage/savage_bci.c | |||
@@ -1082,10 +1082,10 @@ void savage_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv) | |||
1082 | } | 1082 | } |
1083 | 1083 | ||
1084 | struct drm_ioctl_desc savage_ioctls[] = { | 1084 | struct drm_ioctl_desc savage_ioctls[] = { |
1085 | DRM_IOCTL_DEF(DRM_SAVAGE_BCI_INIT, savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1085 | DRM_IOCTL_DEF_DRV(SAVAGE_BCI_INIT, savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1086 | DRM_IOCTL_DEF(DRM_SAVAGE_BCI_CMDBUF, savage_bci_cmdbuf, DRM_AUTH), | 1086 | DRM_IOCTL_DEF_DRV(SAVAGE_BCI_CMDBUF, savage_bci_cmdbuf, DRM_AUTH), |
1087 | DRM_IOCTL_DEF(DRM_SAVAGE_BCI_EVENT_EMIT, savage_bci_event_emit, DRM_AUTH), | 1087 | DRM_IOCTL_DEF_DRV(SAVAGE_BCI_EVENT_EMIT, savage_bci_event_emit, DRM_AUTH), |
1088 | DRM_IOCTL_DEF(DRM_SAVAGE_BCI_EVENT_WAIT, savage_bci_event_wait, DRM_AUTH), | 1088 | DRM_IOCTL_DEF_DRV(SAVAGE_BCI_EVENT_WAIT, savage_bci_event_wait, DRM_AUTH), |
1089 | }; | 1089 | }; |
1090 | 1090 | ||
1091 | int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls); | 1091 | int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls); |
diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c index 07d0f2979ca..7fe2b63412c 100644 --- a/drivers/gpu/drm/sis/sis_mm.c +++ b/drivers/gpu/drm/sis/sis_mm.c | |||
@@ -320,12 +320,12 @@ void sis_reclaim_buffers_locked(struct drm_device *dev, | |||
320 | } | 320 | } |
321 | 321 | ||
322 | struct drm_ioctl_desc sis_ioctls[] = { | 322 | struct drm_ioctl_desc sis_ioctls[] = { |
323 | DRM_IOCTL_DEF(DRM_SIS_FB_ALLOC, sis_fb_alloc, DRM_AUTH), | 323 | DRM_IOCTL_DEF_DRV(SIS_FB_ALLOC, sis_fb_alloc, DRM_AUTH), |
324 | DRM_IOCTL_DEF(DRM_SIS_FB_FREE, sis_drm_free, DRM_AUTH), | 324 | DRM_IOCTL_DEF_DRV(SIS_FB_FREE, sis_drm_free, DRM_AUTH), |
325 | DRM_IOCTL_DEF(DRM_SIS_AGP_INIT, sis_ioctl_agp_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), | 325 | DRM_IOCTL_DEF_DRV(SIS_AGP_INIT, sis_ioctl_agp_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), |
326 | DRM_IOCTL_DEF(DRM_SIS_AGP_ALLOC, sis_ioctl_agp_alloc, DRM_AUTH), | 326 | DRM_IOCTL_DEF_DRV(SIS_AGP_ALLOC, sis_ioctl_agp_alloc, DRM_AUTH), |
327 | DRM_IOCTL_DEF(DRM_SIS_AGP_FREE, sis_drm_free, DRM_AUTH), | 327 | DRM_IOCTL_DEF_DRV(SIS_AGP_FREE, sis_drm_free, DRM_AUTH), |
328 | DRM_IOCTL_DEF(DRM_SIS_FB_INIT, sis_fb_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), | 328 | DRM_IOCTL_DEF_DRV(SIS_FB_INIT, sis_fb_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), |
329 | }; | 329 | }; |
330 | 330 | ||
331 | int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls); | 331 | int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls); |
diff --git a/drivers/gpu/drm/via/via_dma.c b/drivers/gpu/drm/via/via_dma.c index 68dda74a50a..cc0ffa9abd0 100644 --- a/drivers/gpu/drm/via/via_dma.c +++ b/drivers/gpu/drm/via/via_dma.c | |||
@@ -722,20 +722,20 @@ static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file * | |||
722 | } | 722 | } |
723 | 723 | ||
724 | struct drm_ioctl_desc via_ioctls[] = { | 724 | struct drm_ioctl_desc via_ioctls[] = { |
725 | DRM_IOCTL_DEF(DRM_VIA_ALLOCMEM, via_mem_alloc, DRM_AUTH), | 725 | DRM_IOCTL_DEF_DRV(VIA_ALLOCMEM, via_mem_alloc, DRM_AUTH), |
726 | DRM_IOCTL_DEF(DRM_VIA_FREEMEM, via_mem_free, DRM_AUTH), | 726 | DRM_IOCTL_DEF_DRV(VIA_FREEMEM, via_mem_free, DRM_AUTH), |
727 | DRM_IOCTL_DEF(DRM_VIA_AGP_INIT, via_agp_init, DRM_AUTH|DRM_MASTER), | 727 | DRM_IOCTL_DEF_DRV(VIA_AGP_INIT, via_agp_init, DRM_AUTH|DRM_MASTER), |
728 | DRM_IOCTL_DEF(DRM_VIA_FB_INIT, via_fb_init, DRM_AUTH|DRM_MASTER), | 728 | DRM_IOCTL_DEF_DRV(VIA_FB_INIT, via_fb_init, DRM_AUTH|DRM_MASTER), |
729 | DRM_IOCTL_DEF(DRM_VIA_MAP_INIT, via_map_init, DRM_AUTH|DRM_MASTER), | 729 | DRM_IOCTL_DEF_DRV(VIA_MAP_INIT, via_map_init, DRM_AUTH|DRM_MASTER), |
730 | DRM_IOCTL_DEF(DRM_VIA_DEC_FUTEX, via_decoder_futex, DRM_AUTH), | 730 | DRM_IOCTL_DEF_DRV(VIA_DEC_FUTEX, via_decoder_futex, DRM_AUTH), |
731 | DRM_IOCTL_DEF(DRM_VIA_DMA_INIT, via_dma_init, DRM_AUTH), | 731 | DRM_IOCTL_DEF_DRV(VIA_DMA_INIT, via_dma_init, DRM_AUTH), |
732 | DRM_IOCTL_DEF(DRM_VIA_CMDBUFFER, via_cmdbuffer, DRM_AUTH), | 732 | DRM_IOCTL_DEF_DRV(VIA_CMDBUFFER, via_cmdbuffer, DRM_AUTH), |
733 | DRM_IOCTL_DEF(DRM_VIA_FLUSH, via_flush_ioctl, DRM_AUTH), | 733 | DRM_IOCTL_DEF_DRV(VIA_FLUSH, via_flush_ioctl, DRM_AUTH), |
734 | DRM_IOCTL_DEF(DRM_VIA_PCICMD, via_pci_cmdbuffer, DRM_AUTH), | 734 | DRM_IOCTL_DEF_DRV(VIA_PCICMD, via_pci_cmdbuffer, DRM_AUTH), |
735 | DRM_IOCTL_DEF(DRM_VIA_CMDBUF_SIZE, via_cmdbuf_size, DRM_AUTH), | 735 | DRM_IOCTL_DEF_DRV(VIA_CMDBUF_SIZE, via_cmdbuf_size, DRM_AUTH), |
736 | DRM_IOCTL_DEF(DRM_VIA_WAIT_IRQ, via_wait_irq, DRM_AUTH), | 736 | DRM_IOCTL_DEF_DRV(VIA_WAIT_IRQ, via_wait_irq, DRM_AUTH), |
737 | DRM_IOCTL_DEF(DRM_VIA_DMA_BLIT, via_dma_blit, DRM_AUTH), | 737 | DRM_IOCTL_DEF_DRV(VIA_DMA_BLIT, via_dma_blit, DRM_AUTH), |
738 | DRM_IOCTL_DEF(DRM_VIA_BLIT_SYNC, via_dma_blit_sync, DRM_AUTH) | 738 | DRM_IOCTL_DEF_DRV(VIA_BLIT_SYNC, via_dma_blit_sync, DRM_AUTH) |
739 | }; | 739 | }; |
740 | 740 | ||
741 | int via_max_ioctl = DRM_ARRAY_SIZE(via_ioctls); | 741 | int via_max_ioctl = DRM_ARRAY_SIZE(via_ioctls); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 9dd395b9021..72ec2e2b6e9 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -99,47 +99,47 @@ | |||
99 | */ | 99 | */ |
100 | 100 | ||
101 | #define VMW_IOCTL_DEF(ioctl, func, flags) \ | 101 | #define VMW_IOCTL_DEF(ioctl, func, flags) \ |
102 | [DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func} | 102 | [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = {DRM_##ioctl, flags, func, DRM_IOCTL_##ioctl} |
103 | 103 | ||
104 | /** | 104 | /** |
105 | * Ioctl definitions. | 105 | * Ioctl definitions. |
106 | */ | 106 | */ |
107 | 107 | ||
108 | static struct drm_ioctl_desc vmw_ioctls[] = { | 108 | static struct drm_ioctl_desc vmw_ioctls[] = { |
109 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_GET_PARAM, vmw_getparam_ioctl, | 109 | VMW_IOCTL_DEF(VMW_GET_PARAM, vmw_getparam_ioctl, |
110 | DRM_AUTH | DRM_UNLOCKED), | 110 | DRM_AUTH | DRM_UNLOCKED), |
111 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_ALLOC_DMABUF, vmw_dmabuf_alloc_ioctl, | 111 | VMW_IOCTL_DEF(VMW_ALLOC_DMABUF, vmw_dmabuf_alloc_ioctl, |
112 | DRM_AUTH | DRM_UNLOCKED), | 112 | DRM_AUTH | DRM_UNLOCKED), |
113 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_DMABUF, vmw_dmabuf_unref_ioctl, | 113 | VMW_IOCTL_DEF(VMW_UNREF_DMABUF, vmw_dmabuf_unref_ioctl, |
114 | DRM_AUTH | DRM_UNLOCKED), | 114 | DRM_AUTH | DRM_UNLOCKED), |
115 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CURSOR_BYPASS, | 115 | VMW_IOCTL_DEF(VMW_CURSOR_BYPASS, |
116 | vmw_kms_cursor_bypass_ioctl, | 116 | vmw_kms_cursor_bypass_ioctl, |
117 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), | 117 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), |
118 | 118 | ||
119 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CONTROL_STREAM, vmw_overlay_ioctl, | 119 | VMW_IOCTL_DEF(VMW_CONTROL_STREAM, vmw_overlay_ioctl, |
120 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), | 120 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), |
121 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CLAIM_STREAM, vmw_stream_claim_ioctl, | 121 | VMW_IOCTL_DEF(VMW_CLAIM_STREAM, vmw_stream_claim_ioctl, |
122 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), | 122 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), |
123 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_STREAM, vmw_stream_unref_ioctl, | 123 | VMW_IOCTL_DEF(VMW_UNREF_STREAM, vmw_stream_unref_ioctl, |
124 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), | 124 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), |
125 | 125 | ||
126 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_CONTEXT, vmw_context_define_ioctl, | 126 | VMW_IOCTL_DEF(VMW_CREATE_CONTEXT, vmw_context_define_ioctl, |
127 | DRM_AUTH | DRM_UNLOCKED), | 127 | DRM_AUTH | DRM_UNLOCKED), |
128 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl, | 128 | VMW_IOCTL_DEF(VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl, |
129 | DRM_AUTH | DRM_UNLOCKED), | 129 | DRM_AUTH | DRM_UNLOCKED), |
130 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_SURFACE, vmw_surface_define_ioctl, | 130 | VMW_IOCTL_DEF(VMW_CREATE_SURFACE, vmw_surface_define_ioctl, |
131 | DRM_AUTH | DRM_UNLOCKED), | 131 | DRM_AUTH | DRM_UNLOCKED), |
132 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl, | 132 | VMW_IOCTL_DEF(VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl, |
133 | DRM_AUTH | DRM_UNLOCKED), | 133 | DRM_AUTH | DRM_UNLOCKED), |
134 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_REF_SURFACE, vmw_surface_reference_ioctl, | 134 | VMW_IOCTL_DEF(VMW_REF_SURFACE, vmw_surface_reference_ioctl, |
135 | DRM_AUTH | DRM_UNLOCKED), | 135 | DRM_AUTH | DRM_UNLOCKED), |
136 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_EXECBUF, vmw_execbuf_ioctl, | 136 | VMW_IOCTL_DEF(VMW_EXECBUF, vmw_execbuf_ioctl, |
137 | DRM_AUTH | DRM_UNLOCKED), | 137 | DRM_AUTH | DRM_UNLOCKED), |
138 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl, | 138 | VMW_IOCTL_DEF(VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl, |
139 | DRM_AUTH | DRM_ROOT_ONLY | DRM_MASTER | DRM_UNLOCKED), | 139 | DRM_AUTH | DRM_ROOT_ONLY | DRM_MASTER | DRM_UNLOCKED), |
140 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_FENCE_WAIT, vmw_fence_wait_ioctl, | 140 | VMW_IOCTL_DEF(VMW_FENCE_WAIT, vmw_fence_wait_ioctl, |
141 | DRM_AUTH | DRM_UNLOCKED), | 141 | DRM_AUTH | DRM_UNLOCKED), |
142 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UPDATE_LAYOUT, vmw_kms_update_layout_ioctl, | 142 | VMW_IOCTL_DEF(VMW_UPDATE_LAYOUT, vmw_kms_update_layout_ioctl, |
143 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED) | 143 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED) |
144 | }; | 144 | }; |
145 | 145 | ||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index e635199a0cd..0c52899be96 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1299,6 +1299,7 @@ static const struct hid_device_id hid_blacklist[] = { | |||
1299 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, | 1299 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, |
1300 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, | 1300 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, |
1301 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, | 1301 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, |
1302 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, | ||
1302 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, | 1303 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, |
1303 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, | 1304 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, |
1304 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, | 1305 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, |
diff --git a/drivers/hid/hid-egalax.c b/drivers/hid/hid-egalax.c index f44bdc084cb..8ca7f65cf2f 100644 --- a/drivers/hid/hid-egalax.c +++ b/drivers/hid/hid-egalax.c | |||
@@ -159,6 +159,13 @@ static int egalax_event(struct hid_device *hid, struct hid_field *field, | |||
159 | { | 159 | { |
160 | struct egalax_data *td = hid_get_drvdata(hid); | 160 | struct egalax_data *td = hid_get_drvdata(hid); |
161 | 161 | ||
162 | /* Note, eGalax has two product lines: the first is resistive and | ||
163 | * uses a standard parallel multitouch protocol (product ID == | ||
164 | * 48xx). The second is capacitive and uses an unusual "serial" | ||
165 | * protocol with a different message for each multitouch finger | ||
166 | * (product ID == 72xx). We do not yet generate a correct event | ||
167 | * sequence for the capacitive/serial protocol. | ||
168 | */ | ||
162 | if (hid->claimed & HID_CLAIMED_INPUT) { | 169 | if (hid->claimed & HID_CLAIMED_INPUT) { |
163 | struct input_dev *input = field->hidinput->input; | 170 | struct input_dev *input = field->hidinput->input; |
164 | 171 | ||
@@ -246,6 +253,8 @@ static void egalax_remove(struct hid_device *hdev) | |||
246 | static const struct hid_device_id egalax_devices[] = { | 253 | static const struct hid_device_id egalax_devices[] = { |
247 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 254 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, |
248 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, | 255 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, |
256 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
257 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, | ||
249 | { } | 258 | { } |
250 | }; | 259 | }; |
251 | MODULE_DEVICE_TABLE(hid, egalax_devices); | 260 | MODULE_DEVICE_TABLE(hid, egalax_devices); |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index d3fc13ae094..85c6d13c9ff 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -188,6 +188,7 @@ | |||
188 | #define USB_VENDOR_ID_DWAV 0x0eef | 188 | #define USB_VENDOR_ID_DWAV 0x0eef |
189 | #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 | 189 | #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 |
190 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d | 190 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d |
191 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1 0x720c | ||
191 | 192 | ||
192 | #define USB_VENDOR_ID_ELECOM 0x056e | 193 | #define USB_VENDOR_ID_ELECOM 0x056e |
193 | #define USB_DEVICE_ID_ELECOM_BM084 0x0061 | 194 | #define USB_DEVICE_ID_ELECOM_BM084 0x0061 |
diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c index 346f0e34987..bc2e0774062 100644 --- a/drivers/hid/hid-picolcd.c +++ b/drivers/hid/hid-picolcd.c | |||
@@ -547,11 +547,11 @@ static void picolcd_fb_destroy(struct fb_info *info) | |||
547 | ref_cnt--; | 547 | ref_cnt--; |
548 | mutex_lock(&info->lock); | 548 | mutex_lock(&info->lock); |
549 | (*ref_cnt)--; | 549 | (*ref_cnt)--; |
550 | may_release = !ref_cnt; | 550 | may_release = !*ref_cnt; |
551 | mutex_unlock(&info->lock); | 551 | mutex_unlock(&info->lock); |
552 | if (may_release) { | 552 | if (may_release) { |
553 | framebuffer_release(info); | ||
554 | vfree((u8 *)info->fix.smem_start); | 553 | vfree((u8 *)info->fix.smem_start); |
554 | framebuffer_release(info); | ||
555 | } | 555 | } |
556 | } | 556 | } |
557 | 557 | ||
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 254a003af04..0a29c51114a 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
@@ -266,13 +266,15 @@ static int hiddev_open(struct inode *inode, struct file *file) | |||
266 | { | 266 | { |
267 | struct hiddev_list *list; | 267 | struct hiddev_list *list; |
268 | struct usb_interface *intf; | 268 | struct usb_interface *intf; |
269 | struct hid_device *hid; | ||
269 | struct hiddev *hiddev; | 270 | struct hiddev *hiddev; |
270 | int res; | 271 | int res; |
271 | 272 | ||
272 | intf = usb_find_interface(&hiddev_driver, iminor(inode)); | 273 | intf = usb_find_interface(&hiddev_driver, iminor(inode)); |
273 | if (!intf) | 274 | if (!intf) |
274 | return -ENODEV; | 275 | return -ENODEV; |
275 | hiddev = usb_get_intfdata(intf); | 276 | hid = usb_get_intfdata(intf); |
277 | hiddev = hid->hiddev; | ||
276 | 278 | ||
277 | if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL))) | 279 | if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL))) |
278 | return -ENOMEM; | 280 | return -ENOMEM; |
@@ -587,7 +589,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
587 | struct hiddev_list *list = file->private_data; | 589 | struct hiddev_list *list = file->private_data; |
588 | struct hiddev *hiddev = list->hiddev; | 590 | struct hiddev *hiddev = list->hiddev; |
589 | struct hid_device *hid = hiddev->hid; | 591 | struct hid_device *hid = hiddev->hid; |
590 | struct usb_device *dev = hid_to_usb_dev(hid); | 592 | struct usb_device *dev; |
591 | struct hiddev_collection_info cinfo; | 593 | struct hiddev_collection_info cinfo; |
592 | struct hiddev_report_info rinfo; | 594 | struct hiddev_report_info rinfo; |
593 | struct hiddev_field_info finfo; | 595 | struct hiddev_field_info finfo; |
@@ -601,9 +603,11 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
601 | /* Called without BKL by compat methods so no BKL taken */ | 603 | /* Called without BKL by compat methods so no BKL taken */ |
602 | 604 | ||
603 | /* FIXME: Who or what stop this racing with a disconnect ?? */ | 605 | /* FIXME: Who or what stop this racing with a disconnect ?? */ |
604 | if (!hiddev->exist) | 606 | if (!hiddev->exist || !hid) |
605 | return -EIO; | 607 | return -EIO; |
606 | 608 | ||
609 | dev = hid_to_usb_dev(hid); | ||
610 | |||
607 | switch (cmd) { | 611 | switch (cmd) { |
608 | 612 | ||
609 | case HIDIOCGVERSION: | 613 | case HIDIOCGVERSION: |
@@ -888,7 +892,6 @@ int hiddev_connect(struct hid_device *hid, unsigned int force) | |||
888 | hid->hiddev = hiddev; | 892 | hid->hiddev = hiddev; |
889 | hiddev->hid = hid; | 893 | hiddev->hid = hid; |
890 | hiddev->exist = 1; | 894 | hiddev->exist = 1; |
891 | usb_set_intfdata(usbhid->intf, usbhid); | ||
892 | retval = usb_register_dev(usbhid->intf, &hiddev_class); | 895 | retval = usb_register_dev(usbhid->intf, &hiddev_class); |
893 | if (retval) { | 896 | if (retval) { |
894 | err_hid("Not able to get a minor for this device."); | 897 | err_hid("Not able to get a minor for this device."); |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 0fba8294312..4d4d09bdec0 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -332,11 +332,11 @@ config SENSORS_F71805F | |||
332 | will be called f71805f. | 332 | will be called f71805f. |
333 | 333 | ||
334 | config SENSORS_F71882FG | 334 | config SENSORS_F71882FG |
335 | tristate "Fintek F71808E, F71858FG, F71862FG, F71882FG, F71889FG and F8000" | 335 | tristate "Fintek F71858FG, F71862FG, F71882FG, F71889FG and F8000" |
336 | depends on EXPERIMENTAL | 336 | depends on EXPERIMENTAL |
337 | help | 337 | help |
338 | If you say yes here you get support for hardware monitoring features | 338 | If you say yes here you get support for hardware monitoring |
339 | of the Fintek F71808E, F71858FG, F71862FG/71863FG, F71882FG/F71883FG, | 339 | features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG, |
340 | F71889FG and F8000 Super-I/O chips. | 340 | F71889FG and F8000 Super-I/O chips. |
341 | 341 | ||
342 | This driver can also be built as a module. If so, the module | 342 | This driver can also be built as a module. If so, the module |
diff --git a/drivers/hwmon/ads7871.c b/drivers/hwmon/ads7871.c index b300a2048af..52319340e18 100644 --- a/drivers/hwmon/ads7871.c +++ b/drivers/hwmon/ads7871.c | |||
@@ -160,30 +160,12 @@ static const struct attribute_group ads7871_group = { | |||
160 | 160 | ||
161 | static int __devinit ads7871_probe(struct spi_device *spi) | 161 | static int __devinit ads7871_probe(struct spi_device *spi) |
162 | { | 162 | { |
163 | int status, ret, err = 0; | 163 | int ret, err; |
164 | uint8_t val; | 164 | uint8_t val; |
165 | struct ads7871_data *pdata; | 165 | struct ads7871_data *pdata; |
166 | 166 | ||
167 | dev_dbg(&spi->dev, "probe\n"); | 167 | dev_dbg(&spi->dev, "probe\n"); |
168 | 168 | ||
169 | pdata = kzalloc(sizeof(struct ads7871_data), GFP_KERNEL); | ||
170 | if (!pdata) { | ||
171 | err = -ENOMEM; | ||
172 | goto exit; | ||
173 | } | ||
174 | |||
175 | status = sysfs_create_group(&spi->dev.kobj, &ads7871_group); | ||
176 | if (status < 0) | ||
177 | goto error_free; | ||
178 | |||
179 | pdata->hwmon_dev = hwmon_device_register(&spi->dev); | ||
180 | if (IS_ERR(pdata->hwmon_dev)) { | ||
181 | err = PTR_ERR(pdata->hwmon_dev); | ||
182 | goto error_remove; | ||
183 | } | ||
184 | |||
185 | spi_set_drvdata(spi, pdata); | ||
186 | |||
187 | /* Configure the SPI bus */ | 169 | /* Configure the SPI bus */ |
188 | spi->mode = (SPI_MODE_0); | 170 | spi->mode = (SPI_MODE_0); |
189 | spi->bits_per_word = 8; | 171 | spi->bits_per_word = 8; |
@@ -201,6 +183,24 @@ static int __devinit ads7871_probe(struct spi_device *spi) | |||
201 | we need to make sure we really have a chip*/ | 183 | we need to make sure we really have a chip*/ |
202 | if (val != ret) { | 184 | if (val != ret) { |
203 | err = -ENODEV; | 185 | err = -ENODEV; |
186 | goto exit; | ||
187 | } | ||
188 | |||
189 | pdata = kzalloc(sizeof(struct ads7871_data), GFP_KERNEL); | ||
190 | if (!pdata) { | ||
191 | err = -ENOMEM; | ||
192 | goto exit; | ||
193 | } | ||
194 | |||
195 | err = sysfs_create_group(&spi->dev.kobj, &ads7871_group); | ||
196 | if (err < 0) | ||
197 | goto error_free; | ||
198 | |||
199 | spi_set_drvdata(spi, pdata); | ||
200 | |||
201 | pdata->hwmon_dev = hwmon_device_register(&spi->dev); | ||
202 | if (IS_ERR(pdata->hwmon_dev)) { | ||
203 | err = PTR_ERR(pdata->hwmon_dev); | ||
204 | goto error_remove; | 204 | goto error_remove; |
205 | } | 205 | } |
206 | 206 | ||
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index c070c9714cb..de8111114f4 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -518,7 +518,6 @@ static struct notifier_block coretemp_cpu_notifier __refdata = { | |||
518 | static int __init coretemp_init(void) | 518 | static int __init coretemp_init(void) |
519 | { | 519 | { |
520 | int i, err = -ENODEV; | 520 | int i, err = -ENODEV; |
521 | struct pdev_entry *p, *n; | ||
522 | 521 | ||
523 | /* quick check if we run Intel */ | 522 | /* quick check if we run Intel */ |
524 | if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL) | 523 | if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL) |
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 6207120dcd4..537841ef44b 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ | 45 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ |
46 | 46 | ||
47 | #define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ | 47 | #define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ |
48 | #define SIO_F71808_ID 0x0901 /* Chipset ID */ | ||
49 | #define SIO_F71858_ID 0x0507 /* Chipset ID */ | 48 | #define SIO_F71858_ID 0x0507 /* Chipset ID */ |
50 | #define SIO_F71862_ID 0x0601 /* Chipset ID */ | 49 | #define SIO_F71862_ID 0x0601 /* Chipset ID */ |
51 | #define SIO_F71882_ID 0x0541 /* Chipset ID */ | 50 | #define SIO_F71882_ID 0x0541 /* Chipset ID */ |
@@ -97,10 +96,9 @@ static unsigned short force_id; | |||
97 | module_param(force_id, ushort, 0); | 96 | module_param(force_id, ushort, 0); |
98 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | 97 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); |
99 | 98 | ||
100 | enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg, f8000 }; | 99 | enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 }; |
101 | 100 | ||
102 | static const char *f71882fg_names[] = { | 101 | static const char *f71882fg_names[] = { |
103 | "f71808fg", | ||
104 | "f71858fg", | 102 | "f71858fg", |
105 | "f71862fg", | 103 | "f71862fg", |
106 | "f71882fg", | 104 | "f71882fg", |
@@ -308,8 +306,8 @@ static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = { | |||
308 | SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), | 306 | SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), |
309 | }; | 307 | }; |
310 | 308 | ||
311 | /* In attr common to the f71862fg, f71882fg and f71889fg */ | 309 | /* Temp and in attr common to the f71862fg, f71882fg and f71889fg */ |
312 | static struct sensor_device_attribute_2 fxxxx_in_attr[] = { | 310 | static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = { |
313 | SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), | 311 | SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), |
314 | SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), | 312 | SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), |
315 | SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2), | 313 | SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2), |
@@ -319,22 +317,6 @@ static struct sensor_device_attribute_2 fxxxx_in_attr[] = { | |||
319 | SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6), | 317 | SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6), |
320 | SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7), | 318 | SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7), |
321 | SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8), | 319 | SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8), |
322 | }; | ||
323 | |||
324 | /* In attr for the f71808fg */ | ||
325 | static struct sensor_device_attribute_2 f71808_in_attr[] = { | ||
326 | SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), | ||
327 | SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), | ||
328 | SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2), | ||
329 | SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3), | ||
330 | SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4), | ||
331 | SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5), | ||
332 | SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 7), | ||
333 | SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 8), | ||
334 | }; | ||
335 | |||
336 | /* Temp attr common to the f71808fg, f71862fg, f71882fg and f71889fg */ | ||
337 | static struct sensor_device_attribute_2 fxxxx_temp_attr[] = { | ||
338 | SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1), | 320 | SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1), |
339 | SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, | 321 | SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, |
340 | store_temp_max, 0, 1), | 322 | store_temp_max, 0, 1), |
@@ -373,10 +355,6 @@ static struct sensor_device_attribute_2 fxxxx_temp_attr[] = { | |||
373 | store_temp_beep, 0, 6), | 355 | store_temp_beep, 0, 6), |
374 | SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2), | 356 | SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2), |
375 | SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), | 357 | SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), |
376 | }; | ||
377 | |||
378 | /* Temp and in attr common to the f71862fg, f71882fg and f71889fg */ | ||
379 | static struct sensor_device_attribute_2 f71862_temp_attr[] = { | ||
380 | SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3), | 358 | SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3), |
381 | SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max, | 359 | SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max, |
382 | store_temp_max, 0, 3), | 360 | store_temp_max, 0, 3), |
@@ -1011,11 +989,6 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev) | |||
1011 | data->temp_type[1] = 6; | 989 | data->temp_type[1] = 6; |
1012 | break; | 990 | break; |
1013 | } | 991 | } |
1014 | } else if (data->type == f71808fg) { | ||
1015 | reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE); | ||
1016 | data->temp_type[1] = (reg & 0x02) ? 2 : 4; | ||
1017 | data->temp_type[2] = (reg & 0x04) ? 2 : 4; | ||
1018 | |||
1019 | } else { | 992 | } else { |
1020 | reg2 = f71882fg_read8(data, F71882FG_REG_PECI); | 993 | reg2 = f71882fg_read8(data, F71882FG_REG_PECI); |
1021 | if ((reg2 & 0x03) == 0x01) | 994 | if ((reg2 & 0x03) == 0x01) |
@@ -1898,8 +1871,7 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev, | |||
1898 | 1871 | ||
1899 | val /= 1000; | 1872 | val /= 1000; |
1900 | 1873 | ||
1901 | if (data->type == f71889fg | 1874 | if (data->type == f71889fg) |
1902 | || data->type == f71808fg) | ||
1903 | val = SENSORS_LIMIT(val, -128, 127); | 1875 | val = SENSORS_LIMIT(val, -128, 127); |
1904 | else | 1876 | else |
1905 | val = SENSORS_LIMIT(val, 0, 127); | 1877 | val = SENSORS_LIMIT(val, 0, 127); |
@@ -2002,28 +1974,8 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
2002 | /* fall through! */ | 1974 | /* fall through! */ |
2003 | case f71862fg: | 1975 | case f71862fg: |
2004 | err = f71882fg_create_sysfs_files(pdev, | 1976 | err = f71882fg_create_sysfs_files(pdev, |
2005 | f71862_temp_attr, | 1977 | fxxxx_in_temp_attr, |
2006 | ARRAY_SIZE(f71862_temp_attr)); | 1978 | ARRAY_SIZE(fxxxx_in_temp_attr)); |
2007 | if (err) | ||
2008 | goto exit_unregister_sysfs; | ||
2009 | err = f71882fg_create_sysfs_files(pdev, | ||
2010 | fxxxx_in_attr, | ||
2011 | ARRAY_SIZE(fxxxx_in_attr)); | ||
2012 | if (err) | ||
2013 | goto exit_unregister_sysfs; | ||
2014 | err = f71882fg_create_sysfs_files(pdev, | ||
2015 | fxxxx_temp_attr, | ||
2016 | ARRAY_SIZE(fxxxx_temp_attr)); | ||
2017 | break; | ||
2018 | case f71808fg: | ||
2019 | err = f71882fg_create_sysfs_files(pdev, | ||
2020 | f71808_in_attr, | ||
2021 | ARRAY_SIZE(f71808_in_attr)); | ||
2022 | if (err) | ||
2023 | goto exit_unregister_sysfs; | ||
2024 | err = f71882fg_create_sysfs_files(pdev, | ||
2025 | fxxxx_temp_attr, | ||
2026 | ARRAY_SIZE(fxxxx_temp_attr)); | ||
2027 | break; | 1979 | break; |
2028 | case f8000: | 1980 | case f8000: |
2029 | err = f71882fg_create_sysfs_files(pdev, | 1981 | err = f71882fg_create_sysfs_files(pdev, |
@@ -2050,7 +2002,6 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
2050 | case f71862fg: | 2002 | case f71862fg: |
2051 | err = (data->pwm_enable & 0x15) != 0x15; | 2003 | err = (data->pwm_enable & 0x15) != 0x15; |
2052 | break; | 2004 | break; |
2053 | case f71808fg: | ||
2054 | case f71882fg: | 2005 | case f71882fg: |
2055 | case f71889fg: | 2006 | case f71889fg: |
2056 | err = 0; | 2007 | err = 0; |
@@ -2096,7 +2047,6 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
2096 | f8000_auto_pwm_attr, | 2047 | f8000_auto_pwm_attr, |
2097 | ARRAY_SIZE(f8000_auto_pwm_attr)); | 2048 | ARRAY_SIZE(f8000_auto_pwm_attr)); |
2098 | break; | 2049 | break; |
2099 | case f71808fg: | ||
2100 | case f71889fg: | 2050 | case f71889fg: |
2101 | for (i = 0; i < nr_fans; i++) { | 2051 | for (i = 0; i < nr_fans; i++) { |
2102 | data->pwm_auto_point_mapping[i] = | 2052 | data->pwm_auto_point_mapping[i] = |
@@ -2176,22 +2126,8 @@ static int f71882fg_remove(struct platform_device *pdev) | |||
2176 | /* fall through! */ | 2126 | /* fall through! */ |
2177 | case f71862fg: | 2127 | case f71862fg: |
2178 | f71882fg_remove_sysfs_files(pdev, | 2128 | f71882fg_remove_sysfs_files(pdev, |
2179 | f71862_temp_attr, | 2129 | fxxxx_in_temp_attr, |
2180 | ARRAY_SIZE(f71862_temp_attr)); | 2130 | ARRAY_SIZE(fxxxx_in_temp_attr)); |
2181 | f71882fg_remove_sysfs_files(pdev, | ||
2182 | fxxxx_in_attr, | ||
2183 | ARRAY_SIZE(fxxxx_in_attr)); | ||
2184 | f71882fg_remove_sysfs_files(pdev, | ||
2185 | fxxxx_temp_attr, | ||
2186 | ARRAY_SIZE(fxxxx_temp_attr)); | ||
2187 | break; | ||
2188 | case f71808fg: | ||
2189 | f71882fg_remove_sysfs_files(pdev, | ||
2190 | f71808_in_attr, | ||
2191 | ARRAY_SIZE(f71808_in_attr)); | ||
2192 | f71882fg_remove_sysfs_files(pdev, | ||
2193 | fxxxx_temp_attr, | ||
2194 | ARRAY_SIZE(fxxxx_temp_attr)); | ||
2195 | break; | 2131 | break; |
2196 | case f8000: | 2132 | case f8000: |
2197 | f71882fg_remove_sysfs_files(pdev, | 2133 | f71882fg_remove_sysfs_files(pdev, |
@@ -2259,9 +2195,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2259 | 2195 | ||
2260 | devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID); | 2196 | devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID); |
2261 | switch (devid) { | 2197 | switch (devid) { |
2262 | case SIO_F71808_ID: | ||
2263 | sio_data->type = f71808fg; | ||
2264 | break; | ||
2265 | case SIO_F71858_ID: | 2198 | case SIO_F71858_ID: |
2266 | sio_data->type = f71858fg; | 2199 | sio_data->type = f71858fg; |
2267 | break; | 2200 | break; |
diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index b9bb3e0ca53..39ead2a4d3c 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c | |||
@@ -143,6 +143,37 @@ static const struct pci_device_id k8temp_ids[] = { | |||
143 | 143 | ||
144 | MODULE_DEVICE_TABLE(pci, k8temp_ids); | 144 | MODULE_DEVICE_TABLE(pci, k8temp_ids); |
145 | 145 | ||
146 | static int __devinit is_rev_g_desktop(u8 model) | ||
147 | { | ||
148 | u32 brandidx; | ||
149 | |||
150 | if (model < 0x69) | ||
151 | return 0; | ||
152 | |||
153 | if (model == 0xc1 || model == 0x6c || model == 0x7c) | ||
154 | return 0; | ||
155 | |||
156 | /* | ||
157 | * Differentiate between AM2 and ASB1. | ||
158 | * See "Constructing the processor Name String" in "Revision | ||
159 | * Guide for AMD NPT Family 0Fh Processors" (33610). | ||
160 | */ | ||
161 | brandidx = cpuid_ebx(0x80000001); | ||
162 | brandidx = (brandidx >> 9) & 0x1f; | ||
163 | |||
164 | /* Single core */ | ||
165 | if ((model == 0x6f || model == 0x7f) && | ||
166 | (brandidx == 0x7 || brandidx == 0x9 || brandidx == 0xc)) | ||
167 | return 0; | ||
168 | |||
169 | /* Dual core */ | ||
170 | if (model == 0x6b && | ||
171 | (brandidx == 0xb || brandidx == 0xc)) | ||
172 | return 0; | ||
173 | |||
174 | return 1; | ||
175 | } | ||
176 | |||
146 | static int __devinit k8temp_probe(struct pci_dev *pdev, | 177 | static int __devinit k8temp_probe(struct pci_dev *pdev, |
147 | const struct pci_device_id *id) | 178 | const struct pci_device_id *id) |
148 | { | 179 | { |
@@ -179,9 +210,7 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, | |||
179 | "wrong - check erratum #141\n"); | 210 | "wrong - check erratum #141\n"); |
180 | } | 211 | } |
181 | 212 | ||
182 | if ((model >= 0x69) && | 213 | if (is_rev_g_desktop(model)) { |
183 | !(model == 0xc1 || model == 0x6c || model == 0x7c || | ||
184 | model == 0x6b || model == 0x6f || model == 0x7f)) { | ||
185 | /* | 214 | /* |
186 | * RevG desktop CPUs (i.e. no socket S1G1 or | 215 | * RevG desktop CPUs (i.e. no socket S1G1 or |
187 | * ASB1 parts) need additional offset, | 216 | * ASB1 parts) need additional offset, |
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index d0dc1db80b2..50815022cff 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c | |||
@@ -1106,7 +1106,7 @@ static int ohci_iso_recv_init(struct hpsb_iso *iso) | |||
1106 | if (recv->block_irq_interval * 4 > iso->buf_packets) | 1106 | if (recv->block_irq_interval * 4 > iso->buf_packets) |
1107 | recv->block_irq_interval = iso->buf_packets / 4; | 1107 | recv->block_irq_interval = iso->buf_packets / 4; |
1108 | if (recv->block_irq_interval < 1) | 1108 | if (recv->block_irq_interval < 1) |
1109 | recv->block_irq_interval = 1; | 1109 | recv->block_irq_interval = 1; |
1110 | 1110 | ||
1111 | /* choose a buffer stride */ | 1111 | /* choose a buffer stride */ |
1112 | /* must be a power of 2, and <= PAGE_SIZE */ | 1112 | /* must be a power of 2, and <= PAGE_SIZE */ |
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index dcc86b97a15..19fa94af207 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c | |||
@@ -232,13 +232,13 @@ static void hil_dev_handle_ptr_events(struct hil_dev *ptr) | |||
232 | if (absdev) { | 232 | if (absdev) { |
233 | val = lo + (hi << 8); | 233 | val = lo + (hi << 8); |
234 | #ifdef TABLET_AUTOADJUST | 234 | #ifdef TABLET_AUTOADJUST |
235 | if (val < input_abs_min(dev, ABS_X + i)) | 235 | if (val < input_abs_get_min(dev, ABS_X + i)) |
236 | input_abs_set_min(dev, ABS_X + i, val); | 236 | input_abs_set_min(dev, ABS_X + i, val); |
237 | if (val > input_abs_max(dev, ABS_X + i)) | 237 | if (val > input_abs_get_max(dev, ABS_X + i)) |
238 | input_abs_set_max(dev, ABS_X + i, val); | 238 | input_abs_set_max(dev, ABS_X + i, val); |
239 | #endif | 239 | #endif |
240 | if (i % 3) | 240 | if (i % 3) |
241 | val = input_abs_max(dev, ABS_X + i) - val; | 241 | val = input_abs_get_max(dev, ABS_X + i) - val; |
242 | input_report_abs(dev, ABS_X + i, val); | 242 | input_report_abs(dev, ABS_X + i, val); |
243 | } else { | 243 | } else { |
244 | val = (int) (((int8_t) lo) | ((int8_t) hi << 8)); | 244 | val = (int) (((int8_t) lo) | ((int8_t) hi << 8)); |
@@ -388,11 +388,11 @@ static void hil_dev_pointer_setup(struct hil_dev *ptr) | |||
388 | 388 | ||
389 | #ifdef TABLET_AUTOADJUST | 389 | #ifdef TABLET_AUTOADJUST |
390 | for (i = 0; i < ABS_MAX; i++) { | 390 | for (i = 0; i < ABS_MAX; i++) { |
391 | int diff = input_abs_max(input_dev, ABS_X + i) / 10; | 391 | int diff = input_abs_get_max(input_dev, ABS_X + i) / 10; |
392 | input_abs_set_min(input_dev, ABS_X + i, | 392 | input_abs_set_min(input_dev, ABS_X + i, |
393 | input_abs_min(input_dev, ABS_X + i) + diff) | 393 | input_abs_get_min(input_dev, ABS_X + i) + diff); |
394 | input_abs_set_max(input_dev, ABS_X + i, | 394 | input_abs_set_max(input_dev, ABS_X + i, |
395 | input_abs_max(input_dev, ABS_X + i) - diff) | 395 | input_abs_get_max(input_dev, ABS_X + i) - diff); |
396 | } | 396 | } |
397 | #endif | 397 | #endif |
398 | 398 | ||
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 0e53b3bc39a..f32404f9918 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c | |||
@@ -567,8 +567,6 @@ static int __devexit pxa27x_keypad_remove(struct platform_device *pdev) | |||
567 | clk_put(keypad->clk); | 567 | clk_put(keypad->clk); |
568 | 568 | ||
569 | input_unregister_device(keypad->input_dev); | 569 | input_unregister_device(keypad->input_dev); |
570 | input_free_device(keypad->input_dev); | ||
571 | |||
572 | iounmap(keypad->mmio_base); | 570 | iounmap(keypad->mmio_base); |
573 | 571 | ||
574 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 572 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index bb53fd33cd1..0d4266a533a 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c | |||
@@ -811,6 +811,8 @@ static struct miscdevice uinput_misc = { | |||
811 | .minor = UINPUT_MINOR, | 811 | .minor = UINPUT_MINOR, |
812 | .name = UINPUT_NAME, | 812 | .name = UINPUT_NAME, |
813 | }; | 813 | }; |
814 | MODULE_ALIAS_MISCDEV(UINPUT_MINOR); | ||
815 | MODULE_ALIAS("devname:" UINPUT_NAME); | ||
814 | 816 | ||
815 | static int __init uinput_init(void) | 817 | static int __init uinput_init(void) |
816 | { | 818 | { |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 83c24cca234..d528a2dba06 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
@@ -138,8 +138,8 @@ static void mousedev_touchpad_event(struct input_dev *dev, | |||
138 | 138 | ||
139 | fx(0) = value; | 139 | fx(0) = value; |
140 | if (mousedev->touch && mousedev->pkt_count >= 2) { | 140 | if (mousedev->touch && mousedev->pkt_count >= 2) { |
141 | size = input_abs_get_min(dev, ABS_X) - | 141 | size = input_abs_get_max(dev, ABS_X) - |
142 | input_abs_get_max(dev, ABS_X); | 142 | input_abs_get_min(dev, ABS_X); |
143 | if (size == 0) | 143 | if (size == 0) |
144 | size = 256 * 2; | 144 | size = 256 * 2; |
145 | 145 | ||
@@ -155,8 +155,8 @@ static void mousedev_touchpad_event(struct input_dev *dev, | |||
155 | fy(0) = value; | 155 | fy(0) = value; |
156 | if (mousedev->touch && mousedev->pkt_count >= 2) { | 156 | if (mousedev->touch && mousedev->pkt_count >= 2) { |
157 | /* use X size for ABS_Y to keep the same scale */ | 157 | /* use X size for ABS_Y to keep the same scale */ |
158 | size = input_abs_get_min(dev, ABS_X) - | 158 | size = input_abs_get_max(dev, ABS_X) - |
159 | input_abs_get_max(dev, ABS_X); | 159 | input_abs_get_min(dev, ABS_X); |
160 | if (size == 0) | 160 | if (size == 0) |
161 | size = 256 * 2; | 161 | size = 256 * 2; |
162 | 162 | ||
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 35bc2737412..2d17e76066b 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/syscalls.h> | 45 | #include <linux/syscalls.h> |
46 | #include <linux/suspend.h> | 46 | #include <linux/suspend.h> |
47 | #include <linux/cpu.h> | 47 | #include <linux/cpu.h> |
48 | #include <linux/compat.h> | ||
48 | #include <asm/prom.h> | 49 | #include <asm/prom.h> |
49 | #include <asm/machdep.h> | 50 | #include <asm/machdep.h> |
50 | #include <asm/io.h> | 51 | #include <asm/io.h> |
@@ -2349,11 +2350,52 @@ static long pmu_unlocked_ioctl(struct file *filp, | |||
2349 | return ret; | 2350 | return ret; |
2350 | } | 2351 | } |
2351 | 2352 | ||
2353 | #ifdef CONFIG_COMPAT | ||
2354 | #define PMU_IOC_GET_BACKLIGHT32 _IOR('B', 1, compat_size_t) | ||
2355 | #define PMU_IOC_SET_BACKLIGHT32 _IOW('B', 2, compat_size_t) | ||
2356 | #define PMU_IOC_GET_MODEL32 _IOR('B', 3, compat_size_t) | ||
2357 | #define PMU_IOC_HAS_ADB32 _IOR('B', 4, compat_size_t) | ||
2358 | #define PMU_IOC_CAN_SLEEP32 _IOR('B', 5, compat_size_t) | ||
2359 | #define PMU_IOC_GRAB_BACKLIGHT32 _IOR('B', 6, compat_size_t) | ||
2360 | |||
2361 | static long compat_pmu_ioctl (struct file *filp, u_int cmd, u_long arg) | ||
2362 | { | ||
2363 | switch (cmd) { | ||
2364 | case PMU_IOC_SLEEP: | ||
2365 | break; | ||
2366 | case PMU_IOC_GET_BACKLIGHT32: | ||
2367 | cmd = PMU_IOC_GET_BACKLIGHT; | ||
2368 | break; | ||
2369 | case PMU_IOC_SET_BACKLIGHT32: | ||
2370 | cmd = PMU_IOC_SET_BACKLIGHT; | ||
2371 | break; | ||
2372 | case PMU_IOC_GET_MODEL32: | ||
2373 | cmd = PMU_IOC_GET_MODEL; | ||
2374 | break; | ||
2375 | case PMU_IOC_HAS_ADB32: | ||
2376 | cmd = PMU_IOC_HAS_ADB; | ||
2377 | break; | ||
2378 | case PMU_IOC_CAN_SLEEP32: | ||
2379 | cmd = PMU_IOC_CAN_SLEEP; | ||
2380 | break; | ||
2381 | case PMU_IOC_GRAB_BACKLIGHT32: | ||
2382 | cmd = PMU_IOC_GRAB_BACKLIGHT; | ||
2383 | break; | ||
2384 | default: | ||
2385 | return -ENOIOCTLCMD; | ||
2386 | } | ||
2387 | return pmu_unlocked_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); | ||
2388 | } | ||
2389 | #endif | ||
2390 | |||
2352 | static const struct file_operations pmu_device_fops = { | 2391 | static const struct file_operations pmu_device_fops = { |
2353 | .read = pmu_read, | 2392 | .read = pmu_read, |
2354 | .write = pmu_write, | 2393 | .write = pmu_write, |
2355 | .poll = pmu_fpoll, | 2394 | .poll = pmu_fpoll, |
2356 | .unlocked_ioctl = pmu_unlocked_ioctl, | 2395 | .unlocked_ioctl = pmu_unlocked_ioctl, |
2396 | #ifdef CONFIG_COMPAT | ||
2397 | .compat_ioctl = compat_pmu_ioctl, | ||
2398 | #endif | ||
2357 | .open = pmu_open, | 2399 | .open = pmu_open, |
2358 | .release = pmu_release, | 2400 | .release = pmu_release, |
2359 | }; | 2401 | }; |
diff --git a/drivers/md/.gitignore b/drivers/md/.gitignore deleted file mode 100644 index a7afec6b19c..00000000000 --- a/drivers/md/.gitignore +++ /dev/null | |||
@@ -1,4 +0,0 @@ | |||
1 | mktables | ||
2 | raid6altivec*.c | ||
3 | raid6int*.c | ||
4 | raid6tables.c | ||
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 1ba1e122e94..ed4900ade93 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -1542,8 +1542,7 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector) | |||
1542 | atomic_read(&bitmap->mddev->recovery_active) == 0); | 1542 | atomic_read(&bitmap->mddev->recovery_active) == 0); |
1543 | 1543 | ||
1544 | bitmap->mddev->curr_resync_completed = bitmap->mddev->curr_resync; | 1544 | bitmap->mddev->curr_resync_completed = bitmap->mddev->curr_resync; |
1545 | if (bitmap->mddev->persistent) | 1545 | set_bit(MD_CHANGE_CLEAN, &bitmap->mddev->flags); |
1546 | set_bit(MD_CHANGE_CLEAN, &bitmap->mddev->flags); | ||
1547 | sector &= ~((1ULL << CHUNK_BLOCK_SHIFT(bitmap)) - 1); | 1546 | sector &= ~((1ULL << CHUNK_BLOCK_SHIFT(bitmap)) - 1); |
1548 | s = 0; | 1547 | s = 0; |
1549 | while (s < sector && s < bitmap->mddev->resync_max_sectors) { | 1548 | while (s < sector && s < bitmap->mddev->resync_max_sectors) { |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 11567c7999a..43cf9cc9c1d 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -2136,16 +2136,6 @@ static void sync_sbs(mddev_t * mddev, int nospares) | |||
2136 | * with the rest of the array) | 2136 | * with the rest of the array) |
2137 | */ | 2137 | */ |
2138 | mdk_rdev_t *rdev; | 2138 | mdk_rdev_t *rdev; |
2139 | |||
2140 | /* First make sure individual recovery_offsets are correct */ | ||
2141 | list_for_each_entry(rdev, &mddev->disks, same_set) { | ||
2142 | if (rdev->raid_disk >= 0 && | ||
2143 | mddev->delta_disks >= 0 && | ||
2144 | !test_bit(In_sync, &rdev->flags) && | ||
2145 | mddev->curr_resync_completed > rdev->recovery_offset) | ||
2146 | rdev->recovery_offset = mddev->curr_resync_completed; | ||
2147 | |||
2148 | } | ||
2149 | list_for_each_entry(rdev, &mddev->disks, same_set) { | 2139 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
2150 | if (rdev->sb_events == mddev->events || | 2140 | if (rdev->sb_events == mddev->events || |
2151 | (nospares && | 2141 | (nospares && |
@@ -2167,13 +2157,27 @@ static void md_update_sb(mddev_t * mddev, int force_change) | |||
2167 | int sync_req; | 2157 | int sync_req; |
2168 | int nospares = 0; | 2158 | int nospares = 0; |
2169 | 2159 | ||
2170 | mddev->utime = get_seconds(); | ||
2171 | if (mddev->external) | ||
2172 | return; | ||
2173 | repeat: | 2160 | repeat: |
2161 | /* First make sure individual recovery_offsets are correct */ | ||
2162 | list_for_each_entry(rdev, &mddev->disks, same_set) { | ||
2163 | if (rdev->raid_disk >= 0 && | ||
2164 | mddev->delta_disks >= 0 && | ||
2165 | !test_bit(In_sync, &rdev->flags) && | ||
2166 | mddev->curr_resync_completed > rdev->recovery_offset) | ||
2167 | rdev->recovery_offset = mddev->curr_resync_completed; | ||
2168 | |||
2169 | } | ||
2170 | if (!mddev->persistent) { | ||
2171 | clear_bit(MD_CHANGE_CLEAN, &mddev->flags); | ||
2172 | clear_bit(MD_CHANGE_DEVS, &mddev->flags); | ||
2173 | wake_up(&mddev->sb_wait); | ||
2174 | return; | ||
2175 | } | ||
2176 | |||
2174 | spin_lock_irq(&mddev->write_lock); | 2177 | spin_lock_irq(&mddev->write_lock); |
2175 | 2178 | ||
2176 | set_bit(MD_CHANGE_PENDING, &mddev->flags); | 2179 | mddev->utime = get_seconds(); |
2180 | |||
2177 | if (test_and_clear_bit(MD_CHANGE_DEVS, &mddev->flags)) | 2181 | if (test_and_clear_bit(MD_CHANGE_DEVS, &mddev->flags)) |
2178 | force_change = 1; | 2182 | force_change = 1; |
2179 | if (test_and_clear_bit(MD_CHANGE_CLEAN, &mddev->flags)) | 2183 | if (test_and_clear_bit(MD_CHANGE_CLEAN, &mddev->flags)) |
@@ -2221,19 +2225,6 @@ repeat: | |||
2221 | MD_BUG(); | 2225 | MD_BUG(); |
2222 | mddev->events --; | 2226 | mddev->events --; |
2223 | } | 2227 | } |
2224 | |||
2225 | /* | ||
2226 | * do not write anything to disk if using | ||
2227 | * nonpersistent superblocks | ||
2228 | */ | ||
2229 | if (!mddev->persistent) { | ||
2230 | if (!mddev->external) | ||
2231 | clear_bit(MD_CHANGE_PENDING, &mddev->flags); | ||
2232 | |||
2233 | spin_unlock_irq(&mddev->write_lock); | ||
2234 | wake_up(&mddev->sb_wait); | ||
2235 | return; | ||
2236 | } | ||
2237 | sync_sbs(mddev, nospares); | 2228 | sync_sbs(mddev, nospares); |
2238 | spin_unlock_irq(&mddev->write_lock); | 2229 | spin_unlock_irq(&mddev->write_lock); |
2239 | 2230 | ||
@@ -3379,7 +3370,7 @@ array_state_show(mddev_t *mddev, char *page) | |||
3379 | case 0: | 3370 | case 0: |
3380 | if (mddev->in_sync) | 3371 | if (mddev->in_sync) |
3381 | st = clean; | 3372 | st = clean; |
3382 | else if (test_bit(MD_CHANGE_CLEAN, &mddev->flags)) | 3373 | else if (test_bit(MD_CHANGE_PENDING, &mddev->flags)) |
3383 | st = write_pending; | 3374 | st = write_pending; |
3384 | else if (mddev->safemode) | 3375 | else if (mddev->safemode) |
3385 | st = active_idle; | 3376 | st = active_idle; |
@@ -3460,9 +3451,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) | |||
3460 | mddev->in_sync = 1; | 3451 | mddev->in_sync = 1; |
3461 | if (mddev->safemode == 1) | 3452 | if (mddev->safemode == 1) |
3462 | mddev->safemode = 0; | 3453 | mddev->safemode = 0; |
3463 | if (mddev->persistent) | 3454 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); |
3464 | set_bit(MD_CHANGE_CLEAN, | ||
3465 | &mddev->flags); | ||
3466 | } | 3455 | } |
3467 | err = 0; | 3456 | err = 0; |
3468 | } else | 3457 | } else |
@@ -3474,8 +3463,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) | |||
3474 | case active: | 3463 | case active: |
3475 | if (mddev->pers) { | 3464 | if (mddev->pers) { |
3476 | restart_array(mddev); | 3465 | restart_array(mddev); |
3477 | if (mddev->external) | 3466 | clear_bit(MD_CHANGE_PENDING, &mddev->flags); |
3478 | clear_bit(MD_CHANGE_CLEAN, &mddev->flags); | ||
3479 | wake_up(&mddev->sb_wait); | 3467 | wake_up(&mddev->sb_wait); |
3480 | err = 0; | 3468 | err = 0; |
3481 | } else { | 3469 | } else { |
@@ -6580,6 +6568,7 @@ void md_write_start(mddev_t *mddev, struct bio *bi) | |||
6580 | if (mddev->in_sync) { | 6568 | if (mddev->in_sync) { |
6581 | mddev->in_sync = 0; | 6569 | mddev->in_sync = 0; |
6582 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); | 6570 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); |
6571 | set_bit(MD_CHANGE_PENDING, &mddev->flags); | ||
6583 | md_wakeup_thread(mddev->thread); | 6572 | md_wakeup_thread(mddev->thread); |
6584 | did_change = 1; | 6573 | did_change = 1; |
6585 | } | 6574 | } |
@@ -6588,7 +6577,6 @@ void md_write_start(mddev_t *mddev, struct bio *bi) | |||
6588 | if (did_change) | 6577 | if (did_change) |
6589 | sysfs_notify_dirent_safe(mddev->sysfs_state); | 6578 | sysfs_notify_dirent_safe(mddev->sysfs_state); |
6590 | wait_event(mddev->sb_wait, | 6579 | wait_event(mddev->sb_wait, |
6591 | !test_bit(MD_CHANGE_CLEAN, &mddev->flags) && | ||
6592 | !test_bit(MD_CHANGE_PENDING, &mddev->flags)); | 6580 | !test_bit(MD_CHANGE_PENDING, &mddev->flags)); |
6593 | } | 6581 | } |
6594 | 6582 | ||
@@ -6624,6 +6612,7 @@ int md_allow_write(mddev_t *mddev) | |||
6624 | if (mddev->in_sync) { | 6612 | if (mddev->in_sync) { |
6625 | mddev->in_sync = 0; | 6613 | mddev->in_sync = 0; |
6626 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); | 6614 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); |
6615 | set_bit(MD_CHANGE_PENDING, &mddev->flags); | ||
6627 | if (mddev->safemode_delay && | 6616 | if (mddev->safemode_delay && |
6628 | mddev->safemode == 0) | 6617 | mddev->safemode == 0) |
6629 | mddev->safemode = 1; | 6618 | mddev->safemode = 1; |
@@ -6633,7 +6622,7 @@ int md_allow_write(mddev_t *mddev) | |||
6633 | } else | 6622 | } else |
6634 | spin_unlock_irq(&mddev->write_lock); | 6623 | spin_unlock_irq(&mddev->write_lock); |
6635 | 6624 | ||
6636 | if (test_bit(MD_CHANGE_CLEAN, &mddev->flags)) | 6625 | if (test_bit(MD_CHANGE_PENDING, &mddev->flags)) |
6637 | return -EAGAIN; | 6626 | return -EAGAIN; |
6638 | else | 6627 | else |
6639 | return 0; | 6628 | return 0; |
@@ -6831,8 +6820,7 @@ void md_do_sync(mddev_t *mddev) | |||
6831 | atomic_read(&mddev->recovery_active) == 0); | 6820 | atomic_read(&mddev->recovery_active) == 0); |
6832 | mddev->curr_resync_completed = | 6821 | mddev->curr_resync_completed = |
6833 | mddev->curr_resync; | 6822 | mddev->curr_resync; |
6834 | if (mddev->persistent) | 6823 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); |
6835 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); | ||
6836 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | 6824 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); |
6837 | } | 6825 | } |
6838 | 6826 | ||
@@ -7111,8 +7099,7 @@ void md_check_recovery(mddev_t *mddev) | |||
7111 | mddev->recovery_cp == MaxSector) { | 7099 | mddev->recovery_cp == MaxSector) { |
7112 | mddev->in_sync = 1; | 7100 | mddev->in_sync = 1; |
7113 | did_change = 1; | 7101 | did_change = 1; |
7114 | if (mddev->persistent) | 7102 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); |
7115 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); | ||
7116 | } | 7103 | } |
7117 | if (mddev->safemode == 1) | 7104 | if (mddev->safemode == 1) |
7118 | mddev->safemode = 0; | 7105 | mddev->safemode = 0; |
diff --git a/drivers/md/md.h b/drivers/md/md.h index a953fe2808a..3931299788d 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
@@ -140,7 +140,7 @@ struct mddev_s | |||
140 | unsigned long flags; | 140 | unsigned long flags; |
141 | #define MD_CHANGE_DEVS 0 /* Some device status has changed */ | 141 | #define MD_CHANGE_DEVS 0 /* Some device status has changed */ |
142 | #define MD_CHANGE_CLEAN 1 /* transition to or from 'clean' */ | 142 | #define MD_CHANGE_CLEAN 1 /* transition to or from 'clean' */ |
143 | #define MD_CHANGE_PENDING 2 /* superblock update in progress */ | 143 | #define MD_CHANGE_PENDING 2 /* switch from 'clean' to 'active' in progress */ |
144 | 144 | ||
145 | int suspended; | 145 | int suspended; |
146 | atomic_t active_io; | 146 | atomic_t active_io; |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 73cc74ffc26..ad83a4dcadc 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -787,8 +787,8 @@ static int make_request(mddev_t *mddev, struct bio * bio) | |||
787 | struct bio_list bl; | 787 | struct bio_list bl; |
788 | struct page **behind_pages = NULL; | 788 | struct page **behind_pages = NULL; |
789 | const int rw = bio_data_dir(bio); | 789 | const int rw = bio_data_dir(bio); |
790 | const bool do_sync = (bio->bi_rw & REQ_SYNC); | 790 | const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); |
791 | bool do_barriers; | 791 | unsigned long do_barriers; |
792 | mdk_rdev_t *blocked_rdev; | 792 | mdk_rdev_t *blocked_rdev; |
793 | 793 | ||
794 | /* | 794 | /* |
@@ -1120,6 +1120,8 @@ static int raid1_spare_active(mddev_t *mddev) | |||
1120 | { | 1120 | { |
1121 | int i; | 1121 | int i; |
1122 | conf_t *conf = mddev->private; | 1122 | conf_t *conf = mddev->private; |
1123 | int count = 0; | ||
1124 | unsigned long flags; | ||
1123 | 1125 | ||
1124 | /* | 1126 | /* |
1125 | * Find all failed disks within the RAID1 configuration | 1127 | * Find all failed disks within the RAID1 configuration |
@@ -1131,15 +1133,16 @@ static int raid1_spare_active(mddev_t *mddev) | |||
1131 | if (rdev | 1133 | if (rdev |
1132 | && !test_bit(Faulty, &rdev->flags) | 1134 | && !test_bit(Faulty, &rdev->flags) |
1133 | && !test_and_set_bit(In_sync, &rdev->flags)) { | 1135 | && !test_and_set_bit(In_sync, &rdev->flags)) { |
1134 | unsigned long flags; | 1136 | count++; |
1135 | spin_lock_irqsave(&conf->device_lock, flags); | 1137 | sysfs_notify_dirent(rdev->sysfs_state); |
1136 | mddev->degraded--; | ||
1137 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
1138 | } | 1138 | } |
1139 | } | 1139 | } |
1140 | spin_lock_irqsave(&conf->device_lock, flags); | ||
1141 | mddev->degraded -= count; | ||
1142 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
1140 | 1143 | ||
1141 | print_conf(conf); | 1144 | print_conf(conf); |
1142 | return 0; | 1145 | return count; |
1143 | } | 1146 | } |
1144 | 1147 | ||
1145 | 1148 | ||
@@ -1640,7 +1643,7 @@ static void raid1d(mddev_t *mddev) | |||
1640 | * We already have a nr_pending reference on these rdevs. | 1643 | * We already have a nr_pending reference on these rdevs. |
1641 | */ | 1644 | */ |
1642 | int i; | 1645 | int i; |
1643 | const bool do_sync = (r1_bio->master_bio->bi_rw & REQ_SYNC); | 1646 | const unsigned long do_sync = (r1_bio->master_bio->bi_rw & REQ_SYNC); |
1644 | clear_bit(R1BIO_BarrierRetry, &r1_bio->state); | 1647 | clear_bit(R1BIO_BarrierRetry, &r1_bio->state); |
1645 | clear_bit(R1BIO_Barrier, &r1_bio->state); | 1648 | clear_bit(R1BIO_Barrier, &r1_bio->state); |
1646 | for (i=0; i < conf->raid_disks; i++) | 1649 | for (i=0; i < conf->raid_disks; i++) |
@@ -1696,7 +1699,7 @@ static void raid1d(mddev_t *mddev) | |||
1696 | (unsigned long long)r1_bio->sector); | 1699 | (unsigned long long)r1_bio->sector); |
1697 | raid_end_bio_io(r1_bio); | 1700 | raid_end_bio_io(r1_bio); |
1698 | } else { | 1701 | } else { |
1699 | const bool do_sync = r1_bio->master_bio->bi_rw & REQ_SYNC; | 1702 | const unsigned long do_sync = r1_bio->master_bio->bi_rw & REQ_SYNC; |
1700 | r1_bio->bios[r1_bio->read_disk] = | 1703 | r1_bio->bios[r1_bio->read_disk] = |
1701 | mddev->ro ? IO_BLOCKED : NULL; | 1704 | mddev->ro ? IO_BLOCKED : NULL; |
1702 | r1_bio->read_disk = disk; | 1705 | r1_bio->read_disk = disk; |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index a88aeb5198c..84718383124 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -799,7 +799,7 @@ static int make_request(mddev_t *mddev, struct bio * bio) | |||
799 | int i; | 799 | int i; |
800 | int chunk_sects = conf->chunk_mask + 1; | 800 | int chunk_sects = conf->chunk_mask + 1; |
801 | const int rw = bio_data_dir(bio); | 801 | const int rw = bio_data_dir(bio); |
802 | const bool do_sync = (bio->bi_rw & REQ_SYNC); | 802 | const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); |
803 | struct bio_list bl; | 803 | struct bio_list bl; |
804 | unsigned long flags; | 804 | unsigned long flags; |
805 | mdk_rdev_t *blocked_rdev; | 805 | mdk_rdev_t *blocked_rdev; |
@@ -1116,6 +1116,8 @@ static int raid10_spare_active(mddev_t *mddev) | |||
1116 | int i; | 1116 | int i; |
1117 | conf_t *conf = mddev->private; | 1117 | conf_t *conf = mddev->private; |
1118 | mirror_info_t *tmp; | 1118 | mirror_info_t *tmp; |
1119 | int count = 0; | ||
1120 | unsigned long flags; | ||
1119 | 1121 | ||
1120 | /* | 1122 | /* |
1121 | * Find all non-in_sync disks within the RAID10 configuration | 1123 | * Find all non-in_sync disks within the RAID10 configuration |
@@ -1126,15 +1128,16 @@ static int raid10_spare_active(mddev_t *mddev) | |||
1126 | if (tmp->rdev | 1128 | if (tmp->rdev |
1127 | && !test_bit(Faulty, &tmp->rdev->flags) | 1129 | && !test_bit(Faulty, &tmp->rdev->flags) |
1128 | && !test_and_set_bit(In_sync, &tmp->rdev->flags)) { | 1130 | && !test_and_set_bit(In_sync, &tmp->rdev->flags)) { |
1129 | unsigned long flags; | 1131 | count++; |
1130 | spin_lock_irqsave(&conf->device_lock, flags); | 1132 | sysfs_notify_dirent(tmp->rdev->sysfs_state); |
1131 | mddev->degraded--; | ||
1132 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
1133 | } | 1133 | } |
1134 | } | 1134 | } |
1135 | spin_lock_irqsave(&conf->device_lock, flags); | ||
1136 | mddev->degraded -= count; | ||
1137 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
1135 | 1138 | ||
1136 | print_conf(conf); | 1139 | print_conf(conf); |
1137 | return 0; | 1140 | return count; |
1138 | } | 1141 | } |
1139 | 1142 | ||
1140 | 1143 | ||
@@ -1734,7 +1737,7 @@ static void raid10d(mddev_t *mddev) | |||
1734 | raid_end_bio_io(r10_bio); | 1737 | raid_end_bio_io(r10_bio); |
1735 | bio_put(bio); | 1738 | bio_put(bio); |
1736 | } else { | 1739 | } else { |
1737 | const bool do_sync = (r10_bio->master_bio->bi_rw & REQ_SYNC); | 1740 | const unsigned long do_sync = (r10_bio->master_bio->bi_rw & REQ_SYNC); |
1738 | bio_put(bio); | 1741 | bio_put(bio); |
1739 | rdev = conf->mirrors[mirror].rdev; | 1742 | rdev = conf->mirrors[mirror].rdev; |
1740 | if (printk_ratelimit()) | 1743 | if (printk_ratelimit()) |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 866d4b5a144..69b0a169e43 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -5330,6 +5330,8 @@ static int raid5_spare_active(mddev_t *mddev) | |||
5330 | int i; | 5330 | int i; |
5331 | raid5_conf_t *conf = mddev->private; | 5331 | raid5_conf_t *conf = mddev->private; |
5332 | struct disk_info *tmp; | 5332 | struct disk_info *tmp; |
5333 | int count = 0; | ||
5334 | unsigned long flags; | ||
5333 | 5335 | ||
5334 | for (i = 0; i < conf->raid_disks; i++) { | 5336 | for (i = 0; i < conf->raid_disks; i++) { |
5335 | tmp = conf->disks + i; | 5337 | tmp = conf->disks + i; |
@@ -5337,14 +5339,15 @@ static int raid5_spare_active(mddev_t *mddev) | |||
5337 | && tmp->rdev->recovery_offset == MaxSector | 5339 | && tmp->rdev->recovery_offset == MaxSector |
5338 | && !test_bit(Faulty, &tmp->rdev->flags) | 5340 | && !test_bit(Faulty, &tmp->rdev->flags) |
5339 | && !test_and_set_bit(In_sync, &tmp->rdev->flags)) { | 5341 | && !test_and_set_bit(In_sync, &tmp->rdev->flags)) { |
5340 | unsigned long flags; | 5342 | count++; |
5341 | spin_lock_irqsave(&conf->device_lock, flags); | 5343 | sysfs_notify_dirent(tmp->rdev->sysfs_state); |
5342 | mddev->degraded--; | ||
5343 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
5344 | } | 5344 | } |
5345 | } | 5345 | } |
5346 | spin_lock_irqsave(&conf->device_lock, flags); | ||
5347 | mddev->degraded -= count; | ||
5348 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
5346 | print_raid5_conf(conf); | 5349 | print_raid5_conf(conf); |
5347 | return 0; | 5350 | return count; |
5348 | } | 5351 | } |
5349 | 5352 | ||
5350 | static int raid5_remove_disk(mddev_t *mddev, int number) | 5353 | static int raid5_remove_disk(mddev_t *mddev, int number) |
diff --git a/drivers/media/dvb/mantis/Kconfig b/drivers/media/dvb/mantis/Kconfig index decdeda840d..fd0830ed10d 100644 --- a/drivers/media/dvb/mantis/Kconfig +++ b/drivers/media/dvb/mantis/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config MANTIS_CORE | 1 | config MANTIS_CORE |
2 | tristate "Mantis/Hopper PCI bridge based devices" | 2 | tristate "Mantis/Hopper PCI bridge based devices" |
3 | depends on PCI && I2C && INPUT | 3 | depends on PCI && I2C && INPUT && IR_CORE |
4 | 4 | ||
5 | help | 5 | help |
6 | Support for PCI cards based on the Mantis and Hopper PCi bridge. | 6 | Support for PCI cards based on the Mantis and Hopper PCi bridge. |
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 0efe631e50c..d80cfdc8edd 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
@@ -86,7 +86,9 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | |||
86 | init_waitqueue_head(&host->wq); | 86 | init_waitqueue_head(&host->wq); |
87 | INIT_DELAYED_WORK(&host->detect, mmc_rescan); | 87 | INIT_DELAYED_WORK(&host->detect, mmc_rescan); |
88 | INIT_DELAYED_WORK_DEFERRABLE(&host->disable, mmc_host_deeper_disable); | 88 | INIT_DELAYED_WORK_DEFERRABLE(&host->disable, mmc_host_deeper_disable); |
89 | #ifdef CONFIG_PM | ||
89 | host->pm_notify.notifier_call = mmc_pm_notify; | 90 | host->pm_notify.notifier_call = mmc_pm_notify; |
91 | #endif | ||
90 | 92 | ||
91 | /* | 93 | /* |
92 | * By default, hosts do not support SGIO or large requests. | 94 | * By default, hosts do not support SGIO or large requests. |
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 283190bc2a4..68d12794cfd 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
@@ -132,7 +132,7 @@ config MMC_SDHCI_CNS3XXX | |||
132 | 132 | ||
133 | config MMC_SDHCI_S3C | 133 | config MMC_SDHCI_S3C |
134 | tristate "SDHCI support on Samsung S3C SoC" | 134 | tristate "SDHCI support on Samsung S3C SoC" |
135 | depends on MMC_SDHCI && (PLAT_S3C24XX || PLAT_S3C64XX) | 135 | depends on MMC_SDHCI && PLAT_SAMSUNG |
136 | help | 136 | help |
137 | This selects the Secure Digital Host Controller Interface (SDHCI) | 137 | This selects the Secure Digital Host Controller Interface (SDHCI) |
138 | often referrered to as the HSMMC block in some of the Samsung S3C | 138 | often referrered to as the HSMMC block in some of the Samsung S3C |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 0a7f2614c6f..71ad4163b95 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
@@ -242,7 +242,7 @@ static void sdhci_s3c_notify_change(struct platform_device *dev, int state) | |||
242 | { | 242 | { |
243 | struct sdhci_host *host = platform_get_drvdata(dev); | 243 | struct sdhci_host *host = platform_get_drvdata(dev); |
244 | if (host) { | 244 | if (host) { |
245 | mutex_lock(&host->lock); | 245 | spin_lock(&host->lock); |
246 | if (state) { | 246 | if (state) { |
247 | dev_dbg(&dev->dev, "card inserted.\n"); | 247 | dev_dbg(&dev->dev, "card inserted.\n"); |
248 | host->flags &= ~SDHCI_DEVICE_DEAD; | 248 | host->flags &= ~SDHCI_DEVICE_DEAD; |
@@ -252,8 +252,8 @@ static void sdhci_s3c_notify_change(struct platform_device *dev, int state) | |||
252 | host->flags |= SDHCI_DEVICE_DEAD; | 252 | host->flags |= SDHCI_DEVICE_DEAD; |
253 | host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; | 253 | host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; |
254 | } | 254 | } |
255 | sdhci_card_detect(host); | 255 | tasklet_schedule(&host->card_tasklet); |
256 | mutex_unlock(&host->lock); | 256 | spin_unlock(&host->lock); |
257 | } | 257 | } |
258 | } | 258 | } |
259 | 259 | ||
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 785512133b5..401527d273b 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -1180,7 +1180,8 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1180 | else | 1180 | else |
1181 | ctrl &= ~SDHCI_CTRL_4BITBUS; | 1181 | ctrl &= ~SDHCI_CTRL_4BITBUS; |
1182 | 1182 | ||
1183 | if (ios->timing == MMC_TIMING_SD_HS) | 1183 | if (ios->timing == MMC_TIMING_SD_HS && |
1184 | !(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)) | ||
1184 | ctrl |= SDHCI_CTRL_HISPD; | 1185 | ctrl |= SDHCI_CTRL_HISPD; |
1185 | else | 1186 | else |
1186 | ctrl &= ~SDHCI_CTRL_HISPD; | 1187 | ctrl &= ~SDHCI_CTRL_HISPD; |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 036cfae7636..d316bc79b63 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -245,6 +245,8 @@ struct sdhci_host { | |||
245 | #define SDHCI_QUIRK_MISSING_CAPS (1<<27) | 245 | #define SDHCI_QUIRK_MISSING_CAPS (1<<27) |
246 | /* Controller uses Auto CMD12 command to stop the transfer */ | 246 | /* Controller uses Auto CMD12 command to stop the transfer */ |
247 | #define SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 (1<<28) | 247 | #define SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 (1<<28) |
248 | /* Controller doesn't have HISPD bit field in HI-SPEED SD card */ | ||
249 | #define SDHCI_QUIRK_NO_HISPD_BIT (1<<29) | ||
248 | 250 | ||
249 | int irq; /* Device IRQ */ | 251 | int irq; /* Device IRQ */ |
250 | void __iomem * ioaddr; /* Mapped address */ | 252 | void __iomem * ioaddr; /* Mapped address */ |
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 00af55d7afb..fe63f6bd663 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/mtd/partitions.h> | 22 | #include <linux/mtd/partitions.h> |
23 | #include <linux/mtd/concat.h> | 23 | #include <linux/mtd/concat.h> |
24 | #include <linux/of.h> | 24 | #include <linux/of.h> |
25 | #include <linux/of_address.h> | ||
25 | #include <linux/of_platform.h> | 26 | #include <linux/of_platform.h> |
26 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
27 | 28 | ||
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index a3c7473dd40..d551ddd9537 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -2866,6 +2866,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2866 | */ | 2866 | */ |
2867 | if (id_data[0] == id_data[6] && id_data[1] == id_data[7] && | 2867 | if (id_data[0] == id_data[6] && id_data[1] == id_data[7] && |
2868 | id_data[0] == NAND_MFR_SAMSUNG && | 2868 | id_data[0] == NAND_MFR_SAMSUNG && |
2869 | (chip->cellinfo & NAND_CI_CELLTYPE_MSK) && | ||
2869 | id_data[5] != 0x00) { | 2870 | id_data[5] != 0x00) { |
2870 | /* Calc pagesize */ | 2871 | /* Calc pagesize */ |
2871 | mtd->writesize = 2048 << (extid & 0x03); | 2872 | mtd->writesize = 2048 << (extid & 0x03); |
@@ -2934,14 +2935,10 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2934 | chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32)) + 32 - 1; | 2935 | chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32)) + 32 - 1; |
2935 | 2936 | ||
2936 | /* Set the bad block position */ | 2937 | /* Set the bad block position */ |
2937 | if (!(busw & NAND_BUSWIDTH_16) && (*maf_id == NAND_MFR_STMICRO || | 2938 | if (mtd->writesize > 512 || (busw & NAND_BUSWIDTH_16)) |
2938 | (*maf_id == NAND_MFR_SAMSUNG && | ||
2939 | mtd->writesize == 512) || | ||
2940 | *maf_id == NAND_MFR_AMD)) | ||
2941 | chip->badblockpos = NAND_SMALL_BADBLOCK_POS; | ||
2942 | else | ||
2943 | chip->badblockpos = NAND_LARGE_BADBLOCK_POS; | 2939 | chip->badblockpos = NAND_LARGE_BADBLOCK_POS; |
2944 | 2940 | else | |
2941 | chip->badblockpos = NAND_SMALL_BADBLOCK_POS; | ||
2945 | 2942 | ||
2946 | /* Get chip options, preserve non chip based options */ | 2943 | /* Get chip options, preserve non chip based options */ |
2947 | chip->options &= ~NAND_CHIPOPTIONS_MSK; | 2944 | chip->options &= ~NAND_CHIPOPTIONS_MSK; |
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index e02fa4f0e3c..4d89f378020 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
@@ -363,7 +363,7 @@ static struct pxa3xx_nand_flash *builtin_flash_types[] = { | |||
363 | #define tAR_NDTR1(r) (((r) >> 0) & 0xf) | 363 | #define tAR_NDTR1(r) (((r) >> 0) & 0xf) |
364 | 364 | ||
365 | /* convert nano-seconds to nand flash controller clock cycles */ | 365 | /* convert nano-seconds to nand flash controller clock cycles */ |
366 | #define ns2cycle(ns, clk) (int)(((ns) * (clk / 1000000) / 1000) - 1) | 366 | #define ns2cycle(ns, clk) (int)((ns) * (clk / 1000000) / 1000) |
367 | 367 | ||
368 | /* convert nand flash controller clock cycles to nano-seconds */ | 368 | /* convert nand flash controller clock cycles to nano-seconds */ |
369 | #define cycle2ns(c, clk) ((((c) + 1) * 1000000 + clk / 500) / (clk / 1000)) | 369 | #define cycle2ns(c, clk) ((((c) + 1) * 1000000 + clk / 500) / (clk / 1000)) |
diff --git a/drivers/mtd/ubi/Kconfig.debug b/drivers/mtd/ubi/Kconfig.debug index 2246f154e2f..61f6e5e4045 100644 --- a/drivers/mtd/ubi/Kconfig.debug +++ b/drivers/mtd/ubi/Kconfig.debug | |||
@@ -6,7 +6,7 @@ config MTD_UBI_DEBUG | |||
6 | depends on SYSFS | 6 | depends on SYSFS |
7 | depends on MTD_UBI | 7 | depends on MTD_UBI |
8 | select DEBUG_FS | 8 | select DEBUG_FS |
9 | select KALLSYMS_ALL | 9 | select KALLSYMS_ALL if KALLSYMS && DEBUG_KERNEL |
10 | help | 10 | help |
11 | This option enables UBI debugging. | 11 | This option enables UBI debugging. |
12 | 12 | ||
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 4dfa6b90c21..3d2d1a69e9a 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c | |||
@@ -798,18 +798,18 @@ static int rename_volumes(struct ubi_device *ubi, | |||
798 | goto out_free; | 798 | goto out_free; |
799 | } | 799 | } |
800 | 800 | ||
801 | re = kzalloc(sizeof(struct ubi_rename_entry), GFP_KERNEL); | 801 | re1 = kzalloc(sizeof(struct ubi_rename_entry), GFP_KERNEL); |
802 | if (!re) { | 802 | if (!re1) { |
803 | err = -ENOMEM; | 803 | err = -ENOMEM; |
804 | ubi_close_volume(desc); | 804 | ubi_close_volume(desc); |
805 | goto out_free; | 805 | goto out_free; |
806 | } | 806 | } |
807 | 807 | ||
808 | re->remove = 1; | 808 | re1->remove = 1; |
809 | re->desc = desc; | 809 | re1->desc = desc; |
810 | list_add(&re->list, &rename_list); | 810 | list_add(&re1->list, &rename_list); |
811 | dbg_msg("will remove volume %d, name \"%s\"", | 811 | dbg_msg("will remove volume %d, name \"%s\"", |
812 | re->desc->vol->vol_id, re->desc->vol->name); | 812 | re1->desc->vol->vol_id, re1->desc->vol->name); |
813 | } | 813 | } |
814 | 814 | ||
815 | mutex_lock(&ubi->device_mutex); | 815 | mutex_lock(&ubi->device_mutex); |
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 372a15ac999..69b52e9c948 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c | |||
@@ -843,7 +843,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, | |||
843 | case UBI_COMPAT_DELETE: | 843 | case UBI_COMPAT_DELETE: |
844 | ubi_msg("\"delete\" compatible internal volume %d:%d" | 844 | ubi_msg("\"delete\" compatible internal volume %d:%d" |
845 | " found, will remove it", vol_id, lnum); | 845 | " found, will remove it", vol_id, lnum); |
846 | err = add_to_list(si, pnum, ec, &si->corr); | 846 | err = add_to_list(si, pnum, ec, &si->erase); |
847 | if (err) | 847 | if (err) |
848 | return err; | 848 | return err; |
849 | return 0; | 849 | return 0; |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index ee7b1d8fbb9..97a435672ea 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -1212,7 +1212,8 @@ int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum) | |||
1212 | retry: | 1212 | retry: |
1213 | spin_lock(&ubi->wl_lock); | 1213 | spin_lock(&ubi->wl_lock); |
1214 | e = ubi->lookuptbl[pnum]; | 1214 | e = ubi->lookuptbl[pnum]; |
1215 | if (e == ubi->move_from || in_wl_tree(e, &ubi->scrub)) { | 1215 | if (e == ubi->move_from || in_wl_tree(e, &ubi->scrub) || |
1216 | in_wl_tree(e, &ubi->erroneous)) { | ||
1216 | spin_unlock(&ubi->wl_lock); | 1217 | spin_unlock(&ubi->wl_lock); |
1217 | return 0; | 1218 | return 0; |
1218 | } | 1219 | } |
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 7a01588fb6f..e31a6d1919c 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
@@ -633,7 +633,8 @@ struct vortex_private { | |||
633 | open:1, | 633 | open:1, |
634 | medialock:1, | 634 | medialock:1, |
635 | must_free_region:1, /* Flag: if zero, Cardbus owns the I/O region */ | 635 | must_free_region:1, /* Flag: if zero, Cardbus owns the I/O region */ |
636 | large_frames:1; /* accept large frames */ | 636 | large_frames:1, /* accept large frames */ |
637 | handling_irq:1; /* private in_irq indicator */ | ||
637 | int drv_flags; | 638 | int drv_flags; |
638 | u16 status_enable; | 639 | u16 status_enable; |
639 | u16 intr_enable; | 640 | u16 intr_enable; |
@@ -646,7 +647,7 @@ struct vortex_private { | |||
646 | u16 io_size; /* Size of PCI region (for release_region) */ | 647 | u16 io_size; /* Size of PCI region (for release_region) */ |
647 | 648 | ||
648 | /* Serialises access to hardware other than MII and variables below. | 649 | /* Serialises access to hardware other than MII and variables below. |
649 | * The lock hierarchy is rtnl_lock > lock > mii_lock > window_lock. */ | 650 | * The lock hierarchy is rtnl_lock > {lock, mii_lock} > window_lock. */ |
650 | spinlock_t lock; | 651 | spinlock_t lock; |
651 | 652 | ||
652 | spinlock_t mii_lock; /* Serialises access to MII */ | 653 | spinlock_t mii_lock; /* Serialises access to MII */ |
@@ -1993,10 +1994,9 @@ vortex_error(struct net_device *dev, int status) | |||
1993 | } | 1994 | } |
1994 | } | 1995 | } |
1995 | 1996 | ||
1996 | if (status & RxEarly) { /* Rx early is unused. */ | 1997 | if (status & RxEarly) /* Rx early is unused. */ |
1997 | vortex_rx(dev); | ||
1998 | iowrite16(AckIntr | RxEarly, ioaddr + EL3_CMD); | 1998 | iowrite16(AckIntr | RxEarly, ioaddr + EL3_CMD); |
1999 | } | 1999 | |
2000 | if (status & StatsFull) { /* Empty statistics. */ | 2000 | if (status & StatsFull) { /* Empty statistics. */ |
2001 | static int DoneDidThat; | 2001 | static int DoneDidThat; |
2002 | if (vortex_debug > 4) | 2002 | if (vortex_debug > 4) |
@@ -2133,6 +2133,15 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2133 | dev->name, vp->cur_tx); | 2133 | dev->name, vp->cur_tx); |
2134 | } | 2134 | } |
2135 | 2135 | ||
2136 | /* | ||
2137 | * We can't allow a recursion from our interrupt handler back into the | ||
2138 | * tx routine, as they take the same spin lock, and that causes | ||
2139 | * deadlock. Just return NETDEV_TX_BUSY and let the stack try again in | ||
2140 | * a bit | ||
2141 | */ | ||
2142 | if (vp->handling_irq) | ||
2143 | return NETDEV_TX_BUSY; | ||
2144 | |||
2136 | if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) { | 2145 | if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) { |
2137 | if (vortex_debug > 0) | 2146 | if (vortex_debug > 0) |
2138 | pr_warning("%s: BUG! Tx Ring full, refusing to send buffer.\n", | 2147 | pr_warning("%s: BUG! Tx Ring full, refusing to send buffer.\n", |
@@ -2288,7 +2297,12 @@ vortex_interrupt(int irq, void *dev_id) | |||
2288 | if (status & (HostError | RxEarly | StatsFull | TxComplete | IntReq)) { | 2297 | if (status & (HostError | RxEarly | StatsFull | TxComplete | IntReq)) { |
2289 | if (status == 0xffff) | 2298 | if (status == 0xffff) |
2290 | break; | 2299 | break; |
2300 | if (status & RxEarly) | ||
2301 | vortex_rx(dev); | ||
2302 | spin_unlock(&vp->window_lock); | ||
2291 | vortex_error(dev, status); | 2303 | vortex_error(dev, status); |
2304 | spin_lock(&vp->window_lock); | ||
2305 | window_set(vp, 7); | ||
2292 | } | 2306 | } |
2293 | 2307 | ||
2294 | if (--work_done < 0) { | 2308 | if (--work_done < 0) { |
@@ -2335,11 +2349,13 @@ boomerang_interrupt(int irq, void *dev_id) | |||
2335 | 2349 | ||
2336 | ioaddr = vp->ioaddr; | 2350 | ioaddr = vp->ioaddr; |
2337 | 2351 | ||
2352 | |||
2338 | /* | 2353 | /* |
2339 | * It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout | 2354 | * It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout |
2340 | * and boomerang_start_xmit | 2355 | * and boomerang_start_xmit |
2341 | */ | 2356 | */ |
2342 | spin_lock(&vp->lock); | 2357 | spin_lock(&vp->lock); |
2358 | vp->handling_irq = 1; | ||
2343 | 2359 | ||
2344 | status = ioread16(ioaddr + EL3_STATUS); | 2360 | status = ioread16(ioaddr + EL3_STATUS); |
2345 | 2361 | ||
@@ -2447,6 +2463,7 @@ boomerang_interrupt(int irq, void *dev_id) | |||
2447 | pr_debug("%s: exiting interrupt, status %4.4x.\n", | 2463 | pr_debug("%s: exiting interrupt, status %4.4x.\n", |
2448 | dev->name, status); | 2464 | dev->name, status); |
2449 | handler_exit: | 2465 | handler_exit: |
2466 | vp->handling_irq = 0; | ||
2450 | spin_unlock(&vp->lock); | 2467 | spin_unlock(&vp->lock); |
2451 | return IRQ_HANDLED; | 2468 | return IRQ_HANDLED; |
2452 | } | 2469 | } |
@@ -2971,7 +2988,6 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
2971 | { | 2988 | { |
2972 | int err; | 2989 | int err; |
2973 | struct vortex_private *vp = netdev_priv(dev); | 2990 | struct vortex_private *vp = netdev_priv(dev); |
2974 | unsigned long flags; | ||
2975 | pci_power_t state = 0; | 2991 | pci_power_t state = 0; |
2976 | 2992 | ||
2977 | if(VORTEX_PCI(vp)) | 2993 | if(VORTEX_PCI(vp)) |
@@ -2981,9 +2997,7 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
2981 | 2997 | ||
2982 | if(state != 0) | 2998 | if(state != 0) |
2983 | pci_set_power_state(VORTEX_PCI(vp), PCI_D0); | 2999 | pci_set_power_state(VORTEX_PCI(vp), PCI_D0); |
2984 | spin_lock_irqsave(&vp->lock, flags); | ||
2985 | err = generic_mii_ioctl(&vp->mii, if_mii(rq), cmd, NULL); | 3000 | err = generic_mii_ioctl(&vp->mii, if_mii(rq), cmd, NULL); |
2986 | spin_unlock_irqrestore(&vp->lock, flags); | ||
2987 | if(state != 0) | 3001 | if(state != 0) |
2988 | pci_set_power_state(VORTEX_PCI(vp), state); | 3002 | pci_set_power_state(VORTEX_PCI(vp), state); |
2989 | 3003 | ||
diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 7342308718a..8e7c8a8e61c 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c | |||
@@ -848,6 +848,15 @@ static int b44_poll(struct napi_struct *napi, int budget) | |||
848 | b44_tx(bp); | 848 | b44_tx(bp); |
849 | /* spin_unlock(&bp->tx_lock); */ | 849 | /* spin_unlock(&bp->tx_lock); */ |
850 | } | 850 | } |
851 | if (bp->istat & ISTAT_RFO) { /* fast recovery, in ~20msec */ | ||
852 | bp->istat &= ~ISTAT_RFO; | ||
853 | b44_disable_ints(bp); | ||
854 | ssb_device_enable(bp->sdev, 0); /* resets ISTAT_RFO */ | ||
855 | b44_init_rings(bp); | ||
856 | b44_init_hw(bp, B44_FULL_RESET_SKIP_PHY); | ||
857 | netif_wake_queue(bp->dev); | ||
858 | } | ||
859 | |||
851 | spin_unlock_irqrestore(&bp->lock, flags); | 860 | spin_unlock_irqrestore(&bp->lock, flags); |
852 | 861 | ||
853 | work_done = 0; | 862 | work_done = 0; |
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index d1fb7928ffc..4faf6961dce 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h | |||
@@ -181,6 +181,7 @@ struct be_drvr_stats { | |||
181 | u64 be_rx_bytes_prev; | 181 | u64 be_rx_bytes_prev; |
182 | u64 be_rx_pkts; | 182 | u64 be_rx_pkts; |
183 | u32 be_rx_rate; | 183 | u32 be_rx_rate; |
184 | u32 be_rx_mcast_pkt; | ||
184 | /* number of non ether type II frames dropped where | 185 | /* number of non ether type II frames dropped where |
185 | * frame len > length field of Mac Hdr */ | 186 | * frame len > length field of Mac Hdr */ |
186 | u32 be_802_3_dropped_frames; | 187 | u32 be_802_3_dropped_frames; |
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 3d305494a60..34abcc9403d 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
@@ -140,10 +140,8 @@ int be_process_mcc(struct be_adapter *adapter, int *status) | |||
140 | while ((compl = be_mcc_compl_get(adapter))) { | 140 | while ((compl = be_mcc_compl_get(adapter))) { |
141 | if (compl->flags & CQE_FLAGS_ASYNC_MASK) { | 141 | if (compl->flags & CQE_FLAGS_ASYNC_MASK) { |
142 | /* Interpret flags as an async trailer */ | 142 | /* Interpret flags as an async trailer */ |
143 | BUG_ON(!is_link_state_evt(compl->flags)); | 143 | if (is_link_state_evt(compl->flags)) |
144 | 144 | be_async_link_state_process(adapter, | |
145 | /* Interpret compl as a async link evt */ | ||
146 | be_async_link_state_process(adapter, | ||
147 | (struct be_async_event_link_state *) compl); | 145 | (struct be_async_event_link_state *) compl); |
148 | } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { | 146 | } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { |
149 | *status = be_mcc_compl_process(adapter, compl); | 147 | *status = be_mcc_compl_process(adapter, compl); |
@@ -207,7 +205,7 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db) | |||
207 | 205 | ||
208 | if (msecs > 4000) { | 206 | if (msecs > 4000) { |
209 | dev_err(&adapter->pdev->dev, "mbox poll timed out\n"); | 207 | dev_err(&adapter->pdev->dev, "mbox poll timed out\n"); |
210 | be_dump_ue(adapter); | 208 | be_detect_dump_ue(adapter); |
211 | return -1; | 209 | return -1; |
212 | } | 210 | } |
213 | 211 | ||
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index bdc10a28cfd..ad1e6fac60c 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h | |||
@@ -992,5 +992,5 @@ extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, | |||
992 | extern int be_cmd_get_phy_info(struct be_adapter *adapter, | 992 | extern int be_cmd_get_phy_info(struct be_adapter *adapter, |
993 | struct be_dma_mem *cmd); | 993 | struct be_dma_mem *cmd); |
994 | extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); | 994 | extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); |
995 | extern void be_dump_ue(struct be_adapter *adapter); | 995 | extern void be_detect_dump_ue(struct be_adapter *adapter); |
996 | 996 | ||
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 9bedb9ff6e1..d92063420c2 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c | |||
@@ -60,6 +60,7 @@ static const struct be_ethtool_stat et_stats[] = { | |||
60 | {DRVSTAT_INFO(be_rx_events)}, | 60 | {DRVSTAT_INFO(be_rx_events)}, |
61 | {DRVSTAT_INFO(be_tx_compl)}, | 61 | {DRVSTAT_INFO(be_tx_compl)}, |
62 | {DRVSTAT_INFO(be_rx_compl)}, | 62 | {DRVSTAT_INFO(be_rx_compl)}, |
63 | {DRVSTAT_INFO(be_rx_mcast_pkt)}, | ||
63 | {DRVSTAT_INFO(be_ethrx_post_fail)}, | 64 | {DRVSTAT_INFO(be_ethrx_post_fail)}, |
64 | {DRVSTAT_INFO(be_802_3_dropped_frames)}, | 65 | {DRVSTAT_INFO(be_802_3_dropped_frames)}, |
65 | {DRVSTAT_INFO(be_802_3_malformed_frames)}, | 66 | {DRVSTAT_INFO(be_802_3_malformed_frames)}, |
diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index 5d38046402b..a2ec5df0d73 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h | |||
@@ -167,8 +167,11 @@ | |||
167 | #define FLASH_FCoE_BIOS_START_g3 (13631488) | 167 | #define FLASH_FCoE_BIOS_START_g3 (13631488) |
168 | #define FLASH_REDBOOT_START_g3 (262144) | 168 | #define FLASH_REDBOOT_START_g3 (262144) |
169 | 169 | ||
170 | 170 | /************* Rx Packet Type Encoding **************/ | |
171 | 171 | #define BE_UNICAST_PACKET 0 | |
172 | #define BE_MULTICAST_PACKET 1 | ||
173 | #define BE_BROADCAST_PACKET 2 | ||
174 | #define BE_RSVD_PACKET 3 | ||
172 | 175 | ||
173 | /* | 176 | /* |
174 | * BE descriptors: host memory data structures whose formats | 177 | * BE descriptors: host memory data structures whose formats |
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index dcee7a20c0b..43a3a574e2e 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -247,6 +247,7 @@ void netdev_stats_update(struct be_adapter *adapter) | |||
247 | dev_stats->tx_packets = drvr_stats(adapter)->be_tx_pkts; | 247 | dev_stats->tx_packets = drvr_stats(adapter)->be_tx_pkts; |
248 | dev_stats->rx_bytes = drvr_stats(adapter)->be_rx_bytes; | 248 | dev_stats->rx_bytes = drvr_stats(adapter)->be_rx_bytes; |
249 | dev_stats->tx_bytes = drvr_stats(adapter)->be_tx_bytes; | 249 | dev_stats->tx_bytes = drvr_stats(adapter)->be_tx_bytes; |
250 | dev_stats->multicast = drvr_stats(adapter)->be_rx_mcast_pkt; | ||
250 | 251 | ||
251 | /* bad pkts received */ | 252 | /* bad pkts received */ |
252 | dev_stats->rx_errors = port_stats->rx_crc_errors + | 253 | dev_stats->rx_errors = port_stats->rx_crc_errors + |
@@ -294,7 +295,6 @@ void netdev_stats_update(struct be_adapter *adapter) | |||
294 | /* no space available in linux */ | 295 | /* no space available in linux */ |
295 | dev_stats->tx_dropped = 0; | 296 | dev_stats->tx_dropped = 0; |
296 | 297 | ||
297 | dev_stats->multicast = port_stats->rx_multicast_frames; | ||
298 | dev_stats->collisions = 0; | 298 | dev_stats->collisions = 0; |
299 | 299 | ||
300 | /* detailed tx_errors */ | 300 | /* detailed tx_errors */ |
@@ -843,7 +843,7 @@ static void be_rx_rate_update(struct be_adapter *adapter) | |||
843 | } | 843 | } |
844 | 844 | ||
845 | static void be_rx_stats_update(struct be_adapter *adapter, | 845 | static void be_rx_stats_update(struct be_adapter *adapter, |
846 | u32 pktsize, u16 numfrags) | 846 | u32 pktsize, u16 numfrags, u8 pkt_type) |
847 | { | 847 | { |
848 | struct be_drvr_stats *stats = drvr_stats(adapter); | 848 | struct be_drvr_stats *stats = drvr_stats(adapter); |
849 | 849 | ||
@@ -851,6 +851,9 @@ static void be_rx_stats_update(struct be_adapter *adapter, | |||
851 | stats->be_rx_frags += numfrags; | 851 | stats->be_rx_frags += numfrags; |
852 | stats->be_rx_bytes += pktsize; | 852 | stats->be_rx_bytes += pktsize; |
853 | stats->be_rx_pkts++; | 853 | stats->be_rx_pkts++; |
854 | |||
855 | if (pkt_type == BE_MULTICAST_PACKET) | ||
856 | stats->be_rx_mcast_pkt++; | ||
854 | } | 857 | } |
855 | 858 | ||
856 | static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso) | 859 | static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso) |
@@ -920,9 +923,11 @@ static void skb_fill_rx_data(struct be_adapter *adapter, | |||
920 | u16 rxq_idx, i, j; | 923 | u16 rxq_idx, i, j; |
921 | u32 pktsize, hdr_len, curr_frag_len, size; | 924 | u32 pktsize, hdr_len, curr_frag_len, size; |
922 | u8 *start; | 925 | u8 *start; |
926 | u8 pkt_type; | ||
923 | 927 | ||
924 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); | 928 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); |
925 | pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); | 929 | pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); |
930 | pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl, cast_enc, rxcp); | ||
926 | 931 | ||
927 | page_info = get_rx_page_info(adapter, rxq_idx); | 932 | page_info = get_rx_page_info(adapter, rxq_idx); |
928 | 933 | ||
@@ -988,7 +993,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, | |||
988 | BUG_ON(j > MAX_SKB_FRAGS); | 993 | BUG_ON(j > MAX_SKB_FRAGS); |
989 | 994 | ||
990 | done: | 995 | done: |
991 | be_rx_stats_update(adapter, pktsize, num_rcvd); | 996 | be_rx_stats_update(adapter, pktsize, num_rcvd, pkt_type); |
992 | } | 997 | } |
993 | 998 | ||
994 | /* Process the RX completion indicated by rxcp when GRO is disabled */ | 999 | /* Process the RX completion indicated by rxcp when GRO is disabled */ |
@@ -1055,6 +1060,7 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, | |||
1055 | u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; | 1060 | u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; |
1056 | u16 i, rxq_idx = 0, vid, j; | 1061 | u16 i, rxq_idx = 0, vid, j; |
1057 | u8 vtm; | 1062 | u8 vtm; |
1063 | u8 pkt_type; | ||
1058 | 1064 | ||
1059 | num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); | 1065 | num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); |
1060 | /* Is it a flush compl that has no data */ | 1066 | /* Is it a flush compl that has no data */ |
@@ -1065,6 +1071,7 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, | |||
1065 | vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); | 1071 | vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); |
1066 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); | 1072 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); |
1067 | vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp); | 1073 | vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp); |
1074 | pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl, cast_enc, rxcp); | ||
1068 | 1075 | ||
1069 | /* vlanf could be wrongly set in some cards. | 1076 | /* vlanf could be wrongly set in some cards. |
1070 | * ignore if vtm is not set */ | 1077 | * ignore if vtm is not set */ |
@@ -1120,7 +1127,7 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, | |||
1120 | vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, vid); | 1127 | vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, vid); |
1121 | } | 1128 | } |
1122 | 1129 | ||
1123 | be_rx_stats_update(adapter, pkt_size, num_rcvd); | 1130 | be_rx_stats_update(adapter, pkt_size, num_rcvd, pkt_type); |
1124 | } | 1131 | } |
1125 | 1132 | ||
1126 | static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter) | 1133 | static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter) |
@@ -1738,26 +1745,7 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget) | |||
1738 | return 1; | 1745 | return 1; |
1739 | } | 1746 | } |
1740 | 1747 | ||
1741 | static inline bool be_detect_ue(struct be_adapter *adapter) | 1748 | void be_detect_dump_ue(struct be_adapter *adapter) |
1742 | { | ||
1743 | u32 online0 = 0, online1 = 0; | ||
1744 | |||
1745 | pci_read_config_dword(adapter->pdev, PCICFG_ONLINE0, &online0); | ||
1746 | |||
1747 | pci_read_config_dword(adapter->pdev, PCICFG_ONLINE1, &online1); | ||
1748 | |||
1749 | if (!online0 || !online1) { | ||
1750 | adapter->ue_detected = true; | ||
1751 | dev_err(&adapter->pdev->dev, | ||
1752 | "UE Detected!! online0=%d online1=%d\n", | ||
1753 | online0, online1); | ||
1754 | return true; | ||
1755 | } | ||
1756 | |||
1757 | return false; | ||
1758 | } | ||
1759 | |||
1760 | void be_dump_ue(struct be_adapter *adapter) | ||
1761 | { | 1749 | { |
1762 | u32 ue_status_lo, ue_status_hi, ue_status_lo_mask, ue_status_hi_mask; | 1750 | u32 ue_status_lo, ue_status_hi, ue_status_lo_mask, ue_status_hi_mask; |
1763 | u32 i; | 1751 | u32 i; |
@@ -1774,6 +1762,11 @@ void be_dump_ue(struct be_adapter *adapter) | |||
1774 | ue_status_lo = (ue_status_lo & (~ue_status_lo_mask)); | 1762 | ue_status_lo = (ue_status_lo & (~ue_status_lo_mask)); |
1775 | ue_status_hi = (ue_status_hi & (~ue_status_hi_mask)); | 1763 | ue_status_hi = (ue_status_hi & (~ue_status_hi_mask)); |
1776 | 1764 | ||
1765 | if (ue_status_lo || ue_status_hi) { | ||
1766 | adapter->ue_detected = true; | ||
1767 | dev_err(&adapter->pdev->dev, "UE Detected!!\n"); | ||
1768 | } | ||
1769 | |||
1777 | if (ue_status_lo) { | 1770 | if (ue_status_lo) { |
1778 | for (i = 0; ue_status_lo; ue_status_lo >>= 1, i++) { | 1771 | for (i = 0; ue_status_lo; ue_status_lo >>= 1, i++) { |
1779 | if (ue_status_lo & 1) | 1772 | if (ue_status_lo & 1) |
@@ -1809,10 +1802,8 @@ static void be_worker(struct work_struct *work) | |||
1809 | adapter->rx_post_starved = false; | 1802 | adapter->rx_post_starved = false; |
1810 | be_post_rx_frags(adapter); | 1803 | be_post_rx_frags(adapter); |
1811 | } | 1804 | } |
1812 | if (!adapter->ue_detected) { | 1805 | if (!adapter->ue_detected) |
1813 | if (be_detect_ue(adapter)) | 1806 | be_detect_dump_ue(adapter); |
1814 | be_dump_ue(adapter); | ||
1815 | } | ||
1816 | 1807 | ||
1817 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); | 1808 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); |
1818 | } | 1809 | } |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 2cc4cfc3189..3b16f62d560 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -2797,9 +2797,15 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
2797 | * so it can wait | 2797 | * so it can wait |
2798 | */ | 2798 | */ |
2799 | bond_for_each_slave(bond, slave, i) { | 2799 | bond_for_each_slave(bond, slave, i) { |
2800 | unsigned long trans_start = dev_trans_start(slave->dev); | ||
2801 | |||
2800 | if (slave->link != BOND_LINK_UP) { | 2802 | if (slave->link != BOND_LINK_UP) { |
2801 | if (time_before_eq(jiffies, dev_trans_start(slave->dev) + delta_in_ticks) && | 2803 | if (time_in_range(jiffies, |
2802 | time_before_eq(jiffies, slave->dev->last_rx + delta_in_ticks)) { | 2804 | trans_start - delta_in_ticks, |
2805 | trans_start + delta_in_ticks) && | ||
2806 | time_in_range(jiffies, | ||
2807 | slave->dev->last_rx - delta_in_ticks, | ||
2808 | slave->dev->last_rx + delta_in_ticks)) { | ||
2803 | 2809 | ||
2804 | slave->link = BOND_LINK_UP; | 2810 | slave->link = BOND_LINK_UP; |
2805 | slave->state = BOND_STATE_ACTIVE; | 2811 | slave->state = BOND_STATE_ACTIVE; |
@@ -2827,8 +2833,12 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
2827 | * when the source ip is 0, so don't take the link down | 2833 | * when the source ip is 0, so don't take the link down |
2828 | * if we don't know our ip yet | 2834 | * if we don't know our ip yet |
2829 | */ | 2835 | */ |
2830 | if (time_after_eq(jiffies, dev_trans_start(slave->dev) + 2*delta_in_ticks) || | 2836 | if (!time_in_range(jiffies, |
2831 | (time_after_eq(jiffies, slave->dev->last_rx + 2*delta_in_ticks))) { | 2837 | trans_start - delta_in_ticks, |
2838 | trans_start + 2 * delta_in_ticks) || | ||
2839 | !time_in_range(jiffies, | ||
2840 | slave->dev->last_rx - delta_in_ticks, | ||
2841 | slave->dev->last_rx + 2 * delta_in_ticks)) { | ||
2832 | 2842 | ||
2833 | slave->link = BOND_LINK_DOWN; | 2843 | slave->link = BOND_LINK_DOWN; |
2834 | slave->state = BOND_STATE_BACKUP; | 2844 | slave->state = BOND_STATE_BACKUP; |
@@ -2883,13 +2893,16 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) | |||
2883 | { | 2893 | { |
2884 | struct slave *slave; | 2894 | struct slave *slave; |
2885 | int i, commit = 0; | 2895 | int i, commit = 0; |
2896 | unsigned long trans_start; | ||
2886 | 2897 | ||
2887 | bond_for_each_slave(bond, slave, i) { | 2898 | bond_for_each_slave(bond, slave, i) { |
2888 | slave->new_link = BOND_LINK_NOCHANGE; | 2899 | slave->new_link = BOND_LINK_NOCHANGE; |
2889 | 2900 | ||
2890 | if (slave->link != BOND_LINK_UP) { | 2901 | if (slave->link != BOND_LINK_UP) { |
2891 | if (time_before_eq(jiffies, slave_last_rx(bond, slave) + | 2902 | if (time_in_range(jiffies, |
2892 | delta_in_ticks)) { | 2903 | slave_last_rx(bond, slave) - delta_in_ticks, |
2904 | slave_last_rx(bond, slave) + delta_in_ticks)) { | ||
2905 | |||
2893 | slave->new_link = BOND_LINK_UP; | 2906 | slave->new_link = BOND_LINK_UP; |
2894 | commit++; | 2907 | commit++; |
2895 | } | 2908 | } |
@@ -2902,8 +2915,9 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) | |||
2902 | * active. This avoids bouncing, as the last receive | 2915 | * active. This avoids bouncing, as the last receive |
2903 | * times need a full ARP monitor cycle to be updated. | 2916 | * times need a full ARP monitor cycle to be updated. |
2904 | */ | 2917 | */ |
2905 | if (!time_after_eq(jiffies, slave->jiffies + | 2918 | if (time_in_range(jiffies, |
2906 | 2 * delta_in_ticks)) | 2919 | slave->jiffies - delta_in_ticks, |
2920 | slave->jiffies + 2 * delta_in_ticks)) | ||
2907 | continue; | 2921 | continue; |
2908 | 2922 | ||
2909 | /* | 2923 | /* |
@@ -2921,8 +2935,10 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) | |||
2921 | */ | 2935 | */ |
2922 | if (slave->state == BOND_STATE_BACKUP && | 2936 | if (slave->state == BOND_STATE_BACKUP && |
2923 | !bond->current_arp_slave && | 2937 | !bond->current_arp_slave && |
2924 | time_after(jiffies, slave_last_rx(bond, slave) + | 2938 | !time_in_range(jiffies, |
2925 | 3 * delta_in_ticks)) { | 2939 | slave_last_rx(bond, slave) - delta_in_ticks, |
2940 | slave_last_rx(bond, slave) + 3 * delta_in_ticks)) { | ||
2941 | |||
2926 | slave->new_link = BOND_LINK_DOWN; | 2942 | slave->new_link = BOND_LINK_DOWN; |
2927 | commit++; | 2943 | commit++; |
2928 | } | 2944 | } |
@@ -2933,11 +2949,15 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) | |||
2933 | * - (more than 2*delta since receive AND | 2949 | * - (more than 2*delta since receive AND |
2934 | * the bond has an IP address) | 2950 | * the bond has an IP address) |
2935 | */ | 2951 | */ |
2952 | trans_start = dev_trans_start(slave->dev); | ||
2936 | if ((slave->state == BOND_STATE_ACTIVE) && | 2953 | if ((slave->state == BOND_STATE_ACTIVE) && |
2937 | (time_after_eq(jiffies, dev_trans_start(slave->dev) + | 2954 | (!time_in_range(jiffies, |
2938 | 2 * delta_in_ticks) || | 2955 | trans_start - delta_in_ticks, |
2939 | (time_after_eq(jiffies, slave_last_rx(bond, slave) | 2956 | trans_start + 2 * delta_in_ticks) || |
2940 | + 2 * delta_in_ticks)))) { | 2957 | !time_in_range(jiffies, |
2958 | slave_last_rx(bond, slave) - delta_in_ticks, | ||
2959 | slave_last_rx(bond, slave) + 2 * delta_in_ticks))) { | ||
2960 | |||
2941 | slave->new_link = BOND_LINK_DOWN; | 2961 | slave->new_link = BOND_LINK_DOWN; |
2942 | commit++; | 2962 | commit++; |
2943 | } | 2963 | } |
@@ -2956,6 +2976,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks) | |||
2956 | { | 2976 | { |
2957 | struct slave *slave; | 2977 | struct slave *slave; |
2958 | int i; | 2978 | int i; |
2979 | unsigned long trans_start; | ||
2959 | 2980 | ||
2960 | bond_for_each_slave(bond, slave, i) { | 2981 | bond_for_each_slave(bond, slave, i) { |
2961 | switch (slave->new_link) { | 2982 | switch (slave->new_link) { |
@@ -2963,10 +2984,11 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks) | |||
2963 | continue; | 2984 | continue; |
2964 | 2985 | ||
2965 | case BOND_LINK_UP: | 2986 | case BOND_LINK_UP: |
2987 | trans_start = dev_trans_start(slave->dev); | ||
2966 | if ((!bond->curr_active_slave && | 2988 | if ((!bond->curr_active_slave && |
2967 | time_before_eq(jiffies, | 2989 | time_in_range(jiffies, |
2968 | dev_trans_start(slave->dev) + | 2990 | trans_start - delta_in_ticks, |
2969 | delta_in_ticks)) || | 2991 | trans_start + delta_in_ticks)) || |
2970 | bond->curr_active_slave != slave) { | 2992 | bond->curr_active_slave != slave) { |
2971 | slave->link = BOND_LINK_UP; | 2993 | slave->link = BOND_LINK_UP; |
2972 | bond->current_arp_slave = NULL; | 2994 | bond->current_arp_slave = NULL; |
diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig index 631a6242b01..75bfc3a9d95 100644 --- a/drivers/net/caif/Kconfig +++ b/drivers/net/caif/Kconfig | |||
@@ -15,7 +15,7 @@ config CAIF_TTY | |||
15 | 15 | ||
16 | config CAIF_SPI_SLAVE | 16 | config CAIF_SPI_SLAVE |
17 | tristate "CAIF SPI transport driver for slave interface" | 17 | tristate "CAIF SPI transport driver for slave interface" |
18 | depends on CAIF | 18 | depends on CAIF && HAS_DMA |
19 | default n | 19 | default n |
20 | ---help--- | 20 | ---help--- |
21 | The CAIF Link layer SPI Protocol driver for Slave SPI interface. | 21 | The CAIF Link layer SPI Protocol driver for Slave SPI interface. |
diff --git a/drivers/net/ibm_newemac/debug.c b/drivers/net/ibm_newemac/debug.c index 3995fafc1e0..8c6c1e2a875 100644 --- a/drivers/net/ibm_newemac/debug.c +++ b/drivers/net/ibm_newemac/debug.c | |||
@@ -238,7 +238,7 @@ void emac_dbg_dump_all(void) | |||
238 | } | 238 | } |
239 | 239 | ||
240 | #if defined(CONFIG_MAGIC_SYSRQ) | 240 | #if defined(CONFIG_MAGIC_SYSRQ) |
241 | static void emac_sysrq_handler(int key, struct tty_struct *tty) | 241 | static void emac_sysrq_handler(int key) |
242 | { | 242 | { |
243 | emac_dbg_dump_all(); | 243 | emac_dbg_dump_all(); |
244 | } | 244 | } |
diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c index b4fb07a6f13..51919fcd50c 100644 --- a/drivers/net/ks8851.c +++ b/drivers/net/ks8851.c | |||
@@ -503,30 +503,33 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) | |||
503 | ks8851_wrreg16(ks, KS_RXQCR, | 503 | ks8851_wrreg16(ks, KS_RXQCR, |
504 | ks->rc_rxqcr | RXQCR_SDA | RXQCR_ADRFE); | 504 | ks->rc_rxqcr | RXQCR_SDA | RXQCR_ADRFE); |
505 | 505 | ||
506 | if (rxlen > 0) { | 506 | if (rxlen > 4) { |
507 | skb = netdev_alloc_skb(ks->netdev, rxlen + 2 + 8); | 507 | unsigned int rxalign; |
508 | if (!skb) { | 508 | |
509 | /* todo - dump frame and move on */ | 509 | rxlen -= 4; |
510 | } | 510 | rxalign = ALIGN(rxlen, 4); |
511 | skb = netdev_alloc_skb_ip_align(ks->netdev, rxalign); | ||
512 | if (skb) { | ||
511 | 513 | ||
512 | /* two bytes to ensure ip is aligned, and four bytes | 514 | /* 4 bytes of status header + 4 bytes of |
513 | * for the status header and 4 bytes of garbage */ | 515 | * garbage: we put them before ethernet |
514 | skb_reserve(skb, 2 + 4 + 4); | 516 | * header, so that they are copied, |
517 | * but ignored. | ||
518 | */ | ||
515 | 519 | ||
516 | rxpkt = skb_put(skb, rxlen - 4) - 8; | 520 | rxpkt = skb_put(skb, rxlen) - 8; |
517 | 521 | ||
518 | /* align the packet length to 4 bytes, and add 4 bytes | 522 | ks8851_rdfifo(ks, rxpkt, rxalign + 8); |
519 | * as we're getting the rx status header as well */ | ||
520 | ks8851_rdfifo(ks, rxpkt, ALIGN(rxlen, 4) + 8); | ||
521 | 523 | ||
522 | if (netif_msg_pktdata(ks)) | 524 | if (netif_msg_pktdata(ks)) |
523 | ks8851_dbg_dumpkkt(ks, rxpkt); | 525 | ks8851_dbg_dumpkkt(ks, rxpkt); |
524 | 526 | ||
525 | skb->protocol = eth_type_trans(skb, ks->netdev); | 527 | skb->protocol = eth_type_trans(skb, ks->netdev); |
526 | netif_rx(skb); | 528 | netif_rx(skb); |
527 | 529 | ||
528 | ks->netdev->stats.rx_packets++; | 530 | ks->netdev->stats.rx_packets++; |
529 | ks->netdev->stats.rx_bytes += rxlen - 4; | 531 | ks->netdev->stats.rx_bytes += rxlen; |
532 | } | ||
530 | } | 533 | } |
531 | 534 | ||
532 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); | 535 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index cb30df106a2..73d31459223 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -2131,9 +2131,16 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget) | |||
2131 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2131 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2132 | static void netxen_nic_poll_controller(struct net_device *netdev) | 2132 | static void netxen_nic_poll_controller(struct net_device *netdev) |
2133 | { | 2133 | { |
2134 | int ring; | ||
2135 | struct nx_host_sds_ring *sds_ring; | ||
2134 | struct netxen_adapter *adapter = netdev_priv(netdev); | 2136 | struct netxen_adapter *adapter = netdev_priv(netdev); |
2137 | struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; | ||
2138 | |||
2135 | disable_irq(adapter->irq); | 2139 | disable_irq(adapter->irq); |
2136 | netxen_intr(adapter->irq, adapter); | 2140 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
2141 | sds_ring = &recv_ctx->sds_rings[ring]; | ||
2142 | netxen_intr(adapter->irq, sds_ring); | ||
2143 | } | ||
2137 | enable_irq(adapter->irq); | 2144 | enable_irq(adapter->irq); |
2138 | } | 2145 | } |
2139 | #endif | 2146 | #endif |
diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 1f89f472cbf..8e1859c801a 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c | |||
@@ -7269,32 +7269,28 @@ static int niu_get_ethtool_tcam_all(struct niu *np, | |||
7269 | struct niu_parent *parent = np->parent; | 7269 | struct niu_parent *parent = np->parent; |
7270 | struct niu_tcam_entry *tp; | 7270 | struct niu_tcam_entry *tp; |
7271 | int i, idx, cnt; | 7271 | int i, idx, cnt; |
7272 | u16 n_entries; | ||
7273 | unsigned long flags; | 7272 | unsigned long flags; |
7274 | 7273 | int ret = 0; | |
7275 | 7274 | ||
7276 | /* put the tcam size here */ | 7275 | /* put the tcam size here */ |
7277 | nfc->data = tcam_get_size(np); | 7276 | nfc->data = tcam_get_size(np); |
7278 | 7277 | ||
7279 | niu_lock_parent(np, flags); | 7278 | niu_lock_parent(np, flags); |
7280 | n_entries = nfc->rule_cnt; | ||
7281 | for (cnt = 0, i = 0; i < nfc->data; i++) { | 7279 | for (cnt = 0, i = 0; i < nfc->data; i++) { |
7282 | idx = tcam_get_index(np, i); | 7280 | idx = tcam_get_index(np, i); |
7283 | tp = &parent->tcam[idx]; | 7281 | tp = &parent->tcam[idx]; |
7284 | if (!tp->valid) | 7282 | if (!tp->valid) |
7285 | continue; | 7283 | continue; |
7284 | if (cnt == nfc->rule_cnt) { | ||
7285 | ret = -EMSGSIZE; | ||
7286 | break; | ||
7287 | } | ||
7286 | rule_locs[cnt] = i; | 7288 | rule_locs[cnt] = i; |
7287 | cnt++; | 7289 | cnt++; |
7288 | } | 7290 | } |
7289 | niu_unlock_parent(np, flags); | 7291 | niu_unlock_parent(np, flags); |
7290 | 7292 | ||
7291 | if (n_entries != cnt) { | 7293 | return ret; |
7292 | /* print warning, this should not happen */ | ||
7293 | netdev_info(np->dev, "niu%d: In %s(): n_entries[%d] != cnt[%d]!!!\n", | ||
7294 | np->parent->index, __func__, n_entries, cnt); | ||
7295 | } | ||
7296 | |||
7297 | return 0; | ||
7298 | } | 7294 | } |
7299 | 7295 | ||
7300 | static int niu_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd, | 7296 | static int niu_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd, |
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 5ad42e0aee2..e180832c278 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c | |||
@@ -1617,6 +1617,7 @@ static struct pcmcia_device_id pcnet_ids[] = { | |||
1617 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCETTX", 0x547e66dc, 0x6fc5459b), | 1617 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCETTX", 0x547e66dc, 0x6fc5459b), |
1618 | PCMCIA_DEVICE_PROD_ID12("iPort", "10/100 Ethernet Card", 0x56c538d2, 0x11b0ffc0), | 1618 | PCMCIA_DEVICE_PROD_ID12("iPort", "10/100 Ethernet Card", 0x56c538d2, 0x11b0ffc0), |
1619 | PCMCIA_DEVICE_PROD_ID12("KANSAI ELECTRIC CO.,LTD", "KLA-PCM/T", 0xb18dc3b4, 0xcc51a956), | 1619 | PCMCIA_DEVICE_PROD_ID12("KANSAI ELECTRIC CO.,LTD", "KLA-PCM/T", 0xb18dc3b4, 0xcc51a956), |
1620 | PCMCIA_DEVICE_PROD_ID12("KENTRONICS", "KEP-230", 0xaf8144c9, 0x868f6616), | ||
1620 | PCMCIA_DEVICE_PROD_ID12("KCI", "PE520 PCMCIA Ethernet Adapter", 0xa89b87d3, 0x1eb88e64), | 1621 | PCMCIA_DEVICE_PROD_ID12("KCI", "PE520 PCMCIA Ethernet Adapter", 0xa89b87d3, 0x1eb88e64), |
1621 | PCMCIA_DEVICE_PROD_ID12("KINGMAX", "EN10T2T", 0x7bcb459a, 0xa5c81fa5), | 1622 | PCMCIA_DEVICE_PROD_ID12("KINGMAX", "EN10T2T", 0x7bcb459a, 0xa5c81fa5), |
1622 | PCMCIA_DEVICE_PROD_ID12("Kingston", "KNE-PC2", 0x1128e633, 0xce2a89b3), | 1623 | PCMCIA_DEVICE_PROD_ID12("Kingston", "KNE-PC2", 0x1128e633, 0xce2a89b3), |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index c0761197c07..16ddc77313c 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -466,6 +466,8 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, | |||
466 | 466 | ||
467 | phydev->interface = interface; | 467 | phydev->interface = interface; |
468 | 468 | ||
469 | phydev->state = PHY_READY; | ||
470 | |||
469 | /* Do initial configuration here, now that | 471 | /* Do initial configuration here, now that |
470 | * we have certain key parameters | 472 | * we have certain key parameters |
471 | * (dev_flags and interface) */ | 473 | * (dev_flags and interface) */ |
diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c index 764aa909946..75c2ff99d66 100644 --- a/drivers/net/pxa168_eth.c +++ b/drivers/net/pxa168_eth.c | |||
@@ -652,15 +652,15 @@ static void eth_port_start(struct net_device *dev) | |||
652 | /* Assignment of Tx CTRP of given queue */ | 652 | /* Assignment of Tx CTRP of given queue */ |
653 | tx_curr_desc = pep->tx_curr_desc_q; | 653 | tx_curr_desc = pep->tx_curr_desc_q; |
654 | wrl(pep, ETH_C_TX_DESC_1, | 654 | wrl(pep, ETH_C_TX_DESC_1, |
655 | (u32) ((struct tx_desc *)pep->tx_desc_dma + tx_curr_desc)); | 655 | (u32) (pep->tx_desc_dma + tx_curr_desc * sizeof(struct tx_desc))); |
656 | 656 | ||
657 | /* Assignment of Rx CRDP of given queue */ | 657 | /* Assignment of Rx CRDP of given queue */ |
658 | rx_curr_desc = pep->rx_curr_desc_q; | 658 | rx_curr_desc = pep->rx_curr_desc_q; |
659 | wrl(pep, ETH_C_RX_DESC_0, | 659 | wrl(pep, ETH_C_RX_DESC_0, |
660 | (u32) ((struct rx_desc *)pep->rx_desc_dma + rx_curr_desc)); | 660 | (u32) (pep->rx_desc_dma + rx_curr_desc * sizeof(struct rx_desc))); |
661 | 661 | ||
662 | wrl(pep, ETH_F_RX_DESC_0, | 662 | wrl(pep, ETH_F_RX_DESC_0, |
663 | (u32) ((struct rx_desc *)pep->rx_desc_dma + rx_curr_desc)); | 663 | (u32) (pep->rx_desc_dma + rx_curr_desc * sizeof(struct rx_desc))); |
664 | 664 | ||
665 | /* Clear all interrupts */ | 665 | /* Clear all interrupts */ |
666 | wrl(pep, INT_CAUSE, 0); | 666 | wrl(pep, INT_CAUSE, 0); |
@@ -1347,7 +1347,7 @@ static int pxa168_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, | |||
1347 | { | 1347 | { |
1348 | struct pxa168_eth_private *pep = netdev_priv(dev); | 1348 | struct pxa168_eth_private *pep = netdev_priv(dev); |
1349 | if (pep->phy != NULL) | 1349 | if (pep->phy != NULL) |
1350 | return phy_mii_ioctl(pep->phy, if_mii(ifr), cmd); | 1350 | return phy_mii_ioctl(pep->phy, ifr, cmd); |
1351 | 1351 | ||
1352 | return -EOPNOTSUPP; | 1352 | return -EOPNOTSUPP; |
1353 | } | 1353 | } |
@@ -1411,10 +1411,8 @@ static int ethernet_phy_setup(struct net_device *dev) | |||
1411 | { | 1411 | { |
1412 | struct pxa168_eth_private *pep = netdev_priv(dev); | 1412 | struct pxa168_eth_private *pep = netdev_priv(dev); |
1413 | 1413 | ||
1414 | if (pep->pd != NULL) { | 1414 | if (pep->pd->init) |
1415 | if (pep->pd->init) | 1415 | pep->pd->init(); |
1416 | pep->pd->init(); | ||
1417 | } | ||
1418 | pep->phy = phy_scan(pep, pep->pd->phy_addr & 0x1f); | 1416 | pep->phy = phy_scan(pep, pep->pd->phy_addr & 0x1f); |
1419 | if (pep->phy != NULL) | 1417 | if (pep->phy != NULL) |
1420 | phy_init(pep, pep->pd->speed, pep->pd->duplex); | 1418 | phy_init(pep, pep->pd->speed, pep->pd->duplex); |
@@ -1496,7 +1494,7 @@ static int pxa168_eth_probe(struct platform_device *pdev) | |||
1496 | dev = alloc_etherdev(sizeof(struct pxa168_eth_private)); | 1494 | dev = alloc_etherdev(sizeof(struct pxa168_eth_private)); |
1497 | if (!dev) { | 1495 | if (!dev) { |
1498 | err = -ENOMEM; | 1496 | err = -ENOMEM; |
1499 | goto out; | 1497 | goto err_clk; |
1500 | } | 1498 | } |
1501 | 1499 | ||
1502 | platform_set_drvdata(pdev, dev); | 1500 | platform_set_drvdata(pdev, dev); |
@@ -1506,12 +1504,12 @@ static int pxa168_eth_probe(struct platform_device *pdev) | |||
1506 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1504 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1507 | if (res == NULL) { | 1505 | if (res == NULL) { |
1508 | err = -ENODEV; | 1506 | err = -ENODEV; |
1509 | goto out; | 1507 | goto err_netdev; |
1510 | } | 1508 | } |
1511 | pep->base = ioremap(res->start, res->end - res->start + 1); | 1509 | pep->base = ioremap(res->start, res->end - res->start + 1); |
1512 | if (pep->base == NULL) { | 1510 | if (pep->base == NULL) { |
1513 | err = -ENOMEM; | 1511 | err = -ENOMEM; |
1514 | goto out; | 1512 | goto err_netdev; |
1515 | } | 1513 | } |
1516 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 1514 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
1517 | BUG_ON(!res); | 1515 | BUG_ON(!res); |
@@ -1548,7 +1546,7 @@ static int pxa168_eth_probe(struct platform_device *pdev) | |||
1548 | pep->smi_bus = mdiobus_alloc(); | 1546 | pep->smi_bus = mdiobus_alloc(); |
1549 | if (pep->smi_bus == NULL) { | 1547 | if (pep->smi_bus == NULL) { |
1550 | err = -ENOMEM; | 1548 | err = -ENOMEM; |
1551 | goto out; | 1549 | goto err_base; |
1552 | } | 1550 | } |
1553 | pep->smi_bus->priv = pep; | 1551 | pep->smi_bus->priv = pep; |
1554 | pep->smi_bus->name = "pxa168_eth smi"; | 1552 | pep->smi_bus->name = "pxa168_eth smi"; |
@@ -1557,31 +1555,31 @@ static int pxa168_eth_probe(struct platform_device *pdev) | |||
1557 | snprintf(pep->smi_bus->id, MII_BUS_ID_SIZE, "%d", pdev->id); | 1555 | snprintf(pep->smi_bus->id, MII_BUS_ID_SIZE, "%d", pdev->id); |
1558 | pep->smi_bus->parent = &pdev->dev; | 1556 | pep->smi_bus->parent = &pdev->dev; |
1559 | pep->smi_bus->phy_mask = 0xffffffff; | 1557 | pep->smi_bus->phy_mask = 0xffffffff; |
1560 | if (mdiobus_register(pep->smi_bus) < 0) { | 1558 | err = mdiobus_register(pep->smi_bus); |
1561 | err = -ENOMEM; | 1559 | if (err) |
1562 | goto out; | 1560 | goto err_free_mdio; |
1563 | } | 1561 | |
1564 | pxa168_init_hw(pep); | 1562 | pxa168_init_hw(pep); |
1565 | err = ethernet_phy_setup(dev); | 1563 | err = ethernet_phy_setup(dev); |
1566 | if (err) | 1564 | if (err) |
1567 | goto out; | 1565 | goto err_mdiobus; |
1568 | SET_NETDEV_DEV(dev, &pdev->dev); | 1566 | SET_NETDEV_DEV(dev, &pdev->dev); |
1569 | err = register_netdev(dev); | 1567 | err = register_netdev(dev); |
1570 | if (err) | 1568 | if (err) |
1571 | goto out; | 1569 | goto err_mdiobus; |
1572 | return 0; | 1570 | return 0; |
1573 | out: | 1571 | |
1574 | if (pep->clk) { | 1572 | err_mdiobus: |
1575 | clk_disable(pep->clk); | 1573 | mdiobus_unregister(pep->smi_bus); |
1576 | clk_put(pep->clk); | 1574 | err_free_mdio: |
1577 | pep->clk = NULL; | 1575 | mdiobus_free(pep->smi_bus); |
1578 | } | 1576 | err_base: |
1579 | if (pep->base) { | 1577 | iounmap(pep->base); |
1580 | iounmap(pep->base); | 1578 | err_netdev: |
1581 | pep->base = NULL; | 1579 | free_netdev(dev); |
1582 | } | 1580 | err_clk: |
1583 | if (dev) | 1581 | clk_disable(clk); |
1584 | free_netdev(dev); | 1582 | clk_put(clk); |
1585 | return err; | 1583 | return err; |
1586 | } | 1584 | } |
1587 | 1585 | ||
@@ -1605,6 +1603,8 @@ static int pxa168_eth_remove(struct platform_device *pdev) | |||
1605 | 1603 | ||
1606 | iounmap(pep->base); | 1604 | iounmap(pep->base); |
1607 | pep->base = NULL; | 1605 | pep->base = NULL; |
1606 | mdiobus_unregister(pep->smi_bus); | ||
1607 | mdiobus_free(pep->smi_bus); | ||
1608 | unregister_netdev(dev); | 1608 | unregister_netdev(dev); |
1609 | flush_scheduled_work(); | 1609 | flush_scheduled_work(); |
1610 | free_netdev(dev); | 1610 | free_netdev(dev); |
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 5a6445a691b..5fd2abd1eb6 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -2513,9 +2513,16 @@ static int qlcnic_rx_poll(struct napi_struct *napi, int budget) | |||
2513 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2513 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2514 | static void qlcnic_poll_controller(struct net_device *netdev) | 2514 | static void qlcnic_poll_controller(struct net_device *netdev) |
2515 | { | 2515 | { |
2516 | int ring; | ||
2517 | struct qlcnic_host_sds_ring *sds_ring; | ||
2516 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 2518 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
2519 | struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; | ||
2520 | |||
2517 | disable_irq(adapter->irq); | 2521 | disable_irq(adapter->irq); |
2518 | qlcnic_intr(adapter->irq, adapter); | 2522 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
2523 | sds_ring = &recv_ctx->sds_rings[ring]; | ||
2524 | qlcnic_intr(adapter->irq, sds_ring); | ||
2525 | } | ||
2519 | enable_irq(adapter->irq); | 2526 | enable_irq(adapter->irq); |
2520 | } | 2527 | } |
2521 | #endif | 2528 | #endif |
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index e2d0e108b9a..4ffebe83d88 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
@@ -3926,12 +3926,12 @@ static int ql_adapter_down(struct ql_adapter *qdev) | |||
3926 | for (i = 0; i < qdev->rss_ring_count; i++) | 3926 | for (i = 0; i < qdev->rss_ring_count; i++) |
3927 | netif_napi_del(&qdev->rx_ring[i].napi); | 3927 | netif_napi_del(&qdev->rx_ring[i].napi); |
3928 | 3928 | ||
3929 | ql_free_rx_buffers(qdev); | ||
3930 | |||
3931 | status = ql_adapter_reset(qdev); | 3929 | status = ql_adapter_reset(qdev); |
3932 | if (status) | 3930 | if (status) |
3933 | netif_err(qdev, ifdown, qdev->ndev, "reset(func #%d) FAILED!\n", | 3931 | netif_err(qdev, ifdown, qdev->ndev, "reset(func #%d) FAILED!\n", |
3934 | qdev->func); | 3932 | qdev->func); |
3933 | ql_free_rx_buffers(qdev); | ||
3934 | |||
3935 | return status; | 3935 | return status; |
3936 | } | 3936 | } |
3937 | 3937 | ||
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index 1ccea76d89a..03c160c6d75 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c | |||
@@ -1862,15 +1862,15 @@ static int stmmac_resume(struct platform_device *pdev) | |||
1862 | if (!netif_running(dev)) | 1862 | if (!netif_running(dev)) |
1863 | return 0; | 1863 | return 0; |
1864 | 1864 | ||
1865 | spin_lock(&priv->lock); | ||
1866 | |||
1867 | if (priv->shutdown) { | 1865 | if (priv->shutdown) { |
1868 | /* Re-open the interface and re-init the MAC/DMA | 1866 | /* Re-open the interface and re-init the MAC/DMA |
1869 | and the rings. */ | 1867 | and the rings (i.e. on hibernation stage) */ |
1870 | stmmac_open(dev); | 1868 | stmmac_open(dev); |
1871 | goto out_resume; | 1869 | return 0; |
1872 | } | 1870 | } |
1873 | 1871 | ||
1872 | spin_lock(&priv->lock); | ||
1873 | |||
1874 | /* Power Down bit, into the PM register, is cleared | 1874 | /* Power Down bit, into the PM register, is cleared |
1875 | * automatically as soon as a magic packet or a Wake-up frame | 1875 | * automatically as soon as a magic packet or a Wake-up frame |
1876 | * is received. Anyway, it's better to manually clear | 1876 | * is received. Anyway, it's better to manually clear |
@@ -1898,7 +1898,6 @@ static int stmmac_resume(struct platform_device *pdev) | |||
1898 | 1898 | ||
1899 | netif_start_queue(dev); | 1899 | netif_start_queue(dev); |
1900 | 1900 | ||
1901 | out_resume: | ||
1902 | spin_unlock(&priv->lock); | 1901 | spin_unlock(&priv->lock); |
1903 | return 0; | 1902 | return 0; |
1904 | } | 1903 | } |
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index 08e7b6abacd..b2bcf99e6f0 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #define USB_PRODUCT_IPHONE 0x1290 | 58 | #define USB_PRODUCT_IPHONE 0x1290 |
59 | #define USB_PRODUCT_IPHONE_3G 0x1292 | 59 | #define USB_PRODUCT_IPHONE_3G 0x1292 |
60 | #define USB_PRODUCT_IPHONE_3GS 0x1294 | 60 | #define USB_PRODUCT_IPHONE_3GS 0x1294 |
61 | #define USB_PRODUCT_IPHONE_4 0x1297 | ||
61 | 62 | ||
62 | #define IPHETH_USBINTF_CLASS 255 | 63 | #define IPHETH_USBINTF_CLASS 255 |
63 | #define IPHETH_USBINTF_SUBCLASS 253 | 64 | #define IPHETH_USBINTF_SUBCLASS 253 |
@@ -92,6 +93,10 @@ static struct usb_device_id ipheth_table[] = { | |||
92 | USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3GS, | 93 | USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3GS, |
93 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, | 94 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, |
94 | IPHETH_USBINTF_PROTO) }, | 95 | IPHETH_USBINTF_PROTO) }, |
96 | { USB_DEVICE_AND_INTERFACE_INFO( | ||
97 | USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4, | ||
98 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, | ||
99 | IPHETH_USBINTF_PROTO) }, | ||
95 | { } | 100 | { } |
96 | }; | 101 | }; |
97 | MODULE_DEVICE_TABLE(usb, ipheth_table); | 102 | MODULE_DEVICE_TABLE(usb, ipheth_table); |
@@ -424,10 +429,6 @@ static const struct net_device_ops ipheth_netdev_ops = { | |||
424 | .ndo_get_stats = &ipheth_stats, | 429 | .ndo_get_stats = &ipheth_stats, |
425 | }; | 430 | }; |
426 | 431 | ||
427 | static struct device_type ipheth_type = { | ||
428 | .name = "wwan", | ||
429 | }; | ||
430 | |||
431 | static int ipheth_probe(struct usb_interface *intf, | 432 | static int ipheth_probe(struct usb_interface *intf, |
432 | const struct usb_device_id *id) | 433 | const struct usb_device_id *id) |
433 | { | 434 | { |
@@ -445,7 +446,7 @@ static int ipheth_probe(struct usb_interface *intf, | |||
445 | 446 | ||
446 | netdev->netdev_ops = &ipheth_netdev_ops; | 447 | netdev->netdev_ops = &ipheth_netdev_ops; |
447 | netdev->watchdog_timeo = IPHETH_TX_TIMEOUT; | 448 | netdev->watchdog_timeo = IPHETH_TX_TIMEOUT; |
448 | strcpy(netdev->name, "wwan%d"); | 449 | strcpy(netdev->name, "eth%d"); |
449 | 450 | ||
450 | dev = netdev_priv(netdev); | 451 | dev = netdev_priv(netdev); |
451 | dev->udev = udev; | 452 | dev->udev = udev; |
@@ -495,7 +496,6 @@ static int ipheth_probe(struct usb_interface *intf, | |||
495 | 496 | ||
496 | SET_NETDEV_DEV(netdev, &intf->dev); | 497 | SET_NETDEV_DEV(netdev, &intf->dev); |
497 | SET_ETHTOOL_OPS(netdev, &ops); | 498 | SET_ETHTOOL_OPS(netdev, &ops); |
498 | SET_NETDEV_DEVTYPE(netdev, &ipheth_type); | ||
499 | 499 | ||
500 | retval = register_netdev(netdev); | 500 | retval = register_netdev(netdev); |
501 | if (retval) { | 501 | if (retval) { |
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index ed7f4f5c406..6884813b809 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c | |||
@@ -2824,7 +2824,7 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi | |||
2824 | netif_napi_add(dev, &vptr->napi, velocity_poll, VELOCITY_NAPI_WEIGHT); | 2824 | netif_napi_add(dev, &vptr->napi, velocity_poll, VELOCITY_NAPI_WEIGHT); |
2825 | 2825 | ||
2826 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | | 2826 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | |
2827 | NETIF_F_HW_VLAN_RX | NETIF_F_IP_CSUM | NETIF_F_SG; | 2827 | NETIF_F_HW_VLAN_RX | NETIF_F_IP_CSUM; |
2828 | 2828 | ||
2829 | ret = register_netdev(dev); | 2829 | ret = register_netdev(dev); |
2830 | if (ret < 0) | 2830 | if (ret < 0) |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 45789c8990d..116ac66c6e3 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -1327,6 +1327,10 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | |||
1327 | PCI_DMA_TODEVICE); | 1327 | PCI_DMA_TODEVICE); |
1328 | 1328 | ||
1329 | rate = ieee80211_get_tx_rate(sc->hw, info); | 1329 | rate = ieee80211_get_tx_rate(sc->hw, info); |
1330 | if (!rate) { | ||
1331 | ret = -EINVAL; | ||
1332 | goto err_unmap; | ||
1333 | } | ||
1330 | 1334 | ||
1331 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) | 1335 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) |
1332 | flags |= AR5K_TXDESC_NOACK; | 1336 | flags |= AR5K_TXDESC_NOACK; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index b883b174385..057fb69ddf7 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -797,7 +797,7 @@ static bool ar9300_uncompress_block(struct ath_hw *ah, | |||
797 | length = block[it+1]; | 797 | length = block[it+1]; |
798 | length &= 0xff; | 798 | length &= 0xff; |
799 | 799 | ||
800 | if (length > 0 && spot >= 0 && spot+length < mdataSize) { | 800 | if (length > 0 && spot >= 0 && spot+length <= mdataSize) { |
801 | ath_print(common, ATH_DBG_EEPROM, | 801 | ath_print(common, ATH_DBG_EEPROM, |
802 | "Restore at %d: spot=%d " | 802 | "Restore at %d: spot=%d " |
803 | "offset=%d length=%d\n", | 803 | "offset=%d length=%d\n", |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 7f48df1e290..0b09db0f8e7 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h | |||
@@ -62,7 +62,7 @@ | |||
62 | 62 | ||
63 | #define SD_NO_CTL 0xE0 | 63 | #define SD_NO_CTL 0xE0 |
64 | #define NO_CTL 0xff | 64 | #define NO_CTL 0xff |
65 | #define CTL_MODE_M 7 | 65 | #define CTL_MODE_M 0xf |
66 | #define CTL_11A 0 | 66 | #define CTL_11A 0 |
67 | #define CTL_11B 1 | 67 | #define CTL_11B 1 |
68 | #define CTL_11G 2 | 68 | #define CTL_11G 2 |
diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h index a1c39526161..345dd9721b4 100644 --- a/drivers/net/wireless/ath/regd.h +++ b/drivers/net/wireless/ath/regd.h | |||
@@ -31,7 +31,6 @@ enum ctl_group { | |||
31 | #define NO_CTL 0xff | 31 | #define NO_CTL 0xff |
32 | #define SD_NO_CTL 0xE0 | 32 | #define SD_NO_CTL 0xE0 |
33 | #define NO_CTL 0xff | 33 | #define NO_CTL 0xff |
34 | #define CTL_MODE_M 7 | ||
35 | #define CTL_11A 0 | 34 | #define CTL_11A 0 |
36 | #define CTL_11B 1 | 35 | #define CTL_11B 1 |
37 | #define CTL_11G 2 | 36 | #define CTL_11G 2 |
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 1bbaaa44d98..296fd00a512 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
@@ -124,7 +124,7 @@ struct if_sdio_card { | |||
124 | bool helper_allocated; | 124 | bool helper_allocated; |
125 | bool firmware_allocated; | 125 | bool firmware_allocated; |
126 | 126 | ||
127 | u8 buffer[65536]; | 127 | u8 buffer[65536] __attribute__((aligned(4))); |
128 | 128 | ||
129 | spinlock_t lock; | 129 | spinlock_t lock; |
130 | struct if_sdio_packet *packets; | 130 | struct if_sdio_packet *packets; |
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index 8f67db487f5..76b2318a7dc 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c | |||
@@ -446,7 +446,7 @@ static void p54_rx_frame_sent(struct p54_common *priv, struct sk_buff *skb) | |||
446 | } | 446 | } |
447 | 447 | ||
448 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && | 448 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && |
449 | (!payload->status)) | 449 | !(payload->status & P54_TX_FAILED)) |
450 | info->flags |= IEEE80211_TX_STAT_ACK; | 450 | info->flags |= IEEE80211_TX_STAT_ACK; |
451 | if (payload->status & P54_TX_PSM_CANCELLED) | 451 | if (payload->status & P54_TX_PSM_CANCELLED) |
452 | info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | 452 | info->flags |= IEEE80211_TX_STAT_TX_FILTERED; |
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index 45fcc1e96df..3bc72d18b12 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c | |||
@@ -338,9 +338,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) | |||
338 | acpi_handle chandle, handle; | 338 | acpi_handle chandle, handle; |
339 | struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; | 339 | struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; |
340 | 340 | ||
341 | flags &= (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | | 341 | flags &= OSC_SHPC_NATIVE_HP_CONTROL; |
342 | OSC_SHPC_NATIVE_HP_CONTROL | | ||
343 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
344 | if (!flags) { | 342 | if (!flags) { |
345 | err("Invalid flags %u specified!\n", flags); | 343 | err("Invalid flags %u specified!\n", flags); |
346 | return -EINVAL; | 344 | return -EINVAL; |
@@ -360,7 +358,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) | |||
360 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); | 358 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); |
361 | dbg("Trying to get hotplug control for %s\n", | 359 | dbg("Trying to get hotplug control for %s\n", |
362 | (char *)string.pointer); | 360 | (char *)string.pointer); |
363 | status = acpi_pci_osc_control_set(handle, flags); | 361 | status = acpi_pci_osc_control_set(handle, &flags, flags); |
364 | if (ACPI_SUCCESS(status)) | 362 | if (ACPI_SUCCESS(status)) |
365 | goto got_one; | 363 | goto got_one; |
366 | if (status == AE_SUPPORT) | 364 | if (status == AE_SUPPORT) |
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 4ed76b47b6d..73d51398926 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -176,19 +176,11 @@ static inline void pciehp_firmware_init(void) | |||
176 | { | 176 | { |
177 | pciehp_acpi_slot_detection_init(); | 177 | pciehp_acpi_slot_detection_init(); |
178 | } | 178 | } |
179 | |||
180 | static inline int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev) | ||
181 | { | ||
182 | int retval; | ||
183 | u32 flags = (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | | ||
184 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
185 | retval = acpi_get_hp_hw_control_from_firmware(dev, flags); | ||
186 | if (retval) | ||
187 | return retval; | ||
188 | return pciehp_acpi_slot_detection_check(dev); | ||
189 | } | ||
190 | #else | 179 | #else |
191 | #define pciehp_firmware_init() do {} while (0) | 180 | #define pciehp_firmware_init() do {} while (0) |
192 | #define pciehp_get_hp_hw_control_from_firmware(dev) 0 | 181 | static inline int pciehp_acpi_slot_detection_check(struct pci_dev *dev) |
182 | { | ||
183 | return 0; | ||
184 | } | ||
193 | #endif /* CONFIG_ACPI */ | 185 | #endif /* CONFIG_ACPI */ |
194 | #endif /* _PCIEHP_H */ | 186 | #endif /* _PCIEHP_H */ |
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index 1f4000a5a10..2574700db46 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c | |||
@@ -85,9 +85,7 @@ static int __init dummy_probe(struct pcie_device *dev) | |||
85 | acpi_handle handle; | 85 | acpi_handle handle; |
86 | struct dummy_slot *slot, *tmp; | 86 | struct dummy_slot *slot, *tmp; |
87 | struct pci_dev *pdev = dev->port; | 87 | struct pci_dev *pdev = dev->port; |
88 | /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */ | 88 | |
89 | if (pciehp_get_hp_hw_control_from_firmware(pdev)) | ||
90 | return -ENODEV; | ||
91 | pos = pci_pcie_cap(pdev); | 89 | pos = pci_pcie_cap(pdev); |
92 | if (!pos) | 90 | if (!pos) |
93 | return -ENODEV; | 91 | return -ENODEV; |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 3588ea61b0d..aa5f3ff629f 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -59,7 +59,7 @@ module_param(pciehp_force, bool, 0644); | |||
59 | MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not"); | 59 | MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not"); |
60 | MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not"); | 60 | MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not"); |
61 | MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds"); | 61 | MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds"); |
62 | MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing"); | 62 | MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if OSHP is missing"); |
63 | 63 | ||
64 | #define PCIE_MODULE_NAME "pciehp" | 64 | #define PCIE_MODULE_NAME "pciehp" |
65 | 65 | ||
@@ -235,7 +235,7 @@ static int pciehp_probe(struct pcie_device *dev) | |||
235 | dev_info(&dev->device, | 235 | dev_info(&dev->device, |
236 | "Bypassing BIOS check for pciehp use on %s\n", | 236 | "Bypassing BIOS check for pciehp use on %s\n", |
237 | pci_name(dev->port)); | 237 | pci_name(dev->port)); |
238 | else if (pciehp_get_hp_hw_control_from_firmware(dev->port)) | 238 | else if (pciehp_acpi_slot_detection_check(dev->port)) |
239 | goto err_out_none; | 239 | goto err_out_none; |
240 | 240 | ||
241 | ctrl = pcie_init(dev); | 241 | ctrl = pcie_init(dev); |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 679c39de6a8..7754a678ab1 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -140,8 +140,10 @@ static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } | |||
140 | 140 | ||
141 | #ifdef CONFIG_PCIEAER | 141 | #ifdef CONFIG_PCIEAER |
142 | void pci_no_aer(void); | 142 | void pci_no_aer(void); |
143 | bool pci_aer_available(void); | ||
143 | #else | 144 | #else |
144 | static inline void pci_no_aer(void) { } | 145 | static inline void pci_no_aer(void) { } |
146 | static inline bool pci_aer_available(void) { return false; } | ||
145 | #endif | 147 | #endif |
146 | 148 | ||
147 | static inline int pci_no_d1d2(struct pci_dev *dev) | 149 | static inline int pci_no_d1d2(struct pci_dev *dev) |
diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile index ea654545e7c..00c62df5a9f 100644 --- a/drivers/pci/pcie/Makefile +++ b/drivers/pci/pcie/Makefile | |||
@@ -6,10 +6,11 @@ | |||
6 | obj-$(CONFIG_PCIEASPM) += aspm.o | 6 | obj-$(CONFIG_PCIEASPM) += aspm.o |
7 | 7 | ||
8 | pcieportdrv-y := portdrv_core.o portdrv_pci.o portdrv_bus.o | 8 | pcieportdrv-y := portdrv_core.o portdrv_pci.o portdrv_bus.o |
9 | pcieportdrv-$(CONFIG_ACPI) += portdrv_acpi.o | ||
9 | 10 | ||
10 | obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o | 11 | obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o |
11 | 12 | ||
12 | # Build PCI Express AER if needed | 13 | # Build PCI Express AER if needed |
13 | obj-$(CONFIG_PCIEAER) += aer/ | 14 | obj-$(CONFIG_PCIEAER) += aer/ |
14 | 15 | ||
15 | obj-$(CONFIG_PCIE_PME) += pme/ | 16 | obj-$(CONFIG_PCIE_PME) += pme.o |
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 484cc55194b..f409948e1a9 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c | |||
@@ -72,6 +72,11 @@ void pci_no_aer(void) | |||
72 | pcie_aer_disable = 1; /* has priority over 'forceload' */ | 72 | pcie_aer_disable = 1; /* has priority over 'forceload' */ |
73 | } | 73 | } |
74 | 74 | ||
75 | bool pci_aer_available(void) | ||
76 | { | ||
77 | return !pcie_aer_disable && pci_msi_enabled(); | ||
78 | } | ||
79 | |||
75 | static int set_device_error_reporting(struct pci_dev *dev, void *data) | 80 | static int set_device_error_reporting(struct pci_dev *dev, void *data) |
76 | { | 81 | { |
77 | bool enable = *((bool *)data); | 82 | bool enable = *((bool *)data); |
@@ -411,9 +416,7 @@ static void aer_error_resume(struct pci_dev *dev) | |||
411 | */ | 416 | */ |
412 | static int __init aer_service_init(void) | 417 | static int __init aer_service_init(void) |
413 | { | 418 | { |
414 | if (pcie_aer_disable) | 419 | if (!pci_aer_available()) |
415 | return -ENXIO; | ||
416 | if (!pci_msi_enabled()) | ||
417 | return -ENXIO; | 420 | return -ENXIO; |
418 | return pcie_port_service_register(&aerdriver); | 421 | return pcie_port_service_register(&aerdriver); |
419 | } | 422 | } |
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c index f278d7b0d95..2bb9b897221 100644 --- a/drivers/pci/pcie/aer/aerdrv_acpi.c +++ b/drivers/pci/pcie/aer/aerdrv_acpi.c | |||
@@ -19,42 +19,6 @@ | |||
19 | #include <acpi/apei.h> | 19 | #include <acpi/apei.h> |
20 | #include "aerdrv.h" | 20 | #include "aerdrv.h" |
21 | 21 | ||
22 | /** | ||
23 | * aer_osc_setup - run ACPI _OSC method | ||
24 | * @pciedev: pcie_device which AER is being enabled on | ||
25 | * | ||
26 | * @return: Zero on success. Nonzero otherwise. | ||
27 | * | ||
28 | * Invoked when PCIe bus loads AER service driver. To avoid conflict with | ||
29 | * BIOS AER support requires BIOS to yield AER control to OS native driver. | ||
30 | **/ | ||
31 | int aer_osc_setup(struct pcie_device *pciedev) | ||
32 | { | ||
33 | acpi_status status = AE_NOT_FOUND; | ||
34 | struct pci_dev *pdev = pciedev->port; | ||
35 | acpi_handle handle = NULL; | ||
36 | |||
37 | if (acpi_pci_disabled) | ||
38 | return -1; | ||
39 | |||
40 | handle = acpi_find_root_bridge_handle(pdev); | ||
41 | if (handle) { | ||
42 | status = acpi_pci_osc_control_set(handle, | ||
43 | OSC_PCI_EXPRESS_AER_CONTROL | | ||
44 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
45 | } | ||
46 | |||
47 | if (ACPI_FAILURE(status)) { | ||
48 | dev_printk(KERN_DEBUG, &pciedev->device, "AER service couldn't " | ||
49 | "init device: %s\n", | ||
50 | (status == AE_SUPPORT || status == AE_NOT_FOUND) ? | ||
51 | "no _OSC support" : "_OSC failed"); | ||
52 | return -1; | ||
53 | } | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | #ifdef CONFIG_ACPI_APEI | 22 | #ifdef CONFIG_ACPI_APEI |
59 | static inline int hest_match_pci(struct acpi_hest_aer_common *p, | 23 | static inline int hest_match_pci(struct acpi_hest_aer_common *p, |
60 | struct pci_dev *pci) | 24 | struct pci_dev *pci) |
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index fc0b5a93e1d..29e268fadf1 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -772,22 +772,10 @@ void aer_isr(struct work_struct *work) | |||
772 | */ | 772 | */ |
773 | int aer_init(struct pcie_device *dev) | 773 | int aer_init(struct pcie_device *dev) |
774 | { | 774 | { |
775 | if (pcie_aer_get_firmware_first(dev->port)) { | ||
776 | dev_printk(KERN_DEBUG, &dev->device, | ||
777 | "PCIe errors handled by platform firmware.\n"); | ||
778 | goto out; | ||
779 | } | ||
780 | |||
781 | if (aer_osc_setup(dev)) | ||
782 | goto out; | ||
783 | |||
784 | return 0; | ||
785 | out: | ||
786 | if (forceload) { | 775 | if (forceload) { |
787 | dev_printk(KERN_DEBUG, &dev->device, | 776 | dev_printk(KERN_DEBUG, &dev->device, |
788 | "aerdrv forceload requested.\n"); | 777 | "aerdrv forceload requested.\n"); |
789 | pcie_aer_force_firmware_first(dev->port, 0); | 778 | pcie_aer_force_firmware_first(dev->port, 0); |
790 | return 0; | ||
791 | } | 779 | } |
792 | return -ENXIO; | 780 | return 0; |
793 | } | 781 | } |
diff --git a/drivers/pci/pcie/pme/pcie_pme.c b/drivers/pci/pcie/pme.c index bbdea18693d..2f3c9040722 100644 --- a/drivers/pci/pcie/pme/pcie_pme.c +++ b/drivers/pci/pcie/pme.c | |||
@@ -23,38 +23,13 @@ | |||
23 | #include <linux/pci-acpi.h> | 23 | #include <linux/pci-acpi.h> |
24 | #include <linux/pm_runtime.h> | 24 | #include <linux/pm_runtime.h> |
25 | 25 | ||
26 | #include "../../pci.h" | 26 | #include "../pci.h" |
27 | #include "pcie_pme.h" | 27 | #include "portdrv.h" |
28 | 28 | ||
29 | #define PCI_EXP_RTSTA_PME 0x10000 /* PME status */ | 29 | #define PCI_EXP_RTSTA_PME 0x10000 /* PME status */ |
30 | #define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ | 30 | #define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * If set, this switch will prevent the PCIe root port PME service driver from | ||
34 | * being registered. Consequently, the interrupt-based PCIe PME signaling will | ||
35 | * not be used by any PCIe root ports in that case. | ||
36 | */ | ||
37 | static bool pcie_pme_disabled = true; | ||
38 | |||
39 | /* | ||
40 | * The PCI Express Base Specification 2.0, Section 6.1.8, states the following: | ||
41 | * "In order to maintain compatibility with non-PCI Express-aware system | ||
42 | * software, system power management logic must be configured by firmware to use | ||
43 | * the legacy mechanism of signaling PME by default. PCI Express-aware system | ||
44 | * software must notify the firmware prior to enabling native, interrupt-based | ||
45 | * PME signaling." However, if the platform doesn't provide us with a suitable | ||
46 | * notification mechanism or the notification fails, it is not clear whether or | ||
47 | * not we are supposed to use the interrupt-based PCIe PME signaling. The | ||
48 | * switch below can be used to indicate the desired behaviour. When set, it | ||
49 | * will make the kernel use the interrupt-based PCIe PME signaling regardless of | ||
50 | * the platform notification status, although the kernel will attempt to notify | ||
51 | * the platform anyway. When unset, it will prevent the kernel from using the | ||
52 | * the interrupt-based PCIe PME signaling if the platform notification fails, | ||
53 | * which is the default. | ||
54 | */ | ||
55 | static bool pcie_pme_force_enable; | ||
56 | |||
57 | /* | ||
58 | * If this switch is set, MSI will not be used for PCIe PME signaling. This | 33 | * If this switch is set, MSI will not be used for PCIe PME signaling. This |
59 | * causes the PCIe port driver to use INTx interrupts only, but it turns out | 34 | * causes the PCIe port driver to use INTx interrupts only, but it turns out |
60 | * that using MSI for PCIe PME signaling doesn't play well with PCIe PME-based | 35 | * that using MSI for PCIe PME signaling doesn't play well with PCIe PME-based |
@@ -64,38 +39,13 @@ bool pcie_pme_msi_disabled; | |||
64 | 39 | ||
65 | static int __init pcie_pme_setup(char *str) | 40 | static int __init pcie_pme_setup(char *str) |
66 | { | 41 | { |
67 | if (!strncmp(str, "auto", 4)) | 42 | if (!strncmp(str, "nomsi", 5)) |
68 | pcie_pme_disabled = false; | 43 | pcie_pme_msi_disabled = true; |
69 | else if (!strncmp(str, "force", 5)) | ||
70 | pcie_pme_force_enable = true; | ||
71 | |||
72 | str = strchr(str, ','); | ||
73 | if (str) { | ||
74 | str++; | ||
75 | str += strspn(str, " \t"); | ||
76 | if (*str && !strcmp(str, "nomsi")) | ||
77 | pcie_pme_msi_disabled = true; | ||
78 | } | ||
79 | 44 | ||
80 | return 1; | 45 | return 1; |
81 | } | 46 | } |
82 | __setup("pcie_pme=", pcie_pme_setup); | 47 | __setup("pcie_pme=", pcie_pme_setup); |
83 | 48 | ||
84 | /** | ||
85 | * pcie_pme_platform_setup - Ensure that the kernel controls the PCIe PME. | ||
86 | * @srv: PCIe PME root port service to use for carrying out the check. | ||
87 | * | ||
88 | * Notify the platform that the native PCIe PME is going to be used and return | ||
89 | * 'true' if the control of the PCIe PME registers has been acquired from the | ||
90 | * platform. | ||
91 | */ | ||
92 | static bool pcie_pme_platform_setup(struct pcie_device *srv) | ||
93 | { | ||
94 | if (!pcie_pme_platform_notify(srv)) | ||
95 | return true; | ||
96 | return pcie_pme_force_enable; | ||
97 | } | ||
98 | |||
99 | struct pcie_pme_service_data { | 49 | struct pcie_pme_service_data { |
100 | spinlock_t lock; | 50 | spinlock_t lock; |
101 | struct pcie_device *srv; | 51 | struct pcie_device *srv; |
@@ -108,7 +58,7 @@ struct pcie_pme_service_data { | |||
108 | * @dev: PCIe root port or event collector. | 58 | * @dev: PCIe root port or event collector. |
109 | * @enable: Enable or disable the interrupt. | 59 | * @enable: Enable or disable the interrupt. |
110 | */ | 60 | */ |
111 | static void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable) | 61 | void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable) |
112 | { | 62 | { |
113 | int rtctl_pos; | 63 | int rtctl_pos; |
114 | u16 rtctl; | 64 | u16 rtctl; |
@@ -417,9 +367,6 @@ static int pcie_pme_probe(struct pcie_device *srv) | |||
417 | struct pcie_pme_service_data *data; | 367 | struct pcie_pme_service_data *data; |
418 | int ret; | 368 | int ret; |
419 | 369 | ||
420 | if (!pcie_pme_platform_setup(srv)) | ||
421 | return -EACCES; | ||
422 | |||
423 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 370 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
424 | if (!data) | 371 | if (!data) |
425 | return -ENOMEM; | 372 | return -ENOMEM; |
@@ -509,8 +456,7 @@ static struct pcie_port_service_driver pcie_pme_driver = { | |||
509 | */ | 456 | */ |
510 | static int __init pcie_pme_service_init(void) | 457 | static int __init pcie_pme_service_init(void) |
511 | { | 458 | { |
512 | return pcie_pme_disabled ? | 459 | return pcie_port_service_register(&pcie_pme_driver); |
513 | -ENODEV : pcie_port_service_register(&pcie_pme_driver); | ||
514 | } | 460 | } |
515 | 461 | ||
516 | module_init(pcie_pme_service_init); | 462 | module_init(pcie_pme_service_init); |
diff --git a/drivers/pci/pcie/pme/Makefile b/drivers/pci/pcie/pme/Makefile deleted file mode 100644 index 8b923805308..00000000000 --- a/drivers/pci/pcie/pme/Makefile +++ /dev/null | |||
@@ -1,8 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for PCI-Express Root Port PME signaling driver | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_PCIE_PME) += pmedriver.o | ||
6 | |||
7 | pmedriver-objs := pcie_pme.o | ||
8 | pmedriver-$(CONFIG_ACPI) += pcie_pme_acpi.o | ||
diff --git a/drivers/pci/pcie/pme/pcie_pme.h b/drivers/pci/pcie/pme/pcie_pme.h deleted file mode 100644 index b30d2b7c977..00000000000 --- a/drivers/pci/pcie/pme/pcie_pme.h +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/pci/pcie/pme/pcie_pme.h | ||
3 | * | ||
4 | * PCI Express Root Port PME signaling support | ||
5 | * | ||
6 | * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. | ||
7 | */ | ||
8 | |||
9 | #ifndef _PCIE_PME_H_ | ||
10 | #define _PCIE_PME_H_ | ||
11 | |||
12 | struct pcie_device; | ||
13 | |||
14 | #ifdef CONFIG_ACPI | ||
15 | extern int pcie_pme_acpi_setup(struct pcie_device *srv); | ||
16 | |||
17 | static inline int pcie_pme_platform_notify(struct pcie_device *srv) | ||
18 | { | ||
19 | return pcie_pme_acpi_setup(srv); | ||
20 | } | ||
21 | #else /* !CONFIG_ACPI */ | ||
22 | static inline int pcie_pme_platform_notify(struct pcie_device *srv) | ||
23 | { | ||
24 | return 0; | ||
25 | } | ||
26 | #endif /* !CONFIG_ACPI */ | ||
27 | |||
28 | #endif | ||
diff --git a/drivers/pci/pcie/pme/pcie_pme_acpi.c b/drivers/pci/pcie/pme/pcie_pme_acpi.c deleted file mode 100644 index 83ab2287ae3..00000000000 --- a/drivers/pci/pcie/pme/pcie_pme_acpi.c +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | /* | ||
2 | * PCIe Native PME support, ACPI-related part | ||
3 | * | ||
4 | * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License V2. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | |||
11 | #include <linux/pci.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/acpi.h> | ||
15 | #include <linux/pci-acpi.h> | ||
16 | #include <linux/pcieport_if.h> | ||
17 | |||
18 | /** | ||
19 | * pcie_pme_acpi_setup - Request the ACPI BIOS to release control over PCIe PME. | ||
20 | * @srv - PCIe PME service for a root port or event collector. | ||
21 | * | ||
22 | * Invoked when the PCIe bus type loads PCIe PME service driver. To avoid | ||
23 | * conflict with the BIOS PCIe support requires the BIOS to yield PCIe PME | ||
24 | * control to the kernel. | ||
25 | */ | ||
26 | int pcie_pme_acpi_setup(struct pcie_device *srv) | ||
27 | { | ||
28 | acpi_status status = AE_NOT_FOUND; | ||
29 | struct pci_dev *port = srv->port; | ||
30 | acpi_handle handle; | ||
31 | int error = 0; | ||
32 | |||
33 | if (acpi_pci_disabled) | ||
34 | return -ENOSYS; | ||
35 | |||
36 | dev_info(&port->dev, "Requesting control of PCIe PME from ACPI BIOS\n"); | ||
37 | |||
38 | handle = acpi_find_root_bridge_handle(port); | ||
39 | if (!handle) | ||
40 | return -EINVAL; | ||
41 | |||
42 | status = acpi_pci_osc_control_set(handle, | ||
43 | OSC_PCI_EXPRESS_PME_CONTROL | | ||
44 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
45 | if (ACPI_FAILURE(status)) { | ||
46 | dev_info(&port->dev, | ||
47 | "Failed to receive control of PCIe PME service: %s\n", | ||
48 | (status == AE_SUPPORT || status == AE_NOT_FOUND) ? | ||
49 | "no _OSC support" : "ACPI _OSC failed"); | ||
50 | error = -ENODEV; | ||
51 | } | ||
52 | |||
53 | return error; | ||
54 | } | ||
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index 813a5c3427b..7b5aba0a329 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h | |||
@@ -20,6 +20,9 @@ | |||
20 | 20 | ||
21 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) | 21 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) |
22 | 22 | ||
23 | extern bool pcie_ports_disabled; | ||
24 | extern bool pcie_ports_auto; | ||
25 | |||
23 | extern struct bus_type pcie_port_bus_type; | 26 | extern struct bus_type pcie_port_bus_type; |
24 | extern int pcie_port_device_register(struct pci_dev *dev); | 27 | extern int pcie_port_device_register(struct pci_dev *dev); |
25 | #ifdef CONFIG_PM | 28 | #ifdef CONFIG_PM |
@@ -30,6 +33,8 @@ extern void pcie_port_device_remove(struct pci_dev *dev); | |||
30 | extern int __must_check pcie_port_bus_register(void); | 33 | extern int __must_check pcie_port_bus_register(void); |
31 | extern void pcie_port_bus_unregister(void); | 34 | extern void pcie_port_bus_unregister(void); |
32 | 35 | ||
36 | struct pci_dev; | ||
37 | |||
33 | #ifdef CONFIG_PCIE_PME | 38 | #ifdef CONFIG_PCIE_PME |
34 | extern bool pcie_pme_msi_disabled; | 39 | extern bool pcie_pme_msi_disabled; |
35 | 40 | ||
@@ -42,9 +47,26 @@ static inline bool pcie_pme_no_msi(void) | |||
42 | { | 47 | { |
43 | return pcie_pme_msi_disabled; | 48 | return pcie_pme_msi_disabled; |
44 | } | 49 | } |
50 | |||
51 | extern void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable); | ||
45 | #else /* !CONFIG_PCIE_PME */ | 52 | #else /* !CONFIG_PCIE_PME */ |
46 | static inline void pcie_pme_disable_msi(void) {} | 53 | static inline void pcie_pme_disable_msi(void) {} |
47 | static inline bool pcie_pme_no_msi(void) { return false; } | 54 | static inline bool pcie_pme_no_msi(void) { return false; } |
55 | static inline void pcie_pme_interrupt_enable(struct pci_dev *dev, bool en) {} | ||
48 | #endif /* !CONFIG_PCIE_PME */ | 56 | #endif /* !CONFIG_PCIE_PME */ |
49 | 57 | ||
58 | #ifdef CONFIG_ACPI | ||
59 | extern int pcie_port_acpi_setup(struct pci_dev *port, int *mask); | ||
60 | |||
61 | static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask) | ||
62 | { | ||
63 | return pcie_port_acpi_setup(port, mask); | ||
64 | } | ||
65 | #else /* !CONFIG_ACPI */ | ||
66 | static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask) | ||
67 | { | ||
68 | return 0; | ||
69 | } | ||
70 | #endif /* !CONFIG_ACPI */ | ||
71 | |||
50 | #endif /* _PORTDRV_H_ */ | 72 | #endif /* _PORTDRV_H_ */ |
diff --git a/drivers/pci/pcie/portdrv_acpi.c b/drivers/pci/pcie/portdrv_acpi.c new file mode 100644 index 00000000000..b7c4cb1ccb2 --- /dev/null +++ b/drivers/pci/pcie/portdrv_acpi.c | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * PCIe Port Native Services Support, ACPI-Related Part | ||
3 | * | ||
4 | * Copyright (C) 2010 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License V2. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | |||
11 | #include <linux/pci.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/acpi.h> | ||
15 | #include <linux/pci-acpi.h> | ||
16 | #include <linux/pcieport_if.h> | ||
17 | |||
18 | #include "aer/aerdrv.h" | ||
19 | #include "../pci.h" | ||
20 | |||
21 | /** | ||
22 | * pcie_port_acpi_setup - Request the BIOS to release control of PCIe services. | ||
23 | * @port: PCIe Port service for a root port or event collector. | ||
24 | * @srv_mask: Bit mask of services that can be enabled for @port. | ||
25 | * | ||
26 | * Invoked when @port is identified as a PCIe port device. To avoid conflicts | ||
27 | * with the BIOS PCIe port native services support requires the BIOS to yield | ||
28 | * control of these services to the kernel. The mask of services that the BIOS | ||
29 | * allows to be enabled for @port is written to @srv_mask. | ||
30 | * | ||
31 | * NOTE: It turns out that we cannot do that for individual port services | ||
32 | * separately, because that would make some systems work incorrectly. | ||
33 | */ | ||
34 | int pcie_port_acpi_setup(struct pci_dev *port, int *srv_mask) | ||
35 | { | ||
36 | acpi_status status; | ||
37 | acpi_handle handle; | ||
38 | u32 flags; | ||
39 | |||
40 | if (acpi_pci_disabled) | ||
41 | return 0; | ||
42 | |||
43 | handle = acpi_find_root_bridge_handle(port); | ||
44 | if (!handle) | ||
45 | return -EINVAL; | ||
46 | |||
47 | flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL | ||
48 | | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | ||
49 | | OSC_PCI_EXPRESS_PME_CONTROL; | ||
50 | |||
51 | if (pci_aer_available()) { | ||
52 | if (pcie_aer_get_firmware_first(port)) | ||
53 | dev_dbg(&port->dev, "PCIe errors handled by BIOS.\n"); | ||
54 | else | ||
55 | flags |= OSC_PCI_EXPRESS_AER_CONTROL; | ||
56 | } | ||
57 | |||
58 | status = acpi_pci_osc_control_set(handle, &flags, | ||
59 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
60 | if (ACPI_FAILURE(status)) { | ||
61 | dev_dbg(&port->dev, "ACPI _OSC request failed (code %d)\n", | ||
62 | status); | ||
63 | return -ENODEV; | ||
64 | } | ||
65 | |||
66 | dev_info(&port->dev, "ACPI _OSC control granted for 0x%02x\n", flags); | ||
67 | |||
68 | *srv_mask = PCIE_PORT_SERVICE_VC; | ||
69 | if (flags & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL) | ||
70 | *srv_mask |= PCIE_PORT_SERVICE_HP; | ||
71 | if (flags & OSC_PCI_EXPRESS_PME_CONTROL) | ||
72 | *srv_mask |= PCIE_PORT_SERVICE_PME; | ||
73 | if (flags & OSC_PCI_EXPRESS_AER_CONTROL) | ||
74 | *srv_mask |= PCIE_PORT_SERVICE_AER; | ||
75 | |||
76 | return 0; | ||
77 | } | ||
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index e73effbe402..a9c222d79eb 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <linux/string.h> | 14 | #include <linux/string.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/pcieport_if.h> | 16 | #include <linux/pcieport_if.h> |
17 | #include <linux/aer.h> | ||
18 | #include <linux/pci-aspm.h> | ||
17 | 19 | ||
18 | #include "../pci.h" | 20 | #include "../pci.h" |
19 | #include "portdrv.h" | 21 | #include "portdrv.h" |
@@ -236,24 +238,64 @@ static int get_port_device_capability(struct pci_dev *dev) | |||
236 | int services = 0, pos; | 238 | int services = 0, pos; |
237 | u16 reg16; | 239 | u16 reg16; |
238 | u32 reg32; | 240 | u32 reg32; |
241 | int cap_mask; | ||
242 | int err; | ||
243 | |||
244 | err = pcie_port_platform_notify(dev, &cap_mask); | ||
245 | if (pcie_ports_auto) { | ||
246 | if (err) { | ||
247 | pcie_no_aspm(); | ||
248 | return 0; | ||
249 | } | ||
250 | } else { | ||
251 | cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP | ||
252 | | PCIE_PORT_SERVICE_VC; | ||
253 | if (pci_aer_available()) | ||
254 | cap_mask |= PCIE_PORT_SERVICE_AER; | ||
255 | } | ||
239 | 256 | ||
240 | pos = pci_pcie_cap(dev); | 257 | pos = pci_pcie_cap(dev); |
241 | pci_read_config_word(dev, pos + PCI_EXP_FLAGS, ®16); | 258 | pci_read_config_word(dev, pos + PCI_EXP_FLAGS, ®16); |
242 | /* Hot-Plug Capable */ | 259 | /* Hot-Plug Capable */ |
243 | if (reg16 & PCI_EXP_FLAGS_SLOT) { | 260 | if ((cap_mask & PCIE_PORT_SERVICE_HP) && (reg16 & PCI_EXP_FLAGS_SLOT)) { |
244 | pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, ®32); | 261 | pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, ®32); |
245 | if (reg32 & PCI_EXP_SLTCAP_HPC) | 262 | if (reg32 & PCI_EXP_SLTCAP_HPC) { |
246 | services |= PCIE_PORT_SERVICE_HP; | 263 | services |= PCIE_PORT_SERVICE_HP; |
264 | /* | ||
265 | * Disable hot-plug interrupts in case they have been | ||
266 | * enabled by the BIOS and the hot-plug service driver | ||
267 | * is not loaded. | ||
268 | */ | ||
269 | pos += PCI_EXP_SLTCTL; | ||
270 | pci_read_config_word(dev, pos, ®16); | ||
271 | reg16 &= ~(PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE); | ||
272 | pci_write_config_word(dev, pos, reg16); | ||
273 | } | ||
247 | } | 274 | } |
248 | /* AER capable */ | 275 | /* AER capable */ |
249 | if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) | 276 | if ((cap_mask & PCIE_PORT_SERVICE_AER) |
277 | && pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) { | ||
250 | services |= PCIE_PORT_SERVICE_AER; | 278 | services |= PCIE_PORT_SERVICE_AER; |
279 | /* | ||
280 | * Disable AER on this port in case it's been enabled by the | ||
281 | * BIOS (the AER service driver will enable it when necessary). | ||
282 | */ | ||
283 | pci_disable_pcie_error_reporting(dev); | ||
284 | } | ||
251 | /* VC support */ | 285 | /* VC support */ |
252 | if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC)) | 286 | if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC)) |
253 | services |= PCIE_PORT_SERVICE_VC; | 287 | services |= PCIE_PORT_SERVICE_VC; |
254 | /* Root ports are capable of generating PME too */ | 288 | /* Root ports are capable of generating PME too */ |
255 | if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) | 289 | if ((cap_mask & PCIE_PORT_SERVICE_PME) |
290 | && dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) { | ||
256 | services |= PCIE_PORT_SERVICE_PME; | 291 | services |= PCIE_PORT_SERVICE_PME; |
292 | /* | ||
293 | * Disable PME interrupt on this port in case it's been enabled | ||
294 | * by the BIOS (the PME service driver will enable it when | ||
295 | * necessary). | ||
296 | */ | ||
297 | pcie_pme_interrupt_enable(dev, false); | ||
298 | } | ||
257 | 299 | ||
258 | return services; | 300 | return services; |
259 | } | 301 | } |
@@ -494,6 +536,9 @@ static void pcie_port_shutdown_service(struct device *dev) {} | |||
494 | */ | 536 | */ |
495 | int pcie_port_service_register(struct pcie_port_service_driver *new) | 537 | int pcie_port_service_register(struct pcie_port_service_driver *new) |
496 | { | 538 | { |
539 | if (pcie_ports_disabled) | ||
540 | return -ENODEV; | ||
541 | |||
497 | new->driver.name = (char *)new->name; | 542 | new->driver.name = (char *)new->name; |
498 | new->driver.bus = &pcie_port_bus_type; | 543 | new->driver.bus = &pcie_port_bus_type; |
499 | new->driver.probe = pcie_port_probe_service; | 544 | new->driver.probe = pcie_port_probe_service; |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 3debed25e46..f9033e190fb 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/pcieport_if.h> | 15 | #include <linux/pcieport_if.h> |
16 | #include <linux/aer.h> | 16 | #include <linux/aer.h> |
17 | #include <linux/dmi.h> | 17 | #include <linux/dmi.h> |
18 | #include <linux/pci-aspm.h> | ||
18 | 19 | ||
19 | #include "portdrv.h" | 20 | #include "portdrv.h" |
20 | #include "aer/aerdrv.h" | 21 | #include "aer/aerdrv.h" |
@@ -29,6 +30,31 @@ MODULE_AUTHOR(DRIVER_AUTHOR); | |||
29 | MODULE_DESCRIPTION(DRIVER_DESC); | 30 | MODULE_DESCRIPTION(DRIVER_DESC); |
30 | MODULE_LICENSE("GPL"); | 31 | MODULE_LICENSE("GPL"); |
31 | 32 | ||
33 | /* If this switch is set, PCIe port native services should not be enabled. */ | ||
34 | bool pcie_ports_disabled; | ||
35 | |||
36 | /* | ||
37 | * If this switch is set, ACPI _OSC will be used to determine whether or not to | ||
38 | * enable PCIe port native services. | ||
39 | */ | ||
40 | bool pcie_ports_auto = true; | ||
41 | |||
42 | static int __init pcie_port_setup(char *str) | ||
43 | { | ||
44 | if (!strncmp(str, "compat", 6)) { | ||
45 | pcie_ports_disabled = true; | ||
46 | } else if (!strncmp(str, "native", 6)) { | ||
47 | pcie_ports_disabled = false; | ||
48 | pcie_ports_auto = false; | ||
49 | } else if (!strncmp(str, "auto", 4)) { | ||
50 | pcie_ports_disabled = false; | ||
51 | pcie_ports_auto = true; | ||
52 | } | ||
53 | |||
54 | return 1; | ||
55 | } | ||
56 | __setup("pcie_ports=", pcie_port_setup); | ||
57 | |||
32 | /* global data */ | 58 | /* global data */ |
33 | 59 | ||
34 | static int pcie_portdrv_restore_config(struct pci_dev *dev) | 60 | static int pcie_portdrv_restore_config(struct pci_dev *dev) |
@@ -301,6 +327,11 @@ static int __init pcie_portdrv_init(void) | |||
301 | { | 327 | { |
302 | int retval; | 328 | int retval; |
303 | 329 | ||
330 | if (pcie_ports_disabled) { | ||
331 | pcie_no_aspm(); | ||
332 | return -EACCES; | ||
333 | } | ||
334 | |||
304 | dmi_check_system(pcie_portdrv_dmi_table); | 335 | dmi_check_system(pcie_portdrv_dmi_table); |
305 | 336 | ||
306 | retval = pcie_port_bus_register(); | 337 | retval = pcie_port_bus_register(); |
@@ -315,11 +346,4 @@ static int __init pcie_portdrv_init(void) | |||
315 | return retval; | 346 | return retval; |
316 | } | 347 | } |
317 | 348 | ||
318 | static void __exit pcie_portdrv_exit(void) | ||
319 | { | ||
320 | pci_unregister_driver(&pcie_portdriver); | ||
321 | pcie_port_bus_unregister(); | ||
322 | } | ||
323 | |||
324 | module_init(pcie_portdrv_init); | 349 | module_init(pcie_portdrv_init); |
325 | module_exit(pcie_portdrv_exit); | ||
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index 659eaa0fc48..968cfea04f7 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c | |||
@@ -49,7 +49,7 @@ static ssize_t address_read_file(struct pci_slot *slot, char *buf) | |||
49 | } | 49 | } |
50 | 50 | ||
51 | /* these strings match up with the values in pci_bus_speed */ | 51 | /* these strings match up with the values in pci_bus_speed */ |
52 | static char *pci_bus_speed_strings[] = { | 52 | static const char *pci_bus_speed_strings[] = { |
53 | "33 MHz PCI", /* 0x00 */ | 53 | "33 MHz PCI", /* 0x00 */ |
54 | "66 MHz PCI", /* 0x01 */ | 54 | "66 MHz PCI", /* 0x01 */ |
55 | "66 MHz PCI-X", /* 0x02 */ | 55 | "66 MHz PCI-X", /* 0x02 */ |
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 044f430f3b4..cff7cc2c1f0 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -486,10 +486,12 @@ config TOPSTAR_LAPTOP | |||
486 | config ACPI_TOSHIBA | 486 | config ACPI_TOSHIBA |
487 | tristate "Toshiba Laptop Extras" | 487 | tristate "Toshiba Laptop Extras" |
488 | depends on ACPI | 488 | depends on ACPI |
489 | depends on LEDS_CLASS | ||
490 | depends on NEW_LEDS | ||
491 | depends on BACKLIGHT_CLASS_DEVICE | ||
489 | depends on INPUT | 492 | depends on INPUT |
490 | depends on RFKILL || RFKILL = n | 493 | depends on RFKILL || RFKILL = n |
491 | select INPUT_POLLDEV | 494 | select INPUT_POLLDEV |
492 | select BACKLIGHT_CLASS_DEVICE | ||
493 | ---help--- | 495 | ---help--- |
494 | This driver adds support for access to certain system settings | 496 | This driver adds support for access to certain system settings |
495 | on "legacy free" Toshiba laptops. These laptops can be recognized by | 497 | on "legacy free" Toshiba laptops. These laptops can be recognized by |
diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c index e058c2ba2a1..ca05aefd03b 100644 --- a/drivers/platform/x86/asus_acpi.c +++ b/drivers/platform/x86/asus_acpi.c | |||
@@ -938,10 +938,11 @@ static int set_brightness(int value) | |||
938 | /* SPLV laptop */ | 938 | /* SPLV laptop */ |
939 | if (hotk->methods->brightness_set) { | 939 | if (hotk->methods->brightness_set) { |
940 | if (!write_acpi_int(hotk->handle, hotk->methods->brightness_set, | 940 | if (!write_acpi_int(hotk->handle, hotk->methods->brightness_set, |
941 | value, NULL)) | 941 | value, NULL)) { |
942 | printk(KERN_WARNING | 942 | printk(KERN_WARNING |
943 | "Asus ACPI: Error changing brightness\n"); | 943 | "Asus ACPI: Error changing brightness\n"); |
944 | ret = -EIO; | 944 | ret = -EIO; |
945 | } | ||
945 | goto out; | 946 | goto out; |
946 | } | 947 | } |
947 | 948 | ||
@@ -953,10 +954,11 @@ static int set_brightness(int value) | |||
953 | hotk->methods->brightness_down, | 954 | hotk->methods->brightness_down, |
954 | NULL, NULL); | 955 | NULL, NULL); |
955 | (value > 0) ? value-- : value++; | 956 | (value > 0) ? value-- : value++; |
956 | if (ACPI_FAILURE(status)) | 957 | if (ACPI_FAILURE(status)) { |
957 | printk(KERN_WARNING | 958 | printk(KERN_WARNING |
958 | "Asus ACPI: Error changing brightness\n"); | 959 | "Asus ACPI: Error changing brightness\n"); |
959 | ret = -EIO; | 960 | ret = -EIO; |
961 | } | ||
960 | } | 962 | } |
961 | out: | 963 | out: |
962 | return ret; | 964 | return ret; |
diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c index d071ce05632..097083cac41 100644 --- a/drivers/platform/x86/compal-laptop.c +++ b/drivers/platform/x86/compal-laptop.c | |||
@@ -841,6 +841,14 @@ static struct dmi_system_id __initdata compal_dmi_table[] = { | |||
841 | .callback = dmi_check_cb | 841 | .callback = dmi_check_cb |
842 | }, | 842 | }, |
843 | { | 843 | { |
844 | .ident = "Dell Mini 1012", | ||
845 | .matches = { | ||
846 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
847 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"), | ||
848 | }, | ||
849 | .callback = dmi_check_cb | ||
850 | }, | ||
851 | { | ||
844 | .ident = "Dell Inspiron 11z", | 852 | .ident = "Dell Inspiron 11z", |
845 | .matches = { | 853 | .matches = { |
846 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 854 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
@@ -1092,5 +1100,6 @@ MODULE_ALIAS("dmi:*:rnJHL90:rvrREFERENCE:*"); | |||
1092 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron910:*"); | 1100 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron910:*"); |
1093 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1010:*"); | 1101 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1010:*"); |
1094 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1011:*"); | 1102 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1011:*"); |
1103 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1012:*"); | ||
1095 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1110:*"); | 1104 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1110:*"); |
1096 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1210:*"); | 1105 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1210:*"); |
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index b41ed5cab3e..4413975912e 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
@@ -122,6 +122,13 @@ static struct dmi_system_id __devinitdata dell_blacklist[] = { | |||
122 | }, | 122 | }, |
123 | }, | 123 | }, |
124 | { | 124 | { |
125 | .ident = "Dell Mini 1012", | ||
126 | .matches = { | ||
127 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
128 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"), | ||
129 | }, | ||
130 | }, | ||
131 | { | ||
125 | .ident = "Dell Inspiron 11z", | 132 | .ident = "Dell Inspiron 11z", |
126 | .matches = { | 133 | .matches = { |
127 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 134 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index f1551637498..c1741142a4c 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
@@ -79,12 +79,13 @@ struct bios_args { | |||
79 | u32 command; | 79 | u32 command; |
80 | u32 commandtype; | 80 | u32 commandtype; |
81 | u32 datasize; | 81 | u32 datasize; |
82 | char *data; | 82 | u32 data; |
83 | }; | 83 | }; |
84 | 84 | ||
85 | struct bios_return { | 85 | struct bios_return { |
86 | u32 sigpass; | 86 | u32 sigpass; |
87 | u32 return_code; | 87 | u32 return_code; |
88 | u32 value; | ||
88 | }; | 89 | }; |
89 | 90 | ||
90 | struct key_entry { | 91 | struct key_entry { |
@@ -148,7 +149,7 @@ static struct platform_driver hp_wmi_driver = { | |||
148 | * buffer = kzalloc(128, GFP_KERNEL); | 149 | * buffer = kzalloc(128, GFP_KERNEL); |
149 | * ret = hp_wmi_perform_query(0x7, 0, buffer, 128) | 150 | * ret = hp_wmi_perform_query(0x7, 0, buffer, 128) |
150 | */ | 151 | */ |
151 | static int hp_wmi_perform_query(int query, int write, char *buffer, | 152 | static int hp_wmi_perform_query(int query, int write, u32 *buffer, |
152 | int buffersize) | 153 | int buffersize) |
153 | { | 154 | { |
154 | struct bios_return bios_return; | 155 | struct bios_return bios_return; |
@@ -159,7 +160,7 @@ static int hp_wmi_perform_query(int query, int write, char *buffer, | |||
159 | .command = write ? 0x2 : 0x1, | 160 | .command = write ? 0x2 : 0x1, |
160 | .commandtype = query, | 161 | .commandtype = query, |
161 | .datasize = buffersize, | 162 | .datasize = buffersize, |
162 | .data = buffer, | 163 | .data = *buffer, |
163 | }; | 164 | }; |
164 | struct acpi_buffer input = { sizeof(struct bios_args), &args }; | 165 | struct acpi_buffer input = { sizeof(struct bios_args), &args }; |
165 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | 166 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; |
@@ -177,29 +178,14 @@ static int hp_wmi_perform_query(int query, int write, char *buffer, | |||
177 | 178 | ||
178 | bios_return = *((struct bios_return *)obj->buffer.pointer); | 179 | bios_return = *((struct bios_return *)obj->buffer.pointer); |
179 | 180 | ||
180 | if (bios_return.return_code) { | 181 | memcpy(buffer, &bios_return.value, sizeof(bios_return.value)); |
181 | printk(KERN_WARNING PREFIX "Query %d returned %d\n", query, | ||
182 | bios_return.return_code); | ||
183 | kfree(obj); | ||
184 | return bios_return.return_code; | ||
185 | } | ||
186 | if (obj->buffer.length - sizeof(bios_return) > buffersize) { | ||
187 | kfree(obj); | ||
188 | return -EINVAL; | ||
189 | } | ||
190 | |||
191 | memset(buffer, 0, buffersize); | ||
192 | memcpy(buffer, | ||
193 | ((char *)obj->buffer.pointer) + sizeof(struct bios_return), | ||
194 | obj->buffer.length - sizeof(bios_return)); | ||
195 | kfree(obj); | ||
196 | return 0; | 182 | return 0; |
197 | } | 183 | } |
198 | 184 | ||
199 | static int hp_wmi_display_state(void) | 185 | static int hp_wmi_display_state(void) |
200 | { | 186 | { |
201 | int state; | 187 | int state = 0; |
202 | int ret = hp_wmi_perform_query(HPWMI_DISPLAY_QUERY, 0, (char *)&state, | 188 | int ret = hp_wmi_perform_query(HPWMI_DISPLAY_QUERY, 0, &state, |
203 | sizeof(state)); | 189 | sizeof(state)); |
204 | if (ret) | 190 | if (ret) |
205 | return -EINVAL; | 191 | return -EINVAL; |
@@ -208,8 +194,8 @@ static int hp_wmi_display_state(void) | |||
208 | 194 | ||
209 | static int hp_wmi_hddtemp_state(void) | 195 | static int hp_wmi_hddtemp_state(void) |
210 | { | 196 | { |
211 | int state; | 197 | int state = 0; |
212 | int ret = hp_wmi_perform_query(HPWMI_HDDTEMP_QUERY, 0, (char *)&state, | 198 | int ret = hp_wmi_perform_query(HPWMI_HDDTEMP_QUERY, 0, &state, |
213 | sizeof(state)); | 199 | sizeof(state)); |
214 | if (ret) | 200 | if (ret) |
215 | return -EINVAL; | 201 | return -EINVAL; |
@@ -218,8 +204,8 @@ static int hp_wmi_hddtemp_state(void) | |||
218 | 204 | ||
219 | static int hp_wmi_als_state(void) | 205 | static int hp_wmi_als_state(void) |
220 | { | 206 | { |
221 | int state; | 207 | int state = 0; |
222 | int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 0, (char *)&state, | 208 | int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 0, &state, |
223 | sizeof(state)); | 209 | sizeof(state)); |
224 | if (ret) | 210 | if (ret) |
225 | return -EINVAL; | 211 | return -EINVAL; |
@@ -228,8 +214,8 @@ static int hp_wmi_als_state(void) | |||
228 | 214 | ||
229 | static int hp_wmi_dock_state(void) | 215 | static int hp_wmi_dock_state(void) |
230 | { | 216 | { |
231 | int state; | 217 | int state = 0; |
232 | int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, (char *)&state, | 218 | int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, &state, |
233 | sizeof(state)); | 219 | sizeof(state)); |
234 | 220 | ||
235 | if (ret) | 221 | if (ret) |
@@ -240,8 +226,8 @@ static int hp_wmi_dock_state(void) | |||
240 | 226 | ||
241 | static int hp_wmi_tablet_state(void) | 227 | static int hp_wmi_tablet_state(void) |
242 | { | 228 | { |
243 | int state; | 229 | int state = 0; |
244 | int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, (char *)&state, | 230 | int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, &state, |
245 | sizeof(state)); | 231 | sizeof(state)); |
246 | if (ret) | 232 | if (ret) |
247 | return ret; | 233 | return ret; |
@@ -256,7 +242,7 @@ static int hp_wmi_set_block(void *data, bool blocked) | |||
256 | int ret; | 242 | int ret; |
257 | 243 | ||
258 | ret = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, | 244 | ret = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, |
259 | (char *)&query, sizeof(query)); | 245 | &query, sizeof(query)); |
260 | if (ret) | 246 | if (ret) |
261 | return -EINVAL; | 247 | return -EINVAL; |
262 | return 0; | 248 | return 0; |
@@ -268,10 +254,10 @@ static const struct rfkill_ops hp_wmi_rfkill_ops = { | |||
268 | 254 | ||
269 | static bool hp_wmi_get_sw_state(enum hp_wmi_radio r) | 255 | static bool hp_wmi_get_sw_state(enum hp_wmi_radio r) |
270 | { | 256 | { |
271 | int wireless; | 257 | int wireless = 0; |
272 | int mask; | 258 | int mask; |
273 | hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, | 259 | hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, |
274 | (char *)&wireless, sizeof(wireless)); | 260 | &wireless, sizeof(wireless)); |
275 | /* TBD: Pass error */ | 261 | /* TBD: Pass error */ |
276 | 262 | ||
277 | mask = 0x200 << (r * 8); | 263 | mask = 0x200 << (r * 8); |
@@ -284,10 +270,10 @@ static bool hp_wmi_get_sw_state(enum hp_wmi_radio r) | |||
284 | 270 | ||
285 | static bool hp_wmi_get_hw_state(enum hp_wmi_radio r) | 271 | static bool hp_wmi_get_hw_state(enum hp_wmi_radio r) |
286 | { | 272 | { |
287 | int wireless; | 273 | int wireless = 0; |
288 | int mask; | 274 | int mask; |
289 | hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, | 275 | hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, |
290 | (char *)&wireless, sizeof(wireless)); | 276 | &wireless, sizeof(wireless)); |
291 | /* TBD: Pass error */ | 277 | /* TBD: Pass error */ |
292 | 278 | ||
293 | mask = 0x800 << (r * 8); | 279 | mask = 0x800 << (r * 8); |
@@ -347,7 +333,7 @@ static ssize_t set_als(struct device *dev, struct device_attribute *attr, | |||
347 | const char *buf, size_t count) | 333 | const char *buf, size_t count) |
348 | { | 334 | { |
349 | u32 tmp = simple_strtoul(buf, NULL, 10); | 335 | u32 tmp = simple_strtoul(buf, NULL, 10); |
350 | int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 1, (char *)&tmp, | 336 | int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 1, &tmp, |
351 | sizeof(tmp)); | 337 | sizeof(tmp)); |
352 | if (ret) | 338 | if (ret) |
353 | return -EINVAL; | 339 | return -EINVAL; |
@@ -421,7 +407,7 @@ static void hp_wmi_notify(u32 value, void *context) | |||
421 | static struct key_entry *key; | 407 | static struct key_entry *key; |
422 | union acpi_object *obj; | 408 | union acpi_object *obj; |
423 | u32 event_id, event_data; | 409 | u32 event_id, event_data; |
424 | int key_code, ret; | 410 | int key_code = 0, ret; |
425 | u32 *location; | 411 | u32 *location; |
426 | acpi_status status; | 412 | acpi_status status; |
427 | 413 | ||
@@ -475,7 +461,7 @@ static void hp_wmi_notify(u32 value, void *context) | |||
475 | break; | 461 | break; |
476 | case HPWMI_BEZEL_BUTTON: | 462 | case HPWMI_BEZEL_BUTTON: |
477 | ret = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0, | 463 | ret = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0, |
478 | (char *)&key_code, | 464 | &key_code, |
479 | sizeof(key_code)); | 465 | sizeof(key_code)); |
480 | if (ret) | 466 | if (ret) |
481 | break; | 467 | break; |
@@ -578,9 +564,9 @@ static void cleanup_sysfs(struct platform_device *device) | |||
578 | static int __devinit hp_wmi_bios_setup(struct platform_device *device) | 564 | static int __devinit hp_wmi_bios_setup(struct platform_device *device) |
579 | { | 565 | { |
580 | int err; | 566 | int err; |
581 | int wireless; | 567 | int wireless = 0; |
582 | 568 | ||
583 | err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, (char *)&wireless, | 569 | err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, &wireless, |
584 | sizeof(wireless)); | 570 | sizeof(wireless)); |
585 | if (err) | 571 | if (err) |
586 | return err; | 572 | return err; |
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index afe82e50dfe..9024480a822 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c | |||
@@ -1342,8 +1342,10 @@ static struct ips_mcp_limits *ips_detect_cpu(struct ips_driver *ips) | |||
1342 | limits = &ips_lv_limits; | 1342 | limits = &ips_lv_limits; |
1343 | else if (strstr(boot_cpu_data.x86_model_id, "CPU U")) | 1343 | else if (strstr(boot_cpu_data.x86_model_id, "CPU U")) |
1344 | limits = &ips_ulv_limits; | 1344 | limits = &ips_ulv_limits; |
1345 | else | 1345 | else { |
1346 | dev_info(&ips->dev->dev, "No CPUID match found.\n"); | 1346 | dev_info(&ips->dev->dev, "No CPUID match found.\n"); |
1347 | goto out; | ||
1348 | } | ||
1347 | 1349 | ||
1348 | rdmsrl(TURBO_POWER_CURRENT_LIMIT, turbo_power); | 1350 | rdmsrl(TURBO_POWER_CURRENT_LIMIT, turbo_power); |
1349 | tdp = turbo_power & TURBO_TDP_MASK; | 1351 | tdp = turbo_power & TURBO_TDP_MASK; |
@@ -1432,6 +1434,12 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1432 | 1434 | ||
1433 | spin_lock_init(&ips->turbo_status_lock); | 1435 | spin_lock_init(&ips->turbo_status_lock); |
1434 | 1436 | ||
1437 | ret = pci_enable_device(dev); | ||
1438 | if (ret) { | ||
1439 | dev_err(&dev->dev, "can't enable PCI device, aborting\n"); | ||
1440 | goto error_free; | ||
1441 | } | ||
1442 | |||
1435 | if (!pci_resource_start(dev, 0)) { | 1443 | if (!pci_resource_start(dev, 0)) { |
1436 | dev_err(&dev->dev, "TBAR not assigned, aborting\n"); | 1444 | dev_err(&dev->dev, "TBAR not assigned, aborting\n"); |
1437 | ret = -ENXIO; | 1445 | ret = -ENXIO; |
@@ -1444,11 +1452,6 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1444 | goto error_free; | 1452 | goto error_free; |
1445 | } | 1453 | } |
1446 | 1454 | ||
1447 | ret = pci_enable_device(dev); | ||
1448 | if (ret) { | ||
1449 | dev_err(&dev->dev, "can't enable PCI device, aborting\n"); | ||
1450 | goto error_free; | ||
1451 | } | ||
1452 | 1455 | ||
1453 | ips->regmap = ioremap(pci_resource_start(dev, 0), | 1456 | ips->regmap = ioremap(pci_resource_start(dev, 0), |
1454 | pci_resource_len(dev, 0)); | 1457 | pci_resource_len(dev, 0)); |
diff --git a/drivers/platform/x86/intel_rar_register.c b/drivers/platform/x86/intel_rar_register.c index 73f8e6d7266..2b11a33325e 100644 --- a/drivers/platform/x86/intel_rar_register.c +++ b/drivers/platform/x86/intel_rar_register.c | |||
@@ -145,7 +145,7 @@ static void free_rar_device(struct rar_device *rar) | |||
145 | */ | 145 | */ |
146 | static struct rar_device *_rar_to_device(int rar, int *off) | 146 | static struct rar_device *_rar_to_device(int rar, int *off) |
147 | { | 147 | { |
148 | if (rar >= 0 && rar <= 3) { | 148 | if (rar >= 0 && rar < MRST_NUM_RAR) { |
149 | *off = rar; | 149 | *off = rar; |
150 | return &my_rar_device; | 150 | return &my_rar_device; |
151 | } | 151 | } |
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index 943f9084dcb..6abe18e638e 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c | |||
@@ -487,7 +487,7 @@ int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data) | |||
487 | mdelay(1); | 487 | mdelay(1); |
488 | *data = readl(ipcdev.i2c_base + I2C_DATA_ADDR); | 488 | *data = readl(ipcdev.i2c_base + I2C_DATA_ADDR); |
489 | } else if (cmd == IPC_I2C_WRITE) { | 489 | } else if (cmd == IPC_I2C_WRITE) { |
490 | writel(addr, ipcdev.i2c_base + I2C_DATA_ADDR); | 490 | writel(*data, ipcdev.i2c_base + I2C_DATA_ADDR); |
491 | mdelay(1); | 491 | mdelay(1); |
492 | writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR); | 492 | writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR); |
493 | } else { | 493 | } else { |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 5d6119bed00..e35ed128bde 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -1911,6 +1911,17 @@ enum { /* hot key scan codes (derived from ACPI DSDT) */ | |||
1911 | TP_ACPI_HOTKEYSCAN_VOLUMEDOWN, | 1911 | TP_ACPI_HOTKEYSCAN_VOLUMEDOWN, |
1912 | TP_ACPI_HOTKEYSCAN_MUTE, | 1912 | TP_ACPI_HOTKEYSCAN_MUTE, |
1913 | TP_ACPI_HOTKEYSCAN_THINKPAD, | 1913 | TP_ACPI_HOTKEYSCAN_THINKPAD, |
1914 | TP_ACPI_HOTKEYSCAN_UNK1, | ||
1915 | TP_ACPI_HOTKEYSCAN_UNK2, | ||
1916 | TP_ACPI_HOTKEYSCAN_UNK3, | ||
1917 | TP_ACPI_HOTKEYSCAN_UNK4, | ||
1918 | TP_ACPI_HOTKEYSCAN_UNK5, | ||
1919 | TP_ACPI_HOTKEYSCAN_UNK6, | ||
1920 | TP_ACPI_HOTKEYSCAN_UNK7, | ||
1921 | TP_ACPI_HOTKEYSCAN_UNK8, | ||
1922 | |||
1923 | /* Hotkey keymap size */ | ||
1924 | TPACPI_HOTKEY_MAP_LEN | ||
1914 | }; | 1925 | }; |
1915 | 1926 | ||
1916 | enum { /* Keys/events available through NVRAM polling */ | 1927 | enum { /* Keys/events available through NVRAM polling */ |
@@ -3082,6 +3093,8 @@ static const struct tpacpi_quirk tpacpi_hotkey_qtable[] __initconst = { | |||
3082 | TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */ | 3093 | TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */ |
3083 | }; | 3094 | }; |
3084 | 3095 | ||
3096 | typedef u16 tpacpi_keymap_t[TPACPI_HOTKEY_MAP_LEN]; | ||
3097 | |||
3085 | static int __init hotkey_init(struct ibm_init_struct *iibm) | 3098 | static int __init hotkey_init(struct ibm_init_struct *iibm) |
3086 | { | 3099 | { |
3087 | /* Requirements for changing the default keymaps: | 3100 | /* Requirements for changing the default keymaps: |
@@ -3113,9 +3126,17 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3113 | * If the above is too much to ask, don't change the keymap. | 3126 | * If the above is too much to ask, don't change the keymap. |
3114 | * Ask the thinkpad-acpi maintainer to do it, instead. | 3127 | * Ask the thinkpad-acpi maintainer to do it, instead. |
3115 | */ | 3128 | */ |
3116 | static u16 ibm_keycode_map[] __initdata = { | 3129 | |
3130 | enum keymap_index { | ||
3131 | TPACPI_KEYMAP_IBM_GENERIC = 0, | ||
3132 | TPACPI_KEYMAP_LENOVO_GENERIC, | ||
3133 | }; | ||
3134 | |||
3135 | static const tpacpi_keymap_t tpacpi_keymaps[] __initconst = { | ||
3136 | /* Generic keymap for IBM ThinkPads */ | ||
3137 | [TPACPI_KEYMAP_IBM_GENERIC] = { | ||
3117 | /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ | 3138 | /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ |
3118 | KEY_FN_F1, KEY_FN_F2, KEY_COFFEE, KEY_SLEEP, | 3139 | KEY_FN_F1, KEY_BATTERY, KEY_COFFEE, KEY_SLEEP, |
3119 | KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, | 3140 | KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, |
3120 | KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, | 3141 | KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, |
3121 | 3142 | ||
@@ -3146,11 +3167,13 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3146 | /* (assignments unknown, please report if found) */ | 3167 | /* (assignments unknown, please report if found) */ |
3147 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | 3168 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, |
3148 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | 3169 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, |
3149 | }; | 3170 | }, |
3150 | static u16 lenovo_keycode_map[] __initdata = { | 3171 | |
3172 | /* Generic keymap for Lenovo ThinkPads */ | ||
3173 | [TPACPI_KEYMAP_LENOVO_GENERIC] = { | ||
3151 | /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ | 3174 | /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ |
3152 | KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP, | 3175 | KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP, |
3153 | KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, | 3176 | KEY_WLAN, KEY_CAMERA, KEY_SWITCHVIDEOMODE, KEY_FN_F8, |
3154 | KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, | 3177 | KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, |
3155 | 3178 | ||
3156 | /* Scan codes 0x0C to 0x1F: Other ACPI HKEY hot keys */ | 3179 | /* Scan codes 0x0C to 0x1F: Other ACPI HKEY hot keys */ |
@@ -3189,11 +3212,25 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3189 | /* (assignments unknown, please report if found) */ | 3212 | /* (assignments unknown, please report if found) */ |
3190 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | 3213 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, |
3191 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | 3214 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, |
3215 | }, | ||
3216 | }; | ||
3217 | |||
3218 | static const struct tpacpi_quirk tpacpi_keymap_qtable[] __initconst = { | ||
3219 | /* Generic maps (fallback) */ | ||
3220 | { | ||
3221 | .vendor = PCI_VENDOR_ID_IBM, | ||
3222 | .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY, | ||
3223 | .quirks = TPACPI_KEYMAP_IBM_GENERIC, | ||
3224 | }, | ||
3225 | { | ||
3226 | .vendor = PCI_VENDOR_ID_LENOVO, | ||
3227 | .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY, | ||
3228 | .quirks = TPACPI_KEYMAP_LENOVO_GENERIC, | ||
3229 | }, | ||
3192 | }; | 3230 | }; |
3193 | 3231 | ||
3194 | #define TPACPI_HOTKEY_MAP_LEN ARRAY_SIZE(ibm_keycode_map) | 3232 | #define TPACPI_HOTKEY_MAP_SIZE sizeof(tpacpi_keymap_t) |
3195 | #define TPACPI_HOTKEY_MAP_SIZE sizeof(ibm_keycode_map) | 3233 | #define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(tpacpi_keymap_t[0]) |
3196 | #define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(ibm_keycode_map[0]) | ||
3197 | 3234 | ||
3198 | int res, i; | 3235 | int res, i; |
3199 | int status; | 3236 | int status; |
@@ -3202,6 +3239,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3202 | bool tabletsw_state = false; | 3239 | bool tabletsw_state = false; |
3203 | 3240 | ||
3204 | unsigned long quirks; | 3241 | unsigned long quirks; |
3242 | unsigned long keymap_id; | ||
3205 | 3243 | ||
3206 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, | 3244 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, |
3207 | "initializing hotkey subdriver\n"); | 3245 | "initializing hotkey subdriver\n"); |
@@ -3342,7 +3380,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3342 | goto err_exit; | 3380 | goto err_exit; |
3343 | 3381 | ||
3344 | /* Set up key map */ | 3382 | /* Set up key map */ |
3345 | |||
3346 | hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, | 3383 | hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, |
3347 | GFP_KERNEL); | 3384 | GFP_KERNEL); |
3348 | if (!hotkey_keycode_map) { | 3385 | if (!hotkey_keycode_map) { |
@@ -3352,17 +3389,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3352 | goto err_exit; | 3389 | goto err_exit; |
3353 | } | 3390 | } |
3354 | 3391 | ||
3355 | if (tpacpi_is_lenovo()) { | 3392 | keymap_id = tpacpi_check_quirks(tpacpi_keymap_qtable, |
3356 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, | 3393 | ARRAY_SIZE(tpacpi_keymap_qtable)); |
3357 | "using Lenovo default hot key map\n"); | 3394 | BUG_ON(keymap_id >= ARRAY_SIZE(tpacpi_keymaps)); |
3358 | memcpy(hotkey_keycode_map, &lenovo_keycode_map, | 3395 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, |
3359 | TPACPI_HOTKEY_MAP_SIZE); | 3396 | "using keymap number %lu\n", keymap_id); |
3360 | } else { | 3397 | |
3361 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, | 3398 | memcpy(hotkey_keycode_map, &tpacpi_keymaps[keymap_id], |
3362 | "using IBM default hot key map\n"); | 3399 | TPACPI_HOTKEY_MAP_SIZE); |
3363 | memcpy(hotkey_keycode_map, &ibm_keycode_map, | ||
3364 | TPACPI_HOTKEY_MAP_SIZE); | ||
3365 | } | ||
3366 | 3400 | ||
3367 | input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN); | 3401 | input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN); |
3368 | tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; | 3402 | tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; |
@@ -3469,7 +3503,8 @@ static bool hotkey_notify_hotkey(const u32 hkey, | |||
3469 | *send_acpi_ev = true; | 3503 | *send_acpi_ev = true; |
3470 | *ignore_acpi_ev = false; | 3504 | *ignore_acpi_ev = false; |
3471 | 3505 | ||
3472 | if (scancode > 0 && scancode < 0x21) { | 3506 | /* HKEY event 0x1001 is scancode 0x00 */ |
3507 | if (scancode > 0 && scancode <= TPACPI_HOTKEY_MAP_LEN) { | ||
3473 | scancode--; | 3508 | scancode--; |
3474 | if (!(hotkey_source_mask & (1 << scancode))) { | 3509 | if (!(hotkey_source_mask & (1 << scancode))) { |
3475 | tpacpi_input_send_key_masked(scancode); | 3510 | tpacpi_input_send_key_masked(scancode); |
@@ -6080,13 +6115,18 @@ static struct backlight_ops ibm_backlight_data = { | |||
6080 | 6115 | ||
6081 | /* --------------------------------------------------------------------- */ | 6116 | /* --------------------------------------------------------------------- */ |
6082 | 6117 | ||
6118 | /* | ||
6119 | * Call _BCL method of video device. On some ThinkPads this will | ||
6120 | * switch the firmware to the ACPI brightness control mode. | ||
6121 | */ | ||
6122 | |||
6083 | static int __init tpacpi_query_bcl_levels(acpi_handle handle) | 6123 | static int __init tpacpi_query_bcl_levels(acpi_handle handle) |
6084 | { | 6124 | { |
6085 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 6125 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
6086 | union acpi_object *obj; | 6126 | union acpi_object *obj; |
6087 | int rc; | 6127 | int rc; |
6088 | 6128 | ||
6089 | if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) { | 6129 | if (ACPI_SUCCESS(acpi_evaluate_object(handle, "_BCL", NULL, &buffer))) { |
6090 | obj = (union acpi_object *)buffer.pointer; | 6130 | obj = (union acpi_object *)buffer.pointer; |
6091 | if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { | 6131 | if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { |
6092 | printk(TPACPI_ERR "Unknown _BCL data, " | 6132 | printk(TPACPI_ERR "Unknown _BCL data, " |
@@ -6103,55 +6143,22 @@ static int __init tpacpi_query_bcl_levels(acpi_handle handle) | |||
6103 | return rc; | 6143 | return rc; |
6104 | } | 6144 | } |
6105 | 6145 | ||
6106 | static acpi_status __init tpacpi_acpi_walk_find_bcl(acpi_handle handle, | ||
6107 | u32 lvl, void *context, void **rv) | ||
6108 | { | ||
6109 | char name[ACPI_PATH_SEGMENT_LENGTH]; | ||
6110 | struct acpi_buffer buffer = { sizeof(name), &name }; | ||
6111 | |||
6112 | if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) && | ||
6113 | !strncmp("_BCL", name, sizeof(name) - 1)) { | ||
6114 | BUG_ON(!rv || !*rv); | ||
6115 | **(int **)rv = tpacpi_query_bcl_levels(handle); | ||
6116 | return AE_CTRL_TERMINATE; | ||
6117 | } else { | ||
6118 | return AE_OK; | ||
6119 | } | ||
6120 | } | ||
6121 | 6146 | ||
6122 | /* | 6147 | /* |
6123 | * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map | 6148 | * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map |
6124 | */ | 6149 | */ |
6125 | static unsigned int __init tpacpi_check_std_acpi_brightness_support(void) | 6150 | static unsigned int __init tpacpi_check_std_acpi_brightness_support(void) |
6126 | { | 6151 | { |
6127 | int status; | 6152 | acpi_handle video_device; |
6128 | int bcl_levels = 0; | 6153 | int bcl_levels = 0; |
6129 | void *bcl_ptr = &bcl_levels; | ||
6130 | |||
6131 | if (!vid_handle) | ||
6132 | TPACPI_ACPIHANDLE_INIT(vid); | ||
6133 | |||
6134 | if (!vid_handle) | ||
6135 | return 0; | ||
6136 | |||
6137 | /* | ||
6138 | * Search for a _BCL method, and execute it. This is safe on all | ||
6139 | * ThinkPads, and as a side-effect, _BCL will place a Lenovo Vista | ||
6140 | * BIOS in ACPI backlight control mode. We do NOT have to care | ||
6141 | * about calling the _BCL method in an enabled video device, any | ||
6142 | * will do for our purposes. | ||
6143 | */ | ||
6144 | 6154 | ||
6145 | status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3, | 6155 | tpacpi_acpi_handle_locate("video", ACPI_VIDEO_HID, &video_device); |
6146 | tpacpi_acpi_walk_find_bcl, NULL, NULL, | 6156 | if (video_device) |
6147 | &bcl_ptr); | 6157 | bcl_levels = tpacpi_query_bcl_levels(video_device); |
6148 | 6158 | ||
6149 | if (ACPI_SUCCESS(status) && bcl_levels > 2) { | 6159 | tp_features.bright_acpimode = (bcl_levels > 0); |
6150 | tp_features.bright_acpimode = 1; | ||
6151 | return bcl_levels - 2; | ||
6152 | } | ||
6153 | 6160 | ||
6154 | return 0; | 6161 | return (bcl_levels > 2) ? (bcl_levels - 2) : 0; |
6155 | } | 6162 | } |
6156 | 6163 | ||
6157 | /* | 6164 | /* |
@@ -6244,28 +6251,6 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
6244 | if (tp_features.bright_unkfw) | 6251 | if (tp_features.bright_unkfw) |
6245 | return 1; | 6252 | return 1; |
6246 | 6253 | ||
6247 | if (tp_features.bright_acpimode) { | ||
6248 | if (acpi_video_backlight_support()) { | ||
6249 | if (brightness_enable > 1) { | ||
6250 | printk(TPACPI_NOTICE | ||
6251 | "Standard ACPI backlight interface " | ||
6252 | "available, not loading native one.\n"); | ||
6253 | return 1; | ||
6254 | } else if (brightness_enable == 1) { | ||
6255 | printk(TPACPI_NOTICE | ||
6256 | "Backlight control force enabled, even if standard " | ||
6257 | "ACPI backlight interface is available\n"); | ||
6258 | } | ||
6259 | } else { | ||
6260 | if (brightness_enable > 1) { | ||
6261 | printk(TPACPI_NOTICE | ||
6262 | "Standard ACPI backlight interface not " | ||
6263 | "available, thinkpad_acpi native " | ||
6264 | "brightness control enabled\n"); | ||
6265 | } | ||
6266 | } | ||
6267 | } | ||
6268 | |||
6269 | if (!brightness_enable) { | 6254 | if (!brightness_enable) { |
6270 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, | 6255 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, |
6271 | "brightness support disabled by " | 6256 | "brightness support disabled by " |
@@ -6273,6 +6258,26 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
6273 | return 1; | 6258 | return 1; |
6274 | } | 6259 | } |
6275 | 6260 | ||
6261 | if (acpi_video_backlight_support()) { | ||
6262 | if (brightness_enable > 1) { | ||
6263 | printk(TPACPI_INFO | ||
6264 | "Standard ACPI backlight interface " | ||
6265 | "available, not loading native one.\n"); | ||
6266 | return 1; | ||
6267 | } else if (brightness_enable == 1) { | ||
6268 | printk(TPACPI_WARN | ||
6269 | "Cannot enable backlight brightness support, " | ||
6270 | "ACPI is already handling it. Refer to the " | ||
6271 | "acpi_backlight kernel parameter\n"); | ||
6272 | return 1; | ||
6273 | } | ||
6274 | } else if (tp_features.bright_acpimode && brightness_enable > 1) { | ||
6275 | printk(TPACPI_NOTICE | ||
6276 | "Standard ACPI backlight interface not " | ||
6277 | "available, thinkpad_acpi native " | ||
6278 | "brightness control enabled\n"); | ||
6279 | } | ||
6280 | |||
6276 | /* | 6281 | /* |
6277 | * Check for module parameter bogosity, note that we | 6282 | * Check for module parameter bogosity, note that we |
6278 | * init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be | 6283 | * init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be |
diff --git a/drivers/s390/char/ctrlchar.c b/drivers/s390/char/ctrlchar.c index c6cbcb3f925..0e9a309b966 100644 --- a/drivers/s390/char/ctrlchar.c +++ b/drivers/s390/char/ctrlchar.c | |||
@@ -16,12 +16,11 @@ | |||
16 | 16 | ||
17 | #ifdef CONFIG_MAGIC_SYSRQ | 17 | #ifdef CONFIG_MAGIC_SYSRQ |
18 | static int ctrlchar_sysrq_key; | 18 | static int ctrlchar_sysrq_key; |
19 | static struct tty_struct *sysrq_tty; | ||
20 | 19 | ||
21 | static void | 20 | static void |
22 | ctrlchar_handle_sysrq(struct work_struct *work) | 21 | ctrlchar_handle_sysrq(struct work_struct *work) |
23 | { | 22 | { |
24 | handle_sysrq(ctrlchar_sysrq_key, sysrq_tty); | 23 | handle_sysrq(ctrlchar_sysrq_key); |
25 | } | 24 | } |
26 | 25 | ||
27 | static DECLARE_WORK(ctrlchar_work, ctrlchar_handle_sysrq); | 26 | static DECLARE_WORK(ctrlchar_work, ctrlchar_handle_sysrq); |
@@ -54,7 +53,6 @@ ctrlchar_handle(const unsigned char *buf, int len, struct tty_struct *tty) | |||
54 | /* racy */ | 53 | /* racy */ |
55 | if (len == 3 && buf[1] == '-') { | 54 | if (len == 3 && buf[1] == '-') { |
56 | ctrlchar_sysrq_key = buf[2]; | 55 | ctrlchar_sysrq_key = buf[2]; |
57 | sysrq_tty = tty; | ||
58 | schedule_work(&ctrlchar_work); | 56 | schedule_work(&ctrlchar_work); |
59 | return CTRLCHAR_SYSRQ; | 57 | return CTRLCHAR_SYSRQ; |
60 | } | 58 | } |
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c index 18d9a497863..8cd58e412b5 100644 --- a/drivers/s390/char/keyboard.c +++ b/drivers/s390/char/keyboard.c | |||
@@ -305,7 +305,7 @@ kbd_keycode(struct kbd_data *kbd, unsigned int keycode) | |||
305 | if (kbd->sysrq) { | 305 | if (kbd->sysrq) { |
306 | if (kbd->sysrq == K(KT_LATIN, '-')) { | 306 | if (kbd->sysrq == K(KT_LATIN, '-')) { |
307 | kbd->sysrq = 0; | 307 | kbd->sysrq = 0; |
308 | handle_sysrq(value, kbd->tty); | 308 | handle_sysrq(value); |
309 | return; | 309 | return; |
310 | } | 310 | } |
311 | if (value == '-') { | 311 | if (value == '-') { |
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 95a895dd4f1..c8dc392edd5 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <linux/delay.h> | 56 | #include <linux/delay.h> |
57 | #include <linux/dma-mapping.h> | 57 | #include <linux/dma-mapping.h> |
58 | #include <linux/timer.h> | 58 | #include <linux/timer.h> |
59 | #include <linux/slab.h> | ||
59 | #include <linux/pci.h> | 60 | #include <linux/pci.h> |
60 | #include <linux/aer.h> | 61 | #include <linux/aer.h> |
61 | #include <asm/dma.h> | 62 | #include <asm/dma.h> |
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index f065204e401..95a26fb1626 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h | |||
@@ -132,7 +132,7 @@ void qla4_8xxx_idc_unlock(struct scsi_qla_host *ha); | |||
132 | int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha); | 132 | int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha); |
133 | void qla4_8xxx_need_qsnt_handler(struct scsi_qla_host *ha); | 133 | void qla4_8xxx_need_qsnt_handler(struct scsi_qla_host *ha); |
134 | void qla4_8xxx_clear_drv_active(struct scsi_qla_host *ha); | 134 | void qla4_8xxx_clear_drv_active(struct scsi_qla_host *ha); |
135 | inline void qla4_8xxx_set_drv_active(struct scsi_qla_host *ha); | 135 | void qla4_8xxx_set_drv_active(struct scsi_qla_host *ha); |
136 | 136 | ||
137 | extern int ql4xextended_error_logging; | 137 | extern int ql4xextended_error_logging; |
138 | extern int ql4xdiscoverywait; | 138 | extern int ql4xdiscoverywait; |
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index e031a734836..5d4a3822382 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c | |||
@@ -1418,7 +1418,7 @@ static int qla4_8xxx_rcvpeg_ready(struct scsi_qla_host *ha) | |||
1418 | return QLA_SUCCESS; | 1418 | return QLA_SUCCESS; |
1419 | } | 1419 | } |
1420 | 1420 | ||
1421 | inline void | 1421 | void |
1422 | qla4_8xxx_set_drv_active(struct scsi_qla_host *ha) | 1422 | qla4_8xxx_set_drv_active(struct scsi_qla_host *ha) |
1423 | { | 1423 | { |
1424 | uint32_t drv_active; | 1424 | uint32_t drv_active; |
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index 7356a56ac45..be0ebce36e5 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c | |||
@@ -869,7 +869,9 @@ static int get_serial_info(struct m68k_serial * info, | |||
869 | tmp.close_delay = info->close_delay; | 869 | tmp.close_delay = info->close_delay; |
870 | tmp.closing_wait = info->closing_wait; | 870 | tmp.closing_wait = info->closing_wait; |
871 | tmp.custom_divisor = info->custom_divisor; | 871 | tmp.custom_divisor = info->custom_divisor; |
872 | copy_to_user(retinfo,&tmp,sizeof(*retinfo)); | 872 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) |
873 | return -EFAULT; | ||
874 | |||
873 | return 0; | 875 | return 0; |
874 | } | 876 | } |
875 | 877 | ||
@@ -882,7 +884,8 @@ static int set_serial_info(struct m68k_serial * info, | |||
882 | 884 | ||
883 | if (!new_info) | 885 | if (!new_info) |
884 | return -EFAULT; | 886 | return -EFAULT; |
885 | copy_from_user(&new_serial,new_info,sizeof(new_serial)); | 887 | if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) |
888 | return -EFAULT; | ||
886 | old_info = *info; | 889 | old_info = *info; |
887 | 890 | ||
888 | if (!capable(CAP_SYS_ADMIN)) { | 891 | if (!capable(CAP_SYS_ADMIN)) { |
@@ -943,8 +946,7 @@ static int get_lsr_info(struct m68k_serial * info, unsigned int *value) | |||
943 | status = 0; | 946 | status = 0; |
944 | #endif | 947 | #endif |
945 | local_irq_restore(flags); | 948 | local_irq_restore(flags); |
946 | put_user(status,value); | 949 | return put_user(status, value); |
947 | return 0; | ||
948 | } | 950 | } |
949 | 951 | ||
950 | /* | 952 | /* |
@@ -999,27 +1001,18 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, | |||
999 | send_break(info, arg ? arg*(100) : 250); | 1001 | send_break(info, arg ? arg*(100) : 250); |
1000 | return 0; | 1002 | return 0; |
1001 | case TIOCGSERIAL: | 1003 | case TIOCGSERIAL: |
1002 | if (access_ok(VERIFY_WRITE, (void *) arg, | 1004 | return get_serial_info(info, |
1003 | sizeof(struct serial_struct))) | 1005 | (struct serial_struct *) arg); |
1004 | return get_serial_info(info, | ||
1005 | (struct serial_struct *) arg); | ||
1006 | return -EFAULT; | ||
1007 | case TIOCSSERIAL: | 1006 | case TIOCSSERIAL: |
1008 | return set_serial_info(info, | 1007 | return set_serial_info(info, |
1009 | (struct serial_struct *) arg); | 1008 | (struct serial_struct *) arg); |
1010 | case TIOCSERGETLSR: /* Get line status register */ | 1009 | case TIOCSERGETLSR: /* Get line status register */ |
1011 | if (access_ok(VERIFY_WRITE, (void *) arg, | 1010 | return get_lsr_info(info, (unsigned int *) arg); |
1012 | sizeof(unsigned int))) | ||
1013 | return get_lsr_info(info, (unsigned int *) arg); | ||
1014 | return -EFAULT; | ||
1015 | case TIOCSERGSTRUCT: | 1011 | case TIOCSERGSTRUCT: |
1016 | if (!access_ok(VERIFY_WRITE, (void *) arg, | 1012 | if (copy_to_user((struct m68k_serial *) arg, |
1017 | sizeof(struct m68k_serial))) | 1013 | info, sizeof(struct m68k_serial))) |
1018 | return -EFAULT; | 1014 | return -EFAULT; |
1019 | copy_to_user((struct m68k_serial *) arg, | ||
1020 | info, sizeof(struct m68k_serial)); | ||
1021 | return 0; | 1015 | return 0; |
1022 | |||
1023 | default: | 1016 | default: |
1024 | return -ENOIOCTLCMD; | 1017 | return -ENOIOCTLCMD; |
1025 | } | 1018 | } |
diff --git a/drivers/serial/8250_early.c b/drivers/serial/8250_early.c index b745792ec25..eaafb98debe 100644 --- a/drivers/serial/8250_early.c +++ b/drivers/serial/8250_early.c | |||
@@ -203,13 +203,13 @@ static int __init parse_options(struct early_serial8250_device *device, | |||
203 | 203 | ||
204 | if (mmio || mmio32) | 204 | if (mmio || mmio32) |
205 | printk(KERN_INFO | 205 | printk(KERN_INFO |
206 | "Early serial console at MMIO%s 0x%llu (options '%s')\n", | 206 | "Early serial console at MMIO%s 0x%llx (options '%s')\n", |
207 | mmio32 ? "32" : "", | 207 | mmio32 ? "32" : "", |
208 | (unsigned long long)port->mapbase, | 208 | (unsigned long long)port->mapbase, |
209 | device->options); | 209 | device->options); |
210 | else | 210 | else |
211 | printk(KERN_INFO | 211 | printk(KERN_INFO |
212 | "Early serial console at I/O port 0x%lu (options '%s')\n", | 212 | "Early serial console at I/O port 0x%lx (options '%s')\n", |
213 | port->iobase, | 213 | port->iobase, |
214 | device->options); | 214 | device->options); |
215 | 215 | ||
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c index e57fb3d228e..5318dd3774a 100644 --- a/drivers/serial/bfin_sport_uart.c +++ b/drivers/serial/bfin_sport_uart.c | |||
@@ -121,7 +121,7 @@ static int sport_uart_setup(struct sport_uart_port *up, int size, int baud_rate) | |||
121 | unsigned int sclk = get_sclk(); | 121 | unsigned int sclk = get_sclk(); |
122 | 122 | ||
123 | /* Set TCR1 and TCR2, TFSR is not enabled for uart */ | 123 | /* Set TCR1 and TCR2, TFSR is not enabled for uart */ |
124 | SPORT_PUT_TCR1(up, (ITFS | TLSBIT | ITCLK)); | 124 | SPORT_PUT_TCR1(up, (LATFS | ITFS | TFSR | TLSBIT | ITCLK)); |
125 | SPORT_PUT_TCR2(up, size + 1); | 125 | SPORT_PUT_TCR2(up, size + 1); |
126 | pr_debug("%s TCR1:%x, TCR2:%x\n", __func__, SPORT_GET_TCR1(up), SPORT_GET_TCR2(up)); | 126 | pr_debug("%s TCR1:%x, TCR2:%x\n", __func__, SPORT_GET_TCR1(up), SPORT_GET_TCR2(up)); |
127 | 127 | ||
diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index 659a695bdad..2af8fd11312 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c | |||
@@ -14,11 +14,10 @@ | |||
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/serial_core.h> | 15 | #include <linux/serial_core.h> |
16 | #include <linux/serial_8250.h> | 16 | #include <linux/serial_8250.h> |
17 | #include <linux/of_address.h> | ||
17 | #include <linux/of_platform.h> | 18 | #include <linux/of_platform.h> |
18 | #include <linux/nwpserial.h> | 19 | #include <linux/nwpserial.h> |
19 | 20 | ||
20 | #include <asm/prom.h> | ||
21 | |||
22 | struct of_serial_info { | 21 | struct of_serial_info { |
23 | int type; | 22 | int type; |
24 | int line; | 23 | int line; |
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c index 7e5e5efea4e..cff9a306660 100644 --- a/drivers/serial/sn_console.c +++ b/drivers/serial/sn_console.c | |||
@@ -492,7 +492,7 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags) | |||
492 | sysrq_requested = 0; | 492 | sysrq_requested = 0; |
493 | if (ch && time_before(jiffies, sysrq_timeout)) { | 493 | if (ch && time_before(jiffies, sysrq_timeout)) { |
494 | spin_unlock_irqrestore(&port->sc_port.lock, flags); | 494 | spin_unlock_irqrestore(&port->sc_port.lock, flags); |
495 | handle_sysrq(ch, NULL); | 495 | handle_sysrq(ch); |
496 | spin_lock_irqsave(&port->sc_port.lock, flags); | 496 | spin_lock_irqsave(&port->sc_port.lock, flags); |
497 | /* ignore actual sysrq command char */ | 497 | /* ignore actual sysrq command char */ |
498 | continue; | 498 | continue; |
diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c index 544f2e25d0e..6381a0282ee 100644 --- a/drivers/serial/suncore.c +++ b/drivers/serial/suncore.c | |||
@@ -55,7 +55,12 @@ EXPORT_SYMBOL(sunserial_unregister_minors); | |||
55 | int sunserial_console_match(struct console *con, struct device_node *dp, | 55 | int sunserial_console_match(struct console *con, struct device_node *dp, |
56 | struct uart_driver *drv, int line, bool ignore_line) | 56 | struct uart_driver *drv, int line, bool ignore_line) |
57 | { | 57 | { |
58 | if (!con || of_console_device != dp) | 58 | if (!con) |
59 | return 0; | ||
60 | |||
61 | drv->cons = con; | ||
62 | |||
63 | if (of_console_device != dp) | ||
59 | return 0; | 64 | return 0; |
60 | 65 | ||
61 | if (!ignore_line) { | 66 | if (!ignore_line) { |
@@ -69,12 +74,10 @@ int sunserial_console_match(struct console *con, struct device_node *dp, | |||
69 | return 0; | 74 | return 0; |
70 | } | 75 | } |
71 | 76 | ||
72 | con->index = line; | 77 | if (!console_set_on_cmdline) { |
73 | drv->cons = con; | 78 | con->index = line; |
74 | |||
75 | if (!console_set_on_cmdline) | ||
76 | add_preferred_console(con->name, line, NULL); | 79 | add_preferred_console(con->name, line, NULL); |
77 | 80 | } | |
78 | return 1; | 81 | return 1; |
79 | } | 82 | } |
80 | EXPORT_SYMBOL(sunserial_console_match); | 83 | EXPORT_SYMBOL(sunserial_console_match); |
diff --git a/drivers/spi/coldfire_qspi.c b/drivers/spi/coldfire_qspi.c index 59be3efe063..052b3c7fa6a 100644 --- a/drivers/spi/coldfire_qspi.c +++ b/drivers/spi/coldfire_qspi.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/errno.h> | 25 | #include <linux/errno.h> |
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/sched.h> | ||
27 | #include <linux/workqueue.h> | 28 | #include <linux/workqueue.h> |
28 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
29 | #include <linux/io.h> | 30 | #include <linux/io.h> |
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 4a7a7a7f11b..335311a98fd 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
@@ -113,8 +113,6 @@ source "drivers/staging/vme/Kconfig" | |||
113 | 113 | ||
114 | source "drivers/staging/memrar/Kconfig" | 114 | source "drivers/staging/memrar/Kconfig" |
115 | 115 | ||
116 | source "drivers/staging/sep/Kconfig" | ||
117 | |||
118 | source "drivers/staging/iio/Kconfig" | 116 | source "drivers/staging/iio/Kconfig" |
119 | 117 | ||
120 | source "drivers/staging/zram/Kconfig" | 118 | source "drivers/staging/zram/Kconfig" |
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index ca5c03eb3ce..e3f1e1b6095 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile | |||
@@ -38,7 +38,6 @@ obj-$(CONFIG_FB_UDL) += udlfb/ | |||
38 | obj-$(CONFIG_HYPERV) += hv/ | 38 | obj-$(CONFIG_HYPERV) += hv/ |
39 | obj-$(CONFIG_VME_BUS) += vme/ | 39 | obj-$(CONFIG_VME_BUS) += vme/ |
40 | obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/ | 40 | obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/ |
41 | obj-$(CONFIG_DX_SEP) += sep/ | ||
42 | obj-$(CONFIG_IIO) += iio/ | 41 | obj-$(CONFIG_IIO) += iio/ |
43 | obj-$(CONFIG_ZRAM) += zram/ | 42 | obj-$(CONFIG_ZRAM) += zram/ |
44 | obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ | 43 | obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ |
diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c index b4a8d5eb64f..05ca15a6c9f 100644 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ b/drivers/staging/batman-adv/bat_sysfs.c | |||
@@ -267,6 +267,10 @@ static ssize_t store_log_level(struct kobject *kobj, struct attribute *attr, | |||
267 | if (atomic_read(&bat_priv->log_level) == log_level_tmp) | 267 | if (atomic_read(&bat_priv->log_level) == log_level_tmp) |
268 | return count; | 268 | return count; |
269 | 269 | ||
270 | bat_info(net_dev, "Changing log level from: %i to: %li\n", | ||
271 | atomic_read(&bat_priv->log_level), | ||
272 | log_level_tmp); | ||
273 | |||
270 | atomic_set(&bat_priv->log_level, (unsigned)log_level_tmp); | 274 | atomic_set(&bat_priv->log_level, (unsigned)log_level_tmp); |
271 | return count; | 275 | return count; |
272 | } | 276 | } |
diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c index 92c216a5688..baa8b05b9e8 100644 --- a/drivers/staging/batman-adv/hard-interface.c +++ b/drivers/staging/batman-adv/hard-interface.c | |||
@@ -129,6 +129,9 @@ static bool hardif_is_iface_up(struct batman_if *batman_if) | |||
129 | 129 | ||
130 | static void update_mac_addresses(struct batman_if *batman_if) | 130 | static void update_mac_addresses(struct batman_if *batman_if) |
131 | { | 131 | { |
132 | if (!batman_if || !batman_if->packet_buff) | ||
133 | return; | ||
134 | |||
132 | addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr); | 135 | addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr); |
133 | 136 | ||
134 | memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig, | 137 | memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig, |
@@ -194,8 +197,6 @@ static void hardif_activate_interface(struct net_device *net_dev, | |||
194 | if (batman_if->if_status != IF_INACTIVE) | 197 | if (batman_if->if_status != IF_INACTIVE) |
195 | return; | 198 | return; |
196 | 199 | ||
197 | dev_hold(batman_if->net_dev); | ||
198 | |||
199 | update_mac_addresses(batman_if); | 200 | update_mac_addresses(batman_if); |
200 | batman_if->if_status = IF_TO_BE_ACTIVATED; | 201 | batman_if->if_status = IF_TO_BE_ACTIVATED; |
201 | 202 | ||
@@ -222,8 +223,6 @@ static void hardif_deactivate_interface(struct net_device *net_dev, | |||
222 | (batman_if->if_status != IF_TO_BE_ACTIVATED)) | 223 | (batman_if->if_status != IF_TO_BE_ACTIVATED)) |
223 | return; | 224 | return; |
224 | 225 | ||
225 | dev_put(batman_if->net_dev); | ||
226 | |||
227 | batman_if->if_status = IF_INACTIVE; | 226 | batman_if->if_status = IF_INACTIVE; |
228 | 227 | ||
229 | bat_info(net_dev, "Interface deactivated: %s\n", batman_if->dev); | 228 | bat_info(net_dev, "Interface deactivated: %s\n", batman_if->dev); |
@@ -318,11 +317,13 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev) | |||
318 | if (ret != 1) | 317 | if (ret != 1) |
319 | goto out; | 318 | goto out; |
320 | 319 | ||
320 | dev_hold(net_dev); | ||
321 | |||
321 | batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC); | 322 | batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC); |
322 | if (!batman_if) { | 323 | if (!batman_if) { |
323 | pr_err("Can't add interface (%s): out of memory\n", | 324 | pr_err("Can't add interface (%s): out of memory\n", |
324 | net_dev->name); | 325 | net_dev->name); |
325 | goto out; | 326 | goto release_dev; |
326 | } | 327 | } |
327 | 328 | ||
328 | batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC); | 329 | batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC); |
@@ -336,6 +337,7 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev) | |||
336 | batman_if->if_num = -1; | 337 | batman_if->if_num = -1; |
337 | batman_if->net_dev = net_dev; | 338 | batman_if->net_dev = net_dev; |
338 | batman_if->if_status = IF_NOT_IN_USE; | 339 | batman_if->if_status = IF_NOT_IN_USE; |
340 | batman_if->packet_buff = NULL; | ||
339 | INIT_LIST_HEAD(&batman_if->list); | 341 | INIT_LIST_HEAD(&batman_if->list); |
340 | 342 | ||
341 | check_known_mac_addr(batman_if->net_dev->dev_addr); | 343 | check_known_mac_addr(batman_if->net_dev->dev_addr); |
@@ -346,6 +348,8 @@ free_dev: | |||
346 | kfree(batman_if->dev); | 348 | kfree(batman_if->dev); |
347 | free_if: | 349 | free_if: |
348 | kfree(batman_if); | 350 | kfree(batman_if); |
351 | release_dev: | ||
352 | dev_put(net_dev); | ||
349 | out: | 353 | out: |
350 | return NULL; | 354 | return NULL; |
351 | } | 355 | } |
@@ -374,6 +378,7 @@ static void hardif_remove_interface(struct batman_if *batman_if) | |||
374 | batman_if->if_status = IF_TO_BE_REMOVED; | 378 | batman_if->if_status = IF_TO_BE_REMOVED; |
375 | list_del_rcu(&batman_if->list); | 379 | list_del_rcu(&batman_if->list); |
376 | sysfs_del_hardif(&batman_if->hardif_obj); | 380 | sysfs_del_hardif(&batman_if->hardif_obj); |
381 | dev_put(batman_if->net_dev); | ||
377 | call_rcu(&batman_if->rcu, hardif_free_interface); | 382 | call_rcu(&batman_if->rcu, hardif_free_interface); |
378 | } | 383 | } |
379 | 384 | ||
@@ -393,15 +398,13 @@ static int hard_if_event(struct notifier_block *this, | |||
393 | /* FIXME: each batman_if will be attached to a softif */ | 398 | /* FIXME: each batman_if will be attached to a softif */ |
394 | struct bat_priv *bat_priv = netdev_priv(soft_device); | 399 | struct bat_priv *bat_priv = netdev_priv(soft_device); |
395 | 400 | ||
396 | if (!batman_if) | 401 | if (!batman_if && event == NETDEV_REGISTER) |
397 | batman_if = hardif_add_interface(net_dev); | 402 | batman_if = hardif_add_interface(net_dev); |
398 | 403 | ||
399 | if (!batman_if) | 404 | if (!batman_if) |
400 | goto out; | 405 | goto out; |
401 | 406 | ||
402 | switch (event) { | 407 | switch (event) { |
403 | case NETDEV_REGISTER: | ||
404 | break; | ||
405 | case NETDEV_UP: | 408 | case NETDEV_UP: |
406 | hardif_activate_interface(soft_device, bat_priv, batman_if); | 409 | hardif_activate_interface(soft_device, bat_priv, batman_if); |
407 | break; | 410 | break; |
@@ -442,8 +445,6 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | |||
442 | struct bat_priv *bat_priv = netdev_priv(soft_device); | 445 | struct bat_priv *bat_priv = netdev_priv(soft_device); |
443 | struct batman_packet *batman_packet; | 446 | struct batman_packet *batman_packet; |
444 | struct batman_if *batman_if; | 447 | struct batman_if *batman_if; |
445 | struct net_device_stats *stats; | ||
446 | struct rtnl_link_stats64 temp; | ||
447 | int ret; | 448 | int ret; |
448 | 449 | ||
449 | skb = skb_share_check(skb, GFP_ATOMIC); | 450 | skb = skb_share_check(skb, GFP_ATOMIC); |
@@ -479,12 +480,6 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | |||
479 | if (batman_if->if_status != IF_ACTIVE) | 480 | if (batman_if->if_status != IF_ACTIVE) |
480 | goto err_free; | 481 | goto err_free; |
481 | 482 | ||
482 | stats = (struct net_device_stats *)dev_get_stats(skb->dev, &temp); | ||
483 | if (stats) { | ||
484 | stats->rx_packets++; | ||
485 | stats->rx_bytes += skb->len; | ||
486 | } | ||
487 | |||
488 | batman_packet = (struct batman_packet *)skb->data; | 483 | batman_packet = (struct batman_packet *)skb->data; |
489 | 484 | ||
490 | if (batman_packet->version != COMPAT_VERSION) { | 485 | if (batman_packet->version != COMPAT_VERSION) { |
diff --git a/drivers/staging/batman-adv/icmp_socket.c b/drivers/staging/batman-adv/icmp_socket.c index fc3d32c1272..3ae7dd2d2d4 100644 --- a/drivers/staging/batman-adv/icmp_socket.c +++ b/drivers/staging/batman-adv/icmp_socket.c | |||
@@ -67,6 +67,7 @@ static int bat_socket_open(struct inode *inode, struct file *file) | |||
67 | INIT_LIST_HEAD(&socket_client->queue_list); | 67 | INIT_LIST_HEAD(&socket_client->queue_list); |
68 | socket_client->queue_len = 0; | 68 | socket_client->queue_len = 0; |
69 | socket_client->index = i; | 69 | socket_client->index = i; |
70 | socket_client->bat_priv = inode->i_private; | ||
70 | spin_lock_init(&socket_client->lock); | 71 | spin_lock_init(&socket_client->lock); |
71 | init_waitqueue_head(&socket_client->queue_wait); | 72 | init_waitqueue_head(&socket_client->queue_wait); |
72 | 73 | ||
@@ -151,9 +152,8 @@ static ssize_t bat_socket_read(struct file *file, char __user *buf, | |||
151 | static ssize_t bat_socket_write(struct file *file, const char __user *buff, | 152 | static ssize_t bat_socket_write(struct file *file, const char __user *buff, |
152 | size_t len, loff_t *off) | 153 | size_t len, loff_t *off) |
153 | { | 154 | { |
154 | /* FIXME: each orig_node->batman_if will be attached to a softif */ | ||
155 | struct bat_priv *bat_priv = netdev_priv(soft_device); | ||
156 | struct socket_client *socket_client = file->private_data; | 155 | struct socket_client *socket_client = file->private_data; |
156 | struct bat_priv *bat_priv = socket_client->bat_priv; | ||
157 | struct icmp_packet_rr icmp_packet; | 157 | struct icmp_packet_rr icmp_packet; |
158 | struct orig_node *orig_node; | 158 | struct orig_node *orig_node; |
159 | struct batman_if *batman_if; | 159 | struct batman_if *batman_if; |
@@ -168,6 +168,9 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, | |||
168 | return -EINVAL; | 168 | return -EINVAL; |
169 | } | 169 | } |
170 | 170 | ||
171 | if (!bat_priv->primary_if) | ||
172 | return -EFAULT; | ||
173 | |||
171 | if (len >= sizeof(struct icmp_packet_rr)) | 174 | if (len >= sizeof(struct icmp_packet_rr)) |
172 | packet_len = sizeof(struct icmp_packet_rr); | 175 | packet_len = sizeof(struct icmp_packet_rr); |
173 | 176 | ||
@@ -223,7 +226,8 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, | |||
223 | if (batman_if->if_status != IF_ACTIVE) | 226 | if (batman_if->if_status != IF_ACTIVE) |
224 | goto dst_unreach; | 227 | goto dst_unreach; |
225 | 228 | ||
226 | memcpy(icmp_packet.orig, batman_if->net_dev->dev_addr, ETH_ALEN); | 229 | memcpy(icmp_packet.orig, |
230 | bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); | ||
227 | 231 | ||
228 | if (packet_len == sizeof(struct icmp_packet_rr)) | 232 | if (packet_len == sizeof(struct icmp_packet_rr)) |
229 | memcpy(icmp_packet.rr, batman_if->net_dev->dev_addr, ETH_ALEN); | 233 | memcpy(icmp_packet.rr, batman_if->net_dev->dev_addr, ETH_ALEN); |
@@ -271,7 +275,7 @@ int bat_socket_setup(struct bat_priv *bat_priv) | |||
271 | goto err; | 275 | goto err; |
272 | 276 | ||
273 | d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR, | 277 | d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR, |
274 | bat_priv->debug_dir, NULL, &fops); | 278 | bat_priv->debug_dir, bat_priv, &fops); |
275 | if (d) | 279 | if (d) |
276 | goto err; | 280 | goto err; |
277 | 281 | ||
diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index 2686019fe4e..ef7c20ae797 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c | |||
@@ -250,10 +250,13 @@ int choose_orig(void *data, int32_t size) | |||
250 | int is_my_mac(uint8_t *addr) | 250 | int is_my_mac(uint8_t *addr) |
251 | { | 251 | { |
252 | struct batman_if *batman_if; | 252 | struct batman_if *batman_if; |
253 | |||
253 | rcu_read_lock(); | 254 | rcu_read_lock(); |
254 | list_for_each_entry_rcu(batman_if, &if_list, list) { | 255 | list_for_each_entry_rcu(batman_if, &if_list, list) { |
255 | if ((batman_if->net_dev) && | 256 | if (batman_if->if_status != IF_ACTIVE) |
256 | (compare_orig(batman_if->net_dev->dev_addr, addr))) { | 257 | continue; |
258 | |||
259 | if (compare_orig(batman_if->net_dev->dev_addr, addr)) { | ||
257 | rcu_read_unlock(); | 260 | rcu_read_unlock(); |
258 | return 1; | 261 | return 1; |
259 | } | 262 | } |
diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 28bb627ffa1..de5a8c1a810 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c | |||
@@ -391,11 +391,12 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) | |||
391 | int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) | 391 | int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) |
392 | { | 392 | { |
393 | struct orig_node *orig_node; | 393 | struct orig_node *orig_node; |
394 | unsigned long flags; | ||
394 | HASHIT(hashit); | 395 | HASHIT(hashit); |
395 | 396 | ||
396 | /* resize all orig nodes because orig_node->bcast_own(_sum) depend on | 397 | /* resize all orig nodes because orig_node->bcast_own(_sum) depend on |
397 | * if_num */ | 398 | * if_num */ |
398 | spin_lock(&orig_hash_lock); | 399 | spin_lock_irqsave(&orig_hash_lock, flags); |
399 | 400 | ||
400 | while (hash_iterate(orig_hash, &hashit)) { | 401 | while (hash_iterate(orig_hash, &hashit)) { |
401 | orig_node = hashit.bucket->data; | 402 | orig_node = hashit.bucket->data; |
@@ -404,11 +405,11 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) | |||
404 | goto err; | 405 | goto err; |
405 | } | 406 | } |
406 | 407 | ||
407 | spin_unlock(&orig_hash_lock); | 408 | spin_unlock_irqrestore(&orig_hash_lock, flags); |
408 | return 0; | 409 | return 0; |
409 | 410 | ||
410 | err: | 411 | err: |
411 | spin_unlock(&orig_hash_lock); | 412 | spin_unlock_irqrestore(&orig_hash_lock, flags); |
412 | return -ENOMEM; | 413 | return -ENOMEM; |
413 | } | 414 | } |
414 | 415 | ||
@@ -468,12 +469,13 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) | |||
468 | { | 469 | { |
469 | struct batman_if *batman_if_tmp; | 470 | struct batman_if *batman_if_tmp; |
470 | struct orig_node *orig_node; | 471 | struct orig_node *orig_node; |
472 | unsigned long flags; | ||
471 | HASHIT(hashit); | 473 | HASHIT(hashit); |
472 | int ret; | 474 | int ret; |
473 | 475 | ||
474 | /* resize all orig nodes because orig_node->bcast_own(_sum) depend on | 476 | /* resize all orig nodes because orig_node->bcast_own(_sum) depend on |
475 | * if_num */ | 477 | * if_num */ |
476 | spin_lock(&orig_hash_lock); | 478 | spin_lock_irqsave(&orig_hash_lock, flags); |
477 | 479 | ||
478 | while (hash_iterate(orig_hash, &hashit)) { | 480 | while (hash_iterate(orig_hash, &hashit)) { |
479 | orig_node = hashit.bucket->data; | 481 | orig_node = hashit.bucket->data; |
@@ -500,10 +502,10 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) | |||
500 | rcu_read_unlock(); | 502 | rcu_read_unlock(); |
501 | 503 | ||
502 | batman_if->if_num = -1; | 504 | batman_if->if_num = -1; |
503 | spin_unlock(&orig_hash_lock); | 505 | spin_unlock_irqrestore(&orig_hash_lock, flags); |
504 | return 0; | 506 | return 0; |
505 | 507 | ||
506 | err: | 508 | err: |
507 | spin_unlock(&orig_hash_lock); | 509 | spin_unlock_irqrestore(&orig_hash_lock, flags); |
508 | return -ENOMEM; | 510 | return -ENOMEM; |
509 | } | 511 | } |
diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 066cc9149bf..032195e6de9 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c | |||
@@ -783,6 +783,8 @@ int recv_bat_packet(struct sk_buff *skb, | |||
783 | 783 | ||
784 | static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len) | 784 | static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len) |
785 | { | 785 | { |
786 | /* FIXME: each batman_if will be attached to a softif */ | ||
787 | struct bat_priv *bat_priv = netdev_priv(soft_device); | ||
786 | struct orig_node *orig_node; | 788 | struct orig_node *orig_node; |
787 | struct icmp_packet_rr *icmp_packet; | 789 | struct icmp_packet_rr *icmp_packet; |
788 | struct ethhdr *ethhdr; | 790 | struct ethhdr *ethhdr; |
@@ -801,6 +803,9 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len) | |||
801 | return NET_RX_DROP; | 803 | return NET_RX_DROP; |
802 | } | 804 | } |
803 | 805 | ||
806 | if (!bat_priv->primary_if) | ||
807 | return NET_RX_DROP; | ||
808 | |||
804 | /* answer echo request (ping) */ | 809 | /* answer echo request (ping) */ |
805 | /* get routing information */ | 810 | /* get routing information */ |
806 | spin_lock_irqsave(&orig_hash_lock, flags); | 811 | spin_lock_irqsave(&orig_hash_lock, flags); |
@@ -830,7 +835,8 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len) | |||
830 | } | 835 | } |
831 | 836 | ||
832 | memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); | 837 | memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); |
833 | memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN); | 838 | memcpy(icmp_packet->orig, |
839 | bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); | ||
834 | icmp_packet->msg_type = ECHO_REPLY; | 840 | icmp_packet->msg_type = ECHO_REPLY; |
835 | icmp_packet->ttl = TTL; | 841 | icmp_packet->ttl = TTL; |
836 | 842 | ||
@@ -845,6 +851,8 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len) | |||
845 | 851 | ||
846 | static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len) | 852 | static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len) |
847 | { | 853 | { |
854 | /* FIXME: each batman_if will be attached to a softif */ | ||
855 | struct bat_priv *bat_priv = netdev_priv(soft_device); | ||
848 | struct orig_node *orig_node; | 856 | struct orig_node *orig_node; |
849 | struct icmp_packet *icmp_packet; | 857 | struct icmp_packet *icmp_packet; |
850 | struct ethhdr *ethhdr; | 858 | struct ethhdr *ethhdr; |
@@ -865,6 +873,9 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len) | |||
865 | return NET_RX_DROP; | 873 | return NET_RX_DROP; |
866 | } | 874 | } |
867 | 875 | ||
876 | if (!bat_priv->primary_if) | ||
877 | return NET_RX_DROP; | ||
878 | |||
868 | /* get routing information */ | 879 | /* get routing information */ |
869 | spin_lock_irqsave(&orig_hash_lock, flags); | 880 | spin_lock_irqsave(&orig_hash_lock, flags); |
870 | orig_node = ((struct orig_node *) | 881 | orig_node = ((struct orig_node *) |
@@ -892,7 +903,8 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len) | |||
892 | } | 903 | } |
893 | 904 | ||
894 | memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); | 905 | memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); |
895 | memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN); | 906 | memcpy(icmp_packet->orig, |
907 | bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); | ||
896 | icmp_packet->msg_type = TTL_EXCEEDED; | 908 | icmp_packet->msg_type = TTL_EXCEEDED; |
897 | icmp_packet->ttl = TTL; | 909 | icmp_packet->ttl = TTL; |
898 | 910 | ||
diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index 21d0717afb0..9aa9d369c75 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h | |||
@@ -126,6 +126,7 @@ struct socket_client { | |||
126 | unsigned char index; | 126 | unsigned char index; |
127 | spinlock_t lock; | 127 | spinlock_t lock; |
128 | wait_queue_head_t queue_wait; | 128 | wait_queue_head_t queue_wait; |
129 | struct bat_priv *bat_priv; | ||
129 | }; | 130 | }; |
130 | 131 | ||
131 | struct socket_packet { | 132 | struct socket_packet { |
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c index c6aa52f8dce..48d9fb1227d 100644 --- a/drivers/staging/comedi/drivers/das08_cs.c +++ b/drivers/staging/comedi/drivers/das08_cs.c | |||
@@ -222,7 +222,6 @@ static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev, | |||
222 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; | 222 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; |
223 | p_dev->resource[0]->flags |= | 223 | p_dev->resource[0]->flags |= |
224 | pcmcia_io_cfg_data_width(io->flags); | 224 | pcmcia_io_cfg_data_width(io->flags); |
225 | p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; | ||
226 | p_dev->resource[0]->start = io->win[0].base; | 225 | p_dev->resource[0]->start = io->win[0].base; |
227 | p_dev->resource[0]->end = io->win[0].len; | 226 | p_dev->resource[0]->end = io->win[0].len; |
228 | if (io->nwin > 1) { | 227 | if (io->nwin > 1) { |
diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 56e11575c97..64a01147eca 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c | |||
@@ -327,6 +327,9 @@ static const struct net_device_ops device_ops = { | |||
327 | .ndo_stop = netvsc_close, | 327 | .ndo_stop = netvsc_close, |
328 | .ndo_start_xmit = netvsc_start_xmit, | 328 | .ndo_start_xmit = netvsc_start_xmit, |
329 | .ndo_set_multicast_list = netvsc_set_multicast_list, | 329 | .ndo_set_multicast_list = netvsc_set_multicast_list, |
330 | .ndo_change_mtu = eth_change_mtu, | ||
331 | .ndo_validate_addr = eth_validate_addr, | ||
332 | .ndo_set_mac_address = eth_mac_addr, | ||
330 | }; | 333 | }; |
331 | 334 | ||
332 | static int netvsc_probe(struct device *device) | 335 | static int netvsc_probe(struct device *device) |
diff --git a/drivers/staging/hv/ring_buffer.c b/drivers/staging/hv/ring_buffer.c index 17bc7626f70..d78c569ac94 100644 --- a/drivers/staging/hv/ring_buffer.c +++ b/drivers/staging/hv/ring_buffer.c | |||
@@ -193,8 +193,7 @@ Description: | |||
193 | static inline u64 | 193 | static inline u64 |
194 | GetRingBufferIndices(struct hv_ring_buffer_info *RingInfo) | 194 | GetRingBufferIndices(struct hv_ring_buffer_info *RingInfo) |
195 | { | 195 | { |
196 | return ((u64)RingInfo->RingBuffer->WriteIndex << 32) | 196 | return (u64)RingInfo->RingBuffer->WriteIndex << 32; |
197 | || RingInfo->RingBuffer->ReadIndex; | ||
198 | } | 197 | } |
199 | 198 | ||
200 | 199 | ||
diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 0063bde9a4b..8505a1c5f9e 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h | |||
@@ -28,10 +28,10 @@ | |||
28 | #include "vmbus_api.h" | 28 | #include "vmbus_api.h" |
29 | 29 | ||
30 | /* Defines */ | 30 | /* Defines */ |
31 | #define STORVSC_RING_BUFFER_SIZE (10*PAGE_SIZE) | 31 | #define STORVSC_RING_BUFFER_SIZE (20*PAGE_SIZE) |
32 | #define BLKVSC_RING_BUFFER_SIZE (20*PAGE_SIZE) | 32 | #define BLKVSC_RING_BUFFER_SIZE (20*PAGE_SIZE) |
33 | 33 | ||
34 | #define STORVSC_MAX_IO_REQUESTS 64 | 34 | #define STORVSC_MAX_IO_REQUESTS 128 |
35 | 35 | ||
36 | /* | 36 | /* |
37 | * In Hyper-V, each port/path/target maps to 1 scsi host adapter. In | 37 | * In Hyper-V, each port/path/target maps to 1 scsi host adapter. In |
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 075b61bd492..62882a437aa 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c | |||
@@ -495,7 +495,7 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl, | |||
495 | 495 | ||
496 | /* ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); */ | 496 | /* ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); */ |
497 | 497 | ||
498 | if (j == 0) | 498 | if (bounce_addr == 0) |
499 | bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0); | 499 | bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0); |
500 | 500 | ||
501 | while (srclen) { | 501 | while (srclen) { |
@@ -556,7 +556,7 @@ static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl, | |||
556 | destlen = orig_sgl[i].length; | 556 | destlen = orig_sgl[i].length; |
557 | /* ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); */ | 557 | /* ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); */ |
558 | 558 | ||
559 | if (j == 0) | 559 | if (bounce_addr == 0) |
560 | bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0); | 560 | bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0); |
561 | 561 | ||
562 | while (destlen) { | 562 | while (destlen) { |
@@ -615,6 +615,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, | |||
615 | unsigned int request_size = 0; | 615 | unsigned int request_size = 0; |
616 | int i; | 616 | int i; |
617 | struct scatterlist *sgl; | 617 | struct scatterlist *sgl; |
618 | unsigned int sg_count = 0; | ||
618 | 619 | ||
619 | DPRINT_DBG(STORVSC_DRV, "scmnd %p dir %d, use_sg %d buf %p len %d " | 620 | DPRINT_DBG(STORVSC_DRV, "scmnd %p dir %d, use_sg %d buf %p len %d " |
620 | "queue depth %d tagged %d", scmnd, scmnd->sc_data_direction, | 621 | "queue depth %d tagged %d", scmnd, scmnd->sc_data_direction, |
@@ -697,6 +698,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, | |||
697 | request->DataBuffer.Length = scsi_bufflen(scmnd); | 698 | request->DataBuffer.Length = scsi_bufflen(scmnd); |
698 | if (scsi_sg_count(scmnd)) { | 699 | if (scsi_sg_count(scmnd)) { |
699 | sgl = (struct scatterlist *)scsi_sglist(scmnd); | 700 | sgl = (struct scatterlist *)scsi_sglist(scmnd); |
701 | sg_count = scsi_sg_count(scmnd); | ||
700 | 702 | ||
701 | /* check if we need to bounce the sgl */ | 703 | /* check if we need to bounce the sgl */ |
702 | if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) { | 704 | if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) { |
@@ -731,15 +733,16 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, | |||
731 | scsi_sg_count(scmnd)); | 733 | scsi_sg_count(scmnd)); |
732 | 734 | ||
733 | sgl = cmd_request->bounce_sgl; | 735 | sgl = cmd_request->bounce_sgl; |
736 | sg_count = cmd_request->bounce_sgl_count; | ||
734 | } | 737 | } |
735 | 738 | ||
736 | request->DataBuffer.Offset = sgl[0].offset; | 739 | request->DataBuffer.Offset = sgl[0].offset; |
737 | 740 | ||
738 | for (i = 0; i < scsi_sg_count(scmnd); i++) { | 741 | for (i = 0; i < sg_count; i++) { |
739 | DPRINT_DBG(STORVSC_DRV, "sgl[%d] len %d offset %d\n", | 742 | DPRINT_DBG(STORVSC_DRV, "sgl[%d] len %d offset %d\n", |
740 | i, sgl[i].length, sgl[i].offset); | 743 | i, sgl[i].length, sgl[i].offset); |
741 | request->DataBuffer.PfnArray[i] = | 744 | request->DataBuffer.PfnArray[i] = |
742 | page_to_pfn(sg_page((&sgl[i]))); | 745 | page_to_pfn(sg_page((&sgl[i]))); |
743 | } | 746 | } |
744 | } else if (scsi_sglist(scmnd)) { | 747 | } else if (scsi_sglist(scmnd)) { |
745 | /* ASSERT(scsi_bufflen(scmnd) <= PAGE_SIZE); */ | 748 | /* ASSERT(scsi_bufflen(scmnd) <= PAGE_SIZE); */ |
diff --git a/drivers/staging/octeon/Kconfig b/drivers/staging/octeon/Kconfig index 638ad6b3589..9493128e5fd 100644 --- a/drivers/staging/octeon/Kconfig +++ b/drivers/staging/octeon/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config OCTEON_ETHERNET | 1 | config OCTEON_ETHERNET |
2 | tristate "Cavium Networks Octeon Ethernet support" | 2 | tristate "Cavium Networks Octeon Ethernet support" |
3 | depends on CPU_CAVIUM_OCTEON | 3 | depends on CPU_CAVIUM_OCTEON && NETDEVICES |
4 | select PHYLIB | 4 | select PHYLIB |
5 | select MDIO_OCTEON | 5 | select MDIO_OCTEON |
6 | help | 6 | help |
diff --git a/drivers/staging/pohmelfs/path_entry.c b/drivers/staging/pohmelfs/path_entry.c index cdc4dd50d63..8ec83d2dffb 100644 --- a/drivers/staging/pohmelfs/path_entry.c +++ b/drivers/staging/pohmelfs/path_entry.c | |||
@@ -44,9 +44,9 @@ int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int le | |||
44 | return -ENOENT; | 44 | return -ENOENT; |
45 | } | 45 | } |
46 | 46 | ||
47 | read_lock(¤t->fs->lock); | 47 | spin_lock(¤t->fs->lock); |
48 | path.mnt = mntget(current->fs->root.mnt); | 48 | path.mnt = mntget(current->fs->root.mnt); |
49 | read_unlock(¤t->fs->lock); | 49 | spin_unlock(¤t->fs->lock); |
50 | 50 | ||
51 | path.dentry = d; | 51 | path.dentry = d; |
52 | 52 | ||
@@ -91,9 +91,9 @@ int pohmelfs_path_length(struct pohmelfs_inode *pi) | |||
91 | return -ENOENT; | 91 | return -ENOENT; |
92 | } | 92 | } |
93 | 93 | ||
94 | read_lock(¤t->fs->lock); | 94 | spin_lock(¤t->fs->lock); |
95 | root = dget(current->fs->root.dentry); | 95 | root = dget(current->fs->root.dentry); |
96 | read_unlock(¤t->fs->lock); | 96 | spin_unlock(¤t->fs->lock); |
97 | 97 | ||
98 | spin_lock(&dcache_lock); | 98 | spin_lock(&dcache_lock); |
99 | 99 | ||
diff --git a/drivers/staging/rt2860/usb_main_dev.c b/drivers/staging/rt2860/usb_main_dev.c index a0fe31de0a6..ebf9074a908 100644 --- a/drivers/staging/rt2860/usb_main_dev.c +++ b/drivers/staging/rt2860/usb_main_dev.c | |||
@@ -44,6 +44,7 @@ struct usb_device_id rtusb_usb_id[] = { | |||
44 | {USB_DEVICE(0x07B8, 0x2870)}, /* AboCom */ | 44 | {USB_DEVICE(0x07B8, 0x2870)}, /* AboCom */ |
45 | {USB_DEVICE(0x07B8, 0x2770)}, /* AboCom */ | 45 | {USB_DEVICE(0x07B8, 0x2770)}, /* AboCom */ |
46 | {USB_DEVICE(0x0DF6, 0x0039)}, /* Sitecom 2770 */ | 46 | {USB_DEVICE(0x0DF6, 0x0039)}, /* Sitecom 2770 */ |
47 | {USB_DEVICE(0x0DF6, 0x003F)}, /* Sitecom 2770 */ | ||
47 | {USB_DEVICE(0x083A, 0x7512)}, /* Arcadyan 2770 */ | 48 | {USB_DEVICE(0x083A, 0x7512)}, /* Arcadyan 2770 */ |
48 | {USB_DEVICE(0x0789, 0x0162)}, /* Logitec 2870 */ | 49 | {USB_DEVICE(0x0789, 0x0162)}, /* Logitec 2870 */ |
49 | {USB_DEVICE(0x0789, 0x0163)}, /* Logitec 2870 */ | 50 | {USB_DEVICE(0x0789, 0x0163)}, /* Logitec 2870 */ |
@@ -95,7 +96,8 @@ struct usb_device_id rtusb_usb_id[] = { | |||
95 | {USB_DEVICE(0x050d, 0x815c)}, | 96 | {USB_DEVICE(0x050d, 0x815c)}, |
96 | {USB_DEVICE(0x1482, 0x3C09)}, /* Abocom */ | 97 | {USB_DEVICE(0x1482, 0x3C09)}, /* Abocom */ |
97 | {USB_DEVICE(0x14B2, 0x3C09)}, /* Alpha */ | 98 | {USB_DEVICE(0x14B2, 0x3C09)}, /* Alpha */ |
98 | {USB_DEVICE(0x04E8, 0x2018)}, /* samsung */ | 99 | {USB_DEVICE(0x04E8, 0x2018)}, /* samsung linkstick2 */ |
100 | {USB_DEVICE(0x1690, 0x0740)}, /* Askey */ | ||
99 | {USB_DEVICE(0x5A57, 0x0280)}, /* Zinwell */ | 101 | {USB_DEVICE(0x5A57, 0x0280)}, /* Zinwell */ |
100 | {USB_DEVICE(0x5A57, 0x0282)}, /* Zinwell */ | 102 | {USB_DEVICE(0x5A57, 0x0282)}, /* Zinwell */ |
101 | {USB_DEVICE(0x7392, 0x7718)}, | 103 | {USB_DEVICE(0x7392, 0x7718)}, |
@@ -105,21 +107,34 @@ struct usb_device_id rtusb_usb_id[] = { | |||
105 | {USB_DEVICE(0x1737, 0x0071)}, /* Linksys WUSB600N */ | 107 | {USB_DEVICE(0x1737, 0x0071)}, /* Linksys WUSB600N */ |
106 | {USB_DEVICE(0x0411, 0x00e8)}, /* Buffalo WLI-UC-G300N */ | 108 | {USB_DEVICE(0x0411, 0x00e8)}, /* Buffalo WLI-UC-G300N */ |
107 | {USB_DEVICE(0x050d, 0x815c)}, /* Belkin F5D8053 */ | 109 | {USB_DEVICE(0x050d, 0x815c)}, /* Belkin F5D8053 */ |
110 | {USB_DEVICE(0x100D, 0x9031)}, /* Motorola 2770 */ | ||
108 | #endif /* RT2870 // */ | 111 | #endif /* RT2870 // */ |
109 | #ifdef RT3070 | 112 | #ifdef RT3070 |
110 | {USB_DEVICE(0x148F, 0x3070)}, /* Ralink 3070 */ | 113 | {USB_DEVICE(0x148F, 0x3070)}, /* Ralink 3070 */ |
111 | {USB_DEVICE(0x148F, 0x3071)}, /* Ralink 3071 */ | 114 | {USB_DEVICE(0x148F, 0x3071)}, /* Ralink 3071 */ |
112 | {USB_DEVICE(0x148F, 0x3072)}, /* Ralink 3072 */ | 115 | {USB_DEVICE(0x148F, 0x3072)}, /* Ralink 3072 */ |
113 | {USB_DEVICE(0x0DB0, 0x3820)}, /* Ralink 3070 */ | 116 | {USB_DEVICE(0x0DB0, 0x3820)}, /* Ralink 3070 */ |
117 | {USB_DEVICE(0x0DB0, 0x871C)}, /* Ralink 3070 */ | ||
118 | {USB_DEVICE(0x0DB0, 0x822C)}, /* Ralink 3070 */ | ||
119 | {USB_DEVICE(0x0DB0, 0x871B)}, /* Ralink 3070 */ | ||
120 | {USB_DEVICE(0x0DB0, 0x822B)}, /* Ralink 3070 */ | ||
114 | {USB_DEVICE(0x0DF6, 0x003E)}, /* Sitecom 3070 */ | 121 | {USB_DEVICE(0x0DF6, 0x003E)}, /* Sitecom 3070 */ |
115 | {USB_DEVICE(0x0DF6, 0x0042)}, /* Sitecom 3072 */ | 122 | {USB_DEVICE(0x0DF6, 0x0042)}, /* Sitecom 3072 */ |
123 | {USB_DEVICE(0x0DF6, 0x0048)}, /* Sitecom 3070 */ | ||
124 | {USB_DEVICE(0x0DF6, 0x0047)}, /* Sitecom 3071 */ | ||
116 | {USB_DEVICE(0x14B2, 0x3C12)}, /* AL 3070 */ | 125 | {USB_DEVICE(0x14B2, 0x3C12)}, /* AL 3070 */ |
117 | {USB_DEVICE(0x18C5, 0x0012)}, /* Corega 3070 */ | 126 | {USB_DEVICE(0x18C5, 0x0012)}, /* Corega 3070 */ |
118 | {USB_DEVICE(0x083A, 0x7511)}, /* Arcadyan 3070 */ | 127 | {USB_DEVICE(0x083A, 0x7511)}, /* Arcadyan 3070 */ |
128 | {USB_DEVICE(0x083A, 0xA701)}, /* SMC 3070 */ | ||
129 | {USB_DEVICE(0x083A, 0xA702)}, /* SMC 3072 */ | ||
119 | {USB_DEVICE(0x1740, 0x9703)}, /* EnGenius 3070 */ | 130 | {USB_DEVICE(0x1740, 0x9703)}, /* EnGenius 3070 */ |
120 | {USB_DEVICE(0x1740, 0x9705)}, /* EnGenius 3071 */ | 131 | {USB_DEVICE(0x1740, 0x9705)}, /* EnGenius 3071 */ |
121 | {USB_DEVICE(0x1740, 0x9706)}, /* EnGenius 3072 */ | 132 | {USB_DEVICE(0x1740, 0x9706)}, /* EnGenius 3072 */ |
133 | {USB_DEVICE(0x1740, 0x9707)}, /* EnGenius 3070 */ | ||
134 | {USB_DEVICE(0x1740, 0x9708)}, /* EnGenius 3071 */ | ||
135 | {USB_DEVICE(0x1740, 0x9709)}, /* EnGenius 3072 */ | ||
122 | {USB_DEVICE(0x13D3, 0x3273)}, /* AzureWave 3070 */ | 136 | {USB_DEVICE(0x13D3, 0x3273)}, /* AzureWave 3070 */ |
137 | {USB_DEVICE(0x13D3, 0x3305)}, /* AzureWave 3070*/ | ||
123 | {USB_DEVICE(0x1044, 0x800D)}, /* Gigabyte GN-WB32L 3070 */ | 138 | {USB_DEVICE(0x1044, 0x800D)}, /* Gigabyte GN-WB32L 3070 */ |
124 | {USB_DEVICE(0x2019, 0xAB25)}, /* Planex Communications, Inc. RT3070 */ | 139 | {USB_DEVICE(0x2019, 0xAB25)}, /* Planex Communications, Inc. RT3070 */ |
125 | {USB_DEVICE(0x07B8, 0x3070)}, /* AboCom 3070 */ | 140 | {USB_DEVICE(0x07B8, 0x3070)}, /* AboCom 3070 */ |
@@ -132,14 +147,36 @@ struct usb_device_id rtusb_usb_id[] = { | |||
132 | {USB_DEVICE(0x07D1, 0x3C0D)}, /* D-Link 3070 */ | 147 | {USB_DEVICE(0x07D1, 0x3C0D)}, /* D-Link 3070 */ |
133 | {USB_DEVICE(0x07D1, 0x3C0E)}, /* D-Link 3070 */ | 148 | {USB_DEVICE(0x07D1, 0x3C0E)}, /* D-Link 3070 */ |
134 | {USB_DEVICE(0x07D1, 0x3C0F)}, /* D-Link 3070 */ | 149 | {USB_DEVICE(0x07D1, 0x3C0F)}, /* D-Link 3070 */ |
150 | {USB_DEVICE(0x07D1, 0x3C16)}, /* D-Link 3070 */ | ||
151 | {USB_DEVICE(0x07D1, 0x3C17)}, /* D-Link 8070 */ | ||
135 | {USB_DEVICE(0x1D4D, 0x000C)}, /* Pegatron Corporation 3070 */ | 152 | {USB_DEVICE(0x1D4D, 0x000C)}, /* Pegatron Corporation 3070 */ |
136 | {USB_DEVICE(0x1D4D, 0x000E)}, /* Pegatron Corporation 3070 */ | 153 | {USB_DEVICE(0x1D4D, 0x000E)}, /* Pegatron Corporation 3070 */ |
137 | {USB_DEVICE(0x5A57, 0x5257)}, /* Zinwell 3070 */ | 154 | {USB_DEVICE(0x5A57, 0x5257)}, /* Zinwell 3070 */ |
138 | {USB_DEVICE(0x5A57, 0x0283)}, /* Zinwell 3072 */ | 155 | {USB_DEVICE(0x5A57, 0x0283)}, /* Zinwell 3072 */ |
139 | {USB_DEVICE(0x04BB, 0x0945)}, /* I-O DATA 3072 */ | 156 | {USB_DEVICE(0x04BB, 0x0945)}, /* I-O DATA 3072 */ |
157 | {USB_DEVICE(0x04BB, 0x0947)}, /* I-O DATA 3070 */ | ||
158 | {USB_DEVICE(0x04BB, 0x0948)}, /* I-O DATA 3072 */ | ||
140 | {USB_DEVICE(0x203D, 0x1480)}, /* Encore 3070 */ | 159 | {USB_DEVICE(0x203D, 0x1480)}, /* Encore 3070 */ |
160 | {USB_DEVICE(0x20B8, 0x8888)}, /* PARA INDUSTRIAL 3070 */ | ||
161 | {USB_DEVICE(0x0B05, 0x1784)}, /* Asus 3072 */ | ||
162 | {USB_DEVICE(0x203D, 0x14A9)}, /* Encore 3070*/ | ||
163 | {USB_DEVICE(0x0DB0, 0x899A)}, /* MSI 3070*/ | ||
164 | {USB_DEVICE(0x0DB0, 0x3870)}, /* MSI 3070*/ | ||
165 | {USB_DEVICE(0x0DB0, 0x870A)}, /* MSI 3070*/ | ||
166 | {USB_DEVICE(0x0DB0, 0x6899)}, /* MSI 3070 */ | ||
167 | {USB_DEVICE(0x0DB0, 0x3822)}, /* MSI 3070 */ | ||
168 | {USB_DEVICE(0x0DB0, 0x3871)}, /* MSI 3070 */ | ||
169 | {USB_DEVICE(0x0DB0, 0x871A)}, /* MSI 3070 */ | ||
170 | {USB_DEVICE(0x0DB0, 0x822A)}, /* MSI 3070 */ | ||
171 | {USB_DEVICE(0x0DB0, 0x3821)}, /* Ralink 3070 */ | ||
172 | {USB_DEVICE(0x0DB0, 0x821A)}, /* Ralink 3070 */ | ||
173 | {USB_DEVICE(0x083A, 0xA703)}, /* IO-MAGIC */ | ||
174 | {USB_DEVICE(0x13D3, 0x3307)}, /* Azurewave */ | ||
175 | {USB_DEVICE(0x13D3, 0x3321)}, /* Azurewave */ | ||
176 | {USB_DEVICE(0x07FA, 0x7712)}, /* Edimax */ | ||
177 | {USB_DEVICE(0x0789, 0x0166)}, /* Edimax */ | ||
178 | {USB_DEVICE(0x148F, 0x2070)}, /* Edimax */ | ||
141 | #endif /* RT3070 // */ | 179 | #endif /* RT3070 // */ |
142 | {USB_DEVICE(0x0DF6, 0x003F)}, /* Sitecom WL-608 */ | ||
143 | {USB_DEVICE(0x1737, 0x0077)}, /* Linksys WUSB54GC-EU v3 */ | 180 | {USB_DEVICE(0x1737, 0x0077)}, /* Linksys WUSB54GC-EU v3 */ |
144 | {USB_DEVICE(0x2001, 0x3C09)}, /* D-Link */ | 181 | {USB_DEVICE(0x2001, 0x3C09)}, /* D-Link */ |
145 | {USB_DEVICE(0x2001, 0x3C0A)}, /* D-Link 3072 */ | 182 | {USB_DEVICE(0x2001, 0x3C0A)}, /* D-Link 3072 */ |
diff --git a/drivers/staging/sep/Kconfig b/drivers/staging/sep/Kconfig deleted file mode 100644 index 0a9c39c7f2b..00000000000 --- a/drivers/staging/sep/Kconfig +++ /dev/null | |||
@@ -1,10 +0,0 @@ | |||
1 | config DX_SEP | ||
2 | tristate "Discretix SEP driver" | ||
3 | # depends on MRST | ||
4 | depends on RAR_REGISTER && PCI | ||
5 | default y | ||
6 | help | ||
7 | Discretix SEP driver | ||
8 | |||
9 | If unsure say M. The compiled module will be | ||
10 | called sep_driver.ko | ||
diff --git a/drivers/staging/sep/Makefile b/drivers/staging/sep/Makefile deleted file mode 100644 index 628d5f91941..00000000000 --- a/drivers/staging/sep/Makefile +++ /dev/null | |||
@@ -1,2 +0,0 @@ | |||
1 | obj-$(CONFIG_DX_SEP) := sep_driver.o | ||
2 | |||
diff --git a/drivers/staging/sep/TODO b/drivers/staging/sep/TODO deleted file mode 100644 index ff0e931dab6..00000000000 --- a/drivers/staging/sep/TODO +++ /dev/null | |||
@@ -1,8 +0,0 @@ | |||
1 | Todo's so far (from Alan Cox) | ||
2 | - Fix firmware loading | ||
3 | - Get firmware into firmware git tree | ||
4 | - Review and tidy each algorithm function | ||
5 | - Check whether it can be plugged into any of the kernel crypto API | ||
6 | interfaces | ||
7 | - Do something about the magic shared memory interface and replace it | ||
8 | with something saner (in Linux terms) | ||
diff --git a/drivers/staging/sep/sep_dev.h b/drivers/staging/sep/sep_dev.h deleted file mode 100644 index 9200524bb64..00000000000 --- a/drivers/staging/sep/sep_dev.h +++ /dev/null | |||
@@ -1,110 +0,0 @@ | |||
1 | #ifndef __SEP_DEV_H__ | ||
2 | #define __SEP_DEV_H__ | ||
3 | |||
4 | /* | ||
5 | * | ||
6 | * sep_dev.h - Security Processor Device Structures | ||
7 | * | ||
8 | * Copyright(c) 2009 Intel Corporation. All rights reserved. | ||
9 | * Copyright(c) 2009 Discretix. All rights reserved. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the Free | ||
13 | * Software Foundation; either version 2 of the License, or (at your option) | ||
14 | * any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
19 | * more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License along with | ||
22 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
23 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
24 | * | ||
25 | * CONTACTS: | ||
26 | * | ||
27 | * Alan Cox alan@linux.intel.com | ||
28 | * | ||
29 | */ | ||
30 | |||
31 | struct sep_device { | ||
32 | /* pointer to pci dev */ | ||
33 | struct pci_dev *pdev; | ||
34 | |||
35 | unsigned long in_use; | ||
36 | |||
37 | /* address of the shared memory allocated during init for SEP driver | ||
38 | (coherent alloc) */ | ||
39 | void *shared_addr; | ||
40 | /* the physical address of the shared area */ | ||
41 | dma_addr_t shared_bus; | ||
42 | |||
43 | /* restricted access region (coherent alloc) */ | ||
44 | dma_addr_t rar_bus; | ||
45 | void *rar_addr; | ||
46 | /* firmware regions: cache is at rar_addr */ | ||
47 | unsigned long cache_size; | ||
48 | |||
49 | /* follows the cache */ | ||
50 | dma_addr_t resident_bus; | ||
51 | unsigned long resident_size; | ||
52 | void *resident_addr; | ||
53 | |||
54 | /* start address of the access to the SEP registers from driver */ | ||
55 | void __iomem *reg_addr; | ||
56 | /* transaction counter that coordinates the transactions between SEP and HOST */ | ||
57 | unsigned long send_ct; | ||
58 | /* counter for the messages from sep */ | ||
59 | unsigned long reply_ct; | ||
60 | /* counter for the number of bytes allocated in the pool for the current | ||
61 | transaction */ | ||
62 | unsigned long data_pool_bytes_allocated; | ||
63 | |||
64 | /* array of pointers to the pages that represent input data for the synchronic | ||
65 | DMA action */ | ||
66 | struct page **in_page_array; | ||
67 | |||
68 | /* array of pointers to the pages that represent out data for the synchronic | ||
69 | DMA action */ | ||
70 | struct page **out_page_array; | ||
71 | |||
72 | /* number of pages in the sep_in_page_array */ | ||
73 | unsigned long in_num_pages; | ||
74 | |||
75 | /* number of pages in the sep_out_page_array */ | ||
76 | unsigned long out_num_pages; | ||
77 | |||
78 | /* global data for every flow */ | ||
79 | struct sep_flow_context_t flows[SEP_DRIVER_NUM_FLOWS]; | ||
80 | |||
81 | /* pointer to the workqueue that handles the flow done interrupts */ | ||
82 | struct workqueue_struct *flow_wq; | ||
83 | |||
84 | }; | ||
85 | |||
86 | static struct sep_device *sep_dev; | ||
87 | |||
88 | static inline void sep_write_reg(struct sep_device *dev, int reg, u32 value) | ||
89 | { | ||
90 | void __iomem *addr = dev->reg_addr + reg; | ||
91 | writel(value, addr); | ||
92 | } | ||
93 | |||
94 | static inline u32 sep_read_reg(struct sep_device *dev, int reg) | ||
95 | { | ||
96 | void __iomem *addr = dev->reg_addr + reg; | ||
97 | return readl(addr); | ||
98 | } | ||
99 | |||
100 | /* wait for SRAM write complete(indirect write */ | ||
101 | static inline void sep_wait_sram_write(struct sep_device *dev) | ||
102 | { | ||
103 | u32 reg_val; | ||
104 | do | ||
105 | reg_val = sep_read_reg(dev, HW_SRAM_DATA_READY_REG_ADDR); | ||
106 | while (!(reg_val & 1)); | ||
107 | } | ||
108 | |||
109 | |||
110 | #endif | ||
diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c deleted file mode 100644 index ecbde3467b1..00000000000 --- a/drivers/staging/sep/sep_driver.c +++ /dev/null | |||
@@ -1,2742 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * sep_driver.c - Security Processor Driver main group of functions | ||
4 | * | ||
5 | * Copyright(c) 2009 Intel Corporation. All rights reserved. | ||
6 | * Copyright(c) 2009 Discretix. All rights reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the Free | ||
10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along with | ||
19 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
20 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
21 | * | ||
22 | * CONTACTS: | ||
23 | * | ||
24 | * Mark Allyn mark.a.allyn@intel.com | ||
25 | * | ||
26 | * CHANGES: | ||
27 | * | ||
28 | * 2009.06.26 Initial publish | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #include <linux/init.h> | ||
33 | #include <linux/module.h> | ||
34 | #include <linux/fs.h> | ||
35 | #include <linux/cdev.h> | ||
36 | #include <linux/kdev_t.h> | ||
37 | #include <linux/mutex.h> | ||
38 | #include <linux/sched.h> | ||
39 | #include <linux/mm.h> | ||
40 | #include <linux/poll.h> | ||
41 | #include <linux/wait.h> | ||
42 | #include <linux/pci.h> | ||
43 | #include <linux/firmware.h> | ||
44 | #include <linux/slab.h> | ||
45 | #include <asm/ioctl.h> | ||
46 | #include <linux/ioport.h> | ||
47 | #include <asm/io.h> | ||
48 | #include <linux/interrupt.h> | ||
49 | #include <linux/pagemap.h> | ||
50 | #include <asm/cacheflush.h> | ||
51 | #include "sep_driver_hw_defs.h" | ||
52 | #include "sep_driver_config.h" | ||
53 | #include "sep_driver_api.h" | ||
54 | #include "sep_dev.h" | ||
55 | |||
56 | #if SEP_DRIVER_ARM_DEBUG_MODE | ||
57 | |||
58 | #define CRYS_SEP_ROM_length 0x4000 | ||
59 | #define CRYS_SEP_ROM_start_address 0x8000C000UL | ||
60 | #define CRYS_SEP_ROM_start_address_offset 0xC000UL | ||
61 | #define SEP_ROM_BANK_register 0x80008420UL | ||
62 | #define SEP_ROM_BANK_register_offset 0x8420UL | ||
63 | #define SEP_RAR_IO_MEM_REGION_START_ADDRESS 0x82000000 | ||
64 | |||
65 | /* | ||
66 | * THESE 2 definitions are specific to the board - must be | ||
67 | * defined during integration | ||
68 | */ | ||
69 | #define SEP_RAR_IO_MEM_REGION_START_ADDRESS 0xFF0D0000 | ||
70 | |||
71 | /* 2M size */ | ||
72 | |||
73 | static void sep_load_rom_code(struct sep_device *sep) | ||
74 | { | ||
75 | /* Index variables */ | ||
76 | unsigned long i, k, j; | ||
77 | u32 reg; | ||
78 | u32 error; | ||
79 | u32 warning; | ||
80 | |||
81 | /* Loading ROM from SEP_ROM_image.h file */ | ||
82 | k = sizeof(CRYS_SEP_ROM); | ||
83 | |||
84 | edbg("SEP Driver: DX_CC_TST_SepRomLoader start\n"); | ||
85 | |||
86 | edbg("SEP Driver: k is %lu\n", k); | ||
87 | edbg("SEP Driver: sep->reg_addr is %p\n", sep->reg_addr); | ||
88 | edbg("SEP Driver: CRYS_SEP_ROM_start_address_offset is %p\n", CRYS_SEP_ROM_start_address_offset); | ||
89 | |||
90 | for (i = 0; i < 4; i++) { | ||
91 | /* write bank */ | ||
92 | sep_write_reg(sep, SEP_ROM_BANK_register_offset, i); | ||
93 | |||
94 | for (j = 0; j < CRYS_SEP_ROM_length / 4; j++) { | ||
95 | sep_write_reg(sep, CRYS_SEP_ROM_start_address_offset + 4 * j, CRYS_SEP_ROM[i * 0x1000 + j]); | ||
96 | |||
97 | k = k - 4; | ||
98 | |||
99 | if (k == 0) { | ||
100 | j = CRYS_SEP_ROM_length; | ||
101 | i = 4; | ||
102 | } | ||
103 | } | ||
104 | } | ||
105 | |||
106 | /* reset the SEP */ | ||
107 | sep_write_reg(sep, HW_HOST_SEP_SW_RST_REG_ADDR, 0x1); | ||
108 | |||
109 | /* poll for SEP ROM boot finish */ | ||
110 | do | ||
111 | reg = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); | ||
112 | while (!reg); | ||
113 | |||
114 | edbg("SEP Driver: ROM polling ended\n"); | ||
115 | |||
116 | switch (reg) { | ||
117 | case 0x1: | ||
118 | /* fatal error - read erro status from GPRO */ | ||
119 | error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR); | ||
120 | edbg("SEP Driver: ROM polling case 1\n"); | ||
121 | break; | ||
122 | case 0x4: | ||
123 | /* Cold boot ended successfully */ | ||
124 | case 0x8: | ||
125 | /* Warmboot ended successfully */ | ||
126 | case 0x10: | ||
127 | /* ColdWarm boot ended successfully */ | ||
128 | error = 0; | ||
129 | case 0x2: | ||
130 | /* Boot First Phase ended */ | ||
131 | warning = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR); | ||
132 | case 0x20: | ||
133 | edbg("SEP Driver: ROM polling case %d\n", reg); | ||
134 | break; | ||
135 | } | ||
136 | |||
137 | } | ||
138 | |||
139 | #else | ||
140 | static void sep_load_rom_code(struct sep_device *sep) { } | ||
141 | #endif /* SEP_DRIVER_ARM_DEBUG_MODE */ | ||
142 | |||
143 | |||
144 | |||
145 | /*---------------------------------------- | ||
146 | DEFINES | ||
147 | -----------------------------------------*/ | ||
148 | |||
149 | #define BASE_ADDRESS_FOR_SYSTEM 0xfffc0000 | ||
150 | #define SEP_RAR_IO_MEM_REGION_SIZE 0x40000 | ||
151 | |||
152 | /*-------------------------------------------- | ||
153 | GLOBAL variables | ||
154 | --------------------------------------------*/ | ||
155 | |||
156 | /* debug messages level */ | ||
157 | static int debug; | ||
158 | module_param(debug, int , 0); | ||
159 | MODULE_PARM_DESC(debug, "Flag to enable SEP debug messages"); | ||
160 | |||
161 | /* Keep this a single static object for now to keep the conversion easy */ | ||
162 | |||
163 | static struct sep_device sep_instance; | ||
164 | static struct sep_device *sep_dev = &sep_instance; | ||
165 | |||
166 | /* | ||
167 | mutex for the access to the internals of the sep driver | ||
168 | */ | ||
169 | static DEFINE_MUTEX(sep_mutex); | ||
170 | |||
171 | |||
172 | /* wait queue head (event) of the driver */ | ||
173 | static DECLARE_WAIT_QUEUE_HEAD(sep_event); | ||
174 | |||
175 | /** | ||
176 | * sep_load_firmware - copy firmware cache/resident | ||
177 | * @sep: device we are loading | ||
178 | * | ||
179 | * This functions copies the cache and resident from their source | ||
180 | * location into destination shared memory. | ||
181 | */ | ||
182 | |||
183 | static int sep_load_firmware(struct sep_device *sep) | ||
184 | { | ||
185 | const struct firmware *fw; | ||
186 | char *cache_name = "sep/cache.image.bin"; | ||
187 | char *res_name = "sep/resident.image.bin"; | ||
188 | int error; | ||
189 | |||
190 | edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr); | ||
191 | edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus); | ||
192 | |||
193 | /* load cache */ | ||
194 | error = request_firmware(&fw, cache_name, &sep->pdev->dev); | ||
195 | if (error) { | ||
196 | edbg("SEP Driver:cant request cache fw\n"); | ||
197 | return error; | ||
198 | } | ||
199 | edbg("SEP Driver:cache %08Zx@%p\n", fw->size, (void *) fw->data); | ||
200 | |||
201 | memcpy(sep->rar_addr, (void *)fw->data, fw->size); | ||
202 | sep->cache_size = fw->size; | ||
203 | release_firmware(fw); | ||
204 | |||
205 | sep->resident_bus = sep->rar_bus + sep->cache_size; | ||
206 | sep->resident_addr = sep->rar_addr + sep->cache_size; | ||
207 | |||
208 | /* load resident */ | ||
209 | error = request_firmware(&fw, res_name, &sep->pdev->dev); | ||
210 | if (error) { | ||
211 | edbg("SEP Driver:cant request res fw\n"); | ||
212 | return error; | ||
213 | } | ||
214 | edbg("sep: res %08Zx@%p\n", fw->size, (void *)fw->data); | ||
215 | |||
216 | memcpy(sep->resident_addr, (void *) fw->data, fw->size); | ||
217 | sep->resident_size = fw->size; | ||
218 | release_firmware(fw); | ||
219 | |||
220 | edbg("sep: resident v %p b %08llx cache v %p b %08llx\n", | ||
221 | sep->resident_addr, (unsigned long long)sep->resident_bus, | ||
222 | sep->rar_addr, (unsigned long long)sep->rar_bus); | ||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | MODULE_FIRMWARE("sep/cache.image.bin"); | ||
227 | MODULE_FIRMWARE("sep/resident.image.bin"); | ||
228 | |||
229 | /** | ||
230 | * sep_map_and_alloc_shared_area - allocate shared block | ||
231 | * @sep: security processor | ||
232 | * @size: size of shared area | ||
233 | * | ||
234 | * Allocate a shared buffer in host memory that can be used by both the | ||
235 | * kernel and also the hardware interface via DMA. | ||
236 | */ | ||
237 | |||
238 | static int sep_map_and_alloc_shared_area(struct sep_device *sep, | ||
239 | unsigned long size) | ||
240 | { | ||
241 | /* shared_addr = ioremap_nocache(0xda00000,shared_area_size); */ | ||
242 | sep->shared_addr = dma_alloc_coherent(&sep->pdev->dev, size, | ||
243 | &sep->shared_bus, GFP_KERNEL); | ||
244 | |||
245 | if (!sep->shared_addr) { | ||
246 | edbg("sep_driver :shared memory dma_alloc_coherent failed\n"); | ||
247 | return -ENOMEM; | ||
248 | } | ||
249 | /* set the bus address of the shared area */ | ||
250 | edbg("sep: shared_addr %ld bytes @%p (bus %08llx)\n", | ||
251 | size, sep->shared_addr, (unsigned long long)sep->shared_bus); | ||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | /** | ||
256 | * sep_unmap_and_free_shared_area - free shared block | ||
257 | * @sep: security processor | ||
258 | * | ||
259 | * Free the shared area allocated to the security processor. The | ||
260 | * processor must have finished with this and any final posted | ||
261 | * writes cleared before we do so. | ||
262 | */ | ||
263 | static void sep_unmap_and_free_shared_area(struct sep_device *sep, int size) | ||
264 | { | ||
265 | dma_free_coherent(&sep->pdev->dev, size, | ||
266 | sep->shared_addr, sep->shared_bus); | ||
267 | } | ||
268 | |||
269 | /** | ||
270 | * sep_shared_virt_to_bus - convert bus/virt addresses | ||
271 | * | ||
272 | * Returns the bus address inside the shared area according | ||
273 | * to the virtual address. | ||
274 | */ | ||
275 | |||
276 | static dma_addr_t sep_shared_virt_to_bus(struct sep_device *sep, | ||
277 | void *virt_address) | ||
278 | { | ||
279 | dma_addr_t pa = sep->shared_bus + (virt_address - sep->shared_addr); | ||
280 | edbg("sep: virt to bus b %08llx v %p\n", (unsigned long long) pa, | ||
281 | virt_address); | ||
282 | return pa; | ||
283 | } | ||
284 | |||
285 | /** | ||
286 | * sep_shared_bus_to_virt - convert bus/virt addresses | ||
287 | * | ||
288 | * Returns virtual address inside the shared area according | ||
289 | * to the bus address. | ||
290 | */ | ||
291 | |||
292 | static void *sep_shared_bus_to_virt(struct sep_device *sep, | ||
293 | dma_addr_t bus_address) | ||
294 | { | ||
295 | return sep->shared_addr + (bus_address - sep->shared_bus); | ||
296 | } | ||
297 | |||
298 | |||
299 | /** | ||
300 | * sep_try_open - attempt to open a SEP device | ||
301 | * @sep: device to attempt to open | ||
302 | * | ||
303 | * Atomically attempt to get ownership of a SEP device. | ||
304 | * Returns 1 if the device was opened, 0 on failure. | ||
305 | */ | ||
306 | |||
307 | static int sep_try_open(struct sep_device *sep) | ||
308 | { | ||
309 | if (!test_and_set_bit(0, &sep->in_use)) | ||
310 | return 1; | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | /** | ||
315 | * sep_open - device open method | ||
316 | * @inode: inode of sep device | ||
317 | * @filp: file handle to sep device | ||
318 | * | ||
319 | * Open method for the SEP device. Called when userspace opens | ||
320 | * the SEP device node. Must also release the memory data pool | ||
321 | * allocations. | ||
322 | * | ||
323 | * Returns zero on success otherwise an error code. | ||
324 | */ | ||
325 | |||
326 | static int sep_open(struct inode *inode, struct file *filp) | ||
327 | { | ||
328 | if (sep_dev == NULL) | ||
329 | return -ENODEV; | ||
330 | |||
331 | /* check the blocking mode */ | ||
332 | if (filp->f_flags & O_NDELAY) { | ||
333 | if (sep_try_open(sep_dev) == 0) | ||
334 | return -EAGAIN; | ||
335 | } else | ||
336 | if (wait_event_interruptible(sep_event, sep_try_open(sep_dev)) < 0) | ||
337 | return -EINTR; | ||
338 | |||
339 | /* Bind to the device, we only have one which makes it easy */ | ||
340 | filp->private_data = sep_dev; | ||
341 | /* release data pool allocations */ | ||
342 | sep_dev->data_pool_bytes_allocated = 0; | ||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | |||
347 | /** | ||
348 | * sep_release - close a SEP device | ||
349 | * @inode: inode of SEP device | ||
350 | * @filp: file handle being closed | ||
351 | * | ||
352 | * Called on the final close of a SEP device. As the open protects against | ||
353 | * multiple simultaenous opens that means this method is called when the | ||
354 | * final reference to the open handle is dropped. | ||
355 | */ | ||
356 | |||
357 | static int sep_release(struct inode *inode, struct file *filp) | ||
358 | { | ||
359 | struct sep_device *sep = filp->private_data; | ||
360 | #if 0 /*!SEP_DRIVER_POLLING_MODE */ | ||
361 | /* close IMR */ | ||
362 | sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0x7FFF); | ||
363 | /* release IRQ line */ | ||
364 | free_irq(SEP_DIRVER_IRQ_NUM, sep); | ||
365 | |||
366 | #endif | ||
367 | /* Ensure any blocked open progresses */ | ||
368 | clear_bit(0, &sep->in_use); | ||
369 | wake_up(&sep_event); | ||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | /*--------------------------------------------------------------- | ||
374 | map function - this functions maps the message shared area | ||
375 | -----------------------------------------------------------------*/ | ||
376 | static int sep_mmap(struct file *filp, struct vm_area_struct *vma) | ||
377 | { | ||
378 | dma_addr_t bus_addr; | ||
379 | struct sep_device *sep = filp->private_data; | ||
380 | |||
381 | dbg("-------->SEP Driver: mmap start\n"); | ||
382 | |||
383 | /* check that the size of the mapped range is as the size of the message | ||
384 | shared area */ | ||
385 | if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) { | ||
386 | edbg("SEP Driver mmap requested size is more than allowed\n"); | ||
387 | printk(KERN_WARNING "SEP Driver mmap requested size is more than allowed\n"); | ||
388 | printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_end); | ||
389 | printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_start); | ||
390 | return -EAGAIN; | ||
391 | } | ||
392 | |||
393 | edbg("SEP Driver:sep->shared_addr is %p\n", sep->shared_addr); | ||
394 | |||
395 | /* get bus address */ | ||
396 | bus_addr = sep->shared_bus; | ||
397 | |||
398 | edbg("SEP Driver: phys_addr is %08llx\n", (unsigned long long)bus_addr); | ||
399 | |||
400 | if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) { | ||
401 | edbg("SEP Driver remap_page_range failed\n"); | ||
402 | printk(KERN_WARNING "SEP Driver remap_page_range failed\n"); | ||
403 | return -EAGAIN; | ||
404 | } | ||
405 | |||
406 | dbg("SEP Driver:<-------- mmap end\n"); | ||
407 | |||
408 | return 0; | ||
409 | } | ||
410 | |||
411 | |||
412 | /*----------------------------------------------- | ||
413 | poll function | ||
414 | *----------------------------------------------*/ | ||
415 | static unsigned int sep_poll(struct file *filp, poll_table * wait) | ||
416 | { | ||
417 | unsigned long count; | ||
418 | unsigned int mask = 0; | ||
419 | unsigned long retval = 0; /* flow id */ | ||
420 | struct sep_device *sep = filp->private_data; | ||
421 | |||
422 | dbg("---------->SEP Driver poll: start\n"); | ||
423 | |||
424 | |||
425 | #if SEP_DRIVER_POLLING_MODE | ||
426 | |||
427 | while (sep->send_ct != (retval & 0x7FFFFFFF)) { | ||
428 | retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); | ||
429 | |||
430 | for (count = 0; count < 10 * 4; count += 4) | ||
431 | edbg("Poll Debug Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + count))); | ||
432 | } | ||
433 | |||
434 | sep->reply_ct++; | ||
435 | #else | ||
436 | /* add the event to the polling wait table */ | ||
437 | poll_wait(filp, &sep_event, wait); | ||
438 | |||
439 | #endif | ||
440 | |||
441 | edbg("sep->send_ct is %lu\n", sep->send_ct); | ||
442 | edbg("sep->reply_ct is %lu\n", sep->reply_ct); | ||
443 | |||
444 | /* check if the data is ready */ | ||
445 | if (sep->send_ct == sep->reply_ct) { | ||
446 | for (count = 0; count < 12 * 4; count += 4) | ||
447 | edbg("Sep Mesg Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + count))); | ||
448 | |||
449 | for (count = 0; count < 10 * 4; count += 4) | ||
450 | edbg("Debug Data Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + 0x1800 + count))); | ||
451 | |||
452 | retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); | ||
453 | edbg("retval is %lu\n", retval); | ||
454 | /* check if the this is sep reply or request */ | ||
455 | if (retval >> 31) { | ||
456 | edbg("SEP Driver: sep request in\n"); | ||
457 | /* request */ | ||
458 | mask |= POLLOUT | POLLWRNORM; | ||
459 | } else { | ||
460 | edbg("SEP Driver: sep reply in\n"); | ||
461 | mask |= POLLIN | POLLRDNORM; | ||
462 | } | ||
463 | } | ||
464 | dbg("SEP Driver:<-------- poll exit\n"); | ||
465 | return mask; | ||
466 | } | ||
467 | |||
468 | /** | ||
469 | * sep_time_address - address in SEP memory of time | ||
470 | * @sep: SEP device we want the address from | ||
471 | * | ||
472 | * Return the address of the two dwords in memory used for time | ||
473 | * setting. | ||
474 | */ | ||
475 | |||
476 | static u32 *sep_time_address(struct sep_device *sep) | ||
477 | { | ||
478 | return sep->shared_addr + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES; | ||
479 | } | ||
480 | |||
481 | /** | ||
482 | * sep_set_time - set the SEP time | ||
483 | * @sep: the SEP we are setting the time for | ||
484 | * | ||
485 | * Calculates time and sets it at the predefined address. | ||
486 | * Called with the sep mutex held. | ||
487 | */ | ||
488 | static unsigned long sep_set_time(struct sep_device *sep) | ||
489 | { | ||
490 | struct timeval time; | ||
491 | u32 *time_addr; /* address of time as seen by the kernel */ | ||
492 | |||
493 | |||
494 | dbg("sep:sep_set_time start\n"); | ||
495 | |||
496 | do_gettimeofday(&time); | ||
497 | |||
498 | /* set value in the SYSTEM MEMORY offset */ | ||
499 | time_addr = sep_time_address(sep); | ||
500 | |||
501 | time_addr[0] = SEP_TIME_VAL_TOKEN; | ||
502 | time_addr[1] = time.tv_sec; | ||
503 | |||
504 | edbg("SEP Driver:time.tv_sec is %lu\n", time.tv_sec); | ||
505 | edbg("SEP Driver:time_addr is %p\n", time_addr); | ||
506 | edbg("SEP Driver:sep->shared_addr is %p\n", sep->shared_addr); | ||
507 | |||
508 | return time.tv_sec; | ||
509 | } | ||
510 | |||
511 | /** | ||
512 | * sep_dump_message - dump the message that is pending | ||
513 | * @sep: sep device | ||
514 | * | ||
515 | * Dump out the message pending in the shared message area | ||
516 | */ | ||
517 | |||
518 | static void sep_dump_message(struct sep_device *sep) | ||
519 | { | ||
520 | int count; | ||
521 | for (count = 0; count < 12 * 4; count += 4) | ||
522 | edbg("Word %d of the message is %u\n", count, *((u32 *) (sep->shared_addr + count))); | ||
523 | } | ||
524 | |||
525 | /** | ||
526 | * sep_send_command_handler - kick off a command | ||
527 | * @sep: sep being signalled | ||
528 | * | ||
529 | * This function raises interrupt to SEP that signals that is has a new | ||
530 | * command from the host | ||
531 | */ | ||
532 | |||
533 | static void sep_send_command_handler(struct sep_device *sep) | ||
534 | { | ||
535 | dbg("sep:sep_send_command_handler start\n"); | ||
536 | |||
537 | mutex_lock(&sep_mutex); | ||
538 | sep_set_time(sep); | ||
539 | |||
540 | /* FIXME: flush cache */ | ||
541 | flush_cache_all(); | ||
542 | |||
543 | sep_dump_message(sep); | ||
544 | /* update counter */ | ||
545 | sep->send_ct++; | ||
546 | /* send interrupt to SEP */ | ||
547 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2); | ||
548 | dbg("SEP Driver:<-------- sep_send_command_handler end\n"); | ||
549 | mutex_unlock(&sep_mutex); | ||
550 | return; | ||
551 | } | ||
552 | |||
553 | /** | ||
554 | * sep_send_reply_command_handler - kick off a command reply | ||
555 | * @sep: sep being signalled | ||
556 | * | ||
557 | * This function raises interrupt to SEP that signals that is has a new | ||
558 | * command from the host | ||
559 | */ | ||
560 | |||
561 | static void sep_send_reply_command_handler(struct sep_device *sep) | ||
562 | { | ||
563 | dbg("sep:sep_send_reply_command_handler start\n"); | ||
564 | |||
565 | /* flash cache */ | ||
566 | flush_cache_all(); | ||
567 | |||
568 | sep_dump_message(sep); | ||
569 | |||
570 | mutex_lock(&sep_mutex); | ||
571 | sep->send_ct++; /* update counter */ | ||
572 | /* send the interrupt to SEP */ | ||
573 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, sep->send_ct); | ||
574 | /* update both counters */ | ||
575 | sep->send_ct++; | ||
576 | sep->reply_ct++; | ||
577 | mutex_unlock(&sep_mutex); | ||
578 | dbg("sep: sep_send_reply_command_handler end\n"); | ||
579 | } | ||
580 | |||
581 | /* | ||
582 | This function handles the allocate data pool memory request | ||
583 | This function returns calculates the bus address of the | ||
584 | allocated memory, and the offset of this area from the mapped address. | ||
585 | Therefore, the FVOs in user space can calculate the exact virtual | ||
586 | address of this allocated memory | ||
587 | */ | ||
588 | static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, | ||
589 | unsigned long arg) | ||
590 | { | ||
591 | int error; | ||
592 | struct sep_driver_alloc_t command_args; | ||
593 | |||
594 | dbg("SEP Driver:--------> sep_allocate_data_pool_memory_handler start\n"); | ||
595 | |||
596 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_alloc_t)); | ||
597 | if (error) { | ||
598 | error = -EFAULT; | ||
599 | goto end_function; | ||
600 | } | ||
601 | |||
602 | /* allocate memory */ | ||
603 | if ((sep->data_pool_bytes_allocated + command_args.num_bytes) > SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) { | ||
604 | error = -ENOMEM; | ||
605 | goto end_function; | ||
606 | } | ||
607 | |||
608 | /* set the virtual and bus address */ | ||
609 | command_args.offset = SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep->data_pool_bytes_allocated; | ||
610 | command_args.phys_address = sep->shared_bus + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep->data_pool_bytes_allocated; | ||
611 | |||
612 | /* write the memory back to the user space */ | ||
613 | error = copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_alloc_t)); | ||
614 | if (error) { | ||
615 | error = -EFAULT; | ||
616 | goto end_function; | ||
617 | } | ||
618 | |||
619 | /* set the allocation */ | ||
620 | sep->data_pool_bytes_allocated += command_args.num_bytes; | ||
621 | |||
622 | end_function: | ||
623 | dbg("SEP Driver:<-------- sep_allocate_data_pool_memory_handler end\n"); | ||
624 | return error; | ||
625 | } | ||
626 | |||
627 | /* | ||
628 | This function handles write into allocated data pool command | ||
629 | */ | ||
630 | static int sep_write_into_data_pool_handler(struct sep_device *sep, unsigned long arg) | ||
631 | { | ||
632 | int error; | ||
633 | void *virt_address; | ||
634 | unsigned long va; | ||
635 | unsigned long app_in_address; | ||
636 | unsigned long num_bytes; | ||
637 | void *data_pool_area_addr; | ||
638 | |||
639 | dbg("SEP Driver:--------> sep_write_into_data_pool_handler start\n"); | ||
640 | |||
641 | /* get the application address */ | ||
642 | error = get_user(app_in_address, &(((struct sep_driver_write_t *) arg)->app_address)); | ||
643 | if (error) | ||
644 | goto end_function; | ||
645 | |||
646 | /* get the virtual kernel address address */ | ||
647 | error = get_user(va, &(((struct sep_driver_write_t *) arg)->datapool_address)); | ||
648 | if (error) | ||
649 | goto end_function; | ||
650 | virt_address = (void *)va; | ||
651 | |||
652 | /* get the number of bytes */ | ||
653 | error = get_user(num_bytes, &(((struct sep_driver_write_t *) arg)->num_bytes)); | ||
654 | if (error) | ||
655 | goto end_function; | ||
656 | |||
657 | /* calculate the start of the data pool */ | ||
658 | data_pool_area_addr = sep->shared_addr + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES; | ||
659 | |||
660 | |||
661 | /* check that the range of the virtual kernel address is correct */ | ||
662 | if (virt_address < data_pool_area_addr || virt_address > (data_pool_area_addr + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES)) { | ||
663 | error = -EINVAL; | ||
664 | goto end_function; | ||
665 | } | ||
666 | /* copy the application data */ | ||
667 | error = copy_from_user(virt_address, (void *) app_in_address, num_bytes); | ||
668 | if (error) | ||
669 | error = -EFAULT; | ||
670 | end_function: | ||
671 | dbg("SEP Driver:<-------- sep_write_into_data_pool_handler end\n"); | ||
672 | return error; | ||
673 | } | ||
674 | |||
675 | /* | ||
676 | this function handles the read from data pool command | ||
677 | */ | ||
678 | static int sep_read_from_data_pool_handler(struct sep_device *sep, unsigned long arg) | ||
679 | { | ||
680 | int error; | ||
681 | /* virtual address of dest application buffer */ | ||
682 | unsigned long app_out_address; | ||
683 | /* virtual address of the data pool */ | ||
684 | unsigned long va; | ||
685 | void *virt_address; | ||
686 | unsigned long num_bytes; | ||
687 | void *data_pool_area_addr; | ||
688 | |||
689 | dbg("SEP Driver:--------> sep_read_from_data_pool_handler start\n"); | ||
690 | |||
691 | /* get the application address */ | ||
692 | error = get_user(app_out_address, &(((struct sep_driver_write_t *) arg)->app_address)); | ||
693 | if (error) | ||
694 | goto end_function; | ||
695 | |||
696 | /* get the virtual kernel address address */ | ||
697 | error = get_user(va, &(((struct sep_driver_write_t *) arg)->datapool_address)); | ||
698 | if (error) | ||
699 | goto end_function; | ||
700 | virt_address = (void *)va; | ||
701 | |||
702 | /* get the number of bytes */ | ||
703 | error = get_user(num_bytes, &(((struct sep_driver_write_t *) arg)->num_bytes)); | ||
704 | if (error) | ||
705 | goto end_function; | ||
706 | |||
707 | /* calculate the start of the data pool */ | ||
708 | data_pool_area_addr = sep->shared_addr + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES; | ||
709 | |||
710 | /* FIXME: These are incomplete all over the driver: what about + len | ||
711 | and when doing that also overflows */ | ||
712 | /* check that the range of the virtual kernel address is correct */ | ||
713 | if (virt_address < data_pool_area_addr || virt_address > data_pool_area_addr + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) { | ||
714 | error = -EINVAL; | ||
715 | goto end_function; | ||
716 | } | ||
717 | |||
718 | /* copy the application data */ | ||
719 | error = copy_to_user((void *) app_out_address, virt_address, num_bytes); | ||
720 | if (error) | ||
721 | error = -EFAULT; | ||
722 | end_function: | ||
723 | dbg("SEP Driver:<-------- sep_read_from_data_pool_handler end\n"); | ||
724 | return error; | ||
725 | } | ||
726 | |||
727 | /* | ||
728 | This function releases all the application virtual buffer physical pages, | ||
729 | that were previously locked | ||
730 | */ | ||
731 | static int sep_free_dma_pages(struct page **page_array_ptr, unsigned long num_pages, unsigned long dirtyFlag) | ||
732 | { | ||
733 | unsigned long count; | ||
734 | |||
735 | if (dirtyFlag) { | ||
736 | for (count = 0; count < num_pages; count++) { | ||
737 | /* the out array was written, therefore the data was changed */ | ||
738 | if (!PageReserved(page_array_ptr[count])) | ||
739 | SetPageDirty(page_array_ptr[count]); | ||
740 | page_cache_release(page_array_ptr[count]); | ||
741 | } | ||
742 | } else { | ||
743 | /* free in pages - the data was only read, therefore no update was done | ||
744 | on those pages */ | ||
745 | for (count = 0; count < num_pages; count++) | ||
746 | page_cache_release(page_array_ptr[count]); | ||
747 | } | ||
748 | |||
749 | if (page_array_ptr) | ||
750 | /* free the array */ | ||
751 | kfree(page_array_ptr); | ||
752 | |||
753 | return 0; | ||
754 | } | ||
755 | |||
756 | /* | ||
757 | This function locks all the physical pages of the kernel virtual buffer | ||
758 | and construct a basic lli array, where each entry holds the physical | ||
759 | page address and the size that application data holds in this physical pages | ||
760 | */ | ||
761 | static int sep_lock_kernel_pages(struct sep_device *sep, | ||
762 | unsigned long kernel_virt_addr, | ||
763 | unsigned long data_size, | ||
764 | unsigned long *num_pages_ptr, | ||
765 | struct sep_lli_entry_t **lli_array_ptr, | ||
766 | struct page ***page_array_ptr) | ||
767 | { | ||
768 | int error = 0; | ||
769 | /* the the page of the end address of the user space buffer */ | ||
770 | unsigned long end_page; | ||
771 | /* the page of the start address of the user space buffer */ | ||
772 | unsigned long start_page; | ||
773 | /* the range in pages */ | ||
774 | unsigned long num_pages; | ||
775 | struct sep_lli_entry_t *lli_array; | ||
776 | /* next kernel address to map */ | ||
777 | unsigned long next_kernel_address; | ||
778 | unsigned long count; | ||
779 | |||
780 | dbg("SEP Driver:--------> sep_lock_kernel_pages start\n"); | ||
781 | |||
782 | /* set start and end pages and num pages */ | ||
783 | end_page = (kernel_virt_addr + data_size - 1) >> PAGE_SHIFT; | ||
784 | start_page = kernel_virt_addr >> PAGE_SHIFT; | ||
785 | num_pages = end_page - start_page + 1; | ||
786 | |||
787 | edbg("SEP Driver: kernel_virt_addr is %08lx\n", kernel_virt_addr); | ||
788 | edbg("SEP Driver: data_size is %lu\n", data_size); | ||
789 | edbg("SEP Driver: start_page is %lx\n", start_page); | ||
790 | edbg("SEP Driver: end_page is %lx\n", end_page); | ||
791 | edbg("SEP Driver: num_pages is %lu\n", num_pages); | ||
792 | |||
793 | lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC); | ||
794 | if (!lli_array) { | ||
795 | edbg("SEP Driver: kmalloc for lli_array failed\n"); | ||
796 | error = -ENOMEM; | ||
797 | goto end_function; | ||
798 | } | ||
799 | |||
800 | /* set the start address of the first page - app data may start not at | ||
801 | the beginning of the page */ | ||
802 | lli_array[0].physical_address = (unsigned long) virt_to_phys((unsigned long *) kernel_virt_addr); | ||
803 | |||
804 | /* check that not all the data is in the first page only */ | ||
805 | if ((PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK))) >= data_size) | ||
806 | lli_array[0].block_size = data_size; | ||
807 | else | ||
808 | lli_array[0].block_size = PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK)); | ||
809 | |||
810 | /* debug print */ | ||
811 | dbg("lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", lli_array[0].physical_address, lli_array[0].block_size); | ||
812 | |||
813 | /* advance the address to the start of the next page */ | ||
814 | next_kernel_address = (kernel_virt_addr & PAGE_MASK) + PAGE_SIZE; | ||
815 | |||
816 | /* go from the second page to the prev before last */ | ||
817 | for (count = 1; count < (num_pages - 1); count++) { | ||
818 | lli_array[count].physical_address = (unsigned long) virt_to_phys((unsigned long *) next_kernel_address); | ||
819 | lli_array[count].block_size = PAGE_SIZE; | ||
820 | |||
821 | edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size); | ||
822 | next_kernel_address += PAGE_SIZE; | ||
823 | } | ||
824 | |||
825 | /* if more then 1 pages locked - then update for the last page size needed */ | ||
826 | if (num_pages > 1) { | ||
827 | /* update the address of the last page */ | ||
828 | lli_array[count].physical_address = (unsigned long) virt_to_phys((unsigned long *) next_kernel_address); | ||
829 | |||
830 | /* set the size of the last page */ | ||
831 | lli_array[count].block_size = (kernel_virt_addr + data_size) & (~PAGE_MASK); | ||
832 | |||
833 | if (lli_array[count].block_size == 0) { | ||
834 | dbg("app_virt_addr is %08lx\n", kernel_virt_addr); | ||
835 | dbg("data_size is %lu\n", data_size); | ||
836 | while (1); | ||
837 | } | ||
838 | |||
839 | edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size); | ||
840 | } | ||
841 | /* set output params */ | ||
842 | *lli_array_ptr = lli_array; | ||
843 | *num_pages_ptr = num_pages; | ||
844 | *page_array_ptr = 0; | ||
845 | end_function: | ||
846 | dbg("SEP Driver:<-------- sep_lock_kernel_pages end\n"); | ||
847 | return 0; | ||
848 | } | ||
849 | |||
850 | /* | ||
851 | This function locks all the physical pages of the application virtual buffer | ||
852 | and construct a basic lli array, where each entry holds the physical page | ||
853 | address and the size that application data holds in this physical pages | ||
854 | */ | ||
855 | static int sep_lock_user_pages(struct sep_device *sep, | ||
856 | unsigned long app_virt_addr, | ||
857 | unsigned long data_size, | ||
858 | unsigned long *num_pages_ptr, | ||
859 | struct sep_lli_entry_t **lli_array_ptr, | ||
860 | struct page ***page_array_ptr) | ||
861 | { | ||
862 | int error = 0; | ||
863 | /* the the page of the end address of the user space buffer */ | ||
864 | unsigned long end_page; | ||
865 | /* the page of the start address of the user space buffer */ | ||
866 | unsigned long start_page; | ||
867 | /* the range in pages */ | ||
868 | unsigned long num_pages; | ||
869 | struct page **page_array; | ||
870 | struct sep_lli_entry_t *lli_array; | ||
871 | unsigned long count; | ||
872 | int result; | ||
873 | |||
874 | dbg("SEP Driver:--------> sep_lock_user_pages start\n"); | ||
875 | |||
876 | /* set start and end pages and num pages */ | ||
877 | end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT; | ||
878 | start_page = app_virt_addr >> PAGE_SHIFT; | ||
879 | num_pages = end_page - start_page + 1; | ||
880 | |||
881 | edbg("SEP Driver: app_virt_addr is %08lx\n", app_virt_addr); | ||
882 | edbg("SEP Driver: data_size is %lu\n", data_size); | ||
883 | edbg("SEP Driver: start_page is %lu\n", start_page); | ||
884 | edbg("SEP Driver: end_page is %lu\n", end_page); | ||
885 | edbg("SEP Driver: num_pages is %lu\n", num_pages); | ||
886 | |||
887 | /* allocate array of pages structure pointers */ | ||
888 | page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC); | ||
889 | if (!page_array) { | ||
890 | edbg("SEP Driver: kmalloc for page_array failed\n"); | ||
891 | |||
892 | error = -ENOMEM; | ||
893 | goto end_function; | ||
894 | } | ||
895 | |||
896 | lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC); | ||
897 | if (!lli_array) { | ||
898 | edbg("SEP Driver: kmalloc for lli_array failed\n"); | ||
899 | |||
900 | error = -ENOMEM; | ||
901 | goto end_function_with_error1; | ||
902 | } | ||
903 | |||
904 | /* convert the application virtual address into a set of physical */ | ||
905 | down_read(¤t->mm->mmap_sem); | ||
906 | result = get_user_pages(current, current->mm, app_virt_addr, num_pages, 1, 0, page_array, 0); | ||
907 | up_read(¤t->mm->mmap_sem); | ||
908 | |||
909 | /* check the number of pages locked - if not all then exit with error */ | ||
910 | if (result != num_pages) { | ||
911 | dbg("SEP Driver: not all pages locked by get_user_pages\n"); | ||
912 | |||
913 | error = -ENOMEM; | ||
914 | goto end_function_with_error2; | ||
915 | } | ||
916 | |||
917 | /* flush the cache */ | ||
918 | for (count = 0; count < num_pages; count++) | ||
919 | flush_dcache_page(page_array[count]); | ||
920 | |||
921 | /* set the start address of the first page - app data may start not at | ||
922 | the beginning of the page */ | ||
923 | lli_array[0].physical_address = ((unsigned long) page_to_phys(page_array[0])) + (app_virt_addr & (~PAGE_MASK)); | ||
924 | |||
925 | /* check that not all the data is in the first page only */ | ||
926 | if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size) | ||
927 | lli_array[0].block_size = data_size; | ||
928 | else | ||
929 | lli_array[0].block_size = PAGE_SIZE - (app_virt_addr & (~PAGE_MASK)); | ||
930 | |||
931 | /* debug print */ | ||
932 | dbg("lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", lli_array[0].physical_address, lli_array[0].block_size); | ||
933 | |||
934 | /* go from the second page to the prev before last */ | ||
935 | for (count = 1; count < (num_pages - 1); count++) { | ||
936 | lli_array[count].physical_address = (unsigned long) page_to_phys(page_array[count]); | ||
937 | lli_array[count].block_size = PAGE_SIZE; | ||
938 | |||
939 | edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size); | ||
940 | } | ||
941 | |||
942 | /* if more then 1 pages locked - then update for the last page size needed */ | ||
943 | if (num_pages > 1) { | ||
944 | /* update the address of the last page */ | ||
945 | lli_array[count].physical_address = (unsigned long) page_to_phys(page_array[count]); | ||
946 | |||
947 | /* set the size of the last page */ | ||
948 | lli_array[count].block_size = (app_virt_addr + data_size) & (~PAGE_MASK); | ||
949 | |||
950 | if (lli_array[count].block_size == 0) { | ||
951 | dbg("app_virt_addr is %08lx\n", app_virt_addr); | ||
952 | dbg("data_size is %lu\n", data_size); | ||
953 | while (1); | ||
954 | } | ||
955 | edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", | ||
956 | count, lli_array[count].physical_address, | ||
957 | count, lli_array[count].block_size); | ||
958 | } | ||
959 | |||
960 | /* set output params */ | ||
961 | *lli_array_ptr = lli_array; | ||
962 | *num_pages_ptr = num_pages; | ||
963 | *page_array_ptr = page_array; | ||
964 | goto end_function; | ||
965 | |||
966 | end_function_with_error2: | ||
967 | /* release the cache */ | ||
968 | for (count = 0; count < num_pages; count++) | ||
969 | page_cache_release(page_array[count]); | ||
970 | kfree(lli_array); | ||
971 | end_function_with_error1: | ||
972 | kfree(page_array); | ||
973 | end_function: | ||
974 | dbg("SEP Driver:<-------- sep_lock_user_pages end\n"); | ||
975 | return 0; | ||
976 | } | ||
977 | |||
978 | |||
979 | /* | ||
980 | this function calculates the size of data that can be inserted into the lli | ||
981 | table from this array the condition is that either the table is full | ||
982 | (all etnries are entered), or there are no more entries in the lli array | ||
983 | */ | ||
984 | static unsigned long sep_calculate_lli_table_max_size(struct sep_lli_entry_t *lli_in_array_ptr, unsigned long num_array_entries) | ||
985 | { | ||
986 | unsigned long table_data_size = 0; | ||
987 | unsigned long counter; | ||
988 | |||
989 | /* calculate the data in the out lli table if till we fill the whole | ||
990 | table or till the data has ended */ | ||
991 | for (counter = 0; (counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) && (counter < num_array_entries); counter++) | ||
992 | table_data_size += lli_in_array_ptr[counter].block_size; | ||
993 | return table_data_size; | ||
994 | } | ||
995 | |||
996 | /* | ||
997 | this functions builds ont lli table from the lli_array according to | ||
998 | the given size of data | ||
999 | */ | ||
1000 | static void sep_build_lli_table(struct sep_lli_entry_t *lli_array_ptr, struct sep_lli_entry_t *lli_table_ptr, unsigned long *num_processed_entries_ptr, unsigned long *num_table_entries_ptr, unsigned long table_data_size) | ||
1001 | { | ||
1002 | unsigned long curr_table_data_size; | ||
1003 | /* counter of lli array entry */ | ||
1004 | unsigned long array_counter; | ||
1005 | |||
1006 | dbg("SEP Driver:--------> sep_build_lli_table start\n"); | ||
1007 | |||
1008 | /* init currrent table data size and lli array entry counter */ | ||
1009 | curr_table_data_size = 0; | ||
1010 | array_counter = 0; | ||
1011 | *num_table_entries_ptr = 1; | ||
1012 | |||
1013 | edbg("SEP Driver:table_data_size is %lu\n", table_data_size); | ||
1014 | |||
1015 | /* fill the table till table size reaches the needed amount */ | ||
1016 | while (curr_table_data_size < table_data_size) { | ||
1017 | /* update the number of entries in table */ | ||
1018 | (*num_table_entries_ptr)++; | ||
1019 | |||
1020 | lli_table_ptr->physical_address = lli_array_ptr[array_counter].physical_address; | ||
1021 | lli_table_ptr->block_size = lli_array_ptr[array_counter].block_size; | ||
1022 | curr_table_data_size += lli_table_ptr->block_size; | ||
1023 | |||
1024 | edbg("SEP Driver:lli_table_ptr is %08lx\n", (unsigned long) lli_table_ptr); | ||
1025 | edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address); | ||
1026 | edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size); | ||
1027 | |||
1028 | /* check for overflow of the table data */ | ||
1029 | if (curr_table_data_size > table_data_size) { | ||
1030 | edbg("SEP Driver:curr_table_data_size > table_data_size\n"); | ||
1031 | |||
1032 | /* update the size of block in the table */ | ||
1033 | lli_table_ptr->block_size -= (curr_table_data_size - table_data_size); | ||
1034 | |||
1035 | /* update the physical address in the lli array */ | ||
1036 | lli_array_ptr[array_counter].physical_address += lli_table_ptr->block_size; | ||
1037 | |||
1038 | /* update the block size left in the lli array */ | ||
1039 | lli_array_ptr[array_counter].block_size = (curr_table_data_size - table_data_size); | ||
1040 | } else | ||
1041 | /* advance to the next entry in the lli_array */ | ||
1042 | array_counter++; | ||
1043 | |||
1044 | edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address); | ||
1045 | edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size); | ||
1046 | |||
1047 | /* move to the next entry in table */ | ||
1048 | lli_table_ptr++; | ||
1049 | } | ||
1050 | |||
1051 | /* set the info entry to default */ | ||
1052 | lli_table_ptr->physical_address = 0xffffffff; | ||
1053 | lli_table_ptr->block_size = 0; | ||
1054 | |||
1055 | edbg("SEP Driver:lli_table_ptr is %08lx\n", (unsigned long) lli_table_ptr); | ||
1056 | edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address); | ||
1057 | edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size); | ||
1058 | |||
1059 | /* set the output parameter */ | ||
1060 | *num_processed_entries_ptr += array_counter; | ||
1061 | |||
1062 | edbg("SEP Driver:*num_processed_entries_ptr is %lu\n", *num_processed_entries_ptr); | ||
1063 | dbg("SEP Driver:<-------- sep_build_lli_table end\n"); | ||
1064 | return; | ||
1065 | } | ||
1066 | |||
1067 | /* | ||
1068 | this function goes over the list of the print created tables and | ||
1069 | prints all the data | ||
1070 | */ | ||
1071 | static void sep_debug_print_lli_tables(struct sep_device *sep, struct sep_lli_entry_t *lli_table_ptr, unsigned long num_table_entries, unsigned long table_data_size) | ||
1072 | { | ||
1073 | unsigned long table_count; | ||
1074 | unsigned long entries_count; | ||
1075 | |||
1076 | dbg("SEP Driver:--------> sep_debug_print_lli_tables start\n"); | ||
1077 | |||
1078 | table_count = 1; | ||
1079 | while ((unsigned long) lli_table_ptr != 0xffffffff) { | ||
1080 | edbg("SEP Driver: lli table %08lx, table_data_size is %lu\n", table_count, table_data_size); | ||
1081 | edbg("SEP Driver: num_table_entries is %lu\n", num_table_entries); | ||
1082 | |||
1083 | /* print entries of the table (without info entry) */ | ||
1084 | for (entries_count = 0; entries_count < num_table_entries; entries_count++, lli_table_ptr++) { | ||
1085 | edbg("SEP Driver:lli_table_ptr address is %08lx\n", (unsigned long) lli_table_ptr); | ||
1086 | edbg("SEP Driver:phys address is %08lx block size is %lu\n", lli_table_ptr->physical_address, lli_table_ptr->block_size); | ||
1087 | } | ||
1088 | |||
1089 | /* point to the info entry */ | ||
1090 | lli_table_ptr--; | ||
1091 | |||
1092 | edbg("SEP Driver:phys lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size); | ||
1093 | edbg("SEP Driver:phys lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address); | ||
1094 | |||
1095 | |||
1096 | table_data_size = lli_table_ptr->block_size & 0xffffff; | ||
1097 | num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff; | ||
1098 | lli_table_ptr = (struct sep_lli_entry_t *) | ||
1099 | (lli_table_ptr->physical_address); | ||
1100 | |||
1101 | edbg("SEP Driver:phys table_data_size is %lu num_table_entries is %lu lli_table_ptr is%lu\n", table_data_size, num_table_entries, (unsigned long) lli_table_ptr); | ||
1102 | |||
1103 | if ((unsigned long) lli_table_ptr != 0xffffffff) | ||
1104 | lli_table_ptr = (struct sep_lli_entry_t *) sep_shared_bus_to_virt(sep, (unsigned long) lli_table_ptr); | ||
1105 | |||
1106 | table_count++; | ||
1107 | } | ||
1108 | dbg("SEP Driver:<-------- sep_debug_print_lli_tables end\n"); | ||
1109 | } | ||
1110 | |||
1111 | |||
1112 | /* | ||
1113 | This function prepares only input DMA table for synhronic symmetric | ||
1114 | operations (HASH) | ||
1115 | */ | ||
1116 | static int sep_prepare_input_dma_table(struct sep_device *sep, | ||
1117 | unsigned long app_virt_addr, | ||
1118 | unsigned long data_size, | ||
1119 | unsigned long block_size, | ||
1120 | unsigned long *lli_table_ptr, | ||
1121 | unsigned long *num_entries_ptr, | ||
1122 | unsigned long *table_data_size_ptr, | ||
1123 | bool isKernelVirtualAddress) | ||
1124 | { | ||
1125 | /* pointer to the info entry of the table - the last entry */ | ||
1126 | struct sep_lli_entry_t *info_entry_ptr; | ||
1127 | /* array of pointers ot page */ | ||
1128 | struct sep_lli_entry_t *lli_array_ptr; | ||
1129 | /* points to the first entry to be processed in the lli_in_array */ | ||
1130 | unsigned long current_entry; | ||
1131 | /* num entries in the virtual buffer */ | ||
1132 | unsigned long sep_lli_entries; | ||
1133 | /* lli table pointer */ | ||
1134 | struct sep_lli_entry_t *in_lli_table_ptr; | ||
1135 | /* the total data in one table */ | ||
1136 | unsigned long table_data_size; | ||
1137 | /* number of entries in lli table */ | ||
1138 | unsigned long num_entries_in_table; | ||
1139 | /* next table address */ | ||
1140 | void *lli_table_alloc_addr; | ||
1141 | unsigned long result; | ||
1142 | |||
1143 | dbg("SEP Driver:--------> sep_prepare_input_dma_table start\n"); | ||
1144 | |||
1145 | edbg("SEP Driver:data_size is %lu\n", data_size); | ||
1146 | edbg("SEP Driver:block_size is %lu\n", block_size); | ||
1147 | |||
1148 | /* initialize the pages pointers */ | ||
1149 | sep->in_page_array = 0; | ||
1150 | sep->in_num_pages = 0; | ||
1151 | |||
1152 | if (data_size == 0) { | ||
1153 | /* special case - created 2 entries table with zero data */ | ||
1154 | in_lli_table_ptr = (struct sep_lli_entry_t *) (sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES); | ||
1155 | /* FIXME: Should the entry below not be for _bus */ | ||
1156 | in_lli_table_ptr->physical_address = (unsigned long)sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES; | ||
1157 | in_lli_table_ptr->block_size = 0; | ||
1158 | |||
1159 | in_lli_table_ptr++; | ||
1160 | in_lli_table_ptr->physical_address = 0xFFFFFFFF; | ||
1161 | in_lli_table_ptr->block_size = 0; | ||
1162 | |||
1163 | *lli_table_ptr = sep->shared_bus + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES; | ||
1164 | *num_entries_ptr = 2; | ||
1165 | *table_data_size_ptr = 0; | ||
1166 | |||
1167 | goto end_function; | ||
1168 | } | ||
1169 | |||
1170 | /* check if the pages are in Kernel Virtual Address layout */ | ||
1171 | if (isKernelVirtualAddress == true) | ||
1172 | /* lock the pages of the kernel buffer and translate them to pages */ | ||
1173 | result = sep_lock_kernel_pages(sep, app_virt_addr, data_size, &sep->in_num_pages, &lli_array_ptr, &sep->in_page_array); | ||
1174 | else | ||
1175 | /* lock the pages of the user buffer and translate them to pages */ | ||
1176 | result = sep_lock_user_pages(sep, app_virt_addr, data_size, &sep->in_num_pages, &lli_array_ptr, &sep->in_page_array); | ||
1177 | |||
1178 | if (result) | ||
1179 | return result; | ||
1180 | |||
1181 | edbg("SEP Driver:output sep->in_num_pages is %lu\n", sep->in_num_pages); | ||
1182 | |||
1183 | current_entry = 0; | ||
1184 | info_entry_ptr = 0; | ||
1185 | sep_lli_entries = sep->in_num_pages; | ||
1186 | |||
1187 | /* initiate to point after the message area */ | ||
1188 | lli_table_alloc_addr = sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES; | ||
1189 | |||
1190 | /* loop till all the entries in in array are not processed */ | ||
1191 | while (current_entry < sep_lli_entries) { | ||
1192 | /* set the new input and output tables */ | ||
1193 | in_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr; | ||
1194 | |||
1195 | lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; | ||
1196 | |||
1197 | /* calculate the maximum size of data for input table */ | ||
1198 | table_data_size = sep_calculate_lli_table_max_size(&lli_array_ptr[current_entry], (sep_lli_entries - current_entry)); | ||
1199 | |||
1200 | /* now calculate the table size so that it will be module block size */ | ||
1201 | table_data_size = (table_data_size / block_size) * block_size; | ||
1202 | |||
1203 | edbg("SEP Driver:output table_data_size is %lu\n", table_data_size); | ||
1204 | |||
1205 | /* construct input lli table */ | ||
1206 | sep_build_lli_table(&lli_array_ptr[current_entry], in_lli_table_ptr, ¤t_entry, &num_entries_in_table, table_data_size); | ||
1207 | |||
1208 | if (info_entry_ptr == 0) { | ||
1209 | /* set the output parameters to physical addresses */ | ||
1210 | *lli_table_ptr = sep_shared_virt_to_bus(sep, in_lli_table_ptr); | ||
1211 | *num_entries_ptr = num_entries_in_table; | ||
1212 | *table_data_size_ptr = table_data_size; | ||
1213 | |||
1214 | edbg("SEP Driver:output lli_table_in_ptr is %08lx\n", *lli_table_ptr); | ||
1215 | } else { | ||
1216 | /* update the info entry of the previous in table */ | ||
1217 | info_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, in_lli_table_ptr); | ||
1218 | info_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size); | ||
1219 | } | ||
1220 | |||
1221 | /* save the pointer to the info entry of the current tables */ | ||
1222 | info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1; | ||
1223 | } | ||
1224 | |||
1225 | /* print input tables */ | ||
1226 | sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *) | ||
1227 | sep_shared_bus_to_virt(sep, *lli_table_ptr), *num_entries_ptr, *table_data_size_ptr); | ||
1228 | |||
1229 | /* the array of the pages */ | ||
1230 | kfree(lli_array_ptr); | ||
1231 | end_function: | ||
1232 | dbg("SEP Driver:<-------- sep_prepare_input_dma_table end\n"); | ||
1233 | return 0; | ||
1234 | |||
1235 | } | ||
1236 | |||
1237 | /* | ||
1238 | This function creates the input and output dma tables for | ||
1239 | symmetric operations (AES/DES) according to the block size from LLI arays | ||
1240 | */ | ||
1241 | static int sep_construct_dma_tables_from_lli(struct sep_device *sep, | ||
1242 | struct sep_lli_entry_t *lli_in_array, | ||
1243 | unsigned long sep_in_lli_entries, | ||
1244 | struct sep_lli_entry_t *lli_out_array, | ||
1245 | unsigned long sep_out_lli_entries, | ||
1246 | unsigned long block_size, unsigned long *lli_table_in_ptr, unsigned long *lli_table_out_ptr, unsigned long *in_num_entries_ptr, unsigned long *out_num_entries_ptr, unsigned long *table_data_size_ptr) | ||
1247 | { | ||
1248 | /* points to the area where next lli table can be allocated: keep void * | ||
1249 | as there is pointer scaling to fix otherwise */ | ||
1250 | void *lli_table_alloc_addr; | ||
1251 | /* input lli table */ | ||
1252 | struct sep_lli_entry_t *in_lli_table_ptr; | ||
1253 | /* output lli table */ | ||
1254 | struct sep_lli_entry_t *out_lli_table_ptr; | ||
1255 | /* pointer to the info entry of the table - the last entry */ | ||
1256 | struct sep_lli_entry_t *info_in_entry_ptr; | ||
1257 | /* pointer to the info entry of the table - the last entry */ | ||
1258 | struct sep_lli_entry_t *info_out_entry_ptr; | ||
1259 | /* points to the first entry to be processed in the lli_in_array */ | ||
1260 | unsigned long current_in_entry; | ||
1261 | /* points to the first entry to be processed in the lli_out_array */ | ||
1262 | unsigned long current_out_entry; | ||
1263 | /* max size of the input table */ | ||
1264 | unsigned long in_table_data_size; | ||
1265 | /* max size of the output table */ | ||
1266 | unsigned long out_table_data_size; | ||
1267 | /* flag te signifies if this is the first tables build from the arrays */ | ||
1268 | unsigned long first_table_flag; | ||
1269 | /* the data size that should be in table */ | ||
1270 | unsigned long table_data_size; | ||
1271 | /* number of etnries in the input table */ | ||
1272 | unsigned long num_entries_in_table; | ||
1273 | /* number of etnries in the output table */ | ||
1274 | unsigned long num_entries_out_table; | ||
1275 | |||
1276 | dbg("SEP Driver:--------> sep_construct_dma_tables_from_lli start\n"); | ||
1277 | |||
1278 | /* initiate to pint after the message area */ | ||
1279 | lli_table_alloc_addr = sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES; | ||
1280 | |||
1281 | current_in_entry = 0; | ||
1282 | current_out_entry = 0; | ||
1283 | first_table_flag = 1; | ||
1284 | info_in_entry_ptr = 0; | ||
1285 | info_out_entry_ptr = 0; | ||
1286 | |||
1287 | /* loop till all the entries in in array are not processed */ | ||
1288 | while (current_in_entry < sep_in_lli_entries) { | ||
1289 | /* set the new input and output tables */ | ||
1290 | in_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr; | ||
1291 | |||
1292 | lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; | ||
1293 | |||
1294 | /* set the first output tables */ | ||
1295 | out_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr; | ||
1296 | |||
1297 | lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; | ||
1298 | |||
1299 | /* calculate the maximum size of data for input table */ | ||
1300 | in_table_data_size = sep_calculate_lli_table_max_size(&lli_in_array[current_in_entry], (sep_in_lli_entries - current_in_entry)); | ||
1301 | |||
1302 | /* calculate the maximum size of data for output table */ | ||
1303 | out_table_data_size = sep_calculate_lli_table_max_size(&lli_out_array[current_out_entry], (sep_out_lli_entries - current_out_entry)); | ||
1304 | |||
1305 | edbg("SEP Driver:in_table_data_size is %lu\n", in_table_data_size); | ||
1306 | edbg("SEP Driver:out_table_data_size is %lu\n", out_table_data_size); | ||
1307 | |||
1308 | /* check where the data is smallest */ | ||
1309 | table_data_size = in_table_data_size; | ||
1310 | if (table_data_size > out_table_data_size) | ||
1311 | table_data_size = out_table_data_size; | ||
1312 | |||
1313 | /* now calculate the table size so that it will be module block size */ | ||
1314 | table_data_size = (table_data_size / block_size) * block_size; | ||
1315 | |||
1316 | dbg("SEP Driver:table_data_size is %lu\n", table_data_size); | ||
1317 | |||
1318 | /* construct input lli table */ | ||
1319 | sep_build_lli_table(&lli_in_array[current_in_entry], in_lli_table_ptr, ¤t_in_entry, &num_entries_in_table, table_data_size); | ||
1320 | |||
1321 | /* construct output lli table */ | ||
1322 | sep_build_lli_table(&lli_out_array[current_out_entry], out_lli_table_ptr, ¤t_out_entry, &num_entries_out_table, table_data_size); | ||
1323 | |||
1324 | /* if info entry is null - this is the first table built */ | ||
1325 | if (info_in_entry_ptr == 0) { | ||
1326 | /* set the output parameters to physical addresses */ | ||
1327 | *lli_table_in_ptr = sep_shared_virt_to_bus(sep, in_lli_table_ptr); | ||
1328 | *in_num_entries_ptr = num_entries_in_table; | ||
1329 | *lli_table_out_ptr = sep_shared_virt_to_bus(sep, out_lli_table_ptr); | ||
1330 | *out_num_entries_ptr = num_entries_out_table; | ||
1331 | *table_data_size_ptr = table_data_size; | ||
1332 | |||
1333 | edbg("SEP Driver:output lli_table_in_ptr is %08lx\n", *lli_table_in_ptr); | ||
1334 | edbg("SEP Driver:output lli_table_out_ptr is %08lx\n", *lli_table_out_ptr); | ||
1335 | } else { | ||
1336 | /* update the info entry of the previous in table */ | ||
1337 | info_in_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, in_lli_table_ptr); | ||
1338 | info_in_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size); | ||
1339 | |||
1340 | /* update the info entry of the previous in table */ | ||
1341 | info_out_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, out_lli_table_ptr); | ||
1342 | info_out_entry_ptr->block_size = ((num_entries_out_table) << 24) | (table_data_size); | ||
1343 | } | ||
1344 | |||
1345 | /* save the pointer to the info entry of the current tables */ | ||
1346 | info_in_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1; | ||
1347 | info_out_entry_ptr = out_lli_table_ptr + num_entries_out_table - 1; | ||
1348 | |||
1349 | edbg("SEP Driver:output num_entries_out_table is %lu\n", (unsigned long) num_entries_out_table); | ||
1350 | edbg("SEP Driver:output info_in_entry_ptr is %lu\n", (unsigned long) info_in_entry_ptr); | ||
1351 | edbg("SEP Driver:output info_out_entry_ptr is %lu\n", (unsigned long) info_out_entry_ptr); | ||
1352 | } | ||
1353 | |||
1354 | /* print input tables */ | ||
1355 | sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *) | ||
1356 | sep_shared_bus_to_virt(sep, *lli_table_in_ptr), *in_num_entries_ptr, *table_data_size_ptr); | ||
1357 | /* print output tables */ | ||
1358 | sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *) | ||
1359 | sep_shared_bus_to_virt(sep, *lli_table_out_ptr), *out_num_entries_ptr, *table_data_size_ptr); | ||
1360 | dbg("SEP Driver:<-------- sep_construct_dma_tables_from_lli end\n"); | ||
1361 | return 0; | ||
1362 | } | ||
1363 | |||
1364 | |||
1365 | /* | ||
1366 | This function builds input and output DMA tables for synhronic | ||
1367 | symmetric operations (AES, DES). It also checks that each table | ||
1368 | is of the modular block size | ||
1369 | */ | ||
1370 | static int sep_prepare_input_output_dma_table(struct sep_device *sep, | ||
1371 | unsigned long app_virt_in_addr, | ||
1372 | unsigned long app_virt_out_addr, | ||
1373 | unsigned long data_size, | ||
1374 | unsigned long block_size, | ||
1375 | unsigned long *lli_table_in_ptr, unsigned long *lli_table_out_ptr, unsigned long *in_num_entries_ptr, unsigned long *out_num_entries_ptr, unsigned long *table_data_size_ptr, bool isKernelVirtualAddress) | ||
1376 | { | ||
1377 | /* array of pointers of page */ | ||
1378 | struct sep_lli_entry_t *lli_in_array; | ||
1379 | /* array of pointers of page */ | ||
1380 | struct sep_lli_entry_t *lli_out_array; | ||
1381 | int result = 0; | ||
1382 | |||
1383 | dbg("SEP Driver:--------> sep_prepare_input_output_dma_table start\n"); | ||
1384 | |||
1385 | /* initialize the pages pointers */ | ||
1386 | sep->in_page_array = 0; | ||
1387 | sep->out_page_array = 0; | ||
1388 | |||
1389 | /* check if the pages are in Kernel Virtual Address layout */ | ||
1390 | if (isKernelVirtualAddress == true) { | ||
1391 | /* lock the pages of the kernel buffer and translate them to pages */ | ||
1392 | result = sep_lock_kernel_pages(sep, app_virt_in_addr, data_size, &sep->in_num_pages, &lli_in_array, &sep->in_page_array); | ||
1393 | if (result) { | ||
1394 | edbg("SEP Driver: sep_lock_kernel_pages for input virtual buffer failed\n"); | ||
1395 | goto end_function; | ||
1396 | } | ||
1397 | } else { | ||
1398 | /* lock the pages of the user buffer and translate them to pages */ | ||
1399 | result = sep_lock_user_pages(sep, app_virt_in_addr, data_size, &sep->in_num_pages, &lli_in_array, &sep->in_page_array); | ||
1400 | if (result) { | ||
1401 | edbg("SEP Driver: sep_lock_user_pages for input virtual buffer failed\n"); | ||
1402 | goto end_function; | ||
1403 | } | ||
1404 | } | ||
1405 | |||
1406 | if (isKernelVirtualAddress == true) { | ||
1407 | result = sep_lock_kernel_pages(sep, app_virt_out_addr, data_size, &sep->out_num_pages, &lli_out_array, &sep->out_page_array); | ||
1408 | if (result) { | ||
1409 | edbg("SEP Driver: sep_lock_kernel_pages for output virtual buffer failed\n"); | ||
1410 | goto end_function_with_error1; | ||
1411 | } | ||
1412 | } else { | ||
1413 | result = sep_lock_user_pages(sep, app_virt_out_addr, data_size, &sep->out_num_pages, &lli_out_array, &sep->out_page_array); | ||
1414 | if (result) { | ||
1415 | edbg("SEP Driver: sep_lock_user_pages for output virtual buffer failed\n"); | ||
1416 | goto end_function_with_error1; | ||
1417 | } | ||
1418 | } | ||
1419 | edbg("sep->in_num_pages is %lu\n", sep->in_num_pages); | ||
1420 | edbg("sep->out_num_pages is %lu\n", sep->out_num_pages); | ||
1421 | edbg("SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is %x\n", SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); | ||
1422 | |||
1423 | |||
1424 | /* call the fucntion that creates table from the lli arrays */ | ||
1425 | result = sep_construct_dma_tables_from_lli(sep, lli_in_array, sep->in_num_pages, lli_out_array, sep->out_num_pages, block_size, lli_table_in_ptr, lli_table_out_ptr, in_num_entries_ptr, out_num_entries_ptr, table_data_size_ptr); | ||
1426 | if (result) { | ||
1427 | edbg("SEP Driver: sep_construct_dma_tables_from_lli failed\n"); | ||
1428 | goto end_function_with_error2; | ||
1429 | } | ||
1430 | |||
1431 | /* fall through - free the lli entry arrays */ | ||
1432 | dbg("in_num_entries_ptr is %08lx\n", *in_num_entries_ptr); | ||
1433 | dbg("out_num_entries_ptr is %08lx\n", *out_num_entries_ptr); | ||
1434 | dbg("table_data_size_ptr is %08lx\n", *table_data_size_ptr); | ||
1435 | end_function_with_error2: | ||
1436 | kfree(lli_out_array); | ||
1437 | end_function_with_error1: | ||
1438 | kfree(lli_in_array); | ||
1439 | end_function: | ||
1440 | dbg("SEP Driver:<-------- sep_prepare_input_output_dma_table end result = %d\n", (int) result); | ||
1441 | return result; | ||
1442 | |||
1443 | } | ||
1444 | |||
1445 | /* | ||
1446 | this function handles tha request for creation of the DMA table | ||
1447 | for the synchronic symmetric operations (AES,DES) | ||
1448 | */ | ||
1449 | static int sep_create_sync_dma_tables_handler(struct sep_device *sep, | ||
1450 | unsigned long arg) | ||
1451 | { | ||
1452 | int error; | ||
1453 | /* command arguments */ | ||
1454 | struct sep_driver_build_sync_table_t command_args; | ||
1455 | |||
1456 | dbg("SEP Driver:--------> sep_create_sync_dma_tables_handler start\n"); | ||
1457 | |||
1458 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_sync_table_t)); | ||
1459 | if (error) { | ||
1460 | error = -EFAULT; | ||
1461 | goto end_function; | ||
1462 | } | ||
1463 | |||
1464 | edbg("app_in_address is %08lx\n", command_args.app_in_address); | ||
1465 | edbg("app_out_address is %08lx\n", command_args.app_out_address); | ||
1466 | edbg("data_size is %lu\n", command_args.data_in_size); | ||
1467 | edbg("block_size is %lu\n", command_args.block_size); | ||
1468 | |||
1469 | /* check if we need to build only input table or input/output */ | ||
1470 | if (command_args.app_out_address) | ||
1471 | /* prepare input and output tables */ | ||
1472 | error = sep_prepare_input_output_dma_table(sep, | ||
1473 | command_args.app_in_address, | ||
1474 | command_args.app_out_address, | ||
1475 | command_args.data_in_size, | ||
1476 | command_args.block_size, | ||
1477 | &command_args.in_table_address, | ||
1478 | &command_args.out_table_address, &command_args.in_table_num_entries, &command_args.out_table_num_entries, &command_args.table_data_size, command_args.isKernelVirtualAddress); | ||
1479 | else | ||
1480 | /* prepare input tables */ | ||
1481 | error = sep_prepare_input_dma_table(sep, | ||
1482 | command_args.app_in_address, | ||
1483 | command_args.data_in_size, command_args.block_size, &command_args.in_table_address, &command_args.in_table_num_entries, &command_args.table_data_size, command_args.isKernelVirtualAddress); | ||
1484 | |||
1485 | if (error) | ||
1486 | goto end_function; | ||
1487 | /* copy to user */ | ||
1488 | if (copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_build_sync_table_t))) | ||
1489 | error = -EFAULT; | ||
1490 | end_function: | ||
1491 | dbg("SEP Driver:<-------- sep_create_sync_dma_tables_handler end\n"); | ||
1492 | return error; | ||
1493 | } | ||
1494 | |||
1495 | /* | ||
1496 | this function handles the request for freeing dma table for synhronic actions | ||
1497 | */ | ||
1498 | static int sep_free_dma_table_data_handler(struct sep_device *sep) | ||
1499 | { | ||
1500 | dbg("SEP Driver:--------> sep_free_dma_table_data_handler start\n"); | ||
1501 | |||
1502 | /* free input pages array */ | ||
1503 | sep_free_dma_pages(sep->in_page_array, sep->in_num_pages, 0); | ||
1504 | |||
1505 | /* free output pages array if needed */ | ||
1506 | if (sep->out_page_array) | ||
1507 | sep_free_dma_pages(sep->out_page_array, sep->out_num_pages, 1); | ||
1508 | |||
1509 | /* reset all the values */ | ||
1510 | sep->in_page_array = 0; | ||
1511 | sep->out_page_array = 0; | ||
1512 | sep->in_num_pages = 0; | ||
1513 | sep->out_num_pages = 0; | ||
1514 | dbg("SEP Driver:<-------- sep_free_dma_table_data_handler end\n"); | ||
1515 | return 0; | ||
1516 | } | ||
1517 | |||
1518 | /* | ||
1519 | this function find a space for the new flow dma table | ||
1520 | */ | ||
1521 | static int sep_find_free_flow_dma_table_space(struct sep_device *sep, | ||
1522 | unsigned long **table_address_ptr) | ||
1523 | { | ||
1524 | int error = 0; | ||
1525 | /* pointer to the id field of the flow dma table */ | ||
1526 | unsigned long *start_table_ptr; | ||
1527 | /* Do not make start_addr unsigned long * unless fixing the offset | ||
1528 | computations ! */ | ||
1529 | void *flow_dma_area_start_addr; | ||
1530 | unsigned long *flow_dma_area_end_addr; | ||
1531 | /* maximum table size in words */ | ||
1532 | unsigned long table_size_in_words; | ||
1533 | |||
1534 | /* find the start address of the flow DMA table area */ | ||
1535 | flow_dma_area_start_addr = sep->shared_addr + SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES; | ||
1536 | |||
1537 | /* set end address of the flow table area */ | ||
1538 | flow_dma_area_end_addr = flow_dma_area_start_addr + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES; | ||
1539 | |||
1540 | /* set table size in words */ | ||
1541 | table_size_in_words = SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE * (sizeof(struct sep_lli_entry_t) / sizeof(long)) + 2; | ||
1542 | |||
1543 | /* set the pointer to the start address of DMA area */ | ||
1544 | start_table_ptr = flow_dma_area_start_addr; | ||
1545 | |||
1546 | /* find the space for the next table */ | ||
1547 | while (((*start_table_ptr & 0x7FFFFFFF) != 0) && start_table_ptr < flow_dma_area_end_addr) | ||
1548 | start_table_ptr += table_size_in_words; | ||
1549 | |||
1550 | /* check if we reached the end of floa tables area */ | ||
1551 | if (start_table_ptr >= flow_dma_area_end_addr) | ||
1552 | error = -1; | ||
1553 | else | ||
1554 | *table_address_ptr = start_table_ptr; | ||
1555 | |||
1556 | return error; | ||
1557 | } | ||
1558 | |||
1559 | /* | ||
1560 | This function creates one DMA table for flow and returns its data, | ||
1561 | and pointer to its info entry | ||
1562 | */ | ||
1563 | static int sep_prepare_one_flow_dma_table(struct sep_device *sep, | ||
1564 | unsigned long virt_buff_addr, | ||
1565 | unsigned long virt_buff_size, | ||
1566 | struct sep_lli_entry_t *table_data, | ||
1567 | struct sep_lli_entry_t **info_entry_ptr, | ||
1568 | struct sep_flow_context_t *flow_data_ptr, | ||
1569 | bool isKernelVirtualAddress) | ||
1570 | { | ||
1571 | int error; | ||
1572 | /* the range in pages */ | ||
1573 | unsigned long lli_array_size; | ||
1574 | struct sep_lli_entry_t *lli_array; | ||
1575 | struct sep_lli_entry_t *flow_dma_table_entry_ptr; | ||
1576 | unsigned long *start_dma_table_ptr; | ||
1577 | /* total table data counter */ | ||
1578 | unsigned long dma_table_data_count; | ||
1579 | /* pointer that will keep the pointer to the pages of the virtual buffer */ | ||
1580 | struct page **page_array_ptr; | ||
1581 | unsigned long entry_count; | ||
1582 | |||
1583 | /* find the space for the new table */ | ||
1584 | error = sep_find_free_flow_dma_table_space(sep, &start_dma_table_ptr); | ||
1585 | if (error) | ||
1586 | goto end_function; | ||
1587 | |||
1588 | /* check if the pages are in Kernel Virtual Address layout */ | ||
1589 | if (isKernelVirtualAddress == true) | ||
1590 | /* lock kernel buffer in the memory */ | ||
1591 | error = sep_lock_kernel_pages(sep, virt_buff_addr, virt_buff_size, &lli_array_size, &lli_array, &page_array_ptr); | ||
1592 | else | ||
1593 | /* lock user buffer in the memory */ | ||
1594 | error = sep_lock_user_pages(sep, virt_buff_addr, virt_buff_size, &lli_array_size, &lli_array, &page_array_ptr); | ||
1595 | |||
1596 | if (error) | ||
1597 | goto end_function; | ||
1598 | |||
1599 | /* set the pointer to page array at the beginning of table - this table is | ||
1600 | now considered taken */ | ||
1601 | *start_dma_table_ptr = lli_array_size; | ||
1602 | |||
1603 | /* point to the place of the pages pointers of the table */ | ||
1604 | start_dma_table_ptr++; | ||
1605 | |||
1606 | /* set the pages pointer */ | ||
1607 | *start_dma_table_ptr = (unsigned long) page_array_ptr; | ||
1608 | |||
1609 | /* set the pointer to the first entry */ | ||
1610 | flow_dma_table_entry_ptr = (struct sep_lli_entry_t *) (++start_dma_table_ptr); | ||
1611 | |||
1612 | /* now create the entries for table */ | ||
1613 | for (dma_table_data_count = entry_count = 0; entry_count < lli_array_size; entry_count++) { | ||
1614 | flow_dma_table_entry_ptr->physical_address = lli_array[entry_count].physical_address; | ||
1615 | |||
1616 | flow_dma_table_entry_ptr->block_size = lli_array[entry_count].block_size; | ||
1617 | |||
1618 | /* set the total data of a table */ | ||
1619 | dma_table_data_count += lli_array[entry_count].block_size; | ||
1620 | |||
1621 | flow_dma_table_entry_ptr++; | ||
1622 | } | ||
1623 | |||
1624 | /* set the physical address */ | ||
1625 | table_data->physical_address = virt_to_phys(start_dma_table_ptr); | ||
1626 | |||
1627 | /* set the num_entries and total data size */ | ||
1628 | table_data->block_size = ((lli_array_size + 1) << SEP_NUM_ENTRIES_OFFSET_IN_BITS) | (dma_table_data_count); | ||
1629 | |||
1630 | /* set the info entry */ | ||
1631 | flow_dma_table_entry_ptr->physical_address = 0xffffffff; | ||
1632 | flow_dma_table_entry_ptr->block_size = 0; | ||
1633 | |||
1634 | /* set the pointer to info entry */ | ||
1635 | *info_entry_ptr = flow_dma_table_entry_ptr; | ||
1636 | |||
1637 | /* the array of the lli entries */ | ||
1638 | kfree(lli_array); | ||
1639 | end_function: | ||
1640 | return error; | ||
1641 | } | ||
1642 | |||
1643 | |||
1644 | |||
1645 | /* | ||
1646 | This function creates a list of tables for flow and returns the data for | ||
1647 | the first and last tables of the list | ||
1648 | */ | ||
1649 | static int sep_prepare_flow_dma_tables(struct sep_device *sep, | ||
1650 | unsigned long num_virtual_buffers, | ||
1651 | unsigned long first_buff_addr, struct sep_flow_context_t *flow_data_ptr, struct sep_lli_entry_t *first_table_data_ptr, struct sep_lli_entry_t *last_table_data_ptr, bool isKernelVirtualAddress) | ||
1652 | { | ||
1653 | int error; | ||
1654 | unsigned long virt_buff_addr; | ||
1655 | unsigned long virt_buff_size; | ||
1656 | struct sep_lli_entry_t table_data; | ||
1657 | struct sep_lli_entry_t *info_entry_ptr; | ||
1658 | struct sep_lli_entry_t *prev_info_entry_ptr; | ||
1659 | unsigned long i; | ||
1660 | |||
1661 | /* init vars */ | ||
1662 | error = 0; | ||
1663 | prev_info_entry_ptr = 0; | ||
1664 | |||
1665 | /* init the first table to default */ | ||
1666 | table_data.physical_address = 0xffffffff; | ||
1667 | first_table_data_ptr->physical_address = 0xffffffff; | ||
1668 | table_data.block_size = 0; | ||
1669 | |||
1670 | for (i = 0; i < num_virtual_buffers; i++) { | ||
1671 | /* get the virtual buffer address */ | ||
1672 | error = get_user(virt_buff_addr, &first_buff_addr); | ||
1673 | if (error) | ||
1674 | goto end_function; | ||
1675 | |||
1676 | /* get the virtual buffer size */ | ||
1677 | first_buff_addr++; | ||
1678 | error = get_user(virt_buff_size, &first_buff_addr); | ||
1679 | if (error) | ||
1680 | goto end_function; | ||
1681 | |||
1682 | /* advance the address to point to the next pair of address|size */ | ||
1683 | first_buff_addr++; | ||
1684 | |||
1685 | /* now prepare the one flow LLI table from the data */ | ||
1686 | error = sep_prepare_one_flow_dma_table(sep, virt_buff_addr, virt_buff_size, &table_data, &info_entry_ptr, flow_data_ptr, isKernelVirtualAddress); | ||
1687 | if (error) | ||
1688 | goto end_function; | ||
1689 | |||
1690 | if (i == 0) { | ||
1691 | /* if this is the first table - save it to return to the user | ||
1692 | application */ | ||
1693 | *first_table_data_ptr = table_data; | ||
1694 | |||
1695 | /* set the pointer to info entry */ | ||
1696 | prev_info_entry_ptr = info_entry_ptr; | ||
1697 | } else { | ||
1698 | /* not first table - the previous table info entry should | ||
1699 | be updated */ | ||
1700 | prev_info_entry_ptr->block_size = (0x1 << SEP_INT_FLAG_OFFSET_IN_BITS) | (table_data.block_size); | ||
1701 | |||
1702 | /* set the pointer to info entry */ | ||
1703 | prev_info_entry_ptr = info_entry_ptr; | ||
1704 | } | ||
1705 | } | ||
1706 | |||
1707 | /* set the last table data */ | ||
1708 | *last_table_data_ptr = table_data; | ||
1709 | end_function: | ||
1710 | return error; | ||
1711 | } | ||
1712 | |||
1713 | /* | ||
1714 | this function goes over all the flow tables connected to the given | ||
1715 | table and deallocate them | ||
1716 | */ | ||
1717 | static void sep_deallocated_flow_tables(struct sep_lli_entry_t *first_table_ptr) | ||
1718 | { | ||
1719 | /* id pointer */ | ||
1720 | unsigned long *table_ptr; | ||
1721 | /* end address of the flow dma area */ | ||
1722 | unsigned long num_entries; | ||
1723 | unsigned long num_pages; | ||
1724 | struct page **pages_ptr; | ||
1725 | /* maximum table size in words */ | ||
1726 | struct sep_lli_entry_t *info_entry_ptr; | ||
1727 | |||
1728 | /* set the pointer to the first table */ | ||
1729 | table_ptr = (unsigned long *) first_table_ptr->physical_address; | ||
1730 | |||
1731 | /* set the num of entries */ | ||
1732 | num_entries = (first_table_ptr->block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) | ||
1733 | & SEP_NUM_ENTRIES_MASK; | ||
1734 | |||
1735 | /* go over all the connected tables */ | ||
1736 | while (*table_ptr != 0xffffffff) { | ||
1737 | /* get number of pages */ | ||
1738 | num_pages = *(table_ptr - 2); | ||
1739 | |||
1740 | /* get the pointer to the pages */ | ||
1741 | pages_ptr = (struct page **) (*(table_ptr - 1)); | ||
1742 | |||
1743 | /* free the pages */ | ||
1744 | sep_free_dma_pages(pages_ptr, num_pages, 1); | ||
1745 | |||
1746 | /* goto to the info entry */ | ||
1747 | info_entry_ptr = ((struct sep_lli_entry_t *) table_ptr) + (num_entries - 1); | ||
1748 | |||
1749 | table_ptr = (unsigned long *) info_entry_ptr->physical_address; | ||
1750 | num_entries = (info_entry_ptr->block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK; | ||
1751 | } | ||
1752 | |||
1753 | return; | ||
1754 | } | ||
1755 | |||
1756 | /** | ||
1757 | * sep_find_flow_context - find a flow | ||
1758 | * @sep: the SEP we are working with | ||
1759 | * @flow_id: flow identifier | ||
1760 | * | ||
1761 | * Returns a pointer the matching flow, or NULL if the flow does not | ||
1762 | * exist. | ||
1763 | */ | ||
1764 | |||
1765 | static struct sep_flow_context_t *sep_find_flow_context(struct sep_device *sep, | ||
1766 | unsigned long flow_id) | ||
1767 | { | ||
1768 | int count; | ||
1769 | /* | ||
1770 | * always search for flow with id default first - in case we | ||
1771 | * already started working on the flow there can be no situation | ||
1772 | * when 2 flows are with default flag | ||
1773 | */ | ||
1774 | for (count = 0; count < SEP_DRIVER_NUM_FLOWS; count++) { | ||
1775 | if (sep->flows[count].flow_id == flow_id) | ||
1776 | return &sep->flows[count]; | ||
1777 | } | ||
1778 | return NULL; | ||
1779 | } | ||
1780 | |||
1781 | |||
1782 | /* | ||
1783 | this function handles the request to create the DMA tables for flow | ||
1784 | */ | ||
1785 | static int sep_create_flow_dma_tables_handler(struct sep_device *sep, | ||
1786 | unsigned long arg) | ||
1787 | { | ||
1788 | int error = -ENOENT; | ||
1789 | struct sep_driver_build_flow_table_t command_args; | ||
1790 | /* first table - output */ | ||
1791 | struct sep_lli_entry_t first_table_data; | ||
1792 | /* dma table data */ | ||
1793 | struct sep_lli_entry_t last_table_data; | ||
1794 | /* pointer to the info entry of the previuos DMA table */ | ||
1795 | struct sep_lli_entry_t *prev_info_entry_ptr; | ||
1796 | /* pointer to the flow data strucutre */ | ||
1797 | struct sep_flow_context_t *flow_context_ptr; | ||
1798 | |||
1799 | dbg("SEP Driver:--------> sep_create_flow_dma_tables_handler start\n"); | ||
1800 | |||
1801 | /* init variables */ | ||
1802 | prev_info_entry_ptr = 0; | ||
1803 | first_table_data.physical_address = 0xffffffff; | ||
1804 | |||
1805 | /* find the free structure for flow data */ | ||
1806 | error = -EINVAL; | ||
1807 | flow_context_ptr = sep_find_flow_context(sep, SEP_FREE_FLOW_ID); | ||
1808 | if (flow_context_ptr == NULL) | ||
1809 | goto end_function; | ||
1810 | |||
1811 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_flow_table_t)); | ||
1812 | if (error) { | ||
1813 | error = -EFAULT; | ||
1814 | goto end_function; | ||
1815 | } | ||
1816 | |||
1817 | /* create flow tables */ | ||
1818 | error = sep_prepare_flow_dma_tables(sep, command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress); | ||
1819 | if (error) | ||
1820 | goto end_function_with_error; | ||
1821 | |||
1822 | /* check if flow is static */ | ||
1823 | if (!command_args.flow_type) | ||
1824 | /* point the info entry of the last to the info entry of the first */ | ||
1825 | last_table_data = first_table_data; | ||
1826 | |||
1827 | /* set output params */ | ||
1828 | command_args.first_table_addr = first_table_data.physical_address; | ||
1829 | command_args.first_table_num_entries = ((first_table_data.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK); | ||
1830 | command_args.first_table_data_size = (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK); | ||
1831 | |||
1832 | /* send the parameters to user application */ | ||
1833 | error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_build_flow_table_t)); | ||
1834 | if (error) { | ||
1835 | error = -EFAULT; | ||
1836 | goto end_function_with_error; | ||
1837 | } | ||
1838 | |||
1839 | /* all the flow created - update the flow entry with temp id */ | ||
1840 | flow_context_ptr->flow_id = SEP_TEMP_FLOW_ID; | ||
1841 | |||
1842 | /* set the processing tables data in the context */ | ||
1843 | if (command_args.input_output_flag == SEP_DRIVER_IN_FLAG) | ||
1844 | flow_context_ptr->input_tables_in_process = first_table_data; | ||
1845 | else | ||
1846 | flow_context_ptr->output_tables_in_process = first_table_data; | ||
1847 | |||
1848 | goto end_function; | ||
1849 | |||
1850 | end_function_with_error: | ||
1851 | /* free the allocated tables */ | ||
1852 | sep_deallocated_flow_tables(&first_table_data); | ||
1853 | end_function: | ||
1854 | dbg("SEP Driver:<-------- sep_create_flow_dma_tables_handler end\n"); | ||
1855 | return error; | ||
1856 | } | ||
1857 | |||
1858 | /* | ||
1859 | this function handles add tables to flow | ||
1860 | */ | ||
1861 | static int sep_add_flow_tables_handler(struct sep_device *sep, unsigned long arg) | ||
1862 | { | ||
1863 | int error; | ||
1864 | unsigned long num_entries; | ||
1865 | struct sep_driver_add_flow_table_t command_args; | ||
1866 | struct sep_flow_context_t *flow_context_ptr; | ||
1867 | /* first dma table data */ | ||
1868 | struct sep_lli_entry_t first_table_data; | ||
1869 | /* last dma table data */ | ||
1870 | struct sep_lli_entry_t last_table_data; | ||
1871 | /* pointer to the info entry of the current DMA table */ | ||
1872 | struct sep_lli_entry_t *info_entry_ptr; | ||
1873 | |||
1874 | dbg("SEP Driver:--------> sep_add_flow_tables_handler start\n"); | ||
1875 | |||
1876 | /* get input parameters */ | ||
1877 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_flow_table_t)); | ||
1878 | if (error) { | ||
1879 | error = -EFAULT; | ||
1880 | goto end_function; | ||
1881 | } | ||
1882 | |||
1883 | /* find the flow structure for the flow id */ | ||
1884 | flow_context_ptr = sep_find_flow_context(sep, command_args.flow_id); | ||
1885 | if (flow_context_ptr == NULL) | ||
1886 | goto end_function; | ||
1887 | |||
1888 | /* prepare the flow dma tables */ | ||
1889 | error = sep_prepare_flow_dma_tables(sep, command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress); | ||
1890 | if (error) | ||
1891 | goto end_function_with_error; | ||
1892 | |||
1893 | /* now check if there is already an existing add table for this flow */ | ||
1894 | if (command_args.inputOutputFlag == SEP_DRIVER_IN_FLAG) { | ||
1895 | /* this buffer was for input buffers */ | ||
1896 | if (flow_context_ptr->input_tables_flag) { | ||
1897 | /* add table already exists - add the new tables to the end | ||
1898 | of the previous */ | ||
1899 | num_entries = (flow_context_ptr->last_input_table.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK; | ||
1900 | |||
1901 | info_entry_ptr = (struct sep_lli_entry_t *) | ||
1902 | (flow_context_ptr->last_input_table.physical_address + (sizeof(struct sep_lli_entry_t) * (num_entries - 1))); | ||
1903 | |||
1904 | /* connect to list of tables */ | ||
1905 | *info_entry_ptr = first_table_data; | ||
1906 | |||
1907 | /* set the first table data */ | ||
1908 | first_table_data = flow_context_ptr->first_input_table; | ||
1909 | } else { | ||
1910 | /* set the input flag */ | ||
1911 | flow_context_ptr->input_tables_flag = 1; | ||
1912 | |||
1913 | /* set the first table data */ | ||
1914 | flow_context_ptr->first_input_table = first_table_data; | ||
1915 | } | ||
1916 | /* set the last table data */ | ||
1917 | flow_context_ptr->last_input_table = last_table_data; | ||
1918 | } else { /* this is output tables */ | ||
1919 | |||
1920 | /* this buffer was for input buffers */ | ||
1921 | if (flow_context_ptr->output_tables_flag) { | ||
1922 | /* add table already exists - add the new tables to | ||
1923 | the end of the previous */ | ||
1924 | num_entries = (flow_context_ptr->last_output_table.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK; | ||
1925 | |||
1926 | info_entry_ptr = (struct sep_lli_entry_t *) | ||
1927 | (flow_context_ptr->last_output_table.physical_address + (sizeof(struct sep_lli_entry_t) * (num_entries - 1))); | ||
1928 | |||
1929 | /* connect to list of tables */ | ||
1930 | *info_entry_ptr = first_table_data; | ||
1931 | |||
1932 | /* set the first table data */ | ||
1933 | first_table_data = flow_context_ptr->first_output_table; | ||
1934 | } else { | ||
1935 | /* set the input flag */ | ||
1936 | flow_context_ptr->output_tables_flag = 1; | ||
1937 | |||
1938 | /* set the first table data */ | ||
1939 | flow_context_ptr->first_output_table = first_table_data; | ||
1940 | } | ||
1941 | /* set the last table data */ | ||
1942 | flow_context_ptr->last_output_table = last_table_data; | ||
1943 | } | ||
1944 | |||
1945 | /* set output params */ | ||
1946 | command_args.first_table_addr = first_table_data.physical_address; | ||
1947 | command_args.first_table_num_entries = ((first_table_data.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK); | ||
1948 | command_args.first_table_data_size = (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK); | ||
1949 | |||
1950 | /* send the parameters to user application */ | ||
1951 | error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_add_flow_table_t)); | ||
1952 | if (error) | ||
1953 | error = -EFAULT; | ||
1954 | end_function_with_error: | ||
1955 | /* free the allocated tables */ | ||
1956 | sep_deallocated_flow_tables(&first_table_data); | ||
1957 | end_function: | ||
1958 | dbg("SEP Driver:<-------- sep_add_flow_tables_handler end\n"); | ||
1959 | return error; | ||
1960 | } | ||
1961 | |||
1962 | /* | ||
1963 | this function add the flow add message to the specific flow | ||
1964 | */ | ||
1965 | static int sep_add_flow_tables_message_handler(struct sep_device *sep, unsigned long arg) | ||
1966 | { | ||
1967 | int error; | ||
1968 | struct sep_driver_add_message_t command_args; | ||
1969 | struct sep_flow_context_t *flow_context_ptr; | ||
1970 | |||
1971 | dbg("SEP Driver:--------> sep_add_flow_tables_message_handler start\n"); | ||
1972 | |||
1973 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_message_t)); | ||
1974 | if (error) { | ||
1975 | error = -EFAULT; | ||
1976 | goto end_function; | ||
1977 | } | ||
1978 | |||
1979 | /* check input */ | ||
1980 | if (command_args.message_size_in_bytes > SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES) { | ||
1981 | error = -ENOMEM; | ||
1982 | goto end_function; | ||
1983 | } | ||
1984 | |||
1985 | /* find the flow context */ | ||
1986 | flow_context_ptr = sep_find_flow_context(sep, command_args.flow_id); | ||
1987 | if (flow_context_ptr == NULL) | ||
1988 | goto end_function; | ||
1989 | |||
1990 | /* copy the message into context */ | ||
1991 | flow_context_ptr->message_size_in_bytes = command_args.message_size_in_bytes; | ||
1992 | error = copy_from_user(flow_context_ptr->message, (void *) command_args.message_address, command_args.message_size_in_bytes); | ||
1993 | if (error) | ||
1994 | error = -EFAULT; | ||
1995 | end_function: | ||
1996 | dbg("SEP Driver:<-------- sep_add_flow_tables_message_handler end\n"); | ||
1997 | return error; | ||
1998 | } | ||
1999 | |||
2000 | |||
2001 | /* | ||
2002 | this function returns the bus and virtual addresses of the static pool | ||
2003 | */ | ||
2004 | static int sep_get_static_pool_addr_handler(struct sep_device *sep, unsigned long arg) | ||
2005 | { | ||
2006 | int error; | ||
2007 | struct sep_driver_static_pool_addr_t command_args; | ||
2008 | |||
2009 | dbg("SEP Driver:--------> sep_get_static_pool_addr_handler start\n"); | ||
2010 | |||
2011 | /*prepare the output parameters in the struct */ | ||
2012 | command_args.physical_static_address = sep->shared_bus + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES; | ||
2013 | command_args.virtual_static_address = (unsigned long)sep->shared_addr + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES; | ||
2014 | |||
2015 | edbg("SEP Driver:bus_static_address is %08lx, virtual_static_address %08lx\n", command_args.physical_static_address, command_args.virtual_static_address); | ||
2016 | |||
2017 | /* send the parameters to user application */ | ||
2018 | error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_static_pool_addr_t)); | ||
2019 | if (error) | ||
2020 | error = -EFAULT; | ||
2021 | dbg("SEP Driver:<-------- sep_get_static_pool_addr_handler end\n"); | ||
2022 | return error; | ||
2023 | } | ||
2024 | |||
2025 | /* | ||
2026 | this address gets the offset of the physical address from the start | ||
2027 | of the mapped area | ||
2028 | */ | ||
2029 | static int sep_get_physical_mapped_offset_handler(struct sep_device *sep, unsigned long arg) | ||
2030 | { | ||
2031 | int error; | ||
2032 | struct sep_driver_get_mapped_offset_t command_args; | ||
2033 | |||
2034 | dbg("SEP Driver:--------> sep_get_physical_mapped_offset_handler start\n"); | ||
2035 | |||
2036 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_get_mapped_offset_t)); | ||
2037 | if (error) { | ||
2038 | error = -EFAULT; | ||
2039 | goto end_function; | ||
2040 | } | ||
2041 | |||
2042 | if (command_args.physical_address < sep->shared_bus) { | ||
2043 | error = -EINVAL; | ||
2044 | goto end_function; | ||
2045 | } | ||
2046 | |||
2047 | /*prepare the output parameters in the struct */ | ||
2048 | command_args.offset = command_args.physical_address - sep->shared_bus; | ||
2049 | |||
2050 | edbg("SEP Driver:bus_address is %08lx, offset is %lu\n", command_args.physical_address, command_args.offset); | ||
2051 | |||
2052 | /* send the parameters to user application */ | ||
2053 | error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_get_mapped_offset_t)); | ||
2054 | if (error) | ||
2055 | error = -EFAULT; | ||
2056 | end_function: | ||
2057 | dbg("SEP Driver:<-------- sep_get_physical_mapped_offset_handler end\n"); | ||
2058 | return error; | ||
2059 | } | ||
2060 | |||
2061 | |||
2062 | /* | ||
2063 | ? | ||
2064 | */ | ||
2065 | static int sep_start_handler(struct sep_device *sep) | ||
2066 | { | ||
2067 | unsigned long reg_val; | ||
2068 | unsigned long error = 0; | ||
2069 | |||
2070 | dbg("SEP Driver:--------> sep_start_handler start\n"); | ||
2071 | |||
2072 | /* wait in polling for message from SEP */ | ||
2073 | do | ||
2074 | reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); | ||
2075 | while (!reg_val); | ||
2076 | |||
2077 | /* check the value */ | ||
2078 | if (reg_val == 0x1) | ||
2079 | /* fatal error - read error status from GPRO */ | ||
2080 | error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR); | ||
2081 | dbg("SEP Driver:<-------- sep_start_handler end\n"); | ||
2082 | return error; | ||
2083 | } | ||
2084 | |||
2085 | /* | ||
2086 | this function handles the request for SEP initialization | ||
2087 | */ | ||
2088 | static int sep_init_handler(struct sep_device *sep, unsigned long arg) | ||
2089 | { | ||
2090 | unsigned long message_word; | ||
2091 | unsigned long *message_ptr; | ||
2092 | struct sep_driver_init_t command_args; | ||
2093 | unsigned long counter; | ||
2094 | unsigned long error; | ||
2095 | unsigned long reg_val; | ||
2096 | |||
2097 | dbg("SEP Driver:--------> sep_init_handler start\n"); | ||
2098 | error = 0; | ||
2099 | |||
2100 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_init_t)); | ||
2101 | if (error) { | ||
2102 | error = -EFAULT; | ||
2103 | goto end_function; | ||
2104 | } | ||
2105 | dbg("SEP Driver:--------> sep_init_handler - finished copy_from_user\n"); | ||
2106 | |||
2107 | /* PATCH - configure the DMA to single -burst instead of multi-burst */ | ||
2108 | /*sep_configure_dma_burst(); */ | ||
2109 | |||
2110 | dbg("SEP Driver:--------> sep_init_handler - finished sep_configure_dma_burst \n"); | ||
2111 | |||
2112 | message_ptr = (unsigned long *) command_args.message_addr; | ||
2113 | |||
2114 | /* set the base address of the SRAM */ | ||
2115 | sep_write_reg(sep, HW_SRAM_ADDR_REG_ADDR, HW_CC_SRAM_BASE_ADDRESS); | ||
2116 | |||
2117 | for (counter = 0; counter < command_args.message_size_in_words; counter++, message_ptr++) { | ||
2118 | get_user(message_word, message_ptr); | ||
2119 | /* write data to SRAM */ | ||
2120 | sep_write_reg(sep, HW_SRAM_DATA_REG_ADDR, message_word); | ||
2121 | edbg("SEP Driver:message_word is %lu\n", message_word); | ||
2122 | /* wait for write complete */ | ||
2123 | sep_wait_sram_write(sep); | ||
2124 | } | ||
2125 | dbg("SEP Driver:--------> sep_init_handler - finished getting messages from user space\n"); | ||
2126 | /* signal SEP */ | ||
2127 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x1); | ||
2128 | |||
2129 | do | ||
2130 | reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); | ||
2131 | while (!(reg_val & 0xFFFFFFFD)); | ||
2132 | |||
2133 | dbg("SEP Driver:--------> sep_init_handler - finished waiting for reg_val & 0xFFFFFFFD \n"); | ||
2134 | |||
2135 | /* check the value */ | ||
2136 | if (reg_val == 0x1) { | ||
2137 | edbg("SEP Driver:init failed\n"); | ||
2138 | |||
2139 | error = sep_read_reg(sep, 0x8060); | ||
2140 | edbg("SEP Driver:sw monitor is %lu\n", error); | ||
2141 | |||
2142 | /* fatal error - read erro status from GPRO */ | ||
2143 | error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR); | ||
2144 | edbg("SEP Driver:error is %lu\n", error); | ||
2145 | } | ||
2146 | end_function: | ||
2147 | dbg("SEP Driver:<-------- sep_init_handler end\n"); | ||
2148 | return error; | ||
2149 | |||
2150 | } | ||
2151 | |||
2152 | /* | ||
2153 | this function handles the request cache and resident reallocation | ||
2154 | */ | ||
2155 | static int sep_realloc_cache_resident_handler(struct sep_device *sep, | ||
2156 | unsigned long arg) | ||
2157 | { | ||
2158 | struct sep_driver_realloc_cache_resident_t command_args; | ||
2159 | int error; | ||
2160 | |||
2161 | /* copy cache and resident to the their intended locations */ | ||
2162 | error = sep_load_firmware(sep); | ||
2163 | if (error) | ||
2164 | return error; | ||
2165 | |||
2166 | command_args.new_base_addr = sep->shared_bus; | ||
2167 | |||
2168 | /* find the new base address according to the lowest address between | ||
2169 | cache, resident and shared area */ | ||
2170 | if (sep->resident_bus < command_args.new_base_addr) | ||
2171 | command_args.new_base_addr = sep->resident_bus; | ||
2172 | if (sep->rar_bus < command_args.new_base_addr) | ||
2173 | command_args.new_base_addr = sep->rar_bus; | ||
2174 | |||
2175 | /* set the return parameters */ | ||
2176 | command_args.new_cache_addr = sep->rar_bus; | ||
2177 | command_args.new_resident_addr = sep->resident_bus; | ||
2178 | |||
2179 | /* set the new shared area */ | ||
2180 | command_args.new_shared_area_addr = sep->shared_bus; | ||
2181 | |||
2182 | edbg("SEP Driver:command_args.new_shared_addr is %08llx\n", command_args.new_shared_area_addr); | ||
2183 | edbg("SEP Driver:command_args.new_base_addr is %08llx\n", command_args.new_base_addr); | ||
2184 | edbg("SEP Driver:command_args.new_resident_addr is %08llx\n", command_args.new_resident_addr); | ||
2185 | edbg("SEP Driver:command_args.new_rar_addr is %08llx\n", command_args.new_cache_addr); | ||
2186 | |||
2187 | /* return to user */ | ||
2188 | if (copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_realloc_cache_resident_t))) | ||
2189 | return -EFAULT; | ||
2190 | return 0; | ||
2191 | } | ||
2192 | |||
2193 | /** | ||
2194 | * sep_get_time_handler - time request from user space | ||
2195 | * @sep: sep we are to set the time for | ||
2196 | * @arg: pointer to user space arg buffer | ||
2197 | * | ||
2198 | * This function reports back the time and the address in the SEP | ||
2199 | * shared buffer at which it has been placed. (Do we really need this!!!) | ||
2200 | */ | ||
2201 | |||
2202 | static int sep_get_time_handler(struct sep_device *sep, unsigned long arg) | ||
2203 | { | ||
2204 | struct sep_driver_get_time_t command_args; | ||
2205 | |||
2206 | mutex_lock(&sep_mutex); | ||
2207 | command_args.time_value = sep_set_time(sep); | ||
2208 | command_args.time_physical_address = (unsigned long)sep_time_address(sep); | ||
2209 | mutex_unlock(&sep_mutex); | ||
2210 | if (copy_to_user((void __user *)arg, | ||
2211 | &command_args, sizeof(struct sep_driver_get_time_t))) | ||
2212 | return -EFAULT; | ||
2213 | return 0; | ||
2214 | |||
2215 | } | ||
2216 | |||
2217 | /* | ||
2218 | This API handles the end transaction request | ||
2219 | */ | ||
2220 | static int sep_end_transaction_handler(struct sep_device *sep, unsigned long arg) | ||
2221 | { | ||
2222 | dbg("SEP Driver:--------> sep_end_transaction_handler start\n"); | ||
2223 | |||
2224 | #if 0 /*!SEP_DRIVER_POLLING_MODE */ | ||
2225 | /* close IMR */ | ||
2226 | sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0x7FFF); | ||
2227 | |||
2228 | /* release IRQ line */ | ||
2229 | free_irq(SEP_DIRVER_IRQ_NUM, sep); | ||
2230 | |||
2231 | /* lock the sep mutex */ | ||
2232 | mutex_unlock(&sep_mutex); | ||
2233 | #endif | ||
2234 | |||
2235 | dbg("SEP Driver:<-------- sep_end_transaction_handler end\n"); | ||
2236 | |||
2237 | return 0; | ||
2238 | } | ||
2239 | |||
2240 | |||
2241 | /** | ||
2242 | * sep_set_flow_id_handler - handle flow setting | ||
2243 | * @sep: the SEP we are configuring | ||
2244 | * @flow_id: the flow we are setting | ||
2245 | * | ||
2246 | * This function handler the set flow id command | ||
2247 | */ | ||
2248 | static int sep_set_flow_id_handler(struct sep_device *sep, | ||
2249 | unsigned long flow_id) | ||
2250 | { | ||
2251 | int error = 0; | ||
2252 | struct sep_flow_context_t *flow_data_ptr; | ||
2253 | |||
2254 | /* find the flow data structure that was just used for creating new flow | ||
2255 | - its id should be default */ | ||
2256 | |||
2257 | mutex_lock(&sep_mutex); | ||
2258 | flow_data_ptr = sep_find_flow_context(sep, SEP_TEMP_FLOW_ID); | ||
2259 | if (flow_data_ptr) | ||
2260 | flow_data_ptr->flow_id = flow_id; /* set flow id */ | ||
2261 | else | ||
2262 | error = -EINVAL; | ||
2263 | mutex_unlock(&sep_mutex); | ||
2264 | return error; | ||
2265 | } | ||
2266 | |||
2267 | static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | ||
2268 | { | ||
2269 | int error = 0; | ||
2270 | struct sep_device *sep = filp->private_data; | ||
2271 | |||
2272 | dbg("------------>SEP Driver: ioctl start\n"); | ||
2273 | |||
2274 | edbg("SEP Driver: cmd is %x\n", cmd); | ||
2275 | |||
2276 | switch (cmd) { | ||
2277 | case SEP_IOCSENDSEPCOMMAND: | ||
2278 | /* send command to SEP */ | ||
2279 | sep_send_command_handler(sep); | ||
2280 | edbg("SEP Driver: after sep_send_command_handler\n"); | ||
2281 | break; | ||
2282 | case SEP_IOCSENDSEPRPLYCOMMAND: | ||
2283 | /* send reply command to SEP */ | ||
2284 | sep_send_reply_command_handler(sep); | ||
2285 | break; | ||
2286 | case SEP_IOCALLOCDATAPOLL: | ||
2287 | /* allocate data pool */ | ||
2288 | error = sep_allocate_data_pool_memory_handler(sep, arg); | ||
2289 | break; | ||
2290 | case SEP_IOCWRITEDATAPOLL: | ||
2291 | /* write data into memory pool */ | ||
2292 | error = sep_write_into_data_pool_handler(sep, arg); | ||
2293 | break; | ||
2294 | case SEP_IOCREADDATAPOLL: | ||
2295 | /* read data from data pool into application memory */ | ||
2296 | error = sep_read_from_data_pool_handler(sep, arg); | ||
2297 | break; | ||
2298 | case SEP_IOCCREATESYMDMATABLE: | ||
2299 | /* create dma table for synhronic operation */ | ||
2300 | error = sep_create_sync_dma_tables_handler(sep, arg); | ||
2301 | break; | ||
2302 | case SEP_IOCCREATEFLOWDMATABLE: | ||
2303 | /* create flow dma tables */ | ||
2304 | error = sep_create_flow_dma_tables_handler(sep, arg); | ||
2305 | break; | ||
2306 | case SEP_IOCFREEDMATABLEDATA: | ||
2307 | /* free the pages */ | ||
2308 | error = sep_free_dma_table_data_handler(sep); | ||
2309 | break; | ||
2310 | case SEP_IOCSETFLOWID: | ||
2311 | /* set flow id */ | ||
2312 | error = sep_set_flow_id_handler(sep, (unsigned long)arg); | ||
2313 | break; | ||
2314 | case SEP_IOCADDFLOWTABLE: | ||
2315 | /* add tables to the dynamic flow */ | ||
2316 | error = sep_add_flow_tables_handler(sep, arg); | ||
2317 | break; | ||
2318 | case SEP_IOCADDFLOWMESSAGE: | ||
2319 | /* add message of add tables to flow */ | ||
2320 | error = sep_add_flow_tables_message_handler(sep, arg); | ||
2321 | break; | ||
2322 | case SEP_IOCSEPSTART: | ||
2323 | /* start command to sep */ | ||
2324 | error = sep_start_handler(sep); | ||
2325 | break; | ||
2326 | case SEP_IOCSEPINIT: | ||
2327 | /* init command to sep */ | ||
2328 | error = sep_init_handler(sep, arg); | ||
2329 | break; | ||
2330 | case SEP_IOCGETSTATICPOOLADDR: | ||
2331 | /* get the physical and virtual addresses of the static pool */ | ||
2332 | error = sep_get_static_pool_addr_handler(sep, arg); | ||
2333 | break; | ||
2334 | case SEP_IOCENDTRANSACTION: | ||
2335 | error = sep_end_transaction_handler(sep, arg); | ||
2336 | break; | ||
2337 | case SEP_IOCREALLOCCACHERES: | ||
2338 | error = sep_realloc_cache_resident_handler(sep, arg); | ||
2339 | break; | ||
2340 | case SEP_IOCGETMAPPEDADDROFFSET: | ||
2341 | error = sep_get_physical_mapped_offset_handler(sep, arg); | ||
2342 | break; | ||
2343 | case SEP_IOCGETIME: | ||
2344 | error = sep_get_time_handler(sep, arg); | ||
2345 | break; | ||
2346 | default: | ||
2347 | error = -ENOTTY; | ||
2348 | break; | ||
2349 | } | ||
2350 | dbg("SEP Driver:<-------- ioctl end\n"); | ||
2351 | return error; | ||
2352 | } | ||
2353 | |||
2354 | |||
2355 | |||
2356 | #if !SEP_DRIVER_POLLING_MODE | ||
2357 | |||
2358 | /* handler for flow done interrupt */ | ||
2359 | |||
2360 | static void sep_flow_done_handler(struct work_struct *work) | ||
2361 | { | ||
2362 | struct sep_flow_context_t *flow_data_ptr; | ||
2363 | |||
2364 | /* obtain the mutex */ | ||
2365 | mutex_lock(&sep_mutex); | ||
2366 | |||
2367 | /* get the pointer to context */ | ||
2368 | flow_data_ptr = (struct sep_flow_context_t *) work; | ||
2369 | |||
2370 | /* free all the current input tables in sep */ | ||
2371 | sep_deallocated_flow_tables(&flow_data_ptr->input_tables_in_process); | ||
2372 | |||
2373 | /* free all the current tables output tables in SEP (if needed) */ | ||
2374 | if (flow_data_ptr->output_tables_in_process.physical_address != 0xffffffff) | ||
2375 | sep_deallocated_flow_tables(&flow_data_ptr->output_tables_in_process); | ||
2376 | |||
2377 | /* check if we have additional tables to be sent to SEP only input | ||
2378 | flag may be checked */ | ||
2379 | if (flow_data_ptr->input_tables_flag) { | ||
2380 | /* copy the message to the shared RAM and signal SEP */ | ||
2381 | memcpy((void *) flow_data_ptr->message, (void *) sep->shared_addr, flow_data_ptr->message_size_in_bytes); | ||
2382 | |||
2383 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, 0x2); | ||
2384 | } | ||
2385 | mutex_unlock(&sep_mutex); | ||
2386 | } | ||
2387 | /* | ||
2388 | interrupt handler function | ||
2389 | */ | ||
2390 | static irqreturn_t sep_inthandler(int irq, void *dev_id) | ||
2391 | { | ||
2392 | irqreturn_t int_error; | ||
2393 | unsigned long reg_val; | ||
2394 | unsigned long flow_id; | ||
2395 | struct sep_flow_context_t *flow_context_ptr; | ||
2396 | struct sep_device *sep = dev_id; | ||
2397 | |||
2398 | int_error = IRQ_HANDLED; | ||
2399 | |||
2400 | /* read the IRR register to check if this is SEP interrupt */ | ||
2401 | reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR); | ||
2402 | edbg("SEP Interrupt - reg is %08lx\n", reg_val); | ||
2403 | |||
2404 | /* check if this is the flow interrupt */ | ||
2405 | if (0 /*reg_val & (0x1 << 11) */ ) { | ||
2406 | /* read GPRO to find out the which flow is done */ | ||
2407 | flow_id = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR); | ||
2408 | |||
2409 | /* find the contex of the flow */ | ||
2410 | flow_context_ptr = sep_find_flow_context(sep, flow_id >> 28); | ||
2411 | if (flow_context_ptr == NULL) | ||
2412 | goto end_function_with_error; | ||
2413 | |||
2414 | /* queue the work */ | ||
2415 | INIT_WORK(&flow_context_ptr->flow_wq, sep_flow_done_handler); | ||
2416 | queue_work(sep->flow_wq, &flow_context_ptr->flow_wq); | ||
2417 | |||
2418 | } else { | ||
2419 | /* check if this is reply interrupt from SEP */ | ||
2420 | if (reg_val & (0x1 << 13)) { | ||
2421 | /* update the counter of reply messages */ | ||
2422 | sep->reply_ct++; | ||
2423 | /* wake up the waiting process */ | ||
2424 | wake_up(&sep_event); | ||
2425 | } else { | ||
2426 | int_error = IRQ_NONE; | ||
2427 | goto end_function; | ||
2428 | } | ||
2429 | } | ||
2430 | end_function_with_error: | ||
2431 | /* clear the interrupt */ | ||
2432 | sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, reg_val); | ||
2433 | end_function: | ||
2434 | return int_error; | ||
2435 | } | ||
2436 | |||
2437 | #endif | ||
2438 | |||
2439 | |||
2440 | |||
2441 | #if 0 | ||
2442 | |||
2443 | static void sep_wait_busy(struct sep_device *sep) | ||
2444 | { | ||
2445 | u32 reg; | ||
2446 | |||
2447 | do { | ||
2448 | reg = sep_read_reg(sep, HW_HOST_SEP_BUSY_REG_ADDR); | ||
2449 | } while (reg); | ||
2450 | } | ||
2451 | |||
2452 | /* | ||
2453 | PATCH for configuring the DMA to single burst instead of multi-burst | ||
2454 | */ | ||
2455 | static void sep_configure_dma_burst(struct sep_device *sep) | ||
2456 | { | ||
2457 | #define HW_AHB_RD_WR_BURSTS_REG_ADDR 0x0E10UL | ||
2458 | |||
2459 | dbg("SEP Driver:<-------- sep_configure_dma_burst start \n"); | ||
2460 | |||
2461 | /* request access to registers from SEP */ | ||
2462 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2); | ||
2463 | |||
2464 | dbg("SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (write reg) \n"); | ||
2465 | |||
2466 | sep_wait_busy(sep); | ||
2467 | |||
2468 | dbg("SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (while(revVal) wait loop) \n"); | ||
2469 | |||
2470 | /* set the DMA burst register to single burst */ | ||
2471 | sep_write_reg(sep, HW_AHB_RD_WR_BURSTS_REG_ADDR, 0x0UL); | ||
2472 | |||
2473 | /* release the sep busy */ | ||
2474 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x0UL); | ||
2475 | sep_wait_busy(sep); | ||
2476 | |||
2477 | dbg("SEP Driver:<-------- sep_configure_dma_burst done \n"); | ||
2478 | |||
2479 | } | ||
2480 | |||
2481 | #endif | ||
2482 | |||
2483 | /* | ||
2484 | Function that is activated on the successful probe of the SEP device | ||
2485 | */ | ||
2486 | static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | ||
2487 | { | ||
2488 | int error = 0; | ||
2489 | struct sep_device *sep; | ||
2490 | int counter; | ||
2491 | int size; /* size of memory for allocation */ | ||
2492 | |||
2493 | edbg("Sep pci probe starting\n"); | ||
2494 | if (sep_dev != NULL) { | ||
2495 | dev_warn(&pdev->dev, "only one SEP supported.\n"); | ||
2496 | return -EBUSY; | ||
2497 | } | ||
2498 | |||
2499 | /* enable the device */ | ||
2500 | error = pci_enable_device(pdev); | ||
2501 | if (error) { | ||
2502 | edbg("error enabling pci device\n"); | ||
2503 | goto end_function; | ||
2504 | } | ||
2505 | |||
2506 | /* set the pci dev pointer */ | ||
2507 | sep_dev = &sep_instance; | ||
2508 | sep = &sep_instance; | ||
2509 | |||
2510 | edbg("sep->shared_addr = %p\n", sep->shared_addr); | ||
2511 | /* transaction counter that coordinates the transactions between SEP | ||
2512 | and HOST */ | ||
2513 | sep->send_ct = 0; | ||
2514 | /* counter for the messages from sep */ | ||
2515 | sep->reply_ct = 0; | ||
2516 | /* counter for the number of bytes allocated in the pool | ||
2517 | for the current transaction */ | ||
2518 | sep->data_pool_bytes_allocated = 0; | ||
2519 | |||
2520 | /* calculate the total size for allocation */ | ||
2521 | size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + | ||
2522 | SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES; | ||
2523 | |||
2524 | /* allocate the shared area */ | ||
2525 | if (sep_map_and_alloc_shared_area(sep, size)) { | ||
2526 | error = -ENOMEM; | ||
2527 | /* allocation failed */ | ||
2528 | goto end_function_error; | ||
2529 | } | ||
2530 | /* now set the memory regions */ | ||
2531 | #if (SEP_DRIVER_RECONFIG_MESSAGE_AREA == 1) | ||
2532 | /* Note: this test section will need moving before it could ever | ||
2533 | work as the registers are not yet mapped ! */ | ||
2534 | /* send the new SHARED MESSAGE AREA to the SEP */ | ||
2535 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus); | ||
2536 | |||
2537 | /* poll for SEP response */ | ||
2538 | retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); | ||
2539 | while (retval != 0xffffffff && retval != sep->shared_bus) | ||
2540 | retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); | ||
2541 | |||
2542 | /* check the return value (register) */ | ||
2543 | if (retval != sep->shared_bus) { | ||
2544 | error = -ENOMEM; | ||
2545 | goto end_function_deallocate_sep_shared_area; | ||
2546 | } | ||
2547 | #endif | ||
2548 | /* init the flow contextes */ | ||
2549 | for (counter = 0; counter < SEP_DRIVER_NUM_FLOWS; counter++) | ||
2550 | sep->flows[counter].flow_id = SEP_FREE_FLOW_ID; | ||
2551 | |||
2552 | sep->flow_wq = create_singlethread_workqueue("sepflowwq"); | ||
2553 | if (sep->flow_wq == NULL) { | ||
2554 | error = -ENOMEM; | ||
2555 | edbg("sep_driver:flow queue creation failed\n"); | ||
2556 | goto end_function_deallocate_sep_shared_area; | ||
2557 | } | ||
2558 | edbg("SEP Driver: create flow workqueue \n"); | ||
2559 | sep->pdev = pci_dev_get(pdev); | ||
2560 | |||
2561 | sep->reg_addr = pci_ioremap_bar(pdev, 0); | ||
2562 | if (!sep->reg_addr) { | ||
2563 | edbg("sep: ioremap of registers failed.\n"); | ||
2564 | goto end_function_deallocate_sep_shared_area; | ||
2565 | } | ||
2566 | edbg("SEP Driver:reg_addr is %p\n", sep->reg_addr); | ||
2567 | |||
2568 | /* load the rom code */ | ||
2569 | sep_load_rom_code(sep); | ||
2570 | |||
2571 | /* set up system base address and shared memory location */ | ||
2572 | sep->rar_addr = dma_alloc_coherent(&sep->pdev->dev, | ||
2573 | 2 * SEP_RAR_IO_MEM_REGION_SIZE, | ||
2574 | &sep->rar_bus, GFP_KERNEL); | ||
2575 | |||
2576 | if (!sep->rar_addr) { | ||
2577 | edbg("SEP Driver:can't allocate rar\n"); | ||
2578 | goto end_function_uniomap; | ||
2579 | } | ||
2580 | |||
2581 | |||
2582 | edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus); | ||
2583 | edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr); | ||
2584 | |||
2585 | #if !SEP_DRIVER_POLLING_MODE | ||
2586 | |||
2587 | edbg("SEP Driver: about to write IMR and ICR REG_ADDR\n"); | ||
2588 | |||
2589 | /* clear ICR register */ | ||
2590 | sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); | ||
2591 | |||
2592 | /* set the IMR register - open only GPR 2 */ | ||
2593 | sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); | ||
2594 | |||
2595 | edbg("SEP Driver: about to call request_irq\n"); | ||
2596 | /* get the interrupt line */ | ||
2597 | error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED, "sep_driver", sep); | ||
2598 | if (error) | ||
2599 | goto end_function_free_res; | ||
2600 | return 0; | ||
2601 | edbg("SEP Driver: about to write IMR REG_ADDR"); | ||
2602 | |||
2603 | /* set the IMR register - open only GPR 2 */ | ||
2604 | sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); | ||
2605 | |||
2606 | end_function_free_res: | ||
2607 | dma_free_coherent(&sep->pdev->dev, 2 * SEP_RAR_IO_MEM_REGION_SIZE, | ||
2608 | sep->rar_addr, sep->rar_bus); | ||
2609 | #endif /* SEP_DRIVER_POLLING_MODE */ | ||
2610 | end_function_uniomap: | ||
2611 | iounmap(sep->reg_addr); | ||
2612 | end_function_deallocate_sep_shared_area: | ||
2613 | /* de-allocate shared area */ | ||
2614 | sep_unmap_and_free_shared_area(sep, size); | ||
2615 | end_function_error: | ||
2616 | sep_dev = NULL; | ||
2617 | end_function: | ||
2618 | return error; | ||
2619 | } | ||
2620 | |||
2621 | static const struct pci_device_id sep_pci_id_tbl[] = { | ||
2622 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080c)}, | ||
2623 | {0} | ||
2624 | }; | ||
2625 | |||
2626 | MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl); | ||
2627 | |||
2628 | /* field for registering driver to PCI device */ | ||
2629 | static struct pci_driver sep_pci_driver = { | ||
2630 | .name = "sep_sec_driver", | ||
2631 | .id_table = sep_pci_id_tbl, | ||
2632 | .probe = sep_probe | ||
2633 | /* FIXME: remove handler */ | ||
2634 | }; | ||
2635 | |||
2636 | /* major and minor device numbers */ | ||
2637 | static dev_t sep_devno; | ||
2638 | |||
2639 | /* the files operations structure of the driver */ | ||
2640 | static struct file_operations sep_file_operations = { | ||
2641 | .owner = THIS_MODULE, | ||
2642 | .unlocked_ioctl = sep_ioctl, | ||
2643 | .poll = sep_poll, | ||
2644 | .open = sep_open, | ||
2645 | .release = sep_release, | ||
2646 | .mmap = sep_mmap, | ||
2647 | }; | ||
2648 | |||
2649 | |||
2650 | /* cdev struct of the driver */ | ||
2651 | static struct cdev sep_cdev; | ||
2652 | |||
2653 | /* | ||
2654 | this function registers the driver to the file system | ||
2655 | */ | ||
2656 | static int sep_register_driver_to_fs(void) | ||
2657 | { | ||
2658 | int ret_val = alloc_chrdev_region(&sep_devno, 0, 1, "sep_sec_driver"); | ||
2659 | if (ret_val) { | ||
2660 | edbg("sep: major number allocation failed, retval is %d\n", | ||
2661 | ret_val); | ||
2662 | return ret_val; | ||
2663 | } | ||
2664 | /* init cdev */ | ||
2665 | cdev_init(&sep_cdev, &sep_file_operations); | ||
2666 | sep_cdev.owner = THIS_MODULE; | ||
2667 | |||
2668 | /* register the driver with the kernel */ | ||
2669 | ret_val = cdev_add(&sep_cdev, sep_devno, 1); | ||
2670 | if (ret_val) { | ||
2671 | edbg("sep_driver:cdev_add failed, retval is %d\n", ret_val); | ||
2672 | /* unregister dev numbers */ | ||
2673 | unregister_chrdev_region(sep_devno, 1); | ||
2674 | } | ||
2675 | return ret_val; | ||
2676 | } | ||
2677 | |||
2678 | |||
2679 | /*-------------------------------------------------------------- | ||
2680 | init function | ||
2681 | ----------------------------------------------------------------*/ | ||
2682 | static int __init sep_init(void) | ||
2683 | { | ||
2684 | int ret_val = 0; | ||
2685 | dbg("SEP Driver:-------->Init start\n"); | ||
2686 | /* FIXME: Probe can occur before we are ready to survive a probe */ | ||
2687 | ret_val = pci_register_driver(&sep_pci_driver); | ||
2688 | if (ret_val) { | ||
2689 | edbg("sep_driver:sep_driver_to_device failed, ret_val is %d\n", ret_val); | ||
2690 | goto end_function_unregister_from_fs; | ||
2691 | } | ||
2692 | /* register driver to fs */ | ||
2693 | ret_val = sep_register_driver_to_fs(); | ||
2694 | if (ret_val) | ||
2695 | goto end_function_unregister_pci; | ||
2696 | goto end_function; | ||
2697 | end_function_unregister_pci: | ||
2698 | pci_unregister_driver(&sep_pci_driver); | ||
2699 | end_function_unregister_from_fs: | ||
2700 | /* unregister from fs */ | ||
2701 | cdev_del(&sep_cdev); | ||
2702 | /* unregister dev numbers */ | ||
2703 | unregister_chrdev_region(sep_devno, 1); | ||
2704 | end_function: | ||
2705 | dbg("SEP Driver:<-------- Init end\n"); | ||
2706 | return ret_val; | ||
2707 | } | ||
2708 | |||
2709 | |||
2710 | /*------------------------------------------------------------- | ||
2711 | exit function | ||
2712 | --------------------------------------------------------------*/ | ||
2713 | static void __exit sep_exit(void) | ||
2714 | { | ||
2715 | int size; | ||
2716 | |||
2717 | dbg("SEP Driver:--------> Exit start\n"); | ||
2718 | |||
2719 | /* unregister from fs */ | ||
2720 | cdev_del(&sep_cdev); | ||
2721 | /* unregister dev numbers */ | ||
2722 | unregister_chrdev_region(sep_devno, 1); | ||
2723 | /* calculate the total size for de-allocation */ | ||
2724 | size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + | ||
2725 | SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES; | ||
2726 | /* FIXME: We need to do this in the unload for the device */ | ||
2727 | /* free shared area */ | ||
2728 | if (sep_dev) { | ||
2729 | sep_unmap_and_free_shared_area(sep_dev, size); | ||
2730 | edbg("SEP Driver: free pages SEP SHARED AREA \n"); | ||
2731 | iounmap((void *) sep_dev->reg_addr); | ||
2732 | edbg("SEP Driver: iounmap \n"); | ||
2733 | } | ||
2734 | edbg("SEP Driver: release_mem_region \n"); | ||
2735 | dbg("SEP Driver:<-------- Exit end\n"); | ||
2736 | } | ||
2737 | |||
2738 | |||
2739 | module_init(sep_init); | ||
2740 | module_exit(sep_exit); | ||
2741 | |||
2742 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/staging/sep/sep_driver_api.h b/drivers/staging/sep/sep_driver_api.h deleted file mode 100644 index 7ef16da7c4e..00000000000 --- a/drivers/staging/sep/sep_driver_api.h +++ /dev/null | |||
@@ -1,425 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * sep_driver_api.h - Security Processor Driver api definitions | ||
4 | * | ||
5 | * Copyright(c) 2009 Intel Corporation. All rights reserved. | ||
6 | * Copyright(c) 2009 Discretix. All rights reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the Free | ||
10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along with | ||
19 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
20 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
21 | * | ||
22 | * CONTACTS: | ||
23 | * | ||
24 | * Mark Allyn mark.a.allyn@intel.com | ||
25 | * | ||
26 | * CHANGES: | ||
27 | * | ||
28 | * 2009.06.26 Initial publish | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #ifndef __SEP_DRIVER_API_H__ | ||
33 | #define __SEP_DRIVER_API_H__ | ||
34 | |||
35 | |||
36 | |||
37 | /*---------------------------------------------------------------- | ||
38 | IOCTL command defines | ||
39 | -----------------------------------------------------------------*/ | ||
40 | |||
41 | /* magic number 1 of the sep IOCTL command */ | ||
42 | #define SEP_IOC_MAGIC_NUMBER 's' | ||
43 | |||
44 | /* sends interrupt to sep that message is ready */ | ||
45 | #define SEP_IOCSENDSEPCOMMAND _IO(SEP_IOC_MAGIC_NUMBER , 0) | ||
46 | |||
47 | /* sends interrupt to sep that message is ready */ | ||
48 | #define SEP_IOCSENDSEPRPLYCOMMAND _IO(SEP_IOC_MAGIC_NUMBER , 1) | ||
49 | |||
50 | /* allocate memory in data pool */ | ||
51 | #define SEP_IOCALLOCDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 2) | ||
52 | |||
53 | /* write to pre-allocated memory in data pool */ | ||
54 | #define SEP_IOCWRITEDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 3) | ||
55 | |||
56 | /* read from pre-allocated memory in data pool */ | ||
57 | #define SEP_IOCREADDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 4) | ||
58 | |||
59 | /* create sym dma lli tables */ | ||
60 | #define SEP_IOCCREATESYMDMATABLE _IO(SEP_IOC_MAGIC_NUMBER , 5) | ||
61 | |||
62 | /* create flow dma lli tables */ | ||
63 | #define SEP_IOCCREATEFLOWDMATABLE _IO(SEP_IOC_MAGIC_NUMBER , 6) | ||
64 | |||
65 | /* free dynamic data aalocated during table creation */ | ||
66 | #define SEP_IOCFREEDMATABLEDATA _IO(SEP_IOC_MAGIC_NUMBER , 7) | ||
67 | |||
68 | /* get the static pool area addresses (physical and virtual) */ | ||
69 | #define SEP_IOCGETSTATICPOOLADDR _IO(SEP_IOC_MAGIC_NUMBER , 8) | ||
70 | |||
71 | /* set flow id command */ | ||
72 | #define SEP_IOCSETFLOWID _IO(SEP_IOC_MAGIC_NUMBER , 9) | ||
73 | |||
74 | /* add tables to the dynamic flow */ | ||
75 | #define SEP_IOCADDFLOWTABLE _IO(SEP_IOC_MAGIC_NUMBER , 10) | ||
76 | |||
77 | /* add flow add tables message */ | ||
78 | #define SEP_IOCADDFLOWMESSAGE _IO(SEP_IOC_MAGIC_NUMBER , 11) | ||
79 | |||
80 | /* start sep command */ | ||
81 | #define SEP_IOCSEPSTART _IO(SEP_IOC_MAGIC_NUMBER , 12) | ||
82 | |||
83 | /* init sep command */ | ||
84 | #define SEP_IOCSEPINIT _IO(SEP_IOC_MAGIC_NUMBER , 13) | ||
85 | |||
86 | /* end transaction command */ | ||
87 | #define SEP_IOCENDTRANSACTION _IO(SEP_IOC_MAGIC_NUMBER , 15) | ||
88 | |||
89 | /* reallocate cache and resident */ | ||
90 | #define SEP_IOCREALLOCCACHERES _IO(SEP_IOC_MAGIC_NUMBER , 16) | ||
91 | |||
92 | /* get the offset of the address starting from the beginnnig of the map area */ | ||
93 | #define SEP_IOCGETMAPPEDADDROFFSET _IO(SEP_IOC_MAGIC_NUMBER , 17) | ||
94 | |||
95 | /* get time address and value */ | ||
96 | #define SEP_IOCGETIME _IO(SEP_IOC_MAGIC_NUMBER , 19) | ||
97 | |||
98 | /*------------------------------------------- | ||
99 | TYPEDEFS | ||
100 | ----------------------------------------------*/ | ||
101 | |||
102 | /* | ||
103 | init command struct | ||
104 | */ | ||
105 | struct sep_driver_init_t { | ||
106 | /* start of the 1G of the host memory address that SEP can access */ | ||
107 | unsigned long message_addr; | ||
108 | |||
109 | /* start address of resident */ | ||
110 | unsigned long message_size_in_words; | ||
111 | |||
112 | }; | ||
113 | |||
114 | |||
115 | /* | ||
116 | realloc cache resident command | ||
117 | */ | ||
118 | struct sep_driver_realloc_cache_resident_t { | ||
119 | /* new cache address */ | ||
120 | u64 new_cache_addr; | ||
121 | /* new resident address */ | ||
122 | u64 new_resident_addr; | ||
123 | /* new resident address */ | ||
124 | u64 new_shared_area_addr; | ||
125 | /* new base address */ | ||
126 | u64 new_base_addr; | ||
127 | }; | ||
128 | |||
129 | struct sep_driver_alloc_t { | ||
130 | /* virtual address of allocated space */ | ||
131 | unsigned long offset; | ||
132 | |||
133 | /* physical address of allocated space */ | ||
134 | unsigned long phys_address; | ||
135 | |||
136 | /* number of bytes to allocate */ | ||
137 | unsigned long num_bytes; | ||
138 | }; | ||
139 | |||
140 | /* | ||
141 | */ | ||
142 | struct sep_driver_write_t { | ||
143 | /* application space address */ | ||
144 | unsigned long app_address; | ||
145 | |||
146 | /* address of the data pool */ | ||
147 | unsigned long datapool_address; | ||
148 | |||
149 | /* number of bytes to write */ | ||
150 | unsigned long num_bytes; | ||
151 | }; | ||
152 | |||
153 | /* | ||
154 | */ | ||
155 | struct sep_driver_read_t { | ||
156 | /* application space address */ | ||
157 | unsigned long app_address; | ||
158 | |||
159 | /* address of the data pool */ | ||
160 | unsigned long datapool_address; | ||
161 | |||
162 | /* number of bytes to read */ | ||
163 | unsigned long num_bytes; | ||
164 | }; | ||
165 | |||
166 | /* | ||
167 | */ | ||
168 | struct sep_driver_build_sync_table_t { | ||
169 | /* address value of the data in */ | ||
170 | unsigned long app_in_address; | ||
171 | |||
172 | /* size of data in */ | ||
173 | unsigned long data_in_size; | ||
174 | |||
175 | /* address of the data out */ | ||
176 | unsigned long app_out_address; | ||
177 | |||
178 | /* the size of the block of the operation - if needed, | ||
179 | every table will be modulo this parameter */ | ||
180 | unsigned long block_size; | ||
181 | |||
182 | /* the physical address of the first input DMA table */ | ||
183 | unsigned long in_table_address; | ||
184 | |||
185 | /* number of entries in the first input DMA table */ | ||
186 | unsigned long in_table_num_entries; | ||
187 | |||
188 | /* the physical address of the first output DMA table */ | ||
189 | unsigned long out_table_address; | ||
190 | |||
191 | /* number of entries in the first output DMA table */ | ||
192 | unsigned long out_table_num_entries; | ||
193 | |||
194 | /* data in the first input table */ | ||
195 | unsigned long table_data_size; | ||
196 | |||
197 | /* distinct user/kernel layout */ | ||
198 | bool isKernelVirtualAddress; | ||
199 | |||
200 | }; | ||
201 | |||
202 | /* | ||
203 | */ | ||
204 | struct sep_driver_build_flow_table_t { | ||
205 | /* flow type */ | ||
206 | unsigned long flow_type; | ||
207 | |||
208 | /* flag for input output */ | ||
209 | unsigned long input_output_flag; | ||
210 | |||
211 | /* address value of the data in */ | ||
212 | unsigned long virt_buff_data_addr; | ||
213 | |||
214 | /* size of data in */ | ||
215 | unsigned long num_virtual_buffers; | ||
216 | |||
217 | /* the physical address of the first input DMA table */ | ||
218 | unsigned long first_table_addr; | ||
219 | |||
220 | /* number of entries in the first input DMA table */ | ||
221 | unsigned long first_table_num_entries; | ||
222 | |||
223 | /* data in the first input table */ | ||
224 | unsigned long first_table_data_size; | ||
225 | |||
226 | /* distinct user/kernel layout */ | ||
227 | bool isKernelVirtualAddress; | ||
228 | }; | ||
229 | |||
230 | |||
231 | struct sep_driver_add_flow_table_t { | ||
232 | /* flow id */ | ||
233 | unsigned long flow_id; | ||
234 | |||
235 | /* flag for input output */ | ||
236 | unsigned long inputOutputFlag; | ||
237 | |||
238 | /* address value of the data in */ | ||
239 | unsigned long virt_buff_data_addr; | ||
240 | |||
241 | /* size of data in */ | ||
242 | unsigned long num_virtual_buffers; | ||
243 | |||
244 | /* address of the first table */ | ||
245 | unsigned long first_table_addr; | ||
246 | |||
247 | /* number of entries in the first table */ | ||
248 | unsigned long first_table_num_entries; | ||
249 | |||
250 | /* data size of the first table */ | ||
251 | unsigned long first_table_data_size; | ||
252 | |||
253 | /* distinct user/kernel layout */ | ||
254 | bool isKernelVirtualAddress; | ||
255 | |||
256 | }; | ||
257 | |||
258 | /* | ||
259 | command struct for set flow id | ||
260 | */ | ||
261 | struct sep_driver_set_flow_id_t { | ||
262 | /* flow id to set */ | ||
263 | unsigned long flow_id; | ||
264 | }; | ||
265 | |||
266 | |||
267 | /* command struct for add tables message */ | ||
268 | struct sep_driver_add_message_t { | ||
269 | /* flow id to set */ | ||
270 | unsigned long flow_id; | ||
271 | |||
272 | /* message size in bytes */ | ||
273 | unsigned long message_size_in_bytes; | ||
274 | |||
275 | /* address of the message */ | ||
276 | unsigned long message_address; | ||
277 | }; | ||
278 | |||
279 | /* command struct for static pool addresses */ | ||
280 | struct sep_driver_static_pool_addr_t { | ||
281 | /* physical address of the static pool */ | ||
282 | unsigned long physical_static_address; | ||
283 | |||
284 | /* virtual address of the static pool */ | ||
285 | unsigned long virtual_static_address; | ||
286 | }; | ||
287 | |||
288 | /* command struct for getiing offset of the physical address from | ||
289 | the start of the mapped area */ | ||
290 | struct sep_driver_get_mapped_offset_t { | ||
291 | /* physical address of the static pool */ | ||
292 | unsigned long physical_address; | ||
293 | |||
294 | /* virtual address of the static pool */ | ||
295 | unsigned long offset; | ||
296 | }; | ||
297 | |||
298 | /* command struct for getting time value and address */ | ||
299 | struct sep_driver_get_time_t { | ||
300 | /* physical address of stored time */ | ||
301 | unsigned long time_physical_address; | ||
302 | |||
303 | /* value of the stored time */ | ||
304 | unsigned long time_value; | ||
305 | }; | ||
306 | |||
307 | |||
308 | /* | ||
309 | structure that represent one entry in the DMA LLI table | ||
310 | */ | ||
311 | struct sep_lli_entry_t { | ||
312 | /* physical address */ | ||
313 | unsigned long physical_address; | ||
314 | |||
315 | /* block size */ | ||
316 | unsigned long block_size; | ||
317 | }; | ||
318 | |||
319 | /* | ||
320 | structure that reperesents data needed for lli table construction | ||
321 | */ | ||
322 | struct sep_lli_prepare_table_data_t { | ||
323 | /* pointer to the memory where the first lli entry to be built */ | ||
324 | struct sep_lli_entry_t *lli_entry_ptr; | ||
325 | |||
326 | /* pointer to the array of lli entries from which the table is to be built */ | ||
327 | struct sep_lli_entry_t *lli_array_ptr; | ||
328 | |||
329 | /* number of elements in lli array */ | ||
330 | int lli_array_size; | ||
331 | |||
332 | /* number of entries in the created table */ | ||
333 | int num_table_entries; | ||
334 | |||
335 | /* number of array entries processed during table creation */ | ||
336 | int num_array_entries_processed; | ||
337 | |||
338 | /* the totatl data size in the created table */ | ||
339 | int lli_table_total_data_size; | ||
340 | }; | ||
341 | |||
342 | /* | ||
343 | structure that represent tone table - it is not used in code, jkust | ||
344 | to show what table looks like | ||
345 | */ | ||
346 | struct sep_lli_table_t { | ||
347 | /* number of pages mapped in this tables. If 0 - means that the table | ||
348 | is not defined (used as a valid flag) */ | ||
349 | unsigned long num_pages; | ||
350 | /* | ||
351 | pointer to array of page pointers that represent the mapping of the | ||
352 | virtual buffer defined by the table to the physical memory. If this | ||
353 | pointer is NULL, it means that the table is not defined | ||
354 | (used as a valid flag) | ||
355 | */ | ||
356 | struct page **table_page_array_ptr; | ||
357 | |||
358 | /* maximum flow entries in table */ | ||
359 | struct sep_lli_entry_t lli_entries[SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE]; | ||
360 | }; | ||
361 | |||
362 | |||
363 | /* | ||
364 | structure for keeping the mapping of the virtual buffer into physical pages | ||
365 | */ | ||
366 | struct sep_flow_buffer_data { | ||
367 | /* pointer to the array of page structs pointers to the pages of the | ||
368 | virtual buffer */ | ||
369 | struct page **page_array_ptr; | ||
370 | |||
371 | /* number of pages taken by the virtual buffer */ | ||
372 | unsigned long num_pages; | ||
373 | |||
374 | /* this flag signals if this page_array is the last one among many that were | ||
375 | sent in one setting to SEP */ | ||
376 | unsigned long last_page_array_flag; | ||
377 | }; | ||
378 | |||
379 | /* | ||
380 | struct that keeps all the data for one flow | ||
381 | */ | ||
382 | struct sep_flow_context_t { | ||
383 | /* | ||
384 | work struct for handling the flow done interrupt in the workqueue | ||
385 | this structure must be in the first place, since it will be used | ||
386 | forcasting to the containing flow context | ||
387 | */ | ||
388 | struct work_struct flow_wq; | ||
389 | |||
390 | /* flow id */ | ||
391 | unsigned long flow_id; | ||
392 | |||
393 | /* additional input tables exists */ | ||
394 | unsigned long input_tables_flag; | ||
395 | |||
396 | /* additional output tables exists */ | ||
397 | unsigned long output_tables_flag; | ||
398 | |||
399 | /* data of the first input file */ | ||
400 | struct sep_lli_entry_t first_input_table; | ||
401 | |||
402 | /* data of the first output table */ | ||
403 | struct sep_lli_entry_t first_output_table; | ||
404 | |||
405 | /* last input table data */ | ||
406 | struct sep_lli_entry_t last_input_table; | ||
407 | |||
408 | /* last output table data */ | ||
409 | struct sep_lli_entry_t last_output_table; | ||
410 | |||
411 | /* first list of table */ | ||
412 | struct sep_lli_entry_t input_tables_in_process; | ||
413 | |||
414 | /* output table in process (in sep) */ | ||
415 | struct sep_lli_entry_t output_tables_in_process; | ||
416 | |||
417 | /* size of messages in bytes */ | ||
418 | unsigned long message_size_in_bytes; | ||
419 | |||
420 | /* message */ | ||
421 | unsigned char message[SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES]; | ||
422 | }; | ||
423 | |||
424 | |||
425 | #endif | ||
diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h deleted file mode 100644 index 6008fe5eca0..00000000000 --- a/drivers/staging/sep/sep_driver_config.h +++ /dev/null | |||
@@ -1,225 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * sep_driver_config.h - Security Processor Driver configuration | ||
4 | * | ||
5 | * Copyright(c) 2009 Intel Corporation. All rights reserved. | ||
6 | * Copyright(c) 2009 Discretix. All rights reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the Free | ||
10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along with | ||
19 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
20 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
21 | * | ||
22 | * CONTACTS: | ||
23 | * | ||
24 | * Mark Allyn mark.a.allyn@intel.com | ||
25 | * | ||
26 | * CHANGES: | ||
27 | * | ||
28 | * 2009.06.26 Initial publish | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #ifndef __SEP_DRIVER_CONFIG_H__ | ||
33 | #define __SEP_DRIVER_CONFIG_H__ | ||
34 | |||
35 | |||
36 | /*-------------------------------------- | ||
37 | DRIVER CONFIGURATION FLAGS | ||
38 | -------------------------------------*/ | ||
39 | |||
40 | /* if flag is on , then the driver is running in polling and | ||
41 | not interrupt mode */ | ||
42 | #define SEP_DRIVER_POLLING_MODE 1 | ||
43 | |||
44 | /* flag which defines if the shared area address should be | ||
45 | reconfiged (send to SEP anew) during init of the driver */ | ||
46 | #define SEP_DRIVER_RECONFIG_MESSAGE_AREA 0 | ||
47 | |||
48 | /* the mode for running on the ARM1172 Evaluation platform (flag is 1) */ | ||
49 | #define SEP_DRIVER_ARM_DEBUG_MODE 0 | ||
50 | |||
51 | /*------------------------------------------- | ||
52 | INTERNAL DATA CONFIGURATION | ||
53 | -------------------------------------------*/ | ||
54 | |||
55 | /* flag for the input array */ | ||
56 | #define SEP_DRIVER_IN_FLAG 0 | ||
57 | |||
58 | /* flag for output array */ | ||
59 | #define SEP_DRIVER_OUT_FLAG 1 | ||
60 | |||
61 | /* maximum number of entries in one LLI tables */ | ||
62 | #define SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP 8 | ||
63 | |||
64 | |||
65 | /*-------------------------------------------------------- | ||
66 | SHARED AREA memory total size is 36K | ||
67 | it is divided is following: | ||
68 | |||
69 | SHARED_MESSAGE_AREA 8K } | ||
70 | } | ||
71 | STATIC_POOL_AREA 4K } MAPPED AREA ( 24 K) | ||
72 | } | ||
73 | DATA_POOL_AREA 12K } | ||
74 | |||
75 | SYNCHRONIC_DMA_TABLES_AREA 5K | ||
76 | |||
77 | FLOW_DMA_TABLES_AREA 4K | ||
78 | |||
79 | SYSTEM_MEMORY_AREA 3k | ||
80 | |||
81 | SYSTEM_MEMORY total size is 3k | ||
82 | it is divided as following: | ||
83 | |||
84 | TIME_MEMORY_AREA 8B | ||
85 | -----------------------------------------------------------*/ | ||
86 | |||
87 | |||
88 | |||
89 | /* | ||
90 | the maximum length of the message - the rest of the message shared | ||
91 | area will be dedicated to the dma lli tables | ||
92 | */ | ||
93 | #define SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES (8 * 1024) | ||
94 | |||
95 | /* the size of the message shared area in pages */ | ||
96 | #define SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES (8 * 1024) | ||
97 | |||
98 | /* the size of the data pool static area in pages */ | ||
99 | #define SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES (4 * 1024) | ||
100 | |||
101 | /* the size of the data pool shared area size in pages */ | ||
102 | #define SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES (12 * 1024) | ||
103 | |||
104 | /* the size of the message shared area in pages */ | ||
105 | #define SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 5) | ||
106 | |||
107 | |||
108 | /* the size of the data pool shared area size in pages */ | ||
109 | #define SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 4) | ||
110 | |||
111 | /* system data (time, caller id etc') pool */ | ||
112 | #define SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES 100 | ||
113 | |||
114 | |||
115 | /* area size that is mapped - we map the MESSAGE AREA, STATIC POOL and | ||
116 | DATA POOL areas. area must be module 4k */ | ||
117 | #define SEP_DRIVER_MMMAP_AREA_SIZE (1024 * 24) | ||
118 | |||
119 | |||
120 | /*----------------------------------------------- | ||
121 | offsets of the areas starting from the shared area start address | ||
122 | */ | ||
123 | |||
124 | /* message area offset */ | ||
125 | #define SEP_DRIVER_MESSAGE_AREA_OFFSET_IN_BYTES 0 | ||
126 | |||
127 | /* static pool area offset */ | ||
128 | #define SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES \ | ||
129 | (SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES) | ||
130 | |||
131 | /* data pool area offset */ | ||
132 | #define SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES \ | ||
133 | (SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES + \ | ||
134 | SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES) | ||
135 | |||
136 | /* synhronic dma tables area offset */ | ||
137 | #define SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES \ | ||
138 | (SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + \ | ||
139 | SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) | ||
140 | |||
141 | /* sep driver flow dma tables area offset */ | ||
142 | #define SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES \ | ||
143 | (SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES + \ | ||
144 | SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES) | ||
145 | |||
146 | /* system memory offset in bytes */ | ||
147 | #define SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES \ | ||
148 | (SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES + \ | ||
149 | SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES) | ||
150 | |||
151 | /* offset of the time area */ | ||
152 | #define SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES \ | ||
153 | (SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES) | ||
154 | |||
155 | |||
156 | |||
157 | /* start physical address of the SEP registers memory in HOST */ | ||
158 | #define SEP_IO_MEM_REGION_START_ADDRESS 0x80000000 | ||
159 | |||
160 | /* size of the SEP registers memory region in HOST (for now 100 registers) */ | ||
161 | #define SEP_IO_MEM_REGION_SIZE (2 * 0x100000) | ||
162 | |||
163 | /* define the number of IRQ for SEP interrupts */ | ||
164 | #define SEP_DIRVER_IRQ_NUM 1 | ||
165 | |||
166 | /* maximum number of add buffers */ | ||
167 | #define SEP_MAX_NUM_ADD_BUFFERS 100 | ||
168 | |||
169 | /* number of flows */ | ||
170 | #define SEP_DRIVER_NUM_FLOWS 4 | ||
171 | |||
172 | /* maximum number of entries in flow table */ | ||
173 | #define SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE 25 | ||
174 | |||
175 | /* offset of the num entries in the block length entry of the LLI */ | ||
176 | #define SEP_NUM_ENTRIES_OFFSET_IN_BITS 24 | ||
177 | |||
178 | /* offset of the interrupt flag in the block length entry of the LLI */ | ||
179 | #define SEP_INT_FLAG_OFFSET_IN_BITS 31 | ||
180 | |||
181 | /* mask for extracting data size from LLI */ | ||
182 | #define SEP_TABLE_DATA_SIZE_MASK 0xFFFFFF | ||
183 | |||
184 | /* mask for entries after being shifted left */ | ||
185 | #define SEP_NUM_ENTRIES_MASK 0x7F | ||
186 | |||
187 | /* default flow id */ | ||
188 | #define SEP_FREE_FLOW_ID 0xFFFFFFFF | ||
189 | |||
190 | /* temp flow id used during cretiong of new flow until receiving | ||
191 | real flow id from sep */ | ||
192 | #define SEP_TEMP_FLOW_ID (SEP_DRIVER_NUM_FLOWS + 1) | ||
193 | |||
194 | /* maximum add buffers message length in bytes */ | ||
195 | #define SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES (7 * 4) | ||
196 | |||
197 | /* maximum number of concurrent virtual buffers */ | ||
198 | #define SEP_MAX_VIRT_BUFFERS_CONCURRENT 100 | ||
199 | |||
200 | /* the token that defines the start of time address */ | ||
201 | #define SEP_TIME_VAL_TOKEN 0x12345678 | ||
202 | |||
203 | /* DEBUG LEVEL MASKS */ | ||
204 | #define SEP_DEBUG_LEVEL_BASIC 0x1 | ||
205 | |||
206 | #define SEP_DEBUG_LEVEL_EXTENDED 0x4 | ||
207 | |||
208 | |||
209 | /* Debug helpers */ | ||
210 | |||
211 | #define dbg(fmt, args...) \ | ||
212 | do {\ | ||
213 | if (debug & SEP_DEBUG_LEVEL_BASIC) \ | ||
214 | printk(KERN_DEBUG fmt, ##args); \ | ||
215 | } while(0); | ||
216 | |||
217 | #define edbg(fmt, args...) \ | ||
218 | do { \ | ||
219 | if (debug & SEP_DEBUG_LEVEL_EXTENDED) \ | ||
220 | printk(KERN_DEBUG fmt, ##args); \ | ||
221 | } while(0); | ||
222 | |||
223 | |||
224 | |||
225 | #endif | ||
diff --git a/drivers/staging/sep/sep_driver_hw_defs.h b/drivers/staging/sep/sep_driver_hw_defs.h deleted file mode 100644 index ea6abd8a14b..00000000000 --- a/drivers/staging/sep/sep_driver_hw_defs.h +++ /dev/null | |||
@@ -1,232 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * sep_driver_hw_defs.h - Security Processor Driver hardware definitions | ||
4 | * | ||
5 | * Copyright(c) 2009 Intel Corporation. All rights reserved. | ||
6 | * Copyright(c) 2009 Discretix. All rights reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the Free | ||
10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along with | ||
19 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
20 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
21 | * | ||
22 | * CONTACTS: | ||
23 | * | ||
24 | * Mark Allyn mark.a.allyn@intel.com | ||
25 | * | ||
26 | * CHANGES: | ||
27 | * | ||
28 | * 2009.06.26 Initial publish | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #ifndef SEP_DRIVER_HW_DEFS__H | ||
33 | #define SEP_DRIVER_HW_DEFS__H | ||
34 | |||
35 | /*--------------------------------------------------------------------------*/ | ||
36 | /* Abstract: HW Registers Defines. */ | ||
37 | /* */ | ||
38 | /* Note: This file was automatically created !!! */ | ||
39 | /* DO NOT EDIT THIS FILE !!! */ | ||
40 | /*--------------------------------------------------------------------------*/ | ||
41 | |||
42 | |||
43 | /* cf registers */ | ||
44 | #define HW_R0B_ADDR_0_REG_ADDR 0x0000UL | ||
45 | #define HW_R0B_ADDR_1_REG_ADDR 0x0004UL | ||
46 | #define HW_R0B_ADDR_2_REG_ADDR 0x0008UL | ||
47 | #define HW_R0B_ADDR_3_REG_ADDR 0x000cUL | ||
48 | #define HW_R0B_ADDR_4_REG_ADDR 0x0010UL | ||
49 | #define HW_R0B_ADDR_5_REG_ADDR 0x0014UL | ||
50 | #define HW_R0B_ADDR_6_REG_ADDR 0x0018UL | ||
51 | #define HW_R0B_ADDR_7_REG_ADDR 0x001cUL | ||
52 | #define HW_R0B_ADDR_8_REG_ADDR 0x0020UL | ||
53 | #define HW_R2B_ADDR_0_REG_ADDR 0x0080UL | ||
54 | #define HW_R2B_ADDR_1_REG_ADDR 0x0084UL | ||
55 | #define HW_R2B_ADDR_2_REG_ADDR 0x0088UL | ||
56 | #define HW_R2B_ADDR_3_REG_ADDR 0x008cUL | ||
57 | #define HW_R2B_ADDR_4_REG_ADDR 0x0090UL | ||
58 | #define HW_R2B_ADDR_5_REG_ADDR 0x0094UL | ||
59 | #define HW_R2B_ADDR_6_REG_ADDR 0x0098UL | ||
60 | #define HW_R2B_ADDR_7_REG_ADDR 0x009cUL | ||
61 | #define HW_R2B_ADDR_8_REG_ADDR 0x00a0UL | ||
62 | #define HW_R3B_REG_ADDR 0x00C0UL | ||
63 | #define HW_R4B_REG_ADDR 0x0100UL | ||
64 | #define HW_CSA_ADDR_0_REG_ADDR 0x0140UL | ||
65 | #define HW_CSA_ADDR_1_REG_ADDR 0x0144UL | ||
66 | #define HW_CSA_ADDR_2_REG_ADDR 0x0148UL | ||
67 | #define HW_CSA_ADDR_3_REG_ADDR 0x014cUL | ||
68 | #define HW_CSA_ADDR_4_REG_ADDR 0x0150UL | ||
69 | #define HW_CSA_ADDR_5_REG_ADDR 0x0154UL | ||
70 | #define HW_CSA_ADDR_6_REG_ADDR 0x0158UL | ||
71 | #define HW_CSA_ADDR_7_REG_ADDR 0x015cUL | ||
72 | #define HW_CSA_ADDR_8_REG_ADDR 0x0160UL | ||
73 | #define HW_CSA_REG_ADDR 0x0140UL | ||
74 | #define HW_SINB_REG_ADDR 0x0180UL | ||
75 | #define HW_SOUTB_REG_ADDR 0x0184UL | ||
76 | #define HW_PKI_CONTROL_REG_ADDR 0x01C0UL | ||
77 | #define HW_PKI_STATUS_REG_ADDR 0x01C4UL | ||
78 | #define HW_PKI_BUSY_REG_ADDR 0x01C8UL | ||
79 | #define HW_PKI_A_1025_REG_ADDR 0x01CCUL | ||
80 | #define HW_PKI_SDMA_CTL_REG_ADDR 0x01D0UL | ||
81 | #define HW_PKI_SDMA_OFFSET_REG_ADDR 0x01D4UL | ||
82 | #define HW_PKI_SDMA_POINTERS_REG_ADDR 0x01D8UL | ||
83 | #define HW_PKI_SDMA_DLENG_REG_ADDR 0x01DCUL | ||
84 | #define HW_PKI_SDMA_EXP_POINTERS_REG_ADDR 0x01E0UL | ||
85 | #define HW_PKI_SDMA_RES_POINTERS_REG_ADDR 0x01E4UL | ||
86 | #define HW_PKI_CLR_REG_ADDR 0x01E8UL | ||
87 | #define HW_PKI_SDMA_BUSY_REG_ADDR 0x01E8UL | ||
88 | #define HW_PKI_SDMA_FIRST_EXP_N_REG_ADDR 0x01ECUL | ||
89 | #define HW_PKI_SDMA_MUL_BY1_REG_ADDR 0x01F0UL | ||
90 | #define HW_PKI_SDMA_RMUL_SEL_REG_ADDR 0x01F4UL | ||
91 | #define HW_DES_KEY_0_REG_ADDR 0x0208UL | ||
92 | #define HW_DES_KEY_1_REG_ADDR 0x020CUL | ||
93 | #define HW_DES_KEY_2_REG_ADDR 0x0210UL | ||
94 | #define HW_DES_KEY_3_REG_ADDR 0x0214UL | ||
95 | #define HW_DES_KEY_4_REG_ADDR 0x0218UL | ||
96 | #define HW_DES_KEY_5_REG_ADDR 0x021CUL | ||
97 | #define HW_DES_CONTROL_0_REG_ADDR 0x0220UL | ||
98 | #define HW_DES_CONTROL_1_REG_ADDR 0x0224UL | ||
99 | #define HW_DES_IV_0_REG_ADDR 0x0228UL | ||
100 | #define HW_DES_IV_1_REG_ADDR 0x022CUL | ||
101 | #define HW_AES_KEY_0_ADDR_0_REG_ADDR 0x0400UL | ||
102 | #define HW_AES_KEY_0_ADDR_1_REG_ADDR 0x0404UL | ||
103 | #define HW_AES_KEY_0_ADDR_2_REG_ADDR 0x0408UL | ||
104 | #define HW_AES_KEY_0_ADDR_3_REG_ADDR 0x040cUL | ||
105 | #define HW_AES_KEY_0_ADDR_4_REG_ADDR 0x0410UL | ||
106 | #define HW_AES_KEY_0_ADDR_5_REG_ADDR 0x0414UL | ||
107 | #define HW_AES_KEY_0_ADDR_6_REG_ADDR 0x0418UL | ||
108 | #define HW_AES_KEY_0_ADDR_7_REG_ADDR 0x041cUL | ||
109 | #define HW_AES_KEY_0_REG_ADDR 0x0400UL | ||
110 | #define HW_AES_IV_0_ADDR_0_REG_ADDR 0x0440UL | ||
111 | #define HW_AES_IV_0_ADDR_1_REG_ADDR 0x0444UL | ||
112 | #define HW_AES_IV_0_ADDR_2_REG_ADDR 0x0448UL | ||
113 | #define HW_AES_IV_0_ADDR_3_REG_ADDR 0x044cUL | ||
114 | #define HW_AES_IV_0_REG_ADDR 0x0440UL | ||
115 | #define HW_AES_CTR1_ADDR_0_REG_ADDR 0x0460UL | ||
116 | #define HW_AES_CTR1_ADDR_1_REG_ADDR 0x0464UL | ||
117 | #define HW_AES_CTR1_ADDR_2_REG_ADDR 0x0468UL | ||
118 | #define HW_AES_CTR1_ADDR_3_REG_ADDR 0x046cUL | ||
119 | #define HW_AES_CTR1_REG_ADDR 0x0460UL | ||
120 | #define HW_AES_SK_REG_ADDR 0x0478UL | ||
121 | #define HW_AES_MAC_OK_REG_ADDR 0x0480UL | ||
122 | #define HW_AES_PREV_IV_0_ADDR_0_REG_ADDR 0x0490UL | ||
123 | #define HW_AES_PREV_IV_0_ADDR_1_REG_ADDR 0x0494UL | ||
124 | #define HW_AES_PREV_IV_0_ADDR_2_REG_ADDR 0x0498UL | ||
125 | #define HW_AES_PREV_IV_0_ADDR_3_REG_ADDR 0x049cUL | ||
126 | #define HW_AES_PREV_IV_0_REG_ADDR 0x0490UL | ||
127 | #define HW_AES_CONTROL_REG_ADDR 0x04C0UL | ||
128 | #define HW_HASH_H0_REG_ADDR 0x0640UL | ||
129 | #define HW_HASH_H1_REG_ADDR 0x0644UL | ||
130 | #define HW_HASH_H2_REG_ADDR 0x0648UL | ||
131 | #define HW_HASH_H3_REG_ADDR 0x064CUL | ||
132 | #define HW_HASH_H4_REG_ADDR 0x0650UL | ||
133 | #define HW_HASH_H5_REG_ADDR 0x0654UL | ||
134 | #define HW_HASH_H6_REG_ADDR 0x0658UL | ||
135 | #define HW_HASH_H7_REG_ADDR 0x065CUL | ||
136 | #define HW_HASH_H8_REG_ADDR 0x0660UL | ||
137 | #define HW_HASH_H9_REG_ADDR 0x0664UL | ||
138 | #define HW_HASH_H10_REG_ADDR 0x0668UL | ||
139 | #define HW_HASH_H11_REG_ADDR 0x066CUL | ||
140 | #define HW_HASH_H12_REG_ADDR 0x0670UL | ||
141 | #define HW_HASH_H13_REG_ADDR 0x0674UL | ||
142 | #define HW_HASH_H14_REG_ADDR 0x0678UL | ||
143 | #define HW_HASH_H15_REG_ADDR 0x067CUL | ||
144 | #define HW_HASH_CONTROL_REG_ADDR 0x07C0UL | ||
145 | #define HW_HASH_PAD_EN_REG_ADDR 0x07C4UL | ||
146 | #define HW_HASH_PAD_CFG_REG_ADDR 0x07C8UL | ||
147 | #define HW_HASH_CUR_LEN_0_REG_ADDR 0x07CCUL | ||
148 | #define HW_HASH_CUR_LEN_1_REG_ADDR 0x07D0UL | ||
149 | #define HW_HASH_CUR_LEN_2_REG_ADDR 0x07D4UL | ||
150 | #define HW_HASH_CUR_LEN_3_REG_ADDR 0x07D8UL | ||
151 | #define HW_HASH_PARAM_REG_ADDR 0x07DCUL | ||
152 | #define HW_HASH_INT_BUSY_REG_ADDR 0x07E0UL | ||
153 | #define HW_HASH_SW_RESET_REG_ADDR 0x07E4UL | ||
154 | #define HW_HASH_ENDIANESS_REG_ADDR 0x07E8UL | ||
155 | #define HW_HASH_DATA_REG_ADDR 0x07ECUL | ||
156 | #define HW_DRNG_CONTROL_REG_ADDR 0x0800UL | ||
157 | #define HW_DRNG_VALID_REG_ADDR 0x0804UL | ||
158 | #define HW_DRNG_DATA_REG_ADDR 0x0808UL | ||
159 | #define HW_RND_SRC_EN_REG_ADDR 0x080CUL | ||
160 | #define HW_AES_CLK_ENABLE_REG_ADDR 0x0810UL | ||
161 | #define HW_DES_CLK_ENABLE_REG_ADDR 0x0814UL | ||
162 | #define HW_HASH_CLK_ENABLE_REG_ADDR 0x0818UL | ||
163 | #define HW_PKI_CLK_ENABLE_REG_ADDR 0x081CUL | ||
164 | #define HW_CLK_STATUS_REG_ADDR 0x0824UL | ||
165 | #define HW_CLK_ENABLE_REG_ADDR 0x0828UL | ||
166 | #define HW_DRNG_SAMPLE_REG_ADDR 0x0850UL | ||
167 | #define HW_RND_SRC_CTL_REG_ADDR 0x0858UL | ||
168 | #define HW_CRYPTO_CTL_REG_ADDR 0x0900UL | ||
169 | #define HW_CRYPTO_STATUS_REG_ADDR 0x090CUL | ||
170 | #define HW_CRYPTO_BUSY_REG_ADDR 0x0910UL | ||
171 | #define HW_AES_BUSY_REG_ADDR 0x0914UL | ||
172 | #define HW_DES_BUSY_REG_ADDR 0x0918UL | ||
173 | #define HW_HASH_BUSY_REG_ADDR 0x091CUL | ||
174 | #define HW_CONTENT_REG_ADDR 0x0924UL | ||
175 | #define HW_VERSION_REG_ADDR 0x0928UL | ||
176 | #define HW_CONTEXT_ID_REG_ADDR 0x0930UL | ||
177 | #define HW_DIN_BUFFER_REG_ADDR 0x0C00UL | ||
178 | #define HW_DIN_MEM_DMA_BUSY_REG_ADDR 0x0c20UL | ||
179 | #define HW_SRC_LLI_MEM_ADDR_REG_ADDR 0x0c24UL | ||
180 | #define HW_SRC_LLI_WORD0_REG_ADDR 0x0C28UL | ||
181 | #define HW_SRC_LLI_WORD1_REG_ADDR 0x0C2CUL | ||
182 | #define HW_SRAM_SRC_ADDR_REG_ADDR 0x0c30UL | ||
183 | #define HW_DIN_SRAM_BYTES_LEN_REG_ADDR 0x0c34UL | ||
184 | #define HW_DIN_SRAM_DMA_BUSY_REG_ADDR 0x0C38UL | ||
185 | #define HW_WRITE_ALIGN_REG_ADDR 0x0C3CUL | ||
186 | #define HW_OLD_DATA_REG_ADDR 0x0C48UL | ||
187 | #define HW_WRITE_ALIGN_LAST_REG_ADDR 0x0C4CUL | ||
188 | #define HW_DOUT_BUFFER_REG_ADDR 0x0C00UL | ||
189 | #define HW_DST_LLI_WORD0_REG_ADDR 0x0D28UL | ||
190 | #define HW_DST_LLI_WORD1_REG_ADDR 0x0D2CUL | ||
191 | #define HW_DST_LLI_MEM_ADDR_REG_ADDR 0x0D24UL | ||
192 | #define HW_DOUT_MEM_DMA_BUSY_REG_ADDR 0x0D20UL | ||
193 | #define HW_SRAM_DEST_ADDR_REG_ADDR 0x0D30UL | ||
194 | #define HW_DOUT_SRAM_BYTES_LEN_REG_ADDR 0x0D34UL | ||
195 | #define HW_DOUT_SRAM_DMA_BUSY_REG_ADDR 0x0D38UL | ||
196 | #define HW_READ_ALIGN_REG_ADDR 0x0D3CUL | ||
197 | #define HW_READ_LAST_DATA_REG_ADDR 0x0D44UL | ||
198 | #define HW_RC4_THRU_CPU_REG_ADDR 0x0D4CUL | ||
199 | #define HW_AHB_SINGLE_REG_ADDR 0x0E00UL | ||
200 | #define HW_SRAM_DATA_REG_ADDR 0x0F00UL | ||
201 | #define HW_SRAM_ADDR_REG_ADDR 0x0F04UL | ||
202 | #define HW_SRAM_DATA_READY_REG_ADDR 0x0F08UL | ||
203 | #define HW_HOST_IRR_REG_ADDR 0x0A00UL | ||
204 | #define HW_HOST_IMR_REG_ADDR 0x0A04UL | ||
205 | #define HW_HOST_ICR_REG_ADDR 0x0A08UL | ||
206 | #define HW_HOST_SEP_SRAM_THRESHOLD_REG_ADDR 0x0A10UL | ||
207 | #define HW_HOST_SEP_BUSY_REG_ADDR 0x0A14UL | ||
208 | #define HW_HOST_SEP_LCS_REG_ADDR 0x0A18UL | ||
209 | #define HW_HOST_CC_SW_RST_REG_ADDR 0x0A40UL | ||
210 | #define HW_HOST_SEP_SW_RST_REG_ADDR 0x0A44UL | ||
211 | #define HW_HOST_FLOW_DMA_SW_INT0_REG_ADDR 0x0A80UL | ||
212 | #define HW_HOST_FLOW_DMA_SW_INT1_REG_ADDR 0x0A84UL | ||
213 | #define HW_HOST_FLOW_DMA_SW_INT2_REG_ADDR 0x0A88UL | ||
214 | #define HW_HOST_FLOW_DMA_SW_INT3_REG_ADDR 0x0A8cUL | ||
215 | #define HW_HOST_FLOW_DMA_SW_INT4_REG_ADDR 0x0A90UL | ||
216 | #define HW_HOST_FLOW_DMA_SW_INT5_REG_ADDR 0x0A94UL | ||
217 | #define HW_HOST_FLOW_DMA_SW_INT6_REG_ADDR 0x0A98UL | ||
218 | #define HW_HOST_FLOW_DMA_SW_INT7_REG_ADDR 0x0A9cUL | ||
219 | #define HW_HOST_SEP_HOST_GPR0_REG_ADDR 0x0B00UL | ||
220 | #define HW_HOST_SEP_HOST_GPR1_REG_ADDR 0x0B04UL | ||
221 | #define HW_HOST_SEP_HOST_GPR2_REG_ADDR 0x0B08UL | ||
222 | #define HW_HOST_SEP_HOST_GPR3_REG_ADDR 0x0B0CUL | ||
223 | #define HW_HOST_HOST_SEP_GPR0_REG_ADDR 0x0B80UL | ||
224 | #define HW_HOST_HOST_SEP_GPR1_REG_ADDR 0x0B84UL | ||
225 | #define HW_HOST_HOST_SEP_GPR2_REG_ADDR 0x0B88UL | ||
226 | #define HW_HOST_HOST_SEP_GPR3_REG_ADDR 0x0B8CUL | ||
227 | #define HW_HOST_HOST_ENDIAN_REG_ADDR 0x0B90UL | ||
228 | #define HW_HOST_HOST_COMM_CLK_EN_REG_ADDR 0x0B94UL | ||
229 | #define HW_CLR_SRAM_BUSY_REG_REG_ADDR 0x0F0CUL | ||
230 | #define HW_CC_SRAM_BASE_ADDRESS 0x5800UL | ||
231 | |||
232 | #endif /* ifndef HW_DEFS */ | ||
diff --git a/drivers/staging/spectra/Kconfig b/drivers/staging/spectra/Kconfig index 5e2ffefb60a..d231ae27299 100644 --- a/drivers/staging/spectra/Kconfig +++ b/drivers/staging/spectra/Kconfig | |||
@@ -2,6 +2,7 @@ | |||
2 | menuconfig SPECTRA | 2 | menuconfig SPECTRA |
3 | tristate "Denali Spectra Flash Translation Layer" | 3 | tristate "Denali Spectra Flash Translation Layer" |
4 | depends on BLOCK | 4 | depends on BLOCK |
5 | depends on X86_MRST | ||
5 | default n | 6 | default n |
6 | ---help--- | 7 | ---help--- |
7 | Enable the FTL pseudo-filesystem used with the NAND Flash | 8 | Enable the FTL pseudo-filesystem used with the NAND Flash |
diff --git a/drivers/staging/spectra/ffsport.c b/drivers/staging/spectra/ffsport.c index d0c5c97eda3..fa21a0fd8e8 100644 --- a/drivers/staging/spectra/ffsport.c +++ b/drivers/staging/spectra/ffsport.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/kthread.h> | 27 | #include <linux/kthread.h> |
28 | #include <linux/log2.h> | 28 | #include <linux/log2.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/smp_lock.h> | ||
31 | #include <linux/slab.h> | ||
30 | 32 | ||
31 | /**** Helper functions used for Div, Remainder operation on u64 ****/ | 33 | /**** Helper functions used for Div, Remainder operation on u64 ****/ |
32 | 34 | ||
@@ -113,7 +115,6 @@ u64 GLOB_u64_Remainder(u64 addr, u32 divisor_type) | |||
113 | 115 | ||
114 | #define GLOB_SBD_NAME "nd" | 116 | #define GLOB_SBD_NAME "nd" |
115 | #define GLOB_SBD_IRQ_NUM (29) | 117 | #define GLOB_SBD_IRQ_NUM (29) |
116 | #define GLOB_VERSION "driver version 20091110" | ||
117 | 118 | ||
118 | #define GLOB_SBD_IOCTL_GC (0x7701) | 119 | #define GLOB_SBD_IOCTL_GC (0x7701) |
119 | #define GLOB_SBD_IOCTL_WL (0x7702) | 120 | #define GLOB_SBD_IOCTL_WL (0x7702) |
@@ -272,13 +273,6 @@ static int get_res_blk_num_os(void) | |||
272 | return res_blks; | 273 | return res_blks; |
273 | } | 274 | } |
274 | 275 | ||
275 | static void SBD_prepare_flush(struct request_queue *q, struct request *rq) | ||
276 | { | ||
277 | rq->cmd_type = REQ_TYPE_LINUX_BLOCK; | ||
278 | /* rq->timeout = 5 * HZ; */ | ||
279 | rq->cmd[0] = REQ_LB_OP_FLUSH; | ||
280 | } | ||
281 | |||
282 | /* Transfer a full request. */ | 276 | /* Transfer a full request. */ |
283 | static int do_transfer(struct spectra_nand_dev *tr, struct request *req) | 277 | static int do_transfer(struct spectra_nand_dev *tr, struct request *req) |
284 | { | 278 | { |
@@ -296,8 +290,7 @@ static int do_transfer(struct spectra_nand_dev *tr, struct request *req) | |||
296 | IdentifyDeviceData.PagesPerBlock * | 290 | IdentifyDeviceData.PagesPerBlock * |
297 | res_blks_os; | 291 | res_blks_os; |
298 | 292 | ||
299 | if (req->cmd_type == REQ_TYPE_LINUX_BLOCK && | 293 | if (req->cmd_type & REQ_FLUSH) { |
300 | req->cmd[0] == REQ_LB_OP_FLUSH) { | ||
301 | if (force_flush_cache()) /* Fail to flush cache */ | 294 | if (force_flush_cache()) /* Fail to flush cache */ |
302 | return -EIO; | 295 | return -EIO; |
303 | else | 296 | else |
@@ -597,11 +590,23 @@ int GLOB_SBD_ioctl(struct block_device *bdev, fmode_t mode, | |||
597 | return -ENOTTY; | 590 | return -ENOTTY; |
598 | } | 591 | } |
599 | 592 | ||
593 | int GLOB_SBD_unlocked_ioctl(struct block_device *bdev, fmode_t mode, | ||
594 | unsigned int cmd, unsigned long arg) | ||
595 | { | ||
596 | int ret; | ||
597 | |||
598 | lock_kernel(); | ||
599 | ret = GLOB_SBD_ioctl(bdev, mode, cmd, arg); | ||
600 | unlock_kernel(); | ||
601 | |||
602 | return ret; | ||
603 | } | ||
604 | |||
600 | static struct block_device_operations GLOB_SBD_ops = { | 605 | static struct block_device_operations GLOB_SBD_ops = { |
601 | .owner = THIS_MODULE, | 606 | .owner = THIS_MODULE, |
602 | .open = GLOB_SBD_open, | 607 | .open = GLOB_SBD_open, |
603 | .release = GLOB_SBD_release, | 608 | .release = GLOB_SBD_release, |
604 | .locked_ioctl = GLOB_SBD_ioctl, | 609 | .ioctl = GLOB_SBD_unlocked_ioctl, |
605 | .getgeo = GLOB_SBD_getgeo, | 610 | .getgeo = GLOB_SBD_getgeo, |
606 | }; | 611 | }; |
607 | 612 | ||
@@ -650,8 +655,7 @@ static int SBD_setup_device(struct spectra_nand_dev *dev, int which) | |||
650 | /* Here we force report 512 byte hardware sector size to Kernel */ | 655 | /* Here we force report 512 byte hardware sector size to Kernel */ |
651 | blk_queue_logical_block_size(dev->queue, 512); | 656 | blk_queue_logical_block_size(dev->queue, 512); |
652 | 657 | ||
653 | blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH, | 658 | blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH); |
654 | SBD_prepare_flush); | ||
655 | 659 | ||
656 | dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd"); | 660 | dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd"); |
657 | if (IS_ERR(dev->thread)) { | 661 | if (IS_ERR(dev->thread)) { |
diff --git a/drivers/staging/spectra/flash.c b/drivers/staging/spectra/flash.c index 134aa5166a8..9b5218b6ada 100644 --- a/drivers/staging/spectra/flash.c +++ b/drivers/staging/spectra/flash.c | |||
@@ -61,7 +61,6 @@ static void FTL_Cache_Read_Page(u8 *pData, u64 dwPageAddr, | |||
61 | static void FTL_Cache_Write_Page(u8 *pData, u64 dwPageAddr, | 61 | static void FTL_Cache_Write_Page(u8 *pData, u64 dwPageAddr, |
62 | u8 cache_blk, u16 flag); | 62 | u8 cache_blk, u16 flag); |
63 | static int FTL_Cache_Write(void); | 63 | static int FTL_Cache_Write(void); |
64 | static int FTL_Cache_Write_Back(u8 *pData, u64 blk_addr); | ||
65 | static void FTL_Calculate_LRU(void); | 64 | static void FTL_Calculate_LRU(void); |
66 | static u32 FTL_Get_Block_Index(u32 wBlockNum); | 65 | static u32 FTL_Get_Block_Index(u32 wBlockNum); |
67 | 66 | ||
@@ -86,8 +85,6 @@ static u32 FTL_Replace_MWBlock(void); | |||
86 | static int FTL_Replace_Block(u64 blk_addr); | 85 | static int FTL_Replace_Block(u64 blk_addr); |
87 | static int FTL_Adjust_Relative_Erase_Count(u32 Index_of_MAX); | 86 | static int FTL_Adjust_Relative_Erase_Count(u32 Index_of_MAX); |
88 | 87 | ||
89 | static int FTL_Flash_Error_Handle(u8 *pData, u64 old_page_addr, u64 blk_addr); | ||
90 | |||
91 | struct device_info_tag DeviceInfo; | 88 | struct device_info_tag DeviceInfo; |
92 | struct flash_cache_tag Cache; | 89 | struct flash_cache_tag Cache; |
93 | static struct spectra_l2_cache_info cache_l2; | 90 | static struct spectra_l2_cache_info cache_l2; |
@@ -775,7 +772,7 @@ static void dump_cache_l2_table(void) | |||
775 | { | 772 | { |
776 | struct list_head *p; | 773 | struct list_head *p; |
777 | struct spectra_l2_cache_list *pnd; | 774 | struct spectra_l2_cache_list *pnd; |
778 | int n, i; | 775 | int n; |
779 | 776 | ||
780 | n = 0; | 777 | n = 0; |
781 | list_for_each(p, &cache_l2.table.list) { | 778 | list_for_each(p, &cache_l2.table.list) { |
@@ -1538,79 +1535,6 @@ static int FTL_Cache_Write_All(u8 *pData, u64 blk_addr) | |||
1538 | } | 1535 | } |
1539 | 1536 | ||
1540 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | 1537 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |
1541 | * Function: FTL_Cache_Update_Block | ||
1542 | * Inputs: pointer to buffer,page address,block address | ||
1543 | * Outputs: PASS=0 / FAIL=1 | ||
1544 | * Description: It updates the cache | ||
1545 | *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ | ||
1546 | static int FTL_Cache_Update_Block(u8 *pData, | ||
1547 | u64 old_page_addr, u64 blk_addr) | ||
1548 | { | ||
1549 | int i, j; | ||
1550 | u8 *buf = pData; | ||
1551 | int wResult = PASS; | ||
1552 | int wFoundInCache; | ||
1553 | u64 page_addr; | ||
1554 | u64 addr; | ||
1555 | u64 old_blk_addr; | ||
1556 | u16 page_offset; | ||
1557 | |||
1558 | nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n", | ||
1559 | __FILE__, __LINE__, __func__); | ||
1560 | |||
1561 | old_blk_addr = (u64)(old_page_addr >> | ||
1562 | DeviceInfo.nBitsInBlockDataSize) * DeviceInfo.wBlockDataSize; | ||
1563 | page_offset = (u16)(GLOB_u64_Remainder(old_page_addr, 2) >> | ||
1564 | DeviceInfo.nBitsInPageDataSize); | ||
1565 | |||
1566 | for (i = 0; i < DeviceInfo.wPagesPerBlock; i += Cache.pages_per_item) { | ||
1567 | page_addr = old_blk_addr + i * DeviceInfo.wPageDataSize; | ||
1568 | if (i != page_offset) { | ||
1569 | wFoundInCache = FAIL; | ||
1570 | for (j = 0; j < CACHE_ITEM_NUM; j++) { | ||
1571 | addr = Cache.array[j].address; | ||
1572 | addr = FTL_Get_Physical_Block_Addr(addr) + | ||
1573 | GLOB_u64_Remainder(addr, 2); | ||
1574 | if ((addr >= page_addr) && addr < | ||
1575 | (page_addr + Cache.cache_item_size)) { | ||
1576 | wFoundInCache = PASS; | ||
1577 | buf = Cache.array[j].buf; | ||
1578 | Cache.array[j].changed = SET; | ||
1579 | #if CMD_DMA | ||
1580 | #if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE | ||
1581 | int_cache[ftl_cmd_cnt].item = j; | ||
1582 | int_cache[ftl_cmd_cnt].cache.address = | ||
1583 | Cache.array[j].address; | ||
1584 | int_cache[ftl_cmd_cnt].cache.changed = | ||
1585 | Cache.array[j].changed; | ||
1586 | #endif | ||
1587 | #endif | ||
1588 | break; | ||
1589 | } | ||
1590 | } | ||
1591 | if (FAIL == wFoundInCache) { | ||
1592 | if (ERR == FTL_Cache_Read_All(g_pTempBuf, | ||
1593 | page_addr)) { | ||
1594 | wResult = FAIL; | ||
1595 | break; | ||
1596 | } | ||
1597 | buf = g_pTempBuf; | ||
1598 | } | ||
1599 | } else { | ||
1600 | buf = pData; | ||
1601 | } | ||
1602 | |||
1603 | if (FAIL == FTL_Cache_Write_All(buf, | ||
1604 | blk_addr + (page_addr - old_blk_addr))) { | ||
1605 | wResult = FAIL; | ||
1606 | break; | ||
1607 | } | ||
1608 | } | ||
1609 | |||
1610 | return wResult; | ||
1611 | } | ||
1612 | |||
1613 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | ||
1614 | * Function: FTL_Copy_Block | 1538 | * Function: FTL_Copy_Block |
1615 | * Inputs: source block address | 1539 | * Inputs: source block address |
1616 | * Destination block address | 1540 | * Destination block address |
@@ -1698,7 +1622,7 @@ static int get_l2_cache_blks(void) | |||
1698 | static int erase_l2_cache_blocks(void) | 1622 | static int erase_l2_cache_blocks(void) |
1699 | { | 1623 | { |
1700 | int i, ret = PASS; | 1624 | int i, ret = PASS; |
1701 | u32 pblk, lblk; | 1625 | u32 pblk, lblk = BAD_BLOCK; |
1702 | u64 addr; | 1626 | u64 addr; |
1703 | u32 *pbt = (u32 *)g_pBlockTable; | 1627 | u32 *pbt = (u32 *)g_pBlockTable; |
1704 | 1628 | ||
@@ -2004,87 +1928,6 @@ static int search_l2_cache(u8 *buf, u64 logical_addr) | |||
2004 | return ret; | 1928 | return ret; |
2005 | } | 1929 | } |
2006 | 1930 | ||
2007 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | ||
2008 | * Function: FTL_Cache_Write_Back | ||
2009 | * Inputs: pointer to data cached in sys memory | ||
2010 | * address of free block in flash | ||
2011 | * Outputs: PASS=0 / FAIL=1 | ||
2012 | * Description: writes all the pages of Cache Block to flash | ||
2013 | * | ||
2014 | *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ | ||
2015 | static int FTL_Cache_Write_Back(u8 *pData, u64 blk_addr) | ||
2016 | { | ||
2017 | int i, j, iErase; | ||
2018 | u64 old_page_addr, addr, phy_addr; | ||
2019 | u32 *pbt = (u32 *)g_pBlockTable; | ||
2020 | u32 lba; | ||
2021 | |||
2022 | nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n", | ||
2023 | __FILE__, __LINE__, __func__); | ||
2024 | |||
2025 | old_page_addr = FTL_Get_Physical_Block_Addr(blk_addr) + | ||
2026 | GLOB_u64_Remainder(blk_addr, 2); | ||
2027 | |||
2028 | iErase = (FAIL == FTL_Replace_Block(blk_addr)) ? PASS : FAIL; | ||
2029 | |||
2030 | pbt[BLK_FROM_ADDR(blk_addr)] &= (~SPARE_BLOCK); | ||
2031 | |||
2032 | #if CMD_DMA | ||
2033 | p_BTableChangesDelta = (struct BTableChangesDelta *)g_pBTDelta_Free; | ||
2034 | g_pBTDelta_Free += sizeof(struct BTableChangesDelta); | ||
2035 | |||
2036 | p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt; | ||
2037 | p_BTableChangesDelta->BT_Index = (u32)(blk_addr >> | ||
2038 | DeviceInfo.nBitsInBlockDataSize); | ||
2039 | p_BTableChangesDelta->BT_Entry_Value = | ||
2040 | pbt[(u32)(blk_addr >> DeviceInfo.nBitsInBlockDataSize)]; | ||
2041 | p_BTableChangesDelta->ValidFields = 0x0C; | ||
2042 | #endif | ||
2043 | |||
2044 | if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) { | ||
2045 | g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE; | ||
2046 | FTL_Write_IN_Progress_Block_Table_Page(); | ||
2047 | } | ||
2048 | |||
2049 | for (i = 0; i < RETRY_TIMES; i++) { | ||
2050 | if (PASS == iErase) { | ||
2051 | phy_addr = FTL_Get_Physical_Block_Addr(blk_addr); | ||
2052 | if (FAIL == GLOB_FTL_Block_Erase(phy_addr)) { | ||
2053 | lba = BLK_FROM_ADDR(blk_addr); | ||
2054 | MARK_BLOCK_AS_BAD(pbt[lba]); | ||
2055 | i = RETRY_TIMES; | ||
2056 | break; | ||
2057 | } | ||
2058 | } | ||
2059 | |||
2060 | for (j = 0; j < CACHE_ITEM_NUM; j++) { | ||
2061 | addr = Cache.array[j].address; | ||
2062 | if ((addr <= blk_addr) && | ||
2063 | ((addr + Cache.cache_item_size) > blk_addr)) | ||
2064 | cache_block_to_write = j; | ||
2065 | } | ||
2066 | |||
2067 | phy_addr = FTL_Get_Physical_Block_Addr(blk_addr); | ||
2068 | if (PASS == FTL_Cache_Update_Block(pData, | ||
2069 | old_page_addr, phy_addr)) { | ||
2070 | cache_block_to_write = UNHIT_CACHE_ITEM; | ||
2071 | break; | ||
2072 | } else { | ||
2073 | iErase = PASS; | ||
2074 | } | ||
2075 | } | ||
2076 | |||
2077 | if (i >= RETRY_TIMES) { | ||
2078 | if (ERR == FTL_Flash_Error_Handle(pData, | ||
2079 | old_page_addr, blk_addr)) | ||
2080 | return ERR; | ||
2081 | else | ||
2082 | return FAIL; | ||
2083 | } | ||
2084 | |||
2085 | return PASS; | ||
2086 | } | ||
2087 | |||
2088 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | 1931 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |
2089 | * Function: FTL_Cache_Write_Page | 1932 | * Function: FTL_Cache_Write_Page |
2090 | * Inputs: Pointer to buffer, page address, cache block number | 1933 | * Inputs: Pointer to buffer, page address, cache block number |
@@ -2370,159 +2213,6 @@ static int FTL_Write_Block_Table(int wForce) | |||
2370 | return 1; | 2213 | return 1; |
2371 | } | 2214 | } |
2372 | 2215 | ||
2373 | /****************************************************************** | ||
2374 | * Function: GLOB_FTL_Flash_Format | ||
2375 | * Inputs: none | ||
2376 | * Outputs: PASS | ||
2377 | * Description: The block table stores bad block info, including MDF+ | ||
2378 | * blocks gone bad over the ages. Therefore, if we have a | ||
2379 | * block table in place, then use it to scan for bad blocks | ||
2380 | * If not, then scan for MDF. | ||
2381 | * Now, a block table will only be found if spectra was already | ||
2382 | * being used. For a fresh flash, we'll go thru scanning for | ||
2383 | * MDF. If spectra was being used, then there is a chance that | ||
2384 | * the MDF has been corrupted. Spectra avoids writing to the | ||
2385 | * first 2 bytes of the spare area to all pages in a block. This | ||
2386 | * covers all known flash devices. However, since flash | ||
2387 | * manufacturers have no standard of where the MDF is stored, | ||
2388 | * this cannot guarantee that the MDF is protected for future | ||
2389 | * devices too. The initial scanning for the block table assures | ||
2390 | * this. It is ok even if the block table is outdated, as all | ||
2391 | * we're looking for are bad block markers. | ||
2392 | * Use this when mounting a file system or starting a | ||
2393 | * new flash. | ||
2394 | * | ||
2395 | *********************************************************************/ | ||
2396 | static int FTL_Format_Flash(u8 valid_block_table) | ||
2397 | { | ||
2398 | u32 i, j; | ||
2399 | u32 *pbt = (u32 *)g_pBlockTable; | ||
2400 | u32 tempNode; | ||
2401 | int ret; | ||
2402 | |||
2403 | #if CMD_DMA | ||
2404 | u32 *pbtStartingCopy = (u32 *)g_pBTStartingCopy; | ||
2405 | if (ftl_cmd_cnt) | ||
2406 | return FAIL; | ||
2407 | #endif | ||
2408 | |||
2409 | if (FAIL == FTL_Check_Block_Table(FAIL)) | ||
2410 | valid_block_table = 0; | ||
2411 | |||
2412 | if (valid_block_table) { | ||
2413 | u8 switched = 1; | ||
2414 | u32 block, k; | ||
2415 | |||
2416 | k = DeviceInfo.wSpectraStartBlock; | ||
2417 | while (switched && (k < DeviceInfo.wSpectraEndBlock)) { | ||
2418 | switched = 0; | ||
2419 | k++; | ||
2420 | for (j = DeviceInfo.wSpectraStartBlock, i = 0; | ||
2421 | j <= DeviceInfo.wSpectraEndBlock; | ||
2422 | j++, i++) { | ||
2423 | block = (pbt[i] & ~BAD_BLOCK) - | ||
2424 | DeviceInfo.wSpectraStartBlock; | ||
2425 | if (block != i) { | ||
2426 | switched = 1; | ||
2427 | tempNode = pbt[i]; | ||
2428 | pbt[i] = pbt[block]; | ||
2429 | pbt[block] = tempNode; | ||
2430 | } | ||
2431 | } | ||
2432 | } | ||
2433 | if ((k == DeviceInfo.wSpectraEndBlock) && switched) | ||
2434 | valid_block_table = 0; | ||
2435 | } | ||
2436 | |||
2437 | if (!valid_block_table) { | ||
2438 | memset(g_pBlockTable, 0, | ||
2439 | DeviceInfo.wDataBlockNum * sizeof(u32)); | ||
2440 | memset(g_pWearCounter, 0, | ||
2441 | DeviceInfo.wDataBlockNum * sizeof(u8)); | ||
2442 | if (DeviceInfo.MLCDevice) | ||
2443 | memset(g_pReadCounter, 0, | ||
2444 | DeviceInfo.wDataBlockNum * sizeof(u16)); | ||
2445 | #if CMD_DMA | ||
2446 | memset(g_pBTStartingCopy, 0, | ||
2447 | DeviceInfo.wDataBlockNum * sizeof(u32)); | ||
2448 | memset(g_pWearCounterCopy, 0, | ||
2449 | DeviceInfo.wDataBlockNum * sizeof(u8)); | ||
2450 | if (DeviceInfo.MLCDevice) | ||
2451 | memset(g_pReadCounterCopy, 0, | ||
2452 | DeviceInfo.wDataBlockNum * sizeof(u16)); | ||
2453 | #endif | ||
2454 | for (j = DeviceInfo.wSpectraStartBlock, i = 0; | ||
2455 | j <= DeviceInfo.wSpectraEndBlock; | ||
2456 | j++, i++) { | ||
2457 | if (GLOB_LLD_Get_Bad_Block((u32)j)) | ||
2458 | pbt[i] = (u32)(BAD_BLOCK | j); | ||
2459 | } | ||
2460 | } | ||
2461 | |||
2462 | nand_dbg_print(NAND_DBG_WARN, "Erasing all blocks in the NAND\n"); | ||
2463 | |||
2464 | for (j = DeviceInfo.wSpectraStartBlock, i = 0; | ||
2465 | j <= DeviceInfo.wSpectraEndBlock; | ||
2466 | j++, i++) { | ||
2467 | if ((pbt[i] & BAD_BLOCK) != BAD_BLOCK) { | ||
2468 | ret = GLOB_LLD_Erase_Block(j); | ||
2469 | if (FAIL == ret) { | ||
2470 | pbt[i] = (u32)(j); | ||
2471 | MARK_BLOCK_AS_BAD(pbt[i]); | ||
2472 | nand_dbg_print(NAND_DBG_WARN, | ||
2473 | "NAND Program fail in %s, Line %d, " | ||
2474 | "Function: %s, new Bad Block %d generated!\n", | ||
2475 | __FILE__, __LINE__, __func__, (int)j); | ||
2476 | } else { | ||
2477 | pbt[i] = (u32)(SPARE_BLOCK | j); | ||
2478 | } | ||
2479 | } | ||
2480 | #if CMD_DMA | ||
2481 | pbtStartingCopy[i] = pbt[i]; | ||
2482 | #endif | ||
2483 | } | ||
2484 | |||
2485 | g_wBlockTableOffset = 0; | ||
2486 | for (i = 0; (i <= (DeviceInfo.wSpectraEndBlock - | ||
2487 | DeviceInfo.wSpectraStartBlock)) | ||
2488 | && ((pbt[i] & BAD_BLOCK) == BAD_BLOCK); i++) | ||
2489 | ; | ||
2490 | if (i > (DeviceInfo.wSpectraEndBlock - DeviceInfo.wSpectraStartBlock)) { | ||
2491 | printk(KERN_ERR "All blocks bad!\n"); | ||
2492 | return FAIL; | ||
2493 | } else { | ||
2494 | g_wBlockTableIndex = pbt[i] & ~BAD_BLOCK; | ||
2495 | if (i != BLOCK_TABLE_INDEX) { | ||
2496 | tempNode = pbt[i]; | ||
2497 | pbt[i] = pbt[BLOCK_TABLE_INDEX]; | ||
2498 | pbt[BLOCK_TABLE_INDEX] = tempNode; | ||
2499 | } | ||
2500 | } | ||
2501 | pbt[BLOCK_TABLE_INDEX] &= (~SPARE_BLOCK); | ||
2502 | |||
2503 | #if CMD_DMA | ||
2504 | pbtStartingCopy[BLOCK_TABLE_INDEX] &= (~SPARE_BLOCK); | ||
2505 | #endif | ||
2506 | |||
2507 | g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE; | ||
2508 | memset(g_pBTBlocks, 0xFF, | ||
2509 | (1 + LAST_BT_ID - FIRST_BT_ID) * sizeof(u32)); | ||
2510 | g_pBTBlocks[FIRST_BT_ID-FIRST_BT_ID] = g_wBlockTableIndex; | ||
2511 | FTL_Write_Block_Table(FAIL); | ||
2512 | |||
2513 | for (i = 0; i < CACHE_ITEM_NUM; i++) { | ||
2514 | Cache.array[i].address = NAND_CACHE_INIT_ADDR; | ||
2515 | Cache.array[i].use_cnt = 0; | ||
2516 | Cache.array[i].changed = CLEAR; | ||
2517 | } | ||
2518 | |||
2519 | #if (RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE && CMD_DMA) | ||
2520 | memcpy((void *)&cache_start_copy, (void *)&Cache, | ||
2521 | sizeof(struct flash_cache_tag)); | ||
2522 | #endif | ||
2523 | return PASS; | ||
2524 | } | ||
2525 | |||
2526 | static int force_format_nand(void) | 2216 | static int force_format_nand(void) |
2527 | { | 2217 | { |
2528 | u32 i; | 2218 | u32 i; |
@@ -3031,112 +2721,6 @@ static int FTL_Read_Block_Table(void) | |||
3031 | return wResult; | 2721 | return wResult; |
3032 | } | 2722 | } |
3033 | 2723 | ||
3034 | |||
3035 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | ||
3036 | * Function: FTL_Flash_Error_Handle | ||
3037 | * Inputs: Pointer to data | ||
3038 | * Page address | ||
3039 | * Block address | ||
3040 | * Outputs: PASS=0 / FAIL=1 | ||
3041 | * Description: It handles any error occured during Spectra operation | ||
3042 | *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ | ||
3043 | static int FTL_Flash_Error_Handle(u8 *pData, u64 old_page_addr, | ||
3044 | u64 blk_addr) | ||
3045 | { | ||
3046 | u32 i; | ||
3047 | int j; | ||
3048 | u32 tmp_node, blk_node = BLK_FROM_ADDR(blk_addr); | ||
3049 | u64 phy_addr; | ||
3050 | int wErase = FAIL; | ||
3051 | int wResult = FAIL; | ||
3052 | u32 *pbt = (u32 *)g_pBlockTable; | ||
3053 | |||
3054 | nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n", | ||
3055 | __FILE__, __LINE__, __func__); | ||
3056 | |||
3057 | if (ERR == GLOB_FTL_Garbage_Collection()) | ||
3058 | return ERR; | ||
3059 | |||
3060 | do { | ||
3061 | for (i = DeviceInfo.wSpectraEndBlock - | ||
3062 | DeviceInfo.wSpectraStartBlock; | ||
3063 | i > 0; i--) { | ||
3064 | if (IS_SPARE_BLOCK(i)) { | ||
3065 | tmp_node = (u32)(BAD_BLOCK | | ||
3066 | pbt[blk_node]); | ||
3067 | pbt[blk_node] = (u32)(pbt[i] & | ||
3068 | (~SPARE_BLOCK)); | ||
3069 | pbt[i] = tmp_node; | ||
3070 | #if CMD_DMA | ||
3071 | p_BTableChangesDelta = | ||
3072 | (struct BTableChangesDelta *) | ||
3073 | g_pBTDelta_Free; | ||
3074 | g_pBTDelta_Free += | ||
3075 | sizeof(struct BTableChangesDelta); | ||
3076 | |||
3077 | p_BTableChangesDelta->ftl_cmd_cnt = | ||
3078 | ftl_cmd_cnt; | ||
3079 | p_BTableChangesDelta->BT_Index = | ||
3080 | blk_node; | ||
3081 | p_BTableChangesDelta->BT_Entry_Value = | ||
3082 | pbt[blk_node]; | ||
3083 | p_BTableChangesDelta->ValidFields = 0x0C; | ||
3084 | |||
3085 | p_BTableChangesDelta = | ||
3086 | (struct BTableChangesDelta *) | ||
3087 | g_pBTDelta_Free; | ||
3088 | g_pBTDelta_Free += | ||
3089 | sizeof(struct BTableChangesDelta); | ||
3090 | |||
3091 | p_BTableChangesDelta->ftl_cmd_cnt = | ||
3092 | ftl_cmd_cnt; | ||
3093 | p_BTableChangesDelta->BT_Index = i; | ||
3094 | p_BTableChangesDelta->BT_Entry_Value = pbt[i]; | ||
3095 | p_BTableChangesDelta->ValidFields = 0x0C; | ||
3096 | #endif | ||
3097 | wResult = PASS; | ||
3098 | break; | ||
3099 | } | ||
3100 | } | ||
3101 | |||
3102 | if (FAIL == wResult) { | ||
3103 | if (FAIL == GLOB_FTL_Garbage_Collection()) | ||
3104 | break; | ||
3105 | else | ||
3106 | continue; | ||
3107 | } | ||
3108 | |||
3109 | if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) { | ||
3110 | g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE; | ||
3111 | FTL_Write_IN_Progress_Block_Table_Page(); | ||
3112 | } | ||
3113 | |||
3114 | phy_addr = FTL_Get_Physical_Block_Addr(blk_addr); | ||
3115 | |||
3116 | for (j = 0; j < RETRY_TIMES; j++) { | ||
3117 | if (PASS == wErase) { | ||
3118 | if (FAIL == GLOB_FTL_Block_Erase(phy_addr)) { | ||
3119 | MARK_BLOCK_AS_BAD(pbt[blk_node]); | ||
3120 | break; | ||
3121 | } | ||
3122 | } | ||
3123 | if (PASS == FTL_Cache_Update_Block(pData, | ||
3124 | old_page_addr, | ||
3125 | phy_addr)) { | ||
3126 | wResult = PASS; | ||
3127 | break; | ||
3128 | } else { | ||
3129 | wResult = FAIL; | ||
3130 | wErase = PASS; | ||
3131 | } | ||
3132 | } | ||
3133 | } while (FAIL == wResult); | ||
3134 | |||
3135 | FTL_Write_Block_Table(FAIL); | ||
3136 | |||
3137 | return wResult; | ||
3138 | } | ||
3139 | |||
3140 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | 2724 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |
3141 | * Function: FTL_Get_Page_Num | 2725 | * Function: FTL_Get_Page_Num |
3142 | * Inputs: Size in bytes | 2726 | * Inputs: Size in bytes |
diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index 368c30a9d5f..4af83d5318f 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c | |||
@@ -219,6 +219,7 @@ int prism2_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
219 | return -ENOENT; | 219 | return -ENOENT; |
220 | params.key_len = len; | 220 | params.key_len = len; |
221 | params.key = wlandev->wep_keys[key_index]; | 221 | params.key = wlandev->wep_keys[key_index]; |
222 | params.seq_len = 0; | ||
222 | 223 | ||
223 | callback(cookie, ¶ms); | 224 | callback(cookie, ¶ms); |
224 | 225 | ||
@@ -735,6 +736,8 @@ struct wiphy *wlan_create_wiphy(struct device *dev, wlandevice_t *wlandev) | |||
735 | priv->band.n_channels = ARRAY_SIZE(prism2_channels); | 736 | priv->band.n_channels = ARRAY_SIZE(prism2_channels); |
736 | priv->band.bitrates = priv->rates; | 737 | priv->band.bitrates = priv->rates; |
737 | priv->band.n_bitrates = ARRAY_SIZE(prism2_rates); | 738 | priv->band.n_bitrates = ARRAY_SIZE(prism2_rates); |
739 | priv->band.band = IEEE80211_BAND_2GHZ; | ||
740 | priv->band.ht_cap.ht_supported = false; | ||
738 | wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; | 741 | wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; |
739 | 742 | ||
740 | set_wiphy_dev(wiphy, dev); | 743 | set_wiphy_dev(wiphy, dev); |
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 77d4d715a78..722c840ac63 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c | |||
@@ -769,6 +769,7 @@ static int __init zram_init(void) | |||
769 | free_devices: | 769 | free_devices: |
770 | while (dev_id) | 770 | while (dev_id) |
771 | destroy_device(&devices[--dev_id]); | 771 | destroy_device(&devices[--dev_id]); |
772 | kfree(devices); | ||
772 | unregister: | 773 | unregister: |
773 | unregister_blkdev(zram_major, "zram"); | 774 | unregister_blkdev(zram_major, "zram"); |
774 | out: | 775 | out: |
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 1c320bfa6fb..f383cb42b1d 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c | |||
@@ -1127,6 +1127,7 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, | |||
1127 | { | 1127 | { |
1128 | struct cxacru_data *instance; | 1128 | struct cxacru_data *instance; |
1129 | struct usb_device *usb_dev = interface_to_usbdev(intf); | 1129 | struct usb_device *usb_dev = interface_to_usbdev(intf); |
1130 | struct usb_host_endpoint *cmd_ep = usb_dev->ep_in[CXACRU_EP_CMD]; | ||
1130 | int ret; | 1131 | int ret; |
1131 | 1132 | ||
1132 | /* instance init */ | 1133 | /* instance init */ |
@@ -1171,15 +1172,34 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, | |||
1171 | goto fail; | 1172 | goto fail; |
1172 | } | 1173 | } |
1173 | 1174 | ||
1174 | usb_fill_int_urb(instance->rcv_urb, | 1175 | if (!cmd_ep) { |
1176 | dbg("cxacru_bind: no command endpoint"); | ||
1177 | ret = -ENODEV; | ||
1178 | goto fail; | ||
1179 | } | ||
1180 | |||
1181 | if ((cmd_ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | ||
1182 | == USB_ENDPOINT_XFER_INT) { | ||
1183 | usb_fill_int_urb(instance->rcv_urb, | ||
1175 | usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD), | 1184 | usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD), |
1176 | instance->rcv_buf, PAGE_SIZE, | 1185 | instance->rcv_buf, PAGE_SIZE, |
1177 | cxacru_blocking_completion, &instance->rcv_done, 1); | 1186 | cxacru_blocking_completion, &instance->rcv_done, 1); |
1178 | 1187 | ||
1179 | usb_fill_int_urb(instance->snd_urb, | 1188 | usb_fill_int_urb(instance->snd_urb, |
1180 | usb_dev, usb_sndintpipe(usb_dev, CXACRU_EP_CMD), | 1189 | usb_dev, usb_sndintpipe(usb_dev, CXACRU_EP_CMD), |
1181 | instance->snd_buf, PAGE_SIZE, | 1190 | instance->snd_buf, PAGE_SIZE, |
1182 | cxacru_blocking_completion, &instance->snd_done, 4); | 1191 | cxacru_blocking_completion, &instance->snd_done, 4); |
1192 | } else { | ||
1193 | usb_fill_bulk_urb(instance->rcv_urb, | ||
1194 | usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_CMD), | ||
1195 | instance->rcv_buf, PAGE_SIZE, | ||
1196 | cxacru_blocking_completion, &instance->rcv_done); | ||
1197 | |||
1198 | usb_fill_bulk_urb(instance->snd_urb, | ||
1199 | usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD), | ||
1200 | instance->snd_buf, PAGE_SIZE, | ||
1201 | cxacru_blocking_completion, &instance->snd_done); | ||
1202 | } | ||
1183 | 1203 | ||
1184 | mutex_init(&instance->cm_serialize); | 1204 | mutex_init(&instance->cm_serialize); |
1185 | 1205 | ||
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 1833b3a7151..bc62fae0680 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -965,7 +965,8 @@ static int acm_probe(struct usb_interface *intf, | |||
965 | } | 965 | } |
966 | 966 | ||
967 | if (!buflen) { | 967 | if (!buflen) { |
968 | if (intf->cur_altsetting->endpoint->extralen && | 968 | if (intf->cur_altsetting->endpoint && |
969 | intf->cur_altsetting->endpoint->extralen && | ||
969 | intf->cur_altsetting->endpoint->extra) { | 970 | intf->cur_altsetting->endpoint->extra) { |
970 | dev_dbg(&intf->dev, | 971 | dev_dbg(&intf->dev, |
971 | "Seeking extra descriptors on endpoint\n"); | 972 | "Seeking extra descriptors on endpoint\n"); |
@@ -1481,6 +1482,11 @@ static int acm_reset_resume(struct usb_interface *intf) | |||
1481 | USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, \ | 1482 | USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, \ |
1482 | USB_CDC_ACM_PROTO_VENDOR) | 1483 | USB_CDC_ACM_PROTO_VENDOR) |
1483 | 1484 | ||
1485 | #define SAMSUNG_PCSUITE_ACM_INFO(x) \ | ||
1486 | USB_DEVICE_AND_INTERFACE_INFO(0x04e7, x, \ | ||
1487 | USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, \ | ||
1488 | USB_CDC_ACM_PROTO_VENDOR) | ||
1489 | |||
1484 | /* | 1490 | /* |
1485 | * USB driver structure. | 1491 | * USB driver structure. |
1486 | */ | 1492 | */ |
@@ -1591,6 +1597,17 @@ static const struct usb_device_id acm_ids[] = { | |||
1591 | { NOKIA_PCSUITE_ACM_INFO(0x0108), }, /* Nokia 5320 XpressMusic 2G */ | 1597 | { NOKIA_PCSUITE_ACM_INFO(0x0108), }, /* Nokia 5320 XpressMusic 2G */ |
1592 | { NOKIA_PCSUITE_ACM_INFO(0x01f5), }, /* Nokia N97, RM-505 */ | 1598 | { NOKIA_PCSUITE_ACM_INFO(0x01f5), }, /* Nokia N97, RM-505 */ |
1593 | { NOKIA_PCSUITE_ACM_INFO(0x02e3), }, /* Nokia 5230, RM-588 */ | 1599 | { NOKIA_PCSUITE_ACM_INFO(0x02e3), }, /* Nokia 5230, RM-588 */ |
1600 | { NOKIA_PCSUITE_ACM_INFO(0x0178), }, /* Nokia E63 */ | ||
1601 | { NOKIA_PCSUITE_ACM_INFO(0x010e), }, /* Nokia E75 */ | ||
1602 | { NOKIA_PCSUITE_ACM_INFO(0x02d9), }, /* Nokia 6760 Slide */ | ||
1603 | { NOKIA_PCSUITE_ACM_INFO(0x01d0), }, /* Nokia E52 */ | ||
1604 | { NOKIA_PCSUITE_ACM_INFO(0x0223), }, /* Nokia E72 */ | ||
1605 | { NOKIA_PCSUITE_ACM_INFO(0x0275), }, /* Nokia X6 */ | ||
1606 | { NOKIA_PCSUITE_ACM_INFO(0x026c), }, /* Nokia N97 Mini */ | ||
1607 | { NOKIA_PCSUITE_ACM_INFO(0x0154), }, /* Nokia 5800 XpressMusic */ | ||
1608 | { NOKIA_PCSUITE_ACM_INFO(0x04ce), }, /* Nokia E90 */ | ||
1609 | { NOKIA_PCSUITE_ACM_INFO(0x01d4), }, /* Nokia E55 */ | ||
1610 | { SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */ | ||
1594 | 1611 | ||
1595 | /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ | 1612 | /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ |
1596 | 1613 | ||
@@ -1599,6 +1616,10 @@ static const struct usb_device_id acm_ids[] = { | |||
1599 | .driver_info = NOT_A_MODEM, | 1616 | .driver_info = NOT_A_MODEM, |
1600 | }, | 1617 | }, |
1601 | 1618 | ||
1619 | /* control interfaces without any protocol set */ | ||
1620 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, | ||
1621 | USB_CDC_PROTO_NONE) }, | ||
1622 | |||
1602 | /* control interfaces with various AT-command sets */ | 1623 | /* control interfaces with various AT-command sets */ |
1603 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, | 1624 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, |
1604 | USB_CDC_ACM_PROTO_AT_V25TER) }, | 1625 | USB_CDC_ACM_PROTO_AT_V25TER) }, |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index fd4c36ea5e4..844683e5038 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1724,6 +1724,15 @@ free_interfaces: | |||
1724 | if (ret) | 1724 | if (ret) |
1725 | goto free_interfaces; | 1725 | goto free_interfaces; |
1726 | 1726 | ||
1727 | /* if it's already configured, clear out old state first. | ||
1728 | * getting rid of old interfaces means unbinding their drivers. | ||
1729 | */ | ||
1730 | if (dev->state != USB_STATE_ADDRESS) | ||
1731 | usb_disable_device(dev, 1); /* Skip ep0 */ | ||
1732 | |||
1733 | /* Get rid of pending async Set-Config requests for this device */ | ||
1734 | cancel_async_set_config(dev); | ||
1735 | |||
1727 | /* Make sure we have bandwidth (and available HCD resources) for this | 1736 | /* Make sure we have bandwidth (and available HCD resources) for this |
1728 | * configuration. Remove endpoints from the schedule if we're dropping | 1737 | * configuration. Remove endpoints from the schedule if we're dropping |
1729 | * this configuration to set configuration 0. After this point, the | 1738 | * this configuration to set configuration 0. After this point, the |
@@ -1733,20 +1742,11 @@ free_interfaces: | |||
1733 | mutex_lock(&hcd->bandwidth_mutex); | 1742 | mutex_lock(&hcd->bandwidth_mutex); |
1734 | ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); | 1743 | ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); |
1735 | if (ret < 0) { | 1744 | if (ret < 0) { |
1736 | usb_autosuspend_device(dev); | ||
1737 | mutex_unlock(&hcd->bandwidth_mutex); | 1745 | mutex_unlock(&hcd->bandwidth_mutex); |
1746 | usb_autosuspend_device(dev); | ||
1738 | goto free_interfaces; | 1747 | goto free_interfaces; |
1739 | } | 1748 | } |
1740 | 1749 | ||
1741 | /* if it's already configured, clear out old state first. | ||
1742 | * getting rid of old interfaces means unbinding their drivers. | ||
1743 | */ | ||
1744 | if (dev->state != USB_STATE_ADDRESS) | ||
1745 | usb_disable_device(dev, 1); /* Skip ep0 */ | ||
1746 | |||
1747 | /* Get rid of pending async Set-Config requests for this device */ | ||
1748 | cancel_async_set_config(dev); | ||
1749 | |||
1750 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 1750 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
1751 | USB_REQ_SET_CONFIGURATION, 0, configuration, 0, | 1751 | USB_REQ_SET_CONFIGURATION, 0, configuration, 0, |
1752 | NULL, 0, USB_CTRL_SET_TIMEOUT); | 1752 | NULL, 0, USB_CTRL_SET_TIMEOUT); |
@@ -1761,8 +1761,8 @@ free_interfaces: | |||
1761 | if (!cp) { | 1761 | if (!cp) { |
1762 | usb_set_device_state(dev, USB_STATE_ADDRESS); | 1762 | usb_set_device_state(dev, USB_STATE_ADDRESS); |
1763 | usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); | 1763 | usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); |
1764 | usb_autosuspend_device(dev); | ||
1765 | mutex_unlock(&hcd->bandwidth_mutex); | 1764 | mutex_unlock(&hcd->bandwidth_mutex); |
1765 | usb_autosuspend_device(dev); | ||
1766 | goto free_interfaces; | 1766 | goto free_interfaces; |
1767 | } | 1767 | } |
1768 | mutex_unlock(&hcd->bandwidth_mutex); | 1768 | mutex_unlock(&hcd->bandwidth_mutex); |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index e483f80822d..1160c55de7f 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
@@ -723,12 +723,12 @@ int usb_string_ids_tab(struct usb_composite_dev *cdev, struct usb_string *str) | |||
723 | 723 | ||
724 | /** | 724 | /** |
725 | * usb_string_ids_n() - allocate unused string IDs in batch | 725 | * usb_string_ids_n() - allocate unused string IDs in batch |
726 | * @cdev: the device whose string descriptor IDs are being allocated | 726 | * @c: the device whose string descriptor IDs are being allocated |
727 | * @n: number of string IDs to allocate | 727 | * @n: number of string IDs to allocate |
728 | * Context: single threaded during gadget setup | 728 | * Context: single threaded during gadget setup |
729 | * | 729 | * |
730 | * Returns the first requested ID. This ID and next @n-1 IDs are now | 730 | * Returns the first requested ID. This ID and next @n-1 IDs are now |
731 | * valid IDs. At least providind that @n is non zore because if it | 731 | * valid IDs. At least provided that @n is non-zero because if it |
732 | * is, returns last requested ID which is now very useful information. | 732 | * is, returns last requested ID which is now very useful information. |
733 | * | 733 | * |
734 | * @usb_string_ids_n() is called from bind() callbacks to allocate | 734 | * @usb_string_ids_n() is called from bind() callbacks to allocate |
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 166bf71fd34..e03058fe23c 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c | |||
@@ -1609,6 +1609,7 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1609 | /* initialize ucd */ | 1609 | /* initialize ucd */ |
1610 | m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL); | 1610 | m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL); |
1611 | if (m66592 == NULL) { | 1611 | if (m66592 == NULL) { |
1612 | ret = -ENOMEM; | ||
1612 | pr_err("kzalloc error\n"); | 1613 | pr_err("kzalloc error\n"); |
1613 | goto clean_up; | 1614 | goto clean_up; |
1614 | } | 1615 | } |
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 70a81784275..2456ccd9965 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c | |||
@@ -1557,6 +1557,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) | |||
1557 | /* initialize ucd */ | 1557 | /* initialize ucd */ |
1558 | r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL); | 1558 | r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL); |
1559 | if (r8a66597 == NULL) { | 1559 | if (r8a66597 == NULL) { |
1560 | ret = -ENOMEM; | ||
1560 | printk(KERN_ERR "kzalloc error\n"); | 1561 | printk(KERN_ERR "kzalloc error\n"); |
1561 | goto clean_up; | 1562 | goto clean_up; |
1562 | } | 1563 | } |
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 020fa5a25fd..972d5ddd1e1 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c | |||
@@ -293,9 +293,13 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
293 | /* mandatory */ | 293 | /* mandatory */ |
294 | case OID_GEN_VENDOR_DESCRIPTION: | 294 | case OID_GEN_VENDOR_DESCRIPTION: |
295 | pr_debug("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__); | 295 | pr_debug("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__); |
296 | length = strlen (rndis_per_dev_params [configNr].vendorDescr); | 296 | if ( rndis_per_dev_params [configNr].vendorDescr ) { |
297 | memcpy (outbuf, | 297 | length = strlen (rndis_per_dev_params [configNr].vendorDescr); |
298 | rndis_per_dev_params [configNr].vendorDescr, length); | 298 | memcpy (outbuf, |
299 | rndis_per_dev_params [configNr].vendorDescr, length); | ||
300 | } else { | ||
301 | outbuf[0] = 0; | ||
302 | } | ||
299 | retval = 0; | 303 | retval = 0; |
300 | break; | 304 | break; |
301 | 305 | ||
@@ -1148,7 +1152,7 @@ static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS]; | |||
1148 | #endif /* CONFIG_USB_GADGET_DEBUG_FILES */ | 1152 | #endif /* CONFIG_USB_GADGET_DEBUG_FILES */ |
1149 | 1153 | ||
1150 | 1154 | ||
1151 | int __init rndis_init (void) | 1155 | int rndis_init(void) |
1152 | { | 1156 | { |
1153 | u8 i; | 1157 | u8 i; |
1154 | 1158 | ||
diff --git a/drivers/usb/gadget/rndis.h b/drivers/usb/gadget/rndis.h index c236aaa9dcd..907c3300811 100644 --- a/drivers/usb/gadget/rndis.h +++ b/drivers/usb/gadget/rndis.h | |||
@@ -262,7 +262,7 @@ int rndis_signal_disconnect (int configNr); | |||
262 | int rndis_state (int configNr); | 262 | int rndis_state (int configNr); |
263 | extern void rndis_set_host_mac (int configNr, const u8 *addr); | 263 | extern void rndis_set_host_mac (int configNr, const u8 *addr); |
264 | 264 | ||
265 | int __devinit rndis_init (void); | 265 | int rndis_init(void); |
266 | void rndis_exit (void); | 266 | void rndis_exit (void); |
267 | 267 | ||
268 | #endif /* _LINUX_RNDIS_H */ | 268 | #endif /* _LINUX_RNDIS_H */ |
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 521ebed0118..a229744a8c7 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
@@ -12,8 +12,6 @@ | |||
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #define DEBUG | ||
16 | |||
17 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
18 | #include <linux/module.h> | 16 | #include <linux/module.h> |
19 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/uvc_v4l2.c index 2dcffdac86d..5e807f083bc 100644 --- a/drivers/usb/gadget/uvc_v4l2.c +++ b/drivers/usb/gadget/uvc_v4l2.c | |||
@@ -94,7 +94,7 @@ uvc_v4l2_set_format(struct uvc_video *video, struct v4l2_format *fmt) | |||
94 | break; | 94 | break; |
95 | } | 95 | } |
96 | 96 | ||
97 | if (format == NULL || format->fcc != fmt->fmt.pix.pixelformat) { | 97 | if (i == ARRAY_SIZE(uvc_formats)) { |
98 | printk(KERN_INFO "Unsupported format 0x%08x.\n", | 98 | printk(KERN_INFO "Unsupported format 0x%08x.\n", |
99 | fmt->fmt.pix.pixelformat); | 99 | fmt->fmt.pix.pixelformat); |
100 | return -EINVAL; | 100 | return -EINVAL; |
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index 335ee699fd8..ba52be47302 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c | |||
@@ -192,17 +192,19 @@ ehci_hcd_ppc_of_probe(struct platform_device *op, const struct of_device_id *mat | |||
192 | } | 192 | } |
193 | 193 | ||
194 | rv = usb_add_hcd(hcd, irq, 0); | 194 | rv = usb_add_hcd(hcd, irq, 0); |
195 | if (rv == 0) | 195 | if (rv) |
196 | return 0; | 196 | goto err_ehci; |
197 | |||
198 | return 0; | ||
197 | 199 | ||
200 | err_ehci: | ||
201 | if (ehci->has_amcc_usb23) | ||
202 | iounmap(ehci->ohci_hcctrl_reg); | ||
198 | iounmap(hcd->regs); | 203 | iounmap(hcd->regs); |
199 | err_ioremap: | 204 | err_ioremap: |
200 | irq_dispose_mapping(irq); | 205 | irq_dispose_mapping(irq); |
201 | err_irq: | 206 | err_irq: |
202 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 207 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
203 | |||
204 | if (ehci->has_amcc_usb23) | ||
205 | iounmap(ehci->ohci_hcctrl_reg); | ||
206 | err_rmr: | 208 | err_rmr: |
207 | usb_put_hcd(hcd); | 209 | usb_put_hcd(hcd); |
208 | 210 | ||
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index d1a3dfc9a40..bdba8c5d844 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c | |||
@@ -829,6 +829,7 @@ static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, | |||
829 | * almost immediately. With ISP1761, this register requires a delay of | 829 | * almost immediately. With ISP1761, this register requires a delay of |
830 | * 195ns between a write and subsequent read (see section 15.1.1.3). | 830 | * 195ns between a write and subsequent read (see section 15.1.1.3). |
831 | */ | 831 | */ |
832 | mmiowb(); | ||
832 | ndelay(195); | 833 | ndelay(195); |
833 | skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG); | 834 | skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG); |
834 | 835 | ||
@@ -870,6 +871,7 @@ static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, | |||
870 | * almost immediately. With ISP1761, this register requires a delay of | 871 | * almost immediately. With ISP1761, this register requires a delay of |
871 | * 195ns between a write and subsequent read (see section 15.1.1.3). | 872 | * 195ns between a write and subsequent read (see section 15.1.1.3). |
872 | */ | 873 | */ |
874 | mmiowb(); | ||
873 | ndelay(195); | 875 | ndelay(195); |
874 | skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG); | 876 | skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG); |
875 | 877 | ||
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index bc3f4f42706..48e60d166ff 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -131,7 +131,7 @@ static void next_trb(struct xhci_hcd *xhci, | |||
131 | *seg = (*seg)->next; | 131 | *seg = (*seg)->next; |
132 | *trb = ((*seg)->trbs); | 132 | *trb = ((*seg)->trbs); |
133 | } else { | 133 | } else { |
134 | *trb = (*trb)++; | 134 | (*trb)++; |
135 | } | 135 | } |
136 | } | 136 | } |
137 | 137 | ||
@@ -1551,6 +1551,10 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1551 | /* calc actual length */ | 1551 | /* calc actual length */ |
1552 | if (ep->skip) { | 1552 | if (ep->skip) { |
1553 | td->urb->iso_frame_desc[idx].actual_length = 0; | 1553 | td->urb->iso_frame_desc[idx].actual_length = 0; |
1554 | /* Update ring dequeue pointer */ | ||
1555 | while (ep_ring->dequeue != td->last_trb) | ||
1556 | inc_deq(xhci, ep_ring, false); | ||
1557 | inc_deq(xhci, ep_ring, false); | ||
1554 | return finish_td(xhci, td, event_trb, event, ep, status, true); | 1558 | return finish_td(xhci, td, event_trb, event, ep, status, true); |
1555 | } | 1559 | } |
1556 | 1560 | ||
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index d240de097c6..801324af947 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c | |||
@@ -439,7 +439,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, | |||
439 | /* drain secondary buffer */ | 439 | /* drain secondary buffer */ |
440 | int amount = bytes_to_read < data_in_secondary ? bytes_to_read : data_in_secondary; | 440 | int amount = bytes_to_read < data_in_secondary ? bytes_to_read : data_in_secondary; |
441 | i = copy_to_user(buffer, dev->read_buffer_secondary+dev->secondary_head, amount); | 441 | i = copy_to_user(buffer, dev->read_buffer_secondary+dev->secondary_head, amount); |
442 | if (i < 0) { | 442 | if (i) { |
443 | retval = -EFAULT; | 443 | retval = -EFAULT; |
444 | goto exit; | 444 | goto exit; |
445 | } | 445 | } |
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 2de49c8887c..bc88c79875a 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c | |||
@@ -542,7 +542,7 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd, | |||
542 | retval = io_res; | 542 | retval = io_res; |
543 | else { | 543 | else { |
544 | io_res = copy_to_user(user_buffer, buffer, dev->report_size); | 544 | io_res = copy_to_user(user_buffer, buffer, dev->report_size); |
545 | if (io_res < 0) | 545 | if (io_res) |
546 | retval = -EFAULT; | 546 | retval = -EFAULT; |
547 | } | 547 | } |
548 | break; | 548 | break; |
@@ -574,7 +574,7 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd, | |||
574 | } | 574 | } |
575 | io_res = copy_to_user((struct iowarrior_info __user *)arg, &info, | 575 | io_res = copy_to_user((struct iowarrior_info __user *)arg, &info, |
576 | sizeof(struct iowarrior_info)); | 576 | sizeof(struct iowarrior_info)); |
577 | if (io_res < 0) | 577 | if (io_res) |
578 | retval = -EFAULT; | 578 | retval = -EFAULT; |
579 | break; | 579 | break; |
580 | } | 580 | } |
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 0e8888588d4..05aaac1c386 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c | |||
@@ -550,6 +550,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
550 | struct twl4030_usb_data *pdata = pdev->dev.platform_data; | 550 | struct twl4030_usb_data *pdata = pdev->dev.platform_data; |
551 | struct twl4030_usb *twl; | 551 | struct twl4030_usb *twl; |
552 | int status, err; | 552 | int status, err; |
553 | u8 pwr; | ||
553 | 554 | ||
554 | if (!pdata) { | 555 | if (!pdata) { |
555 | dev_dbg(&pdev->dev, "platform_data not available\n"); | 556 | dev_dbg(&pdev->dev, "platform_data not available\n"); |
@@ -568,7 +569,10 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
568 | twl->otg.set_peripheral = twl4030_set_peripheral; | 569 | twl->otg.set_peripheral = twl4030_set_peripheral; |
569 | twl->otg.set_suspend = twl4030_set_suspend; | 570 | twl->otg.set_suspend = twl4030_set_suspend; |
570 | twl->usb_mode = pdata->usb_mode; | 571 | twl->usb_mode = pdata->usb_mode; |
571 | twl->asleep = 1; | 572 | |
573 | pwr = twl4030_usb_read(twl, PHY_PWR_CTRL); | ||
574 | |||
575 | twl->asleep = (pwr & PHY_PWR_PHYPWD); | ||
572 | 576 | ||
573 | /* init spinlock for workqueue */ | 577 | /* init spinlock for workqueue */ |
574 | spin_lock_init(&twl->lock); | 578 | spin_lock_init(&twl->lock); |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 2bef4415c19..4f1744c5871 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -56,6 +56,7 @@ static int debug; | |||
56 | static const struct usb_device_id id_table[] = { | 56 | static const struct usb_device_id id_table[] = { |
57 | { USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */ | 57 | { USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */ |
58 | { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ | 58 | { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ |
59 | { USB_DEVICE(0x0489, 0xE003) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ | ||
59 | { USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */ | 60 | { USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */ |
60 | { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ | 61 | { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ |
61 | { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */ | 62 | { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */ |
@@ -88,6 +89,7 @@ static const struct usb_device_id id_table[] = { | |||
88 | { USB_DEVICE(0x10C4, 0x8149) }, /* West Mountain Radio Computerized Battery Analyzer */ | 89 | { USB_DEVICE(0x10C4, 0x8149) }, /* West Mountain Radio Computerized Battery Analyzer */ |
89 | { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ | 90 | { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ |
90 | { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ | 91 | { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ |
92 | { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */ | ||
91 | { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ | 93 | { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ |
92 | { USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */ | 94 | { USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */ |
93 | { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ | 95 | { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ |
@@ -109,6 +111,7 @@ static const struct usb_device_id id_table[] = { | |||
109 | { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */ | 111 | { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */ |
110 | { USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */ | 112 | { USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */ |
111 | { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ | 113 | { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ |
114 | { USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */ | ||
112 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ | 115 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ |
113 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ | 116 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ |
114 | { USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */ | 117 | { USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */ |
@@ -122,14 +125,14 @@ static const struct usb_device_id id_table[] = { | |||
122 | { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */ | 125 | { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */ |
123 | { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ | 126 | { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ |
124 | { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ | 127 | { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ |
125 | { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */ | ||
126 | { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ | ||
127 | { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ | ||
128 | { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ | ||
129 | { USB_DEVICE(0x16DC, 0x0010) }, /* W-IE-NE-R Plein & Baus GmbH PL512 Power Supply */ | 128 | { USB_DEVICE(0x16DC, 0x0010) }, /* W-IE-NE-R Plein & Baus GmbH PL512 Power Supply */ |
130 | { USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */ | 129 | { USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */ |
131 | { USB_DEVICE(0x16DC, 0x0012) }, /* W-IE-NE-R Plein & Baus GmbH MPOD Multi Channel Power Supply */ | 130 | { USB_DEVICE(0x16DC, 0x0012) }, /* W-IE-NE-R Plein & Baus GmbH MPOD Multi Channel Power Supply */ |
132 | { USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */ | 131 | { USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */ |
132 | { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */ | ||
133 | { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ | ||
134 | { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ | ||
135 | { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ | ||
133 | { } /* Terminating Entry */ | 136 | { } /* Terminating Entry */ |
134 | }; | 137 | }; |
135 | 138 | ||
@@ -222,8 +225,8 @@ static struct usb_serial_driver cp210x_device = { | |||
222 | #define BITS_STOP_2 0x0002 | 225 | #define BITS_STOP_2 0x0002 |
223 | 226 | ||
224 | /* CP210X_SET_BREAK */ | 227 | /* CP210X_SET_BREAK */ |
225 | #define BREAK_ON 0x0000 | 228 | #define BREAK_ON 0x0001 |
226 | #define BREAK_OFF 0x0001 | 229 | #define BREAK_OFF 0x0000 |
227 | 230 | ||
228 | /* CP210X_(SET_MHS|GET_MDMSTS) */ | 231 | /* CP210X_(SET_MHS|GET_MDMSTS) */ |
229 | #define CONTROL_DTR 0x0001 | 232 | #define CONTROL_DTR 0x0001 |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index eb12d9b096b..97cc87d654c 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -180,6 +180,7 @@ static struct usb_device_id id_table_combined [] = { | |||
180 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, | 180 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, |
181 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, | 181 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, |
182 | { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, | 182 | { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, |
183 | { USB_DEVICE(FTDI_VID, FTDI_LENZ_LIUSB_PID) }, | ||
183 | { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) }, | 184 | { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) }, |
184 | { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) }, | 185 | { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) }, |
185 | { USB_DEVICE(FTDI_VID, FTDI_XF_547_PID) }, | 186 | { USB_DEVICE(FTDI_VID, FTDI_XF_547_PID) }, |
@@ -750,6 +751,16 @@ static struct usb_device_id id_table_combined [] = { | |||
750 | { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH4_PID), | 751 | { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH4_PID), |
751 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 752 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
752 | { USB_DEVICE(FTDI_VID, SEGWAY_RMP200_PID) }, | 753 | { USB_DEVICE(FTDI_VID, SEGWAY_RMP200_PID) }, |
754 | { USB_DEVICE(IONICS_VID, IONICS_PLUGCOMPUTER_PID), | ||
755 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||
756 | { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_24_MASTER_WING_PID) }, | ||
757 | { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_PC_WING_PID) }, | ||
758 | { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_USB_DMX_PID) }, | ||
759 | { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MIDI_TIMECODE_PID) }, | ||
760 | { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MINI_WING_PID) }, | ||
761 | { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MAXI_WING_PID) }, | ||
762 | { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MEDIA_WING_PID) }, | ||
763 | { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_WING_PID) }, | ||
753 | { }, /* Optional parameter entry */ | 764 | { }, /* Optional parameter entry */ |
754 | { } /* Terminating entry */ | 765 | { } /* Terminating entry */ |
755 | }; | 766 | }; |
@@ -1376,7 +1387,7 @@ static void ftdi_set_max_packet_size(struct usb_serial_port *port) | |||
1376 | } | 1387 | } |
1377 | 1388 | ||
1378 | /* set max packet size based on descriptor */ | 1389 | /* set max packet size based on descriptor */ |
1379 | priv->max_packet_size = ep_desc->wMaxPacketSize; | 1390 | priv->max_packet_size = le16_to_cpu(ep_desc->wMaxPacketSize); |
1380 | 1391 | ||
1381 | dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); | 1392 | dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); |
1382 | } | 1393 | } |
@@ -1831,7 +1842,7 @@ static int ftdi_process_packet(struct tty_struct *tty, | |||
1831 | 1842 | ||
1832 | if (port->port.console && port->sysrq) { | 1843 | if (port->port.console && port->sysrq) { |
1833 | for (i = 0; i < len; i++, ch++) { | 1844 | for (i = 0; i < len; i++, ch++) { |
1834 | if (!usb_serial_handle_sysrq_char(tty, port, *ch)) | 1845 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
1835 | tty_insert_flip_char(tty, *ch, flag); | 1846 | tty_insert_flip_char(tty, *ch, flag); |
1836 | } | 1847 | } |
1837 | } else { | 1848 | } else { |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 6e612c52e76..15a4583775a 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -110,6 +110,9 @@ | |||
110 | /* Propox devices */ | 110 | /* Propox devices */ |
111 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 | 111 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 |
112 | 112 | ||
113 | /* Lenz LI-USB Computer Interface. */ | ||
114 | #define FTDI_LENZ_LIUSB_PID 0xD780 | ||
115 | |||
113 | /* | 116 | /* |
114 | * Xsens Technologies BV products (http://www.xsens.com). | 117 | * Xsens Technologies BV products (http://www.xsens.com). |
115 | */ | 118 | */ |
@@ -132,6 +135,18 @@ | |||
132 | #define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */ | 135 | #define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */ |
133 | 136 | ||
134 | /* | 137 | /* |
138 | * ChamSys Limited (www.chamsys.co.uk) USB wing/interface product IDs | ||
139 | */ | ||
140 | #define FTDI_CHAMSYS_24_MASTER_WING_PID 0xDAF8 | ||
141 | #define FTDI_CHAMSYS_PC_WING_PID 0xDAF9 | ||
142 | #define FTDI_CHAMSYS_USB_DMX_PID 0xDAFA | ||
143 | #define FTDI_CHAMSYS_MIDI_TIMECODE_PID 0xDAFB | ||
144 | #define FTDI_CHAMSYS_MINI_WING_PID 0xDAFC | ||
145 | #define FTDI_CHAMSYS_MAXI_WING_PID 0xDAFD | ||
146 | #define FTDI_CHAMSYS_MEDIA_WING_PID 0xDAFE | ||
147 | #define FTDI_CHAMSYS_WING_PID 0xDAFF | ||
148 | |||
149 | /* | ||
135 | * Westrex International devices submitted by Cory Lee | 150 | * Westrex International devices submitted by Cory Lee |
136 | */ | 151 | */ |
137 | #define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ | 152 | #define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ |
@@ -989,6 +1004,12 @@ | |||
989 | #define ALTI2_N3_PID 0x6001 /* Neptune 3 */ | 1004 | #define ALTI2_N3_PID 0x6001 /* Neptune 3 */ |
990 | 1005 | ||
991 | /* | 1006 | /* |
1007 | * Ionics PlugComputer | ||
1008 | */ | ||
1009 | #define IONICS_VID 0x1c0c | ||
1010 | #define IONICS_PLUGCOMPUTER_PID 0x0102 | ||
1011 | |||
1012 | /* | ||
992 | * Dresden Elektronik Sensor Terminal Board | 1013 | * Dresden Elektronik Sensor Terminal Board |
993 | */ | 1014 | */ |
994 | #define DE_VID 0x1cf1 /* Vendor ID */ | 1015 | #define DE_VID 0x1cf1 /* Vendor ID */ |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index ca92f67747c..e6833e216fc 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -343,7 +343,7 @@ void usb_serial_generic_process_read_urb(struct urb *urb) | |||
343 | tty_insert_flip_string(tty, ch, urb->actual_length); | 343 | tty_insert_flip_string(tty, ch, urb->actual_length); |
344 | else { | 344 | else { |
345 | for (i = 0; i < urb->actual_length; i++, ch++) { | 345 | for (i = 0; i < urb->actual_length; i++, ch++) { |
346 | if (!usb_serial_handle_sysrq_char(tty, port, *ch)) | 346 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
347 | tty_insert_flip_char(tty, *ch, TTY_NORMAL); | 347 | tty_insert_flip_char(tty, *ch, TTY_NORMAL); |
348 | } | 348 | } |
349 | } | 349 | } |
@@ -448,12 +448,11 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty) | |||
448 | EXPORT_SYMBOL_GPL(usb_serial_generic_unthrottle); | 448 | EXPORT_SYMBOL_GPL(usb_serial_generic_unthrottle); |
449 | 449 | ||
450 | #ifdef CONFIG_MAGIC_SYSRQ | 450 | #ifdef CONFIG_MAGIC_SYSRQ |
451 | int usb_serial_handle_sysrq_char(struct tty_struct *tty, | 451 | int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) |
452 | struct usb_serial_port *port, unsigned int ch) | ||
453 | { | 452 | { |
454 | if (port->sysrq && port->port.console) { | 453 | if (port->sysrq && port->port.console) { |
455 | if (ch && time_before(jiffies, port->sysrq)) { | 454 | if (ch && time_before(jiffies, port->sysrq)) { |
456 | handle_sysrq(ch, tty); | 455 | handle_sysrq(ch); |
457 | port->sysrq = 0; | 456 | port->sysrq = 0; |
458 | return 1; | 457 | return 1; |
459 | } | 458 | } |
@@ -462,8 +461,7 @@ int usb_serial_handle_sysrq_char(struct tty_struct *tty, | |||
462 | return 0; | 461 | return 0; |
463 | } | 462 | } |
464 | #else | 463 | #else |
465 | int usb_serial_handle_sysrq_char(struct tty_struct *tty, | 464 | int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) |
466 | struct usb_serial_port *port, unsigned int ch) | ||
467 | { | 465 | { |
468 | return 0; | 466 | return 0; |
469 | } | 467 | } |
@@ -518,6 +516,7 @@ void usb_serial_generic_disconnect(struct usb_serial *serial) | |||
518 | for (i = 0; i < serial->num_ports; ++i) | 516 | for (i = 0; i < serial->num_ports; ++i) |
519 | generic_cleanup(serial->port[i]); | 517 | generic_cleanup(serial->port[i]); |
520 | } | 518 | } |
519 | EXPORT_SYMBOL_GPL(usb_serial_generic_disconnect); | ||
521 | 520 | ||
522 | void usb_serial_generic_release(struct usb_serial *serial) | 521 | void usb_serial_generic_release(struct usb_serial *serial) |
523 | { | 522 | { |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index dc47f986df5..a7cfc595293 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -1151,7 +1151,7 @@ static int download_fw(struct edgeport_serial *serial) | |||
1151 | 1151 | ||
1152 | /* Check if we have an old version in the I2C and | 1152 | /* Check if we have an old version in the I2C and |
1153 | update if necessary */ | 1153 | update if necessary */ |
1154 | if (download_cur_ver != download_new_ver) { | 1154 | if (download_cur_ver < download_new_ver) { |
1155 | dbg("%s - Update I2C dld from %d.%d to %d.%d", | 1155 | dbg("%s - Update I2C dld from %d.%d to %d.%d", |
1156 | __func__, | 1156 | __func__, |
1157 | firmware_version->Ver_Major, | 1157 | firmware_version->Ver_Major, |
@@ -1284,7 +1284,7 @@ static int download_fw(struct edgeport_serial *serial) | |||
1284 | kfree(header); | 1284 | kfree(header); |
1285 | kfree(rom_desc); | 1285 | kfree(rom_desc); |
1286 | kfree(ti_manuf_desc); | 1286 | kfree(ti_manuf_desc); |
1287 | return status; | 1287 | return -EINVAL; |
1288 | } | 1288 | } |
1289 | 1289 | ||
1290 | /* Update I2C with type 0xf2 record with correct | 1290 | /* Update I2C with type 0xf2 record with correct |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 585b7e66374..1c9b6e9b238 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -119,16 +119,20 @@ | |||
119 | * by making a change here, in moschip_port_id_table, and in | 119 | * by making a change here, in moschip_port_id_table, and in |
120 | * moschip_id_table_combined | 120 | * moschip_id_table_combined |
121 | */ | 121 | */ |
122 | #define USB_VENDOR_ID_BANDB 0x0856 | 122 | #define USB_VENDOR_ID_BANDB 0x0856 |
123 | #define BANDB_DEVICE_ID_USO9ML2_2 0xAC22 | 123 | #define BANDB_DEVICE_ID_USO9ML2_2 0xAC22 |
124 | #define BANDB_DEVICE_ID_USO9ML2_4 0xAC24 | 124 | #define BANDB_DEVICE_ID_USO9ML2_2P 0xBC00 |
125 | #define BANDB_DEVICE_ID_US9ML2_2 0xAC29 | 125 | #define BANDB_DEVICE_ID_USO9ML2_4 0xAC24 |
126 | #define BANDB_DEVICE_ID_US9ML2_4 0xAC30 | 126 | #define BANDB_DEVICE_ID_USO9ML2_4P 0xBC01 |
127 | #define BANDB_DEVICE_ID_USPTL4_2 0xAC31 | 127 | #define BANDB_DEVICE_ID_US9ML2_2 0xAC29 |
128 | #define BANDB_DEVICE_ID_USPTL4_4 0xAC32 | 128 | #define BANDB_DEVICE_ID_US9ML2_4 0xAC30 |
129 | #define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 | 129 | #define BANDB_DEVICE_ID_USPTL4_2 0xAC31 |
130 | #define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 | 130 | #define BANDB_DEVICE_ID_USPTL4_4 0xAC32 |
131 | #define BANDB_DEVICE_ID_USOPTL2_4 0xAC24 | 131 | #define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 |
132 | #define BANDB_DEVICE_ID_USOPTL4_2P 0xBC02 | ||
133 | #define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 | ||
134 | #define BANDB_DEVICE_ID_USOPTL4_4P 0xBC03 | ||
135 | #define BANDB_DEVICE_ID_USOPTL2_4 0xAC24 | ||
132 | 136 | ||
133 | /* This driver also supports | 137 | /* This driver also supports |
134 | * ATEN UC2324 device using Moschip MCS7840 | 138 | * ATEN UC2324 device using Moschip MCS7840 |
@@ -184,13 +188,17 @@ static const struct usb_device_id moschip_port_id_table[] = { | |||
184 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, | 188 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, |
185 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, | 189 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, |
186 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, | 190 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, |
191 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)}, | ||
187 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)}, | 192 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)}, |
193 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4P)}, | ||
188 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)}, | 194 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)}, |
189 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)}, | 195 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)}, |
190 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)}, | 196 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)}, |
191 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, | 197 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, |
192 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, | 198 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, |
199 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2P)}, | ||
193 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, | 200 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, |
201 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4P)}, | ||
194 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)}, | 202 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)}, |
195 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, | 203 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, |
196 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, | 204 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, |
@@ -201,13 +209,17 @@ static const struct usb_device_id moschip_id_table_combined[] __devinitconst = { | |||
201 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, | 209 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, |
202 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, | 210 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, |
203 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, | 211 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, |
212 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)}, | ||
204 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)}, | 213 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)}, |
214 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4P)}, | ||
205 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)}, | 215 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)}, |
206 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)}, | 216 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)}, |
207 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)}, | 217 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)}, |
208 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, | 218 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, |
209 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, | 219 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, |
220 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2P)}, | ||
210 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, | 221 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, |
222 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4P)}, | ||
211 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)}, | 223 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)}, |
212 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, | 224 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, |
213 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, | 225 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, |
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c index a6b207c8491..1f00f243c26 100644 --- a/drivers/usb/serial/navman.c +++ b/drivers/usb/serial/navman.c | |||
@@ -25,6 +25,7 @@ static int debug; | |||
25 | 25 | ||
26 | static const struct usb_device_id id_table[] = { | 26 | static const struct usb_device_id id_table[] = { |
27 | { USB_DEVICE(0x0a99, 0x0001) }, /* Talon Technology device */ | 27 | { USB_DEVICE(0x0a99, 0x0001) }, /* Talon Technology device */ |
28 | { USB_DEVICE(0x0df7, 0x0900) }, /* Mobile Action i-gotU */ | ||
28 | { }, | 29 | { }, |
29 | }; | 30 | }; |
30 | MODULE_DEVICE_TABLE(usb, id_table); | 31 | MODULE_DEVICE_TABLE(usb, id_table); |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 9fc6ea2c681..c46911af282 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -164,6 +164,14 @@ static void option_instat_callback(struct urb *urb); | |||
164 | #define YISO_VENDOR_ID 0x0EAB | 164 | #define YISO_VENDOR_ID 0x0EAB |
165 | #define YISO_PRODUCT_U893 0xC893 | 165 | #define YISO_PRODUCT_U893 0xC893 |
166 | 166 | ||
167 | /* | ||
168 | * NOVATEL WIRELESS PRODUCTS | ||
169 | * | ||
170 | * Note from Novatel Wireless: | ||
171 | * If your Novatel modem does not work on linux, don't | ||
172 | * change the option module, but check our website. If | ||
173 | * that does not help, contact ddeschepper@nvtl.com | ||
174 | */ | ||
167 | /* MERLIN EVDO PRODUCTS */ | 175 | /* MERLIN EVDO PRODUCTS */ |
168 | #define NOVATELWIRELESS_PRODUCT_V640 0x1100 | 176 | #define NOVATELWIRELESS_PRODUCT_V640 0x1100 |
169 | #define NOVATELWIRELESS_PRODUCT_V620 0x1110 | 177 | #define NOVATELWIRELESS_PRODUCT_V620 0x1110 |
@@ -185,24 +193,39 @@ static void option_instat_callback(struct urb *urb); | |||
185 | #define NOVATELWIRELESS_PRODUCT_EU730 0x2400 | 193 | #define NOVATELWIRELESS_PRODUCT_EU730 0x2400 |
186 | #define NOVATELWIRELESS_PRODUCT_EU740 0x2410 | 194 | #define NOVATELWIRELESS_PRODUCT_EU740 0x2410 |
187 | #define NOVATELWIRELESS_PRODUCT_EU870D 0x2420 | 195 | #define NOVATELWIRELESS_PRODUCT_EU870D 0x2420 |
188 | |||
189 | /* OVATION PRODUCTS */ | 196 | /* OVATION PRODUCTS */ |
190 | #define NOVATELWIRELESS_PRODUCT_MC727 0x4100 | 197 | #define NOVATELWIRELESS_PRODUCT_MC727 0x4100 |
191 | #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 | 198 | #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 |
192 | #define NOVATELWIRELESS_PRODUCT_U727 0x5010 | 199 | /* |
193 | #define NOVATELWIRELESS_PRODUCT_MC727_NEW 0x5100 | 200 | * Note from Novatel Wireless: |
194 | #define NOVATELWIRELESS_PRODUCT_MC760 0x6000 | 201 | * All PID in the 5xxx range are currently reserved for |
202 | * auto-install CDROMs, and should not be added to this | ||
203 | * module. | ||
204 | * | ||
205 | * #define NOVATELWIRELESS_PRODUCT_U727 0x5010 | ||
206 | * #define NOVATELWIRELESS_PRODUCT_MC727_NEW 0x5100 | ||
207 | */ | ||
195 | #define NOVATELWIRELESS_PRODUCT_OVMC760 0x6002 | 208 | #define NOVATELWIRELESS_PRODUCT_OVMC760 0x6002 |
196 | 209 | #define NOVATELWIRELESS_PRODUCT_MC780 0x6010 | |
197 | /* FUTURE NOVATEL PRODUCTS */ | 210 | #define NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED 0x6000 |
198 | #define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001 | 211 | #define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0x6001 |
199 | #define NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED 0X7000 | 212 | #define NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED 0x7000 |
200 | #define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED 0X7001 | 213 | #define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED 0x7001 |
201 | #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED 0X8000 | 214 | #define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED3 0x7003 |
202 | #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0X8001 | 215 | #define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED4 0x7004 |
203 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0X9000 | 216 | #define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED5 0x7005 |
204 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0X9001 | 217 | #define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED6 0x7006 |
205 | #define NOVATELWIRELESS_PRODUCT_GLOBAL 0XA001 | 218 | #define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED7 0x7007 |
219 | #define NOVATELWIRELESS_PRODUCT_MC996D 0x7030 | ||
220 | #define NOVATELWIRELESS_PRODUCT_MF3470 0x7041 | ||
221 | #define NOVATELWIRELESS_PRODUCT_MC547 0x7042 | ||
222 | #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED 0x8000 | ||
223 | #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0x8001 | ||
224 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000 | ||
225 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001 | ||
226 | #define NOVATELWIRELESS_PRODUCT_G1 0xA001 | ||
227 | #define NOVATELWIRELESS_PRODUCT_G1_M 0xA002 | ||
228 | #define NOVATELWIRELESS_PRODUCT_G2 0xA010 | ||
206 | 229 | ||
207 | /* AMOI PRODUCTS */ | 230 | /* AMOI PRODUCTS */ |
208 | #define AMOI_VENDOR_ID 0x1614 | 231 | #define AMOI_VENDOR_ID 0x1614 |
@@ -365,6 +388,10 @@ static void option_instat_callback(struct urb *urb); | |||
365 | #define OLIVETTI_VENDOR_ID 0x0b3c | 388 | #define OLIVETTI_VENDOR_ID 0x0b3c |
366 | #define OLIVETTI_PRODUCT_OLICARD100 0xc000 | 389 | #define OLIVETTI_PRODUCT_OLICARD100 0xc000 |
367 | 390 | ||
391 | /* Celot products */ | ||
392 | #define CELOT_VENDOR_ID 0x211f | ||
393 | #define CELOT_PRODUCT_CT680M 0x6801 | ||
394 | |||
368 | /* some devices interfaces need special handling due to a number of reasons */ | 395 | /* some devices interfaces need special handling due to a number of reasons */ |
369 | enum option_blacklist_reason { | 396 | enum option_blacklist_reason { |
370 | OPTION_BLACKLIST_NONE = 0, | 397 | OPTION_BLACKLIST_NONE = 0, |
@@ -486,36 +513,44 @@ static const struct usb_device_id option_ids[] = { | |||
486 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) }, | 513 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) }, |
487 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, | 514 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, |
488 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC) }, | 515 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC) }, |
489 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */ | 516 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, |
490 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */ | 517 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, |
491 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, /* Novatel Merlin EX720/V740/X720 */ | 518 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, |
492 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V720) }, /* Novatel Merlin V720/S720/PC720 */ | 519 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V720) }, |
493 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U730) }, /* Novatel U730/U740 (VF version) */ | 520 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U730) }, |
494 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U740) }, /* Novatel U740 */ | 521 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U740) }, |
495 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U870) }, /* Novatel U870 */ | 522 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U870) }, |
496 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_XU870) }, /* Novatel Merlin XU870 HSDPA/3G */ | 523 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_XU870) }, |
497 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_X950D) }, /* Novatel X950D */ | 524 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_X950D) }, |
498 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EV620) }, /* Novatel EV620/ES620 CDMA/EV-DO */ | 525 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EV620) }, |
499 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES720) }, /* Novatel ES620/ES720/U720/USB720 */ | 526 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES720) }, |
500 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E725) }, /* Novatel E725/E726 */ | 527 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E725) }, |
501 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES620) }, /* Novatel Merlin ES620 SM Bus */ | 528 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES620) }, |
502 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU730) }, /* Novatel EU730 and Vodafone EU740 */ | 529 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU730) }, |
503 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU740) }, /* Novatel non-Vodafone EU740 */ | 530 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU740) }, |
504 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */ | 531 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, |
505 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ | 532 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, |
506 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ | 533 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, |
507 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727_NEW) }, /* Novatel MC727/U727/USB727 refresh */ | 534 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_OVMC760) }, |
508 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */ | 535 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC780) }, |
509 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC760) }, /* Novatel MC760/U760/USB760 */ | 536 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED) }, |
510 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_OVMC760) }, /* Novatel Ovation MC760 */ | 537 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, |
511 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */ | 538 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, |
512 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */ | 539 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, |
513 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */ | 540 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) }, |
514 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) }, /* Novatel EVDO product */ | 541 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED3) }, |
515 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED) }, /* Novatel HSPA product */ | 542 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED4) }, |
516 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED) }, /* Novatel EVDO Embedded product */ | 543 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED5) }, |
517 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED) }, /* Novatel HSPA Embedded product */ | 544 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED6) }, |
518 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL) }, /* Novatel Global product */ | 545 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED7) }, |
546 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC996D) }, | ||
547 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MF3470) }, | ||
548 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC547) }, | ||
549 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED) }, | ||
550 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED) }, | ||
551 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1) }, | ||
552 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1_M) }, | ||
553 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) }, | ||
519 | 554 | ||
520 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, | 555 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, |
521 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, | 556 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, |
@@ -887,10 +922,9 @@ static const struct usb_device_id option_ids[] = { | |||
887 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) }, | 922 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) }, |
888 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)}, | 923 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)}, |
889 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, | 924 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, |
890 | |||
891 | { USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) }, | 925 | { USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) }, |
892 | |||
893 | { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, | 926 | { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, |
927 | { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ | ||
894 | { } /* Terminating entry */ | 928 | { } /* Terminating entry */ |
895 | }; | 929 | }; |
896 | MODULE_DEVICE_TABLE(usb, option_ids); | 930 | MODULE_DEVICE_TABLE(usb, option_ids); |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 6b600182227..8ae4c6cbc38 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -86,6 +86,7 @@ static const struct usb_device_id id_table[] = { | |||
86 | { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, | 86 | { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, |
87 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, | 87 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, |
88 | { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, | 88 | { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, |
89 | { USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) }, | ||
89 | { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, | 90 | { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, |
90 | { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, | 91 | { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, |
91 | { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, | 92 | { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, |
@@ -788,7 +789,7 @@ static void pl2303_process_read_urb(struct urb *urb) | |||
788 | 789 | ||
789 | if (port->port.console && port->sysrq) { | 790 | if (port->port.console && port->sysrq) { |
790 | for (i = 0; i < urb->actual_length; ++i) | 791 | for (i = 0; i < urb->actual_length; ++i) |
791 | if (!usb_serial_handle_sysrq_char(tty, port, data[i])) | 792 | if (!usb_serial_handle_sysrq_char(port, data[i])) |
792 | tty_insert_flip_char(tty, data[i], tty_flag); | 793 | tty_insert_flip_char(tty, data[i], tty_flag); |
793 | } else { | 794 | } else { |
794 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, | 795 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, |
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index a871645389d..43eb9bdad42 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
@@ -128,6 +128,10 @@ | |||
128 | #define CRESSI_VENDOR_ID 0x04b8 | 128 | #define CRESSI_VENDOR_ID 0x04b8 |
129 | #define CRESSI_EDY_PRODUCT_ID 0x0521 | 129 | #define CRESSI_EDY_PRODUCT_ID 0x0521 |
130 | 130 | ||
131 | /* Zeagle dive computer interface */ | ||
132 | #define ZEAGLE_VENDOR_ID 0x04b8 | ||
133 | #define ZEAGLE_N2ITION3_PRODUCT_ID 0x0522 | ||
134 | |||
131 | /* Sony, USB data cable for CMD-Jxx mobile phones */ | 135 | /* Sony, USB data cable for CMD-Jxx mobile phones */ |
132 | #define SONY_VENDOR_ID 0x054c | 136 | #define SONY_VENDOR_ID 0x054c |
133 | #define SONY_QN3USB_PRODUCT_ID 0x0437 | 137 | #define SONY_QN3USB_PRODUCT_ID 0x0437 |
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index 6e82d4f54bc..e986002b384 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/serial.h> | 15 | #include <linux/serial.h> |
16 | #include <linux/usb.h> | 16 | #include <linux/usb.h> |
17 | #include <linux/usb/serial.h> | 17 | #include <linux/usb/serial.h> |
18 | #include <linux/serial_reg.h> | ||
18 | #include <linux/uaccess.h> | 19 | #include <linux/uaccess.h> |
19 | 20 | ||
20 | #define QT_OPEN_CLOSE_CHANNEL 0xca | 21 | #define QT_OPEN_CLOSE_CHANNEL 0xca |
@@ -27,36 +28,11 @@ | |||
27 | #define QT_HW_FLOW_CONTROL_MASK 0xc5 | 28 | #define QT_HW_FLOW_CONTROL_MASK 0xc5 |
28 | #define QT_SW_FLOW_CONTROL_MASK 0xc6 | 29 | #define QT_SW_FLOW_CONTROL_MASK 0xc6 |
29 | 30 | ||
30 | #define MODEM_CTL_REGISTER 0x04 | ||
31 | #define MODEM_STATUS_REGISTER 0x06 | ||
32 | |||
33 | |||
34 | #define SERIAL_LSR_OE 0x02 | ||
35 | #define SERIAL_LSR_PE 0x04 | ||
36 | #define SERIAL_LSR_FE 0x08 | ||
37 | #define SERIAL_LSR_BI 0x10 | ||
38 | |||
39 | #define SERIAL_LSR_TEMT 0x40 | ||
40 | |||
41 | #define SERIAL_MCR_DTR 0x01 | ||
42 | #define SERIAL_MCR_RTS 0x02 | ||
43 | #define SERIAL_MCR_LOOP 0x10 | ||
44 | |||
45 | #define SERIAL_MSR_CTS 0x10 | ||
46 | #define SERIAL_MSR_CD 0x80 | ||
47 | #define SERIAL_MSR_RI 0x40 | ||
48 | #define SERIAL_MSR_DSR 0x20 | ||
49 | #define SERIAL_MSR_MASK 0xf0 | 31 | #define SERIAL_MSR_MASK 0xf0 |
50 | 32 | ||
51 | #define SERIAL_CRTSCTS ((SERIAL_MCR_RTS << 8) | SERIAL_MSR_CTS) | 33 | #define SERIAL_CRTSCTS ((UART_MCR_RTS << 8) | UART_MSR_CTS) |
52 | 34 | ||
53 | #define SERIAL_8_DATA 0x03 | 35 | #define SERIAL_EVEN_PARITY (UART_LCR_PARITY | UART_LCR_EPAR) |
54 | #define SERIAL_7_DATA 0x02 | ||
55 | #define SERIAL_6_DATA 0x01 | ||
56 | #define SERIAL_5_DATA 0x00 | ||
57 | |||
58 | #define SERIAL_ODD_PARITY 0X08 | ||
59 | #define SERIAL_EVEN_PARITY 0X18 | ||
60 | 36 | ||
61 | #define MAX_BAUD_RATE 460800 | 37 | #define MAX_BAUD_RATE 460800 |
62 | 38 | ||
@@ -70,7 +46,7 @@ | |||
70 | #define FULLPWRBIT 0x00000080 | 46 | #define FULLPWRBIT 0x00000080 |
71 | #define NEXT_BOARD_POWER_BIT 0x00000004 | 47 | #define NEXT_BOARD_POWER_BIT 0x00000004 |
72 | 48 | ||
73 | static int debug = 1; | 49 | static int debug; |
74 | 50 | ||
75 | /* Version Information */ | 51 | /* Version Information */ |
76 | #define DRIVER_VERSION "v0.1" | 52 | #define DRIVER_VERSION "v0.1" |
@@ -99,10 +75,12 @@ static struct usb_driver ssu100_driver = { | |||
99 | }; | 75 | }; |
100 | 76 | ||
101 | struct ssu100_port_private { | 77 | struct ssu100_port_private { |
78 | spinlock_t status_lock; | ||
102 | u8 shadowLSR; | 79 | u8 shadowLSR; |
103 | u8 shadowMSR; | 80 | u8 shadowMSR; |
104 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ | 81 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ |
105 | unsigned short max_packet_size; | 82 | unsigned short max_packet_size; |
83 | struct async_icount icount; | ||
106 | }; | 84 | }; |
107 | 85 | ||
108 | static void ssu100_release(struct usb_serial *serial) | 86 | static void ssu100_release(struct usb_serial *serial) |
@@ -150,9 +128,10 @@ static inline int ssu100_getregister(struct usb_device *dev, | |||
150 | 128 | ||
151 | static inline int ssu100_setregister(struct usb_device *dev, | 129 | static inline int ssu100_setregister(struct usb_device *dev, |
152 | unsigned short uart, | 130 | unsigned short uart, |
131 | unsigned short reg, | ||
153 | u16 data) | 132 | u16 data) |
154 | { | 133 | { |
155 | u16 value = (data << 8) | MODEM_CTL_REGISTER; | 134 | u16 value = (data << 8) | reg; |
156 | 135 | ||
157 | return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 136 | return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
158 | QT_SET_GET_REGISTER, 0x40, value, uart, | 137 | QT_SET_GET_REGISTER, 0x40, value, uart, |
@@ -178,11 +157,11 @@ static inline int update_mctrl(struct usb_device *dev, unsigned int set, | |||
178 | clear &= ~set; /* 'set' takes precedence over 'clear' */ | 157 | clear &= ~set; /* 'set' takes precedence over 'clear' */ |
179 | urb_value = 0; | 158 | urb_value = 0; |
180 | if (set & TIOCM_DTR) | 159 | if (set & TIOCM_DTR) |
181 | urb_value |= SERIAL_MCR_DTR; | 160 | urb_value |= UART_MCR_DTR; |
182 | if (set & TIOCM_RTS) | 161 | if (set & TIOCM_RTS) |
183 | urb_value |= SERIAL_MCR_RTS; | 162 | urb_value |= UART_MCR_RTS; |
184 | 163 | ||
185 | result = ssu100_setregister(dev, 0, urb_value); | 164 | result = ssu100_setregister(dev, 0, UART_MCR, urb_value); |
186 | if (result < 0) | 165 | if (result < 0) |
187 | dbg("%s Error from MODEM_CTRL urb", __func__); | 166 | dbg("%s Error from MODEM_CTRL urb", __func__); |
188 | 167 | ||
@@ -264,24 +243,24 @@ static void ssu100_set_termios(struct tty_struct *tty, | |||
264 | 243 | ||
265 | if (cflag & PARENB) { | 244 | if (cflag & PARENB) { |
266 | if (cflag & PARODD) | 245 | if (cflag & PARODD) |
267 | urb_value |= SERIAL_ODD_PARITY; | 246 | urb_value |= UART_LCR_PARITY; |
268 | else | 247 | else |
269 | urb_value |= SERIAL_EVEN_PARITY; | 248 | urb_value |= SERIAL_EVEN_PARITY; |
270 | } | 249 | } |
271 | 250 | ||
272 | switch (cflag & CSIZE) { | 251 | switch (cflag & CSIZE) { |
273 | case CS5: | 252 | case CS5: |
274 | urb_value |= SERIAL_5_DATA; | 253 | urb_value |= UART_LCR_WLEN5; |
275 | break; | 254 | break; |
276 | case CS6: | 255 | case CS6: |
277 | urb_value |= SERIAL_6_DATA; | 256 | urb_value |= UART_LCR_WLEN6; |
278 | break; | 257 | break; |
279 | case CS7: | 258 | case CS7: |
280 | urb_value |= SERIAL_7_DATA; | 259 | urb_value |= UART_LCR_WLEN7; |
281 | break; | 260 | break; |
282 | default: | 261 | default: |
283 | case CS8: | 262 | case CS8: |
284 | urb_value |= SERIAL_8_DATA; | 263 | urb_value |= UART_LCR_WLEN8; |
285 | break; | 264 | break; |
286 | } | 265 | } |
287 | 266 | ||
@@ -333,6 +312,7 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
333 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | 312 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); |
334 | u8 *data; | 313 | u8 *data; |
335 | int result; | 314 | int result; |
315 | unsigned long flags; | ||
336 | 316 | ||
337 | dbg("%s - port %d", __func__, port->number); | 317 | dbg("%s - port %d", __func__, port->number); |
338 | 318 | ||
@@ -350,11 +330,10 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
350 | return result; | 330 | return result; |
351 | } | 331 | } |
352 | 332 | ||
353 | priv->shadowLSR = data[0] & (SERIAL_LSR_OE | SERIAL_LSR_PE | | 333 | spin_lock_irqsave(&priv->status_lock, flags); |
354 | SERIAL_LSR_FE | SERIAL_LSR_BI); | 334 | priv->shadowLSR = data[0]; |
355 | 335 | priv->shadowMSR = data[1]; | |
356 | priv->shadowMSR = data[1] & (SERIAL_MSR_CTS | SERIAL_MSR_DSR | | 336 | spin_unlock_irqrestore(&priv->status_lock, flags); |
357 | SERIAL_MSR_RI | SERIAL_MSR_CD); | ||
358 | 337 | ||
359 | kfree(data); | 338 | kfree(data); |
360 | 339 | ||
@@ -398,11 +377,51 @@ static int get_serial_info(struct usb_serial_port *port, | |||
398 | return 0; | 377 | return 0; |
399 | } | 378 | } |
400 | 379 | ||
380 | static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) | ||
381 | { | ||
382 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | ||
383 | struct async_icount prev, cur; | ||
384 | unsigned long flags; | ||
385 | |||
386 | spin_lock_irqsave(&priv->status_lock, flags); | ||
387 | prev = priv->icount; | ||
388 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
389 | |||
390 | while (1) { | ||
391 | wait_event_interruptible(priv->delta_msr_wait, | ||
392 | ((priv->icount.rng != prev.rng) || | ||
393 | (priv->icount.dsr != prev.dsr) || | ||
394 | (priv->icount.dcd != prev.dcd) || | ||
395 | (priv->icount.cts != prev.cts))); | ||
396 | |||
397 | if (signal_pending(current)) | ||
398 | return -ERESTARTSYS; | ||
399 | |||
400 | spin_lock_irqsave(&priv->status_lock, flags); | ||
401 | cur = priv->icount; | ||
402 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
403 | |||
404 | if ((prev.rng == cur.rng) && | ||
405 | (prev.dsr == cur.dsr) && | ||
406 | (prev.dcd == cur.dcd) && | ||
407 | (prev.cts == cur.cts)) | ||
408 | return -EIO; | ||
409 | |||
410 | if ((arg & TIOCM_RNG && (prev.rng != cur.rng)) || | ||
411 | (arg & TIOCM_DSR && (prev.dsr != cur.dsr)) || | ||
412 | (arg & TIOCM_CD && (prev.dcd != cur.dcd)) || | ||
413 | (arg & TIOCM_CTS && (prev.cts != cur.cts))) | ||
414 | return 0; | ||
415 | } | ||
416 | return 0; | ||
417 | } | ||
418 | |||
401 | static int ssu100_ioctl(struct tty_struct *tty, struct file *file, | 419 | static int ssu100_ioctl(struct tty_struct *tty, struct file *file, |
402 | unsigned int cmd, unsigned long arg) | 420 | unsigned int cmd, unsigned long arg) |
403 | { | 421 | { |
404 | struct usb_serial_port *port = tty->driver_data; | 422 | struct usb_serial_port *port = tty->driver_data; |
405 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | 423 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); |
424 | void __user *user_arg = (void __user *)arg; | ||
406 | 425 | ||
407 | dbg("%s cmd 0x%04x", __func__, cmd); | 426 | dbg("%s cmd 0x%04x", __func__, cmd); |
408 | 427 | ||
@@ -412,28 +431,28 @@ static int ssu100_ioctl(struct tty_struct *tty, struct file *file, | |||
412 | (struct serial_struct __user *) arg); | 431 | (struct serial_struct __user *) arg); |
413 | 432 | ||
414 | case TIOCMIWAIT: | 433 | case TIOCMIWAIT: |
415 | while (priv != NULL) { | 434 | return wait_modem_info(port, arg); |
416 | u8 prevMSR = priv->shadowMSR & SERIAL_MSR_MASK; | 435 | |
417 | interruptible_sleep_on(&priv->delta_msr_wait); | 436 | case TIOCGICOUNT: |
418 | /* see if a signal did it */ | 437 | { |
419 | if (signal_pending(current)) | 438 | struct serial_icounter_struct icount; |
420 | return -ERESTARTSYS; | 439 | struct async_icount cnow = priv->icount; |
421 | else { | 440 | memset(&icount, 0, sizeof(icount)); |
422 | u8 diff = (priv->shadowMSR & SERIAL_MSR_MASK) ^ prevMSR; | 441 | icount.cts = cnow.cts; |
423 | if (!diff) | 442 | icount.dsr = cnow.dsr; |
424 | return -EIO; /* no change => error */ | 443 | icount.rng = cnow.rng; |
425 | 444 | icount.dcd = cnow.dcd; | |
426 | /* Return 0 if caller wanted to know about | 445 | icount.rx = cnow.rx; |
427 | these bits */ | 446 | icount.tx = cnow.tx; |
428 | 447 | icount.frame = cnow.frame; | |
429 | if (((arg & TIOCM_RNG) && (diff & SERIAL_MSR_RI)) || | 448 | icount.overrun = cnow.overrun; |
430 | ((arg & TIOCM_DSR) && (diff & SERIAL_MSR_DSR)) || | 449 | icount.parity = cnow.parity; |
431 | ((arg & TIOCM_CD) && (diff & SERIAL_MSR_CD)) || | 450 | icount.brk = cnow.brk; |
432 | ((arg & TIOCM_CTS) && (diff & SERIAL_MSR_CTS))) | 451 | icount.buf_overrun = cnow.buf_overrun; |
433 | return 0; | 452 | if (copy_to_user(user_arg, &icount, sizeof(icount))) |
434 | } | 453 | return -EFAULT; |
435 | } | ||
436 | return 0; | 454 | return 0; |
455 | } | ||
437 | 456 | ||
438 | default: | 457 | default: |
439 | break; | 458 | break; |
@@ -455,6 +474,7 @@ static void ssu100_set_max_packet_size(struct usb_serial_port *port) | |||
455 | 474 | ||
456 | unsigned num_endpoints; | 475 | unsigned num_endpoints; |
457 | int i; | 476 | int i; |
477 | unsigned long flags; | ||
458 | 478 | ||
459 | num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; | 479 | num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; |
460 | dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); | 480 | dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); |
@@ -466,7 +486,9 @@ static void ssu100_set_max_packet_size(struct usb_serial_port *port) | |||
466 | } | 486 | } |
467 | 487 | ||
468 | /* set max packet size based on descriptor */ | 488 | /* set max packet size based on descriptor */ |
489 | spin_lock_irqsave(&priv->status_lock, flags); | ||
469 | priv->max_packet_size = ep_desc->wMaxPacketSize; | 490 | priv->max_packet_size = ep_desc->wMaxPacketSize; |
491 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
470 | 492 | ||
471 | dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); | 493 | dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); |
472 | } | 494 | } |
@@ -485,9 +507,9 @@ static int ssu100_attach(struct usb_serial *serial) | |||
485 | return -ENOMEM; | 507 | return -ENOMEM; |
486 | } | 508 | } |
487 | 509 | ||
510 | spin_lock_init(&priv->status_lock); | ||
488 | init_waitqueue_head(&priv->delta_msr_wait); | 511 | init_waitqueue_head(&priv->delta_msr_wait); |
489 | usb_set_serial_port_data(port, priv); | 512 | usb_set_serial_port_data(port, priv); |
490 | |||
491 | ssu100_set_max_packet_size(port); | 513 | ssu100_set_max_packet_size(port); |
492 | 514 | ||
493 | return ssu100_initdevice(serial->dev); | 515 | return ssu100_initdevice(serial->dev); |
@@ -506,20 +528,20 @@ static int ssu100_tiocmget(struct tty_struct *tty, struct file *file) | |||
506 | if (!d) | 528 | if (!d) |
507 | return -ENOMEM; | 529 | return -ENOMEM; |
508 | 530 | ||
509 | r = ssu100_getregister(dev, 0, MODEM_CTL_REGISTER, d); | 531 | r = ssu100_getregister(dev, 0, UART_MCR, d); |
510 | if (r < 0) | 532 | if (r < 0) |
511 | goto mget_out; | 533 | goto mget_out; |
512 | 534 | ||
513 | r = ssu100_getregister(dev, 0, MODEM_STATUS_REGISTER, d+1); | 535 | r = ssu100_getregister(dev, 0, UART_MSR, d+1); |
514 | if (r < 0) | 536 | if (r < 0) |
515 | goto mget_out; | 537 | goto mget_out; |
516 | 538 | ||
517 | r = (d[0] & SERIAL_MCR_DTR ? TIOCM_DTR : 0) | | 539 | r = (d[0] & UART_MCR_DTR ? TIOCM_DTR : 0) | |
518 | (d[0] & SERIAL_MCR_RTS ? TIOCM_RTS : 0) | | 540 | (d[0] & UART_MCR_RTS ? TIOCM_RTS : 0) | |
519 | (d[1] & SERIAL_MSR_CTS ? TIOCM_CTS : 0) | | 541 | (d[1] & UART_MSR_CTS ? TIOCM_CTS : 0) | |
520 | (d[1] & SERIAL_MSR_CD ? TIOCM_CAR : 0) | | 542 | (d[1] & UART_MSR_DCD ? TIOCM_CAR : 0) | |
521 | (d[1] & SERIAL_MSR_RI ? TIOCM_RI : 0) | | 543 | (d[1] & UART_MSR_RI ? TIOCM_RI : 0) | |
522 | (d[1] & SERIAL_MSR_DSR ? TIOCM_DSR : 0); | 544 | (d[1] & UART_MSR_DSR ? TIOCM_DSR : 0); |
523 | 545 | ||
524 | mget_out: | 546 | mget_out: |
525 | kfree(d); | 547 | kfree(d); |
@@ -546,7 +568,7 @@ static void ssu100_dtr_rts(struct usb_serial_port *port, int on) | |||
546 | if (!port->serial->disconnected) { | 568 | if (!port->serial->disconnected) { |
547 | /* Disable flow control */ | 569 | /* Disable flow control */ |
548 | if (!on && | 570 | if (!on && |
549 | ssu100_setregister(dev, 0, 0) < 0) | 571 | ssu100_setregister(dev, 0, UART_MCR, 0) < 0) |
550 | dev_err(&port->dev, "error from flowcontrol urb\n"); | 572 | dev_err(&port->dev, "error from flowcontrol urb\n"); |
551 | /* drop RTS and DTR */ | 573 | /* drop RTS and DTR */ |
552 | if (on) | 574 | if (on) |
@@ -557,34 +579,88 @@ static void ssu100_dtr_rts(struct usb_serial_port *port, int on) | |||
557 | mutex_unlock(&port->serial->disc_mutex); | 579 | mutex_unlock(&port->serial->disc_mutex); |
558 | } | 580 | } |
559 | 581 | ||
582 | static void ssu100_update_msr(struct usb_serial_port *port, u8 msr) | ||
583 | { | ||
584 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | ||
585 | unsigned long flags; | ||
586 | |||
587 | spin_lock_irqsave(&priv->status_lock, flags); | ||
588 | priv->shadowMSR = msr; | ||
589 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
590 | |||
591 | if (msr & UART_MSR_ANY_DELTA) { | ||
592 | /* update input line counters */ | ||
593 | if (msr & UART_MSR_DCTS) | ||
594 | priv->icount.cts++; | ||
595 | if (msr & UART_MSR_DDSR) | ||
596 | priv->icount.dsr++; | ||
597 | if (msr & UART_MSR_DDCD) | ||
598 | priv->icount.dcd++; | ||
599 | if (msr & UART_MSR_TERI) | ||
600 | priv->icount.rng++; | ||
601 | wake_up_interruptible(&priv->delta_msr_wait); | ||
602 | } | ||
603 | } | ||
604 | |||
605 | static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr, | ||
606 | char *tty_flag) | ||
607 | { | ||
608 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | ||
609 | unsigned long flags; | ||
610 | |||
611 | spin_lock_irqsave(&priv->status_lock, flags); | ||
612 | priv->shadowLSR = lsr; | ||
613 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
614 | |||
615 | *tty_flag = TTY_NORMAL; | ||
616 | if (lsr & UART_LSR_BRK_ERROR_BITS) { | ||
617 | /* we always want to update icount, but we only want to | ||
618 | * update tty_flag for one case */ | ||
619 | if (lsr & UART_LSR_BI) { | ||
620 | priv->icount.brk++; | ||
621 | *tty_flag = TTY_BREAK; | ||
622 | usb_serial_handle_break(port); | ||
623 | } | ||
624 | if (lsr & UART_LSR_PE) { | ||
625 | priv->icount.parity++; | ||
626 | if (*tty_flag == TTY_NORMAL) | ||
627 | *tty_flag = TTY_PARITY; | ||
628 | } | ||
629 | if (lsr & UART_LSR_FE) { | ||
630 | priv->icount.frame++; | ||
631 | if (*tty_flag == TTY_NORMAL) | ||
632 | *tty_flag = TTY_FRAME; | ||
633 | } | ||
634 | if (lsr & UART_LSR_OE){ | ||
635 | priv->icount.overrun++; | ||
636 | if (*tty_flag == TTY_NORMAL) | ||
637 | *tty_flag = TTY_OVERRUN; | ||
638 | } | ||
639 | } | ||
640 | |||
641 | } | ||
642 | |||
560 | static int ssu100_process_packet(struct tty_struct *tty, | 643 | static int ssu100_process_packet(struct tty_struct *tty, |
561 | struct usb_serial_port *port, | 644 | struct usb_serial_port *port, |
562 | struct ssu100_port_private *priv, | 645 | struct ssu100_port_private *priv, |
563 | char *packet, int len) | 646 | char *packet, int len) |
564 | { | 647 | { |
565 | int i; | 648 | int i; |
566 | char flag; | 649 | char flag = TTY_NORMAL; |
567 | char *ch; | 650 | char *ch; |
568 | 651 | ||
569 | dbg("%s - port %d", __func__, port->number); | 652 | dbg("%s - port %d", __func__, port->number); |
570 | 653 | ||
571 | if (len < 4) { | 654 | if ((len >= 4) && |
572 | dbg("%s - malformed packet", __func__); | 655 | (packet[0] == 0x1b) && (packet[1] == 0x1b) && |
573 | return 0; | ||
574 | } | ||
575 | |||
576 | if ((packet[0] == 0x1b) && (packet[1] == 0x1b) && | ||
577 | ((packet[2] == 0x00) || (packet[2] == 0x01))) { | 656 | ((packet[2] == 0x00) || (packet[2] == 0x01))) { |
578 | if (packet[2] == 0x00) | 657 | if (packet[2] == 0x00) { |
579 | priv->shadowLSR = packet[3] & (SERIAL_LSR_OE | | 658 | ssu100_update_lsr(port, packet[3], &flag); |
580 | SERIAL_LSR_PE | | 659 | if (flag == TTY_OVERRUN) |
581 | SERIAL_LSR_FE | | 660 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
582 | SERIAL_LSR_BI); | ||
583 | |||
584 | if (packet[2] == 0x01) { | ||
585 | priv->shadowMSR = packet[3]; | ||
586 | wake_up_interruptible(&priv->delta_msr_wait); | ||
587 | } | 661 | } |
662 | if (packet[2] == 0x01) | ||
663 | ssu100_update_msr(port, packet[3]); | ||
588 | 664 | ||
589 | len -= 4; | 665 | len -= 4; |
590 | ch = packet + 4; | 666 | ch = packet + 4; |
@@ -596,7 +672,7 @@ static int ssu100_process_packet(struct tty_struct *tty, | |||
596 | 672 | ||
597 | if (port->port.console && port->sysrq) { | 673 | if (port->port.console && port->sysrq) { |
598 | for (i = 0; i < len; i++, ch++) { | 674 | for (i = 0; i < len; i++, ch++) { |
599 | if (!usb_serial_handle_sysrq_char(tty, port, *ch)) | 675 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
600 | tty_insert_flip_char(tty, *ch, flag); | 676 | tty_insert_flip_char(tty, *ch, flag); |
601 | } | 677 | } |
602 | } else | 678 | } else |
@@ -631,7 +707,6 @@ static void ssu100_process_read_urb(struct urb *urb) | |||
631 | tty_kref_put(tty); | 707 | tty_kref_put(tty); |
632 | } | 708 | } |
633 | 709 | ||
634 | |||
635 | static struct usb_serial_driver ssu100_device = { | 710 | static struct usb_serial_driver ssu100_device = { |
636 | .driver = { | 711 | .driver = { |
637 | .owner = THIS_MODULE, | 712 | .owner = THIS_MODULE, |
@@ -653,6 +728,7 @@ static struct usb_serial_driver ssu100_device = { | |||
653 | .tiocmset = ssu100_tiocmset, | 728 | .tiocmset = ssu100_tiocmset, |
654 | .ioctl = ssu100_ioctl, | 729 | .ioctl = ssu100_ioctl, |
655 | .set_termios = ssu100_set_termios, | 730 | .set_termios = ssu100_set_termios, |
731 | .disconnect = usb_serial_generic_disconnect, | ||
656 | }; | 732 | }; |
657 | 733 | ||
658 | static int __init ssu100_init(void) | 734 | static int __init ssu100_init(void) |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 2a982e62963..7a2177c79bd 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -736,6 +736,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
736 | 736 | ||
737 | serial = create_serial(dev, interface, type); | 737 | serial = create_serial(dev, interface, type); |
738 | if (!serial) { | 738 | if (!serial) { |
739 | module_put(type->driver.owner); | ||
739 | dev_err(&interface->dev, "%s - out of memory\n", __func__); | 740 | dev_err(&interface->dev, "%s - out of memory\n", __func__); |
740 | return -ENOMEM; | 741 | return -ENOMEM; |
741 | } | 742 | } |
@@ -746,11 +747,11 @@ int usb_serial_probe(struct usb_interface *interface, | |||
746 | 747 | ||
747 | id = get_iface_id(type, interface); | 748 | id = get_iface_id(type, interface); |
748 | retval = type->probe(serial, id); | 749 | retval = type->probe(serial, id); |
749 | module_put(type->driver.owner); | ||
750 | 750 | ||
751 | if (retval) { | 751 | if (retval) { |
752 | dbg("sub driver rejected device"); | 752 | dbg("sub driver rejected device"); |
753 | kfree(serial); | 753 | kfree(serial); |
754 | module_put(type->driver.owner); | ||
754 | return retval; | 755 | return retval; |
755 | } | 756 | } |
756 | } | 757 | } |
@@ -822,6 +823,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
822 | if (num_bulk_in == 0 || num_bulk_out == 0) { | 823 | if (num_bulk_in == 0 || num_bulk_out == 0) { |
823 | dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); | 824 | dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); |
824 | kfree(serial); | 825 | kfree(serial); |
826 | module_put(type->driver.owner); | ||
825 | return -ENODEV; | 827 | return -ENODEV; |
826 | } | 828 | } |
827 | } | 829 | } |
@@ -835,22 +837,15 @@ int usb_serial_probe(struct usb_interface *interface, | |||
835 | dev_err(&interface->dev, | 837 | dev_err(&interface->dev, |
836 | "Generic device with no bulk out, not allowed.\n"); | 838 | "Generic device with no bulk out, not allowed.\n"); |
837 | kfree(serial); | 839 | kfree(serial); |
840 | module_put(type->driver.owner); | ||
838 | return -EIO; | 841 | return -EIO; |
839 | } | 842 | } |
840 | } | 843 | } |
841 | #endif | 844 | #endif |
842 | if (!num_ports) { | 845 | if (!num_ports) { |
843 | /* if this device type has a calc_num_ports function, call it */ | 846 | /* if this device type has a calc_num_ports function, call it */ |
844 | if (type->calc_num_ports) { | 847 | if (type->calc_num_ports) |
845 | if (!try_module_get(type->driver.owner)) { | ||
846 | dev_err(&interface->dev, | ||
847 | "module get failed, exiting\n"); | ||
848 | kfree(serial); | ||
849 | return -EIO; | ||
850 | } | ||
851 | num_ports = type->calc_num_ports(serial); | 848 | num_ports = type->calc_num_ports(serial); |
852 | module_put(type->driver.owner); | ||
853 | } | ||
854 | if (!num_ports) | 849 | if (!num_ports) |
855 | num_ports = type->num_ports; | 850 | num_ports = type->num_ports; |
856 | } | 851 | } |
@@ -1039,13 +1034,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
1039 | 1034 | ||
1040 | /* if this device type has an attach function, call it */ | 1035 | /* if this device type has an attach function, call it */ |
1041 | if (type->attach) { | 1036 | if (type->attach) { |
1042 | if (!try_module_get(type->driver.owner)) { | ||
1043 | dev_err(&interface->dev, | ||
1044 | "module get failed, exiting\n"); | ||
1045 | goto probe_error; | ||
1046 | } | ||
1047 | retval = type->attach(serial); | 1037 | retval = type->attach(serial); |
1048 | module_put(type->driver.owner); | ||
1049 | if (retval < 0) | 1038 | if (retval < 0) |
1050 | goto probe_error; | 1039 | goto probe_error; |
1051 | serial->attached = 1; | 1040 | serial->attached = 1; |
@@ -1088,10 +1077,12 @@ int usb_serial_probe(struct usb_interface *interface, | |||
1088 | exit: | 1077 | exit: |
1089 | /* success */ | 1078 | /* success */ |
1090 | usb_set_intfdata(interface, serial); | 1079 | usb_set_intfdata(interface, serial); |
1080 | module_put(type->driver.owner); | ||
1091 | return 0; | 1081 | return 0; |
1092 | 1082 | ||
1093 | probe_error: | 1083 | probe_error: |
1094 | usb_serial_put(serial); | 1084 | usb_serial_put(serial); |
1085 | module_put(type->driver.owner); | ||
1095 | return -EIO; | 1086 | return -EIO; |
1096 | } | 1087 | } |
1097 | EXPORT_SYMBOL_GPL(usb_serial_probe); | 1088 | EXPORT_SYMBOL_GPL(usb_serial_probe); |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index e05557d5299..c579dcc9200 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -60,22 +60,25 @@ static int vhost_poll_wakeup(wait_queue_t *wait, unsigned mode, int sync, | |||
60 | return 0; | 60 | return 0; |
61 | } | 61 | } |
62 | 62 | ||
63 | static void vhost_work_init(struct vhost_work *work, vhost_work_fn_t fn) | ||
64 | { | ||
65 | INIT_LIST_HEAD(&work->node); | ||
66 | work->fn = fn; | ||
67 | init_waitqueue_head(&work->done); | ||
68 | work->flushing = 0; | ||
69 | work->queue_seq = work->done_seq = 0; | ||
70 | } | ||
71 | |||
63 | /* Init poll structure */ | 72 | /* Init poll structure */ |
64 | void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn, | 73 | void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn, |
65 | unsigned long mask, struct vhost_dev *dev) | 74 | unsigned long mask, struct vhost_dev *dev) |
66 | { | 75 | { |
67 | struct vhost_work *work = &poll->work; | ||
68 | |||
69 | init_waitqueue_func_entry(&poll->wait, vhost_poll_wakeup); | 76 | init_waitqueue_func_entry(&poll->wait, vhost_poll_wakeup); |
70 | init_poll_funcptr(&poll->table, vhost_poll_func); | 77 | init_poll_funcptr(&poll->table, vhost_poll_func); |
71 | poll->mask = mask; | 78 | poll->mask = mask; |
72 | poll->dev = dev; | 79 | poll->dev = dev; |
73 | 80 | ||
74 | INIT_LIST_HEAD(&work->node); | 81 | vhost_work_init(&poll->work, fn); |
75 | work->fn = fn; | ||
76 | init_waitqueue_head(&work->done); | ||
77 | work->flushing = 0; | ||
78 | work->queue_seq = work->done_seq = 0; | ||
79 | } | 82 | } |
80 | 83 | ||
81 | /* Start polling a file. We add ourselves to file's wait queue. The caller must | 84 | /* Start polling a file. We add ourselves to file's wait queue. The caller must |
@@ -95,35 +98,38 @@ void vhost_poll_stop(struct vhost_poll *poll) | |||
95 | remove_wait_queue(poll->wqh, &poll->wait); | 98 | remove_wait_queue(poll->wqh, &poll->wait); |
96 | } | 99 | } |
97 | 100 | ||
98 | /* Flush any work that has been scheduled. When calling this, don't hold any | 101 | static void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work) |
99 | * locks that are also used by the callback. */ | ||
100 | void vhost_poll_flush(struct vhost_poll *poll) | ||
101 | { | 102 | { |
102 | struct vhost_work *work = &poll->work; | ||
103 | unsigned seq; | 103 | unsigned seq; |
104 | int left; | 104 | int left; |
105 | int flushing; | 105 | int flushing; |
106 | 106 | ||
107 | spin_lock_irq(&poll->dev->work_lock); | 107 | spin_lock_irq(&dev->work_lock); |
108 | seq = work->queue_seq; | 108 | seq = work->queue_seq; |
109 | work->flushing++; | 109 | work->flushing++; |
110 | spin_unlock_irq(&poll->dev->work_lock); | 110 | spin_unlock_irq(&dev->work_lock); |
111 | wait_event(work->done, ({ | 111 | wait_event(work->done, ({ |
112 | spin_lock_irq(&poll->dev->work_lock); | 112 | spin_lock_irq(&dev->work_lock); |
113 | left = seq - work->done_seq <= 0; | 113 | left = seq - work->done_seq <= 0; |
114 | spin_unlock_irq(&poll->dev->work_lock); | 114 | spin_unlock_irq(&dev->work_lock); |
115 | left; | 115 | left; |
116 | })); | 116 | })); |
117 | spin_lock_irq(&poll->dev->work_lock); | 117 | spin_lock_irq(&dev->work_lock); |
118 | flushing = --work->flushing; | 118 | flushing = --work->flushing; |
119 | spin_unlock_irq(&poll->dev->work_lock); | 119 | spin_unlock_irq(&dev->work_lock); |
120 | BUG_ON(flushing < 0); | 120 | BUG_ON(flushing < 0); |
121 | } | 121 | } |
122 | 122 | ||
123 | void vhost_poll_queue(struct vhost_poll *poll) | 123 | /* Flush any work that has been scheduled. When calling this, don't hold any |
124 | * locks that are also used by the callback. */ | ||
125 | void vhost_poll_flush(struct vhost_poll *poll) | ||
126 | { | ||
127 | vhost_work_flush(poll->dev, &poll->work); | ||
128 | } | ||
129 | |||
130 | static inline void vhost_work_queue(struct vhost_dev *dev, | ||
131 | struct vhost_work *work) | ||
124 | { | 132 | { |
125 | struct vhost_dev *dev = poll->dev; | ||
126 | struct vhost_work *work = &poll->work; | ||
127 | unsigned long flags; | 133 | unsigned long flags; |
128 | 134 | ||
129 | spin_lock_irqsave(&dev->work_lock, flags); | 135 | spin_lock_irqsave(&dev->work_lock, flags); |
@@ -135,6 +141,11 @@ void vhost_poll_queue(struct vhost_poll *poll) | |||
135 | spin_unlock_irqrestore(&dev->work_lock, flags); | 141 | spin_unlock_irqrestore(&dev->work_lock, flags); |
136 | } | 142 | } |
137 | 143 | ||
144 | void vhost_poll_queue(struct vhost_poll *poll) | ||
145 | { | ||
146 | vhost_work_queue(poll->dev, &poll->work); | ||
147 | } | ||
148 | |||
138 | static void vhost_vq_reset(struct vhost_dev *dev, | 149 | static void vhost_vq_reset(struct vhost_dev *dev, |
139 | struct vhost_virtqueue *vq) | 150 | struct vhost_virtqueue *vq) |
140 | { | 151 | { |
@@ -236,6 +247,29 @@ long vhost_dev_check_owner(struct vhost_dev *dev) | |||
236 | return dev->mm == current->mm ? 0 : -EPERM; | 247 | return dev->mm == current->mm ? 0 : -EPERM; |
237 | } | 248 | } |
238 | 249 | ||
250 | struct vhost_attach_cgroups_struct { | ||
251 | struct vhost_work work; | ||
252 | struct task_struct *owner; | ||
253 | int ret; | ||
254 | }; | ||
255 | |||
256 | static void vhost_attach_cgroups_work(struct vhost_work *work) | ||
257 | { | ||
258 | struct vhost_attach_cgroups_struct *s; | ||
259 | s = container_of(work, struct vhost_attach_cgroups_struct, work); | ||
260 | s->ret = cgroup_attach_task_all(s->owner, current); | ||
261 | } | ||
262 | |||
263 | static int vhost_attach_cgroups(struct vhost_dev *dev) | ||
264 | { | ||
265 | struct vhost_attach_cgroups_struct attach; | ||
266 | attach.owner = current; | ||
267 | vhost_work_init(&attach.work, vhost_attach_cgroups_work); | ||
268 | vhost_work_queue(dev, &attach.work); | ||
269 | vhost_work_flush(dev, &attach.work); | ||
270 | return attach.ret; | ||
271 | } | ||
272 | |||
239 | /* Caller should have device mutex */ | 273 | /* Caller should have device mutex */ |
240 | static long vhost_dev_set_owner(struct vhost_dev *dev) | 274 | static long vhost_dev_set_owner(struct vhost_dev *dev) |
241 | { | 275 | { |
@@ -255,14 +289,16 @@ static long vhost_dev_set_owner(struct vhost_dev *dev) | |||
255 | } | 289 | } |
256 | 290 | ||
257 | dev->worker = worker; | 291 | dev->worker = worker; |
258 | err = cgroup_attach_task_current_cg(worker); | 292 | wake_up_process(worker); /* avoid contributing to loadavg */ |
293 | |||
294 | err = vhost_attach_cgroups(dev); | ||
259 | if (err) | 295 | if (err) |
260 | goto err_cgroup; | 296 | goto err_cgroup; |
261 | wake_up_process(worker); /* avoid contributing to loadavg */ | ||
262 | 297 | ||
263 | return 0; | 298 | return 0; |
264 | err_cgroup: | 299 | err_cgroup: |
265 | kthread_stop(worker); | 300 | kthread_stop(worker); |
301 | dev->worker = NULL; | ||
266 | err_worker: | 302 | err_worker: |
267 | if (dev->mm) | 303 | if (dev->mm) |
268 | mmput(dev->mm); | 304 | mmput(dev->mm); |
@@ -323,7 +359,10 @@ void vhost_dev_cleanup(struct vhost_dev *dev) | |||
323 | dev->mm = NULL; | 359 | dev->mm = NULL; |
324 | 360 | ||
325 | WARN_ON(!list_empty(&dev->work_list)); | 361 | WARN_ON(!list_empty(&dev->work_list)); |
326 | kthread_stop(dev->worker); | 362 | if (dev->worker) { |
363 | kthread_stop(dev->worker); | ||
364 | dev->worker = NULL; | ||
365 | } | ||
327 | } | 366 | } |
328 | 367 | ||
329 | static int log_access_ok(void __user *log_base, u64 addr, unsigned long sz) | 368 | static int log_access_ok(void __user *log_base, u64 addr, unsigned long sz) |
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c index afe21e6eb54..1c2c68356ea 100644 --- a/drivers/video/amba-clcd.c +++ b/drivers/video/amba-clcd.c | |||
@@ -80,7 +80,10 @@ static void clcdfb_disable(struct clcd_fb *fb) | |||
80 | /* | 80 | /* |
81 | * Disable CLCD clock source. | 81 | * Disable CLCD clock source. |
82 | */ | 82 | */ |
83 | clk_disable(fb->clk); | 83 | if (fb->clk_enabled) { |
84 | fb->clk_enabled = false; | ||
85 | clk_disable(fb->clk); | ||
86 | } | ||
84 | } | 87 | } |
85 | 88 | ||
86 | static void clcdfb_enable(struct clcd_fb *fb, u32 cntl) | 89 | static void clcdfb_enable(struct clcd_fb *fb, u32 cntl) |
@@ -88,7 +91,10 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl) | |||
88 | /* | 91 | /* |
89 | * Enable the CLCD clock source. | 92 | * Enable the CLCD clock source. |
90 | */ | 93 | */ |
91 | clk_enable(fb->clk); | 94 | if (!fb->clk_enabled) { |
95 | fb->clk_enabled = true; | ||
96 | clk_enable(fb->clk); | ||
97 | } | ||
92 | 98 | ||
93 | /* | 99 | /* |
94 | * Bring up by first enabling.. | 100 | * Bring up by first enabling.. |
diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h index f3a4e15672d..f96a471cb1a 100644 --- a/drivers/video/matrox/matroxfb_base.h +++ b/drivers/video/matrox/matroxfb_base.h | |||
@@ -151,13 +151,13 @@ static inline void mga_writel(vaddr_t va, unsigned int offs, u_int32_t value) { | |||
151 | static inline void mga_memcpy_toio(vaddr_t va, const void* src, int len) { | 151 | static inline void mga_memcpy_toio(vaddr_t va, const void* src, int len) { |
152 | #if defined(__alpha__) || defined(__i386__) || defined(__x86_64__) | 152 | #if defined(__alpha__) || defined(__i386__) || defined(__x86_64__) |
153 | /* | 153 | /* |
154 | * memcpy_toio works for us if: | 154 | * iowrite32_rep works for us if: |
155 | * (1) Copies data as 32bit quantities, not byte after byte, | 155 | * (1) Copies data as 32bit quantities, not byte after byte, |
156 | * (2) Performs LE ordered stores, and | 156 | * (2) Performs LE ordered stores, and |
157 | * (3) It copes with unaligned source (destination is guaranteed to be page | 157 | * (3) It copes with unaligned source (destination is guaranteed to be page |
158 | * aligned and length is guaranteed to be multiple of 4). | 158 | * aligned and length is guaranteed to be multiple of 4). |
159 | */ | 159 | */ |
160 | memcpy_toio(va.vaddr, src, len); | 160 | iowrite32_rep(va.vaddr, src, len >> 2); |
161 | #else | 161 | #else |
162 | u_int32_t __iomem* addr = va.vaddr; | 162 | u_int32_t __iomem* addr = va.vaddr; |
163 | 163 | ||
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 72f91bff29c..13365ba3521 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -112,6 +112,7 @@ static inline unsigned long *cpu_evtchn_mask(int cpu) | |||
112 | #define VALID_EVTCHN(chn) ((chn) != 0) | 112 | #define VALID_EVTCHN(chn) ((chn) != 0) |
113 | 113 | ||
114 | static struct irq_chip xen_dynamic_chip; | 114 | static struct irq_chip xen_dynamic_chip; |
115 | static struct irq_chip xen_percpu_chip; | ||
115 | 116 | ||
116 | /* Constructor for packed IRQ information. */ | 117 | /* Constructor for packed IRQ information. */ |
117 | static struct irq_info mk_unbound_info(void) | 118 | static struct irq_info mk_unbound_info(void) |
@@ -377,7 +378,7 @@ int bind_evtchn_to_irq(unsigned int evtchn) | |||
377 | irq = find_unbound_irq(); | 378 | irq = find_unbound_irq(); |
378 | 379 | ||
379 | set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, | 380 | set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, |
380 | handle_level_irq, "event"); | 381 | handle_edge_irq, "event"); |
381 | 382 | ||
382 | evtchn_to_irq[evtchn] = irq; | 383 | evtchn_to_irq[evtchn] = irq; |
383 | irq_info[irq] = mk_evtchn_info(evtchn); | 384 | irq_info[irq] = mk_evtchn_info(evtchn); |
@@ -403,8 +404,8 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu) | |||
403 | if (irq < 0) | 404 | if (irq < 0) |
404 | goto out; | 405 | goto out; |
405 | 406 | ||
406 | set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, | 407 | set_irq_chip_and_handler_name(irq, &xen_percpu_chip, |
407 | handle_level_irq, "ipi"); | 408 | handle_percpu_irq, "ipi"); |
408 | 409 | ||
409 | bind_ipi.vcpu = cpu; | 410 | bind_ipi.vcpu = cpu; |
410 | if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi, | 411 | if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi, |
@@ -444,8 +445,8 @@ static int bind_virq_to_irq(unsigned int virq, unsigned int cpu) | |||
444 | 445 | ||
445 | irq = find_unbound_irq(); | 446 | irq = find_unbound_irq(); |
446 | 447 | ||
447 | set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, | 448 | set_irq_chip_and_handler_name(irq, &xen_percpu_chip, |
448 | handle_level_irq, "virq"); | 449 | handle_percpu_irq, "virq"); |
449 | 450 | ||
450 | evtchn_to_irq[evtchn] = irq; | 451 | evtchn_to_irq[evtchn] = irq; |
451 | irq_info[irq] = mk_virq_info(evtchn, virq); | 452 | irq_info[irq] = mk_virq_info(evtchn, virq); |
@@ -964,6 +965,16 @@ static struct irq_chip xen_dynamic_chip __read_mostly = { | |||
964 | .retrigger = retrigger_dynirq, | 965 | .retrigger = retrigger_dynirq, |
965 | }; | 966 | }; |
966 | 967 | ||
968 | static struct irq_chip xen_percpu_chip __read_mostly = { | ||
969 | .name = "xen-percpu", | ||
970 | |||
971 | .disable = disable_dynirq, | ||
972 | .mask = disable_dynirq, | ||
973 | .unmask = enable_dynirq, | ||
974 | |||
975 | .ack = ack_dynirq, | ||
976 | }; | ||
977 | |||
967 | int xen_set_callback_via(uint64_t via) | 978 | int xen_set_callback_via(uint64_t via) |
968 | { | 979 | { |
969 | struct xen_hvm_param a; | 980 | struct xen_hvm_param a; |
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 1799bd89031..ef9c7db5207 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c | |||
@@ -237,7 +237,7 @@ static void sysrq_handler(struct xenbus_watch *watch, const char **vec, | |||
237 | goto again; | 237 | goto again; |
238 | 238 | ||
239 | if (sysrq_key != '\0') | 239 | if (sysrq_key != '\0') |
240 | handle_sysrq(sysrq_key, NULL); | 240 | handle_sysrq(sysrq_key); |
241 | } | 241 | } |
242 | 242 | ||
243 | static struct xenbus_watch sysrq_watch = { | 243 | static struct xenbus_watch sysrq_watch = { |
diff --git a/firmware/Makefile b/firmware/Makefile index b27f09f05d1..9c2d19452d0 100644 --- a/firmware/Makefile +++ b/firmware/Makefile | |||
@@ -142,7 +142,7 @@ fw-shipped-$(CONFIG_YAM) += yam/1200.bin yam/9600.bin | |||
142 | fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-) | 142 | fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-) |
143 | 143 | ||
144 | # Directories which we _might_ need to create, so we have a rule for them. | 144 | # Directories which we _might_ need to create, so we have a rule for them. |
145 | firmware-dirs := $(sort $(patsubst %,$(objtree)/$(obj)/%/,$(dir $(fw-external-y) $(fw-shipped-all)))) | 145 | firmware-dirs := $(sort $(addprefix $(objtree)/$(obj)/,$(dir $(fw-external-y) $(fw-shipped-all)))) |
146 | 146 | ||
147 | quiet_cmd_mkdir = MKDIR $(patsubst $(objtree)/%,%,$@) | 147 | quiet_cmd_mkdir = MKDIR $(patsubst $(objtree)/%,%,$@) |
148 | cmd_mkdir = mkdir -p $@ | 148 | cmd_mkdir = mkdir -p $@ |
diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 35856368906..6406f896bf9 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c | |||
@@ -242,7 +242,8 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) | |||
242 | } | 242 | } |
243 | kfree(wnames); | 243 | kfree(wnames); |
244 | fid_out: | 244 | fid_out: |
245 | v9fs_fid_add(dentry, fid); | 245 | if (!IS_ERR(fid)) |
246 | v9fs_fid_add(dentry, fid); | ||
246 | err_out: | 247 | err_out: |
247 | up_read(&v9ses->rename_sem); | 248 | up_read(&v9ses->rename_sem); |
248 | return fid; | 249 | return fid; |
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index 9e60fd20171..a7528b91393 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c | |||
@@ -108,7 +108,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
108 | Node *fmt; | 108 | Node *fmt; |
109 | struct file * interp_file = NULL; | 109 | struct file * interp_file = NULL; |
110 | char iname[BINPRM_BUF_SIZE]; | 110 | char iname[BINPRM_BUF_SIZE]; |
111 | char *iname_addr = iname; | 111 | const char *iname_addr = iname; |
112 | int retval; | 112 | int retval; |
113 | int fd_binary = -1; | 113 | int fd_binary = -1; |
114 | 114 | ||
diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c index aca9d55afb2..396a9884591 100644 --- a/fs/binfmt_script.c +++ b/fs/binfmt_script.c | |||
@@ -16,7 +16,8 @@ | |||
16 | 16 | ||
17 | static int load_script(struct linux_binprm *bprm,struct pt_regs *regs) | 17 | static int load_script(struct linux_binprm *bprm,struct pt_regs *regs) |
18 | { | 18 | { |
19 | char *cp, *i_name, *i_arg; | 19 | const char *i_arg, *i_name; |
20 | char *cp; | ||
20 | struct file *file; | 21 | struct file *file; |
21 | char interp[BINPRM_BUF_SIZE]; | 22 | char interp[BINPRM_BUF_SIZE]; |
22 | int retval; | 23 | int retval; |
diff --git a/fs/buffer.c b/fs/buffer.c index 50efa339e05..3e7dca279d1 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -770,11 +770,12 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list) | |||
770 | spin_unlock(lock); | 770 | spin_unlock(lock); |
771 | /* | 771 | /* |
772 | * Ensure any pending I/O completes so that | 772 | * Ensure any pending I/O completes so that |
773 | * ll_rw_block() actually writes the current | 773 | * write_dirty_buffer() actually writes the |
774 | * contents - it is a noop if I/O is still in | 774 | * current contents - it is a noop if I/O is |
775 | * flight on potentially older contents. | 775 | * still in flight on potentially older |
776 | * contents. | ||
776 | */ | 777 | */ |
777 | ll_rw_block(SWRITE_SYNC_PLUG, 1, &bh); | 778 | write_dirty_buffer(bh, WRITE_SYNC_PLUG); |
778 | 779 | ||
779 | /* | 780 | /* |
780 | * Kick off IO for the previous mapping. Note | 781 | * Kick off IO for the previous mapping. Note |
@@ -2912,13 +2913,6 @@ int submit_bh(int rw, struct buffer_head * bh) | |||
2912 | BUG_ON(buffer_unwritten(bh)); | 2913 | BUG_ON(buffer_unwritten(bh)); |
2913 | 2914 | ||
2914 | /* | 2915 | /* |
2915 | * Mask in barrier bit for a write (could be either a WRITE or a | ||
2916 | * WRITE_SYNC | ||
2917 | */ | ||
2918 | if (buffer_ordered(bh) && (rw & WRITE)) | ||
2919 | rw |= WRITE_BARRIER; | ||
2920 | |||
2921 | /* | ||
2922 | * Only clear out a write error when rewriting | 2916 | * Only clear out a write error when rewriting |
2923 | */ | 2917 | */ |
2924 | if (test_set_buffer_req(bh) && (rw & WRITE)) | 2918 | if (test_set_buffer_req(bh) && (rw & WRITE)) |
@@ -2956,22 +2950,21 @@ EXPORT_SYMBOL(submit_bh); | |||
2956 | 2950 | ||
2957 | /** | 2951 | /** |
2958 | * ll_rw_block: low-level access to block devices (DEPRECATED) | 2952 | * ll_rw_block: low-level access to block devices (DEPRECATED) |
2959 | * @rw: whether to %READ or %WRITE or %SWRITE or maybe %READA (readahead) | 2953 | * @rw: whether to %READ or %WRITE or maybe %READA (readahead) |
2960 | * @nr: number of &struct buffer_heads in the array | 2954 | * @nr: number of &struct buffer_heads in the array |
2961 | * @bhs: array of pointers to &struct buffer_head | 2955 | * @bhs: array of pointers to &struct buffer_head |
2962 | * | 2956 | * |
2963 | * ll_rw_block() takes an array of pointers to &struct buffer_heads, and | 2957 | * ll_rw_block() takes an array of pointers to &struct buffer_heads, and |
2964 | * requests an I/O operation on them, either a %READ or a %WRITE. The third | 2958 | * requests an I/O operation on them, either a %READ or a %WRITE. The third |
2965 | * %SWRITE is like %WRITE only we make sure that the *current* data in buffers | 2959 | * %READA option is described in the documentation for generic_make_request() |
2966 | * are sent to disk. The fourth %READA option is described in the documentation | 2960 | * which ll_rw_block() calls. |
2967 | * for generic_make_request() which ll_rw_block() calls. | ||
2968 | * | 2961 | * |
2969 | * This function drops any buffer that it cannot get a lock on (with the | 2962 | * This function drops any buffer that it cannot get a lock on (with the |
2970 | * BH_Lock state bit) unless SWRITE is required, any buffer that appears to be | 2963 | * BH_Lock state bit), any buffer that appears to be clean when doing a write |
2971 | * clean when doing a write request, and any buffer that appears to be | 2964 | * request, and any buffer that appears to be up-to-date when doing read |
2972 | * up-to-date when doing read request. Further it marks as clean buffers that | 2965 | * request. Further it marks as clean buffers that are processed for |
2973 | * are processed for writing (the buffer cache won't assume that they are | 2966 | * writing (the buffer cache won't assume that they are actually clean |
2974 | * actually clean until the buffer gets unlocked). | 2967 | * until the buffer gets unlocked). |
2975 | * | 2968 | * |
2976 | * ll_rw_block sets b_end_io to simple completion handler that marks | 2969 | * ll_rw_block sets b_end_io to simple completion handler that marks |
2977 | * the buffer up-to-date (if approriate), unlocks the buffer and wakes | 2970 | * the buffer up-to-date (if approriate), unlocks the buffer and wakes |
@@ -2987,20 +2980,13 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[]) | |||
2987 | for (i = 0; i < nr; i++) { | 2980 | for (i = 0; i < nr; i++) { |
2988 | struct buffer_head *bh = bhs[i]; | 2981 | struct buffer_head *bh = bhs[i]; |
2989 | 2982 | ||
2990 | if (rw == SWRITE || rw == SWRITE_SYNC || rw == SWRITE_SYNC_PLUG) | 2983 | if (!trylock_buffer(bh)) |
2991 | lock_buffer(bh); | ||
2992 | else if (!trylock_buffer(bh)) | ||
2993 | continue; | 2984 | continue; |
2994 | 2985 | if (rw == WRITE) { | |
2995 | if (rw == WRITE || rw == SWRITE || rw == SWRITE_SYNC || | ||
2996 | rw == SWRITE_SYNC_PLUG) { | ||
2997 | if (test_clear_buffer_dirty(bh)) { | 2986 | if (test_clear_buffer_dirty(bh)) { |
2998 | bh->b_end_io = end_buffer_write_sync; | 2987 | bh->b_end_io = end_buffer_write_sync; |
2999 | get_bh(bh); | 2988 | get_bh(bh); |
3000 | if (rw == SWRITE_SYNC) | 2989 | submit_bh(WRITE, bh); |
3001 | submit_bh(WRITE_SYNC, bh); | ||
3002 | else | ||
3003 | submit_bh(WRITE, bh); | ||
3004 | continue; | 2990 | continue; |
3005 | } | 2991 | } |
3006 | } else { | 2992 | } else { |
@@ -3016,12 +3002,25 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[]) | |||
3016 | } | 3002 | } |
3017 | EXPORT_SYMBOL(ll_rw_block); | 3003 | EXPORT_SYMBOL(ll_rw_block); |
3018 | 3004 | ||
3005 | void write_dirty_buffer(struct buffer_head *bh, int rw) | ||
3006 | { | ||
3007 | lock_buffer(bh); | ||
3008 | if (!test_clear_buffer_dirty(bh)) { | ||
3009 | unlock_buffer(bh); | ||
3010 | return; | ||
3011 | } | ||
3012 | bh->b_end_io = end_buffer_write_sync; | ||
3013 | get_bh(bh); | ||
3014 | submit_bh(rw, bh); | ||
3015 | } | ||
3016 | EXPORT_SYMBOL(write_dirty_buffer); | ||
3017 | |||
3019 | /* | 3018 | /* |
3020 | * For a data-integrity writeout, we need to wait upon any in-progress I/O | 3019 | * For a data-integrity writeout, we need to wait upon any in-progress I/O |
3021 | * and then start new I/O and then wait upon it. The caller must have a ref on | 3020 | * and then start new I/O and then wait upon it. The caller must have a ref on |
3022 | * the buffer_head. | 3021 | * the buffer_head. |
3023 | */ | 3022 | */ |
3024 | int sync_dirty_buffer(struct buffer_head *bh) | 3023 | int __sync_dirty_buffer(struct buffer_head *bh, int rw) |
3025 | { | 3024 | { |
3026 | int ret = 0; | 3025 | int ret = 0; |
3027 | 3026 | ||
@@ -3030,7 +3029,7 @@ int sync_dirty_buffer(struct buffer_head *bh) | |||
3030 | if (test_clear_buffer_dirty(bh)) { | 3029 | if (test_clear_buffer_dirty(bh)) { |
3031 | get_bh(bh); | 3030 | get_bh(bh); |
3032 | bh->b_end_io = end_buffer_write_sync; | 3031 | bh->b_end_io = end_buffer_write_sync; |
3033 | ret = submit_bh(WRITE_SYNC, bh); | 3032 | ret = submit_bh(rw, bh); |
3034 | wait_on_buffer(bh); | 3033 | wait_on_buffer(bh); |
3035 | if (buffer_eopnotsupp(bh)) { | 3034 | if (buffer_eopnotsupp(bh)) { |
3036 | clear_buffer_eopnotsupp(bh); | 3035 | clear_buffer_eopnotsupp(bh); |
@@ -3043,6 +3042,12 @@ int sync_dirty_buffer(struct buffer_head *bh) | |||
3043 | } | 3042 | } |
3044 | return ret; | 3043 | return ret; |
3045 | } | 3044 | } |
3045 | EXPORT_SYMBOL(__sync_dirty_buffer); | ||
3046 | |||
3047 | int sync_dirty_buffer(struct buffer_head *bh) | ||
3048 | { | ||
3049 | return __sync_dirty_buffer(bh, WRITE_SYNC); | ||
3050 | } | ||
3046 | EXPORT_SYMBOL(sync_dirty_buffer); | 3051 | EXPORT_SYMBOL(sync_dirty_buffer); |
3047 | 3052 | ||
3048 | /* | 3053 | /* |
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 5598a0d0229..4cfce1ee31f 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c | |||
@@ -87,7 +87,7 @@ static int ceph_set_page_dirty(struct page *page) | |||
87 | 87 | ||
88 | /* dirty the head */ | 88 | /* dirty the head */ |
89 | spin_lock(&inode->i_lock); | 89 | spin_lock(&inode->i_lock); |
90 | if (ci->i_wrbuffer_ref_head == 0) | 90 | if (ci->i_head_snapc == NULL) |
91 | ci->i_head_snapc = ceph_get_snap_context(snapc); | 91 | ci->i_head_snapc = ceph_get_snap_context(snapc); |
92 | ++ci->i_wrbuffer_ref_head; | 92 | ++ci->i_wrbuffer_ref_head; |
93 | if (ci->i_wrbuffer_ref == 0) | 93 | if (ci->i_wrbuffer_ref == 0) |
@@ -105,13 +105,7 @@ static int ceph_set_page_dirty(struct page *page) | |||
105 | spin_lock_irq(&mapping->tree_lock); | 105 | spin_lock_irq(&mapping->tree_lock); |
106 | if (page->mapping) { /* Race with truncate? */ | 106 | if (page->mapping) { /* Race with truncate? */ |
107 | WARN_ON_ONCE(!PageUptodate(page)); | 107 | WARN_ON_ONCE(!PageUptodate(page)); |
108 | 108 | account_page_dirtied(page, page->mapping); | |
109 | if (mapping_cap_account_dirty(mapping)) { | ||
110 | __inc_zone_page_state(page, NR_FILE_DIRTY); | ||
111 | __inc_bdi_stat(mapping->backing_dev_info, | ||
112 | BDI_RECLAIMABLE); | ||
113 | task_io_account_write(PAGE_CACHE_SIZE); | ||
114 | } | ||
115 | radix_tree_tag_set(&mapping->page_tree, | 109 | radix_tree_tag_set(&mapping->page_tree, |
116 | page_index(page), PAGECACHE_TAG_DIRTY); | 110 | page_index(page), PAGECACHE_TAG_DIRTY); |
117 | 111 | ||
@@ -352,7 +346,7 @@ static struct ceph_snap_context *get_oldest_context(struct inode *inode, | |||
352 | break; | 346 | break; |
353 | } | 347 | } |
354 | } | 348 | } |
355 | if (!snapc && ci->i_head_snapc) { | 349 | if (!snapc && ci->i_wrbuffer_ref_head) { |
356 | snapc = ceph_get_snap_context(ci->i_head_snapc); | 350 | snapc = ceph_get_snap_context(ci->i_head_snapc); |
357 | dout(" head snapc %p has %d dirty pages\n", | 351 | dout(" head snapc %p has %d dirty pages\n", |
358 | snapc, ci->i_wrbuffer_ref_head); | 352 | snapc, ci->i_wrbuffer_ref_head); |
diff --git a/fs/ceph/auth_x.c b/fs/ceph/auth_x.c index 582e0b2caf8..a2d002cbdec 100644 --- a/fs/ceph/auth_x.c +++ b/fs/ceph/auth_x.c | |||
@@ -376,7 +376,7 @@ static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed) | |||
376 | 376 | ||
377 | th = get_ticket_handler(ac, service); | 377 | th = get_ticket_handler(ac, service); |
378 | 378 | ||
379 | if (!th) { | 379 | if (IS_ERR(th)) { |
380 | *pneed |= service; | 380 | *pneed |= service; |
381 | continue; | 381 | continue; |
382 | } | 382 | } |
@@ -399,6 +399,9 @@ static int ceph_x_build_request(struct ceph_auth_client *ac, | |||
399 | struct ceph_x_ticket_handler *th = | 399 | struct ceph_x_ticket_handler *th = |
400 | get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH); | 400 | get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH); |
401 | 401 | ||
402 | if (IS_ERR(th)) | ||
403 | return PTR_ERR(th); | ||
404 | |||
402 | ceph_x_validate_tickets(ac, &need); | 405 | ceph_x_validate_tickets(ac, &need); |
403 | 406 | ||
404 | dout("build_request want %x have %x need %x\n", | 407 | dout("build_request want %x have %x need %x\n", |
@@ -450,7 +453,6 @@ static int ceph_x_build_request(struct ceph_auth_client *ac, | |||
450 | return -ERANGE; | 453 | return -ERANGE; |
451 | head->op = cpu_to_le16(CEPHX_GET_PRINCIPAL_SESSION_KEY); | 454 | head->op = cpu_to_le16(CEPHX_GET_PRINCIPAL_SESSION_KEY); |
452 | 455 | ||
453 | BUG_ON(!th); | ||
454 | ret = ceph_x_build_authorizer(ac, th, &xi->auth_authorizer); | 456 | ret = ceph_x_build_authorizer(ac, th, &xi->auth_authorizer); |
455 | if (ret) | 457 | if (ret) |
456 | return ret; | 458 | return ret; |
@@ -505,7 +507,8 @@ static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result, | |||
505 | 507 | ||
506 | case CEPHX_GET_PRINCIPAL_SESSION_KEY: | 508 | case CEPHX_GET_PRINCIPAL_SESSION_KEY: |
507 | th = get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH); | 509 | th = get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH); |
508 | BUG_ON(!th); | 510 | if (IS_ERR(th)) |
511 | return PTR_ERR(th); | ||
509 | ret = ceph_x_proc_ticket_reply(ac, &th->session_key, | 512 | ret = ceph_x_proc_ticket_reply(ac, &th->session_key, |
510 | buf + sizeof(*head), end); | 513 | buf + sizeof(*head), end); |
511 | break; | 514 | break; |
@@ -563,8 +566,8 @@ static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac, | |||
563 | void *end = p + sizeof(au->reply_buf); | 566 | void *end = p + sizeof(au->reply_buf); |
564 | 567 | ||
565 | th = get_ticket_handler(ac, au->service); | 568 | th = get_ticket_handler(ac, au->service); |
566 | if (!th) | 569 | if (IS_ERR(th)) |
567 | return -EIO; /* hrm! */ | 570 | return PTR_ERR(th); |
568 | ret = ceph_x_decrypt(&th->session_key, &p, end, &reply, sizeof(reply)); | 571 | ret = ceph_x_decrypt(&th->session_key, &p, end, &reply, sizeof(reply)); |
569 | if (ret < 0) | 572 | if (ret < 0) |
570 | return ret; | 573 | return ret; |
@@ -626,7 +629,7 @@ static void ceph_x_invalidate_authorizer(struct ceph_auth_client *ac, | |||
626 | struct ceph_x_ticket_handler *th; | 629 | struct ceph_x_ticket_handler *th; |
627 | 630 | ||
628 | th = get_ticket_handler(ac, peer_type); | 631 | th = get_ticket_handler(ac, peer_type); |
629 | if (th && !IS_ERR(th)) | 632 | if (!IS_ERR(th)) |
630 | remove_ticket_handler(ac, th); | 633 | remove_ticket_handler(ac, th); |
631 | } | 634 | } |
632 | 635 | ||
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 7bf182b0397..a2069b6680a 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -1082,6 +1082,7 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | |||
1082 | gid_t gid; | 1082 | gid_t gid; |
1083 | struct ceph_mds_session *session; | 1083 | struct ceph_mds_session *session; |
1084 | u64 xattr_version = 0; | 1084 | u64 xattr_version = 0; |
1085 | struct ceph_buffer *xattr_blob = NULL; | ||
1085 | int delayed = 0; | 1086 | int delayed = 0; |
1086 | u64 flush_tid = 0; | 1087 | u64 flush_tid = 0; |
1087 | int i; | 1088 | int i; |
@@ -1142,6 +1143,10 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | |||
1142 | for (i = 0; i < CEPH_CAP_BITS; i++) | 1143 | for (i = 0; i < CEPH_CAP_BITS; i++) |
1143 | if (flushing & (1 << i)) | 1144 | if (flushing & (1 << i)) |
1144 | ci->i_cap_flush_tid[i] = flush_tid; | 1145 | ci->i_cap_flush_tid[i] = flush_tid; |
1146 | |||
1147 | follows = ci->i_head_snapc->seq; | ||
1148 | } else { | ||
1149 | follows = 0; | ||
1145 | } | 1150 | } |
1146 | 1151 | ||
1147 | keep = cap->implemented; | 1152 | keep = cap->implemented; |
@@ -1155,14 +1160,14 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | |||
1155 | mtime = inode->i_mtime; | 1160 | mtime = inode->i_mtime; |
1156 | atime = inode->i_atime; | 1161 | atime = inode->i_atime; |
1157 | time_warp_seq = ci->i_time_warp_seq; | 1162 | time_warp_seq = ci->i_time_warp_seq; |
1158 | follows = ci->i_snap_realm->cached_context->seq; | ||
1159 | uid = inode->i_uid; | 1163 | uid = inode->i_uid; |
1160 | gid = inode->i_gid; | 1164 | gid = inode->i_gid; |
1161 | mode = inode->i_mode; | 1165 | mode = inode->i_mode; |
1162 | 1166 | ||
1163 | if (dropping & CEPH_CAP_XATTR_EXCL) { | 1167 | if (flushing & CEPH_CAP_XATTR_EXCL) { |
1164 | __ceph_build_xattrs_blob(ci); | 1168 | __ceph_build_xattrs_blob(ci); |
1165 | xattr_version = ci->i_xattrs.version + 1; | 1169 | xattr_blob = ci->i_xattrs.blob; |
1170 | xattr_version = ci->i_xattrs.version; | ||
1166 | } | 1171 | } |
1167 | 1172 | ||
1168 | spin_unlock(&inode->i_lock); | 1173 | spin_unlock(&inode->i_lock); |
@@ -1170,9 +1175,7 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | |||
1170 | ret = send_cap_msg(session, ceph_vino(inode).ino, cap_id, | 1175 | ret = send_cap_msg(session, ceph_vino(inode).ino, cap_id, |
1171 | op, keep, want, flushing, seq, flush_tid, issue_seq, mseq, | 1176 | op, keep, want, flushing, seq, flush_tid, issue_seq, mseq, |
1172 | size, max_size, &mtime, &atime, time_warp_seq, | 1177 | size, max_size, &mtime, &atime, time_warp_seq, |
1173 | uid, gid, mode, | 1178 | uid, gid, mode, xattr_version, xattr_blob, |
1174 | xattr_version, | ||
1175 | (flushing & CEPH_CAP_XATTR_EXCL) ? ci->i_xattrs.blob : NULL, | ||
1176 | follows); | 1179 | follows); |
1177 | if (ret < 0) { | 1180 | if (ret < 0) { |
1178 | dout("error sending cap msg, must requeue %p\n", inode); | 1181 | dout("error sending cap msg, must requeue %p\n", inode); |
@@ -1282,7 +1285,7 @@ retry: | |||
1282 | &capsnap->mtime, &capsnap->atime, | 1285 | &capsnap->mtime, &capsnap->atime, |
1283 | capsnap->time_warp_seq, | 1286 | capsnap->time_warp_seq, |
1284 | capsnap->uid, capsnap->gid, capsnap->mode, | 1287 | capsnap->uid, capsnap->gid, capsnap->mode, |
1285 | 0, NULL, | 1288 | capsnap->xattr_version, capsnap->xattr_blob, |
1286 | capsnap->follows); | 1289 | capsnap->follows); |
1287 | 1290 | ||
1288 | next_follows = capsnap->follows + 1; | 1291 | next_follows = capsnap->follows + 1; |
@@ -1332,7 +1335,11 @@ void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask) | |||
1332 | ceph_cap_string(was | mask)); | 1335 | ceph_cap_string(was | mask)); |
1333 | ci->i_dirty_caps |= mask; | 1336 | ci->i_dirty_caps |= mask; |
1334 | if (was == 0) { | 1337 | if (was == 0) { |
1335 | dout(" inode %p now dirty\n", &ci->vfs_inode); | 1338 | if (!ci->i_head_snapc) |
1339 | ci->i_head_snapc = ceph_get_snap_context( | ||
1340 | ci->i_snap_realm->cached_context); | ||
1341 | dout(" inode %p now dirty snapc %p\n", &ci->vfs_inode, | ||
1342 | ci->i_head_snapc); | ||
1336 | BUG_ON(!list_empty(&ci->i_dirty_item)); | 1343 | BUG_ON(!list_empty(&ci->i_dirty_item)); |
1337 | spin_lock(&mdsc->cap_dirty_lock); | 1344 | spin_lock(&mdsc->cap_dirty_lock); |
1338 | list_add(&ci->i_dirty_item, &mdsc->cap_dirty); | 1345 | list_add(&ci->i_dirty_item, &mdsc->cap_dirty); |
@@ -2190,7 +2197,9 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, | |||
2190 | 2197 | ||
2191 | if (ci->i_head_snapc == snapc) { | 2198 | if (ci->i_head_snapc == snapc) { |
2192 | ci->i_wrbuffer_ref_head -= nr; | 2199 | ci->i_wrbuffer_ref_head -= nr; |
2193 | if (!ci->i_wrbuffer_ref_head) { | 2200 | if (ci->i_wrbuffer_ref_head == 0 && |
2201 | ci->i_dirty_caps == 0 && ci->i_flushing_caps == 0) { | ||
2202 | BUG_ON(!ci->i_head_snapc); | ||
2194 | ceph_put_snap_context(ci->i_head_snapc); | 2203 | ceph_put_snap_context(ci->i_head_snapc); |
2195 | ci->i_head_snapc = NULL; | 2204 | ci->i_head_snapc = NULL; |
2196 | } | 2205 | } |
@@ -2483,6 +2492,11 @@ static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid, | |||
2483 | dout(" inode %p now clean\n", inode); | 2492 | dout(" inode %p now clean\n", inode); |
2484 | BUG_ON(!list_empty(&ci->i_dirty_item)); | 2493 | BUG_ON(!list_empty(&ci->i_dirty_item)); |
2485 | drop = 1; | 2494 | drop = 1; |
2495 | if (ci->i_wrbuffer_ref_head == 0) { | ||
2496 | BUG_ON(!ci->i_head_snapc); | ||
2497 | ceph_put_snap_context(ci->i_head_snapc); | ||
2498 | ci->i_head_snapc = NULL; | ||
2499 | } | ||
2486 | } else { | 2500 | } else { |
2487 | BUG_ON(list_empty(&ci->i_dirty_item)); | 2501 | BUG_ON(list_empty(&ci->i_dirty_item)); |
2488 | } | 2502 | } |
diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index 360c4f22718..6fd8b20a861 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c | |||
@@ -171,6 +171,8 @@ static int mdsc_show(struct seq_file *s, void *p) | |||
171 | } else if (req->r_dentry) { | 171 | } else if (req->r_dentry) { |
172 | path = ceph_mdsc_build_path(req->r_dentry, &pathlen, | 172 | path = ceph_mdsc_build_path(req->r_dentry, &pathlen, |
173 | &pathbase, 0); | 173 | &pathbase, 0); |
174 | if (IS_ERR(path)) | ||
175 | path = NULL; | ||
174 | spin_lock(&req->r_dentry->d_lock); | 176 | spin_lock(&req->r_dentry->d_lock); |
175 | seq_printf(s, " #%llx/%.*s (%s)", | 177 | seq_printf(s, " #%llx/%.*s (%s)", |
176 | ceph_ino(req->r_dentry->d_parent->d_inode), | 178 | ceph_ino(req->r_dentry->d_parent->d_inode), |
@@ -187,6 +189,8 @@ static int mdsc_show(struct seq_file *s, void *p) | |||
187 | if (req->r_old_dentry) { | 189 | if (req->r_old_dentry) { |
188 | path = ceph_mdsc_build_path(req->r_old_dentry, &pathlen, | 190 | path = ceph_mdsc_build_path(req->r_old_dentry, &pathlen, |
189 | &pathbase, 0); | 191 | &pathbase, 0); |
192 | if (IS_ERR(path)) | ||
193 | path = NULL; | ||
190 | spin_lock(&req->r_old_dentry->d_lock); | 194 | spin_lock(&req->r_old_dentry->d_lock); |
191 | seq_printf(s, " #%llx/%.*s (%s)", | 195 | seq_printf(s, " #%llx/%.*s (%s)", |
192 | ceph_ino(req->r_old_dentry->d_parent->d_inode), | 196 | ceph_ino(req->r_old_dentry->d_parent->d_inode), |
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 67bbb41d552..6e4f43ff23e 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -46,7 +46,7 @@ int ceph_init_dentry(struct dentry *dentry) | |||
46 | else | 46 | else |
47 | dentry->d_op = &ceph_snap_dentry_ops; | 47 | dentry->d_op = &ceph_snap_dentry_ops; |
48 | 48 | ||
49 | di = kmem_cache_alloc(ceph_dentry_cachep, GFP_NOFS); | 49 | di = kmem_cache_alloc(ceph_dentry_cachep, GFP_NOFS | __GFP_ZERO); |
50 | if (!di) | 50 | if (!di) |
51 | return -ENOMEM; /* oh well */ | 51 | return -ENOMEM; /* oh well */ |
52 | 52 | ||
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 5d893d31e39..e7cca414da0 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -677,6 +677,7 @@ static int fill_inode(struct inode *inode, | |||
677 | if (ci->i_files == 0 && ci->i_subdirs == 0 && | 677 | if (ci->i_files == 0 && ci->i_subdirs == 0 && |
678 | ceph_snap(inode) == CEPH_NOSNAP && | 678 | ceph_snap(inode) == CEPH_NOSNAP && |
679 | (le32_to_cpu(info->cap.caps) & CEPH_CAP_FILE_SHARED) && | 679 | (le32_to_cpu(info->cap.caps) & CEPH_CAP_FILE_SHARED) && |
680 | (issued & CEPH_CAP_FILE_EXCL) == 0 && | ||
680 | (ci->i_ceph_flags & CEPH_I_COMPLETE) == 0) { | 681 | (ci->i_ceph_flags & CEPH_I_COMPLETE) == 0) { |
681 | dout(" marking %p complete (empty)\n", inode); | 682 | dout(" marking %p complete (empty)\n", inode); |
682 | ci->i_ceph_flags |= CEPH_I_COMPLETE; | 683 | ci->i_ceph_flags |= CEPH_I_COMPLETE; |
@@ -1229,11 +1230,11 @@ retry_lookup: | |||
1229 | in = dn->d_inode; | 1230 | in = dn->d_inode; |
1230 | } else { | 1231 | } else { |
1231 | in = ceph_get_inode(parent->d_sb, vino); | 1232 | in = ceph_get_inode(parent->d_sb, vino); |
1232 | if (in == NULL) { | 1233 | if (IS_ERR(in)) { |
1233 | dout("new_inode badness\n"); | 1234 | dout("new_inode badness\n"); |
1234 | d_delete(dn); | 1235 | d_delete(dn); |
1235 | dput(dn); | 1236 | dput(dn); |
1236 | err = -ENOMEM; | 1237 | err = PTR_ERR(in); |
1237 | goto out; | 1238 | goto out; |
1238 | } | 1239 | } |
1239 | dn = splice_dentry(dn, in, NULL); | 1240 | dn = splice_dentry(dn, in, NULL); |
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index ae85af06454..ff4e753aae9 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c | |||
@@ -82,7 +82,8 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) | |||
82 | length = fl->fl_end - fl->fl_start + 1; | 82 | length = fl->fl_end - fl->fl_start + 1; |
83 | 83 | ||
84 | err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, | 84 | err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, |
85 | (u64)fl->fl_pid, (u64)fl->fl_nspid, | 85 | (u64)fl->fl_pid, |
86 | (u64)(unsigned long)fl->fl_nspid, | ||
86 | lock_cmd, fl->fl_start, | 87 | lock_cmd, fl->fl_start, |
87 | length, wait); | 88 | length, wait); |
88 | if (!err) { | 89 | if (!err) { |
@@ -92,7 +93,8 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) | |||
92 | /* undo! This should only happen if the kernel detects | 93 | /* undo! This should only happen if the kernel detects |
93 | * local deadlock. */ | 94 | * local deadlock. */ |
94 | ceph_lock_message(CEPH_LOCK_FCNTL, op, file, | 95 | ceph_lock_message(CEPH_LOCK_FCNTL, op, file, |
95 | (u64)fl->fl_pid, (u64)fl->fl_nspid, | 96 | (u64)fl->fl_pid, |
97 | (u64)(unsigned long)fl->fl_nspid, | ||
96 | CEPH_LOCK_UNLOCK, fl->fl_start, | 98 | CEPH_LOCK_UNLOCK, fl->fl_start, |
97 | length, 0); | 99 | length, 0); |
98 | dout("got %d on posix_lock_file, undid lock", err); | 100 | dout("got %d on posix_lock_file, undid lock", err); |
@@ -132,7 +134,8 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl) | |||
132 | length = fl->fl_end - fl->fl_start + 1; | 134 | length = fl->fl_end - fl->fl_start + 1; |
133 | 135 | ||
134 | err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK, | 136 | err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK, |
135 | file, (u64)fl->fl_pid, (u64)fl->fl_nspid, | 137 | file, (u64)fl->fl_pid, |
138 | (u64)(unsigned long)fl->fl_nspid, | ||
136 | lock_cmd, fl->fl_start, | 139 | lock_cmd, fl->fl_start, |
137 | length, wait); | 140 | length, wait); |
138 | if (!err) { | 141 | if (!err) { |
@@ -141,7 +144,7 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl) | |||
141 | ceph_lock_message(CEPH_LOCK_FLOCK, | 144 | ceph_lock_message(CEPH_LOCK_FLOCK, |
142 | CEPH_MDS_OP_SETFILELOCK, | 145 | CEPH_MDS_OP_SETFILELOCK, |
143 | file, (u64)fl->fl_pid, | 146 | file, (u64)fl->fl_pid, |
144 | (u64)fl->fl_nspid, | 147 | (u64)(unsigned long)fl->fl_nspid, |
145 | CEPH_LOCK_UNLOCK, fl->fl_start, | 148 | CEPH_LOCK_UNLOCK, fl->fl_start, |
146 | length, 0); | 149 | length, 0); |
147 | dout("got %d on flock_lock_file_wait, undid lock", err); | 150 | dout("got %d on flock_lock_file_wait, undid lock", err); |
@@ -235,7 +238,8 @@ int lock_to_ceph_filelock(struct file_lock *lock, | |||
235 | cephlock->length = cpu_to_le64(lock->fl_end - lock->fl_start + 1); | 238 | cephlock->length = cpu_to_le64(lock->fl_end - lock->fl_start + 1); |
236 | cephlock->client = cpu_to_le64(0); | 239 | cephlock->client = cpu_to_le64(0); |
237 | cephlock->pid = cpu_to_le64(lock->fl_pid); | 240 | cephlock->pid = cpu_to_le64(lock->fl_pid); |
238 | cephlock->pid_namespace = cpu_to_le64((u64)lock->fl_nspid); | 241 | cephlock->pid_namespace = |
242 | cpu_to_le64((u64)(unsigned long)lock->fl_nspid); | ||
239 | 243 | ||
240 | switch (lock->fl_type) { | 244 | switch (lock->fl_type) { |
241 | case F_RDLCK: | 245 | case F_RDLCK: |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index a75ddbf9fe3..f091b135178 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -560,6 +560,13 @@ static void __unregister_request(struct ceph_mds_client *mdsc, | |||
560 | * | 560 | * |
561 | * Called under mdsc->mutex. | 561 | * Called under mdsc->mutex. |
562 | */ | 562 | */ |
563 | struct dentry *get_nonsnap_parent(struct dentry *dentry) | ||
564 | { | ||
565 | while (!IS_ROOT(dentry) && ceph_snap(dentry->d_inode) != CEPH_NOSNAP) | ||
566 | dentry = dentry->d_parent; | ||
567 | return dentry; | ||
568 | } | ||
569 | |||
563 | static int __choose_mds(struct ceph_mds_client *mdsc, | 570 | static int __choose_mds(struct ceph_mds_client *mdsc, |
564 | struct ceph_mds_request *req) | 571 | struct ceph_mds_request *req) |
565 | { | 572 | { |
@@ -590,14 +597,29 @@ static int __choose_mds(struct ceph_mds_client *mdsc, | |||
590 | if (req->r_inode) { | 597 | if (req->r_inode) { |
591 | inode = req->r_inode; | 598 | inode = req->r_inode; |
592 | } else if (req->r_dentry) { | 599 | } else if (req->r_dentry) { |
593 | if (req->r_dentry->d_inode) { | 600 | struct inode *dir = req->r_dentry->d_parent->d_inode; |
601 | |||
602 | if (dir->i_sb != mdsc->client->sb) { | ||
603 | /* not this fs! */ | ||
604 | inode = req->r_dentry->d_inode; | ||
605 | } else if (ceph_snap(dir) != CEPH_NOSNAP) { | ||
606 | /* direct snapped/virtual snapdir requests | ||
607 | * based on parent dir inode */ | ||
608 | struct dentry *dn = | ||
609 | get_nonsnap_parent(req->r_dentry->d_parent); | ||
610 | inode = dn->d_inode; | ||
611 | dout("__choose_mds using nonsnap parent %p\n", inode); | ||
612 | } else if (req->r_dentry->d_inode) { | ||
613 | /* dentry target */ | ||
594 | inode = req->r_dentry->d_inode; | 614 | inode = req->r_dentry->d_inode; |
595 | } else { | 615 | } else { |
596 | inode = req->r_dentry->d_parent->d_inode; | 616 | /* dir + name */ |
617 | inode = dir; | ||
597 | hash = req->r_dentry->d_name.hash; | 618 | hash = req->r_dentry->d_name.hash; |
598 | is_hash = true; | 619 | is_hash = true; |
599 | } | 620 | } |
600 | } | 621 | } |
622 | |||
601 | dout("__choose_mds %p is_hash=%d (%d) mode %d\n", inode, (int)is_hash, | 623 | dout("__choose_mds %p is_hash=%d (%d) mode %d\n", inode, (int)is_hash, |
602 | (int)hash, mode); | 624 | (int)hash, mode); |
603 | if (!inode) | 625 | if (!inode) |
@@ -2208,7 +2230,7 @@ static void handle_session(struct ceph_mds_session *session, | |||
2208 | pr_info("mds%d reconnect denied\n", session->s_mds); | 2230 | pr_info("mds%d reconnect denied\n", session->s_mds); |
2209 | remove_session_caps(session); | 2231 | remove_session_caps(session); |
2210 | wake = 1; /* for good measure */ | 2232 | wake = 1; /* for good measure */ |
2211 | complete_all(&mdsc->session_close_waiters); | 2233 | wake_up_all(&mdsc->session_close_wq); |
2212 | kick_requests(mdsc, mds); | 2234 | kick_requests(mdsc, mds); |
2213 | break; | 2235 | break; |
2214 | 2236 | ||
@@ -2302,7 +2324,7 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, | |||
2302 | path = ceph_mdsc_build_path(dentry, &pathlen, &pathbase, 0); | 2324 | path = ceph_mdsc_build_path(dentry, &pathlen, &pathbase, 0); |
2303 | if (IS_ERR(path)) { | 2325 | if (IS_ERR(path)) { |
2304 | err = PTR_ERR(path); | 2326 | err = PTR_ERR(path); |
2305 | BUG_ON(err); | 2327 | goto out_dput; |
2306 | } | 2328 | } |
2307 | } else { | 2329 | } else { |
2308 | path = NULL; | 2330 | path = NULL; |
@@ -2310,7 +2332,7 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, | |||
2310 | } | 2332 | } |
2311 | err = ceph_pagelist_encode_string(pagelist, path, pathlen); | 2333 | err = ceph_pagelist_encode_string(pagelist, path, pathlen); |
2312 | if (err) | 2334 | if (err) |
2313 | goto out; | 2335 | goto out_free; |
2314 | 2336 | ||
2315 | spin_lock(&inode->i_lock); | 2337 | spin_lock(&inode->i_lock); |
2316 | cap->seq = 0; /* reset cap seq */ | 2338 | cap->seq = 0; /* reset cap seq */ |
@@ -2354,8 +2376,9 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, | |||
2354 | unlock_kernel(); | 2376 | unlock_kernel(); |
2355 | } | 2377 | } |
2356 | 2378 | ||
2357 | out: | 2379 | out_free: |
2358 | kfree(path); | 2380 | kfree(path); |
2381 | out_dput: | ||
2359 | dput(dentry); | 2382 | dput(dentry); |
2360 | return err; | 2383 | return err; |
2361 | } | 2384 | } |
@@ -2876,7 +2899,7 @@ int ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client) | |||
2876 | return -ENOMEM; | 2899 | return -ENOMEM; |
2877 | 2900 | ||
2878 | init_completion(&mdsc->safe_umount_waiters); | 2901 | init_completion(&mdsc->safe_umount_waiters); |
2879 | init_completion(&mdsc->session_close_waiters); | 2902 | init_waitqueue_head(&mdsc->session_close_wq); |
2880 | INIT_LIST_HEAD(&mdsc->waiting_for_map); | 2903 | INIT_LIST_HEAD(&mdsc->waiting_for_map); |
2881 | mdsc->sessions = NULL; | 2904 | mdsc->sessions = NULL; |
2882 | mdsc->max_sessions = 0; | 2905 | mdsc->max_sessions = 0; |
@@ -3021,6 +3044,23 @@ void ceph_mdsc_sync(struct ceph_mds_client *mdsc) | |||
3021 | wait_event(mdsc->cap_flushing_wq, check_cap_flush(mdsc, want_flush)); | 3044 | wait_event(mdsc->cap_flushing_wq, check_cap_flush(mdsc, want_flush)); |
3022 | } | 3045 | } |
3023 | 3046 | ||
3047 | /* | ||
3048 | * true if all sessions are closed, or we force unmount | ||
3049 | */ | ||
3050 | bool done_closing_sessions(struct ceph_mds_client *mdsc) | ||
3051 | { | ||
3052 | int i, n = 0; | ||
3053 | |||
3054 | if (mdsc->client->mount_state == CEPH_MOUNT_SHUTDOWN) | ||
3055 | return true; | ||
3056 | |||
3057 | mutex_lock(&mdsc->mutex); | ||
3058 | for (i = 0; i < mdsc->max_sessions; i++) | ||
3059 | if (mdsc->sessions[i]) | ||
3060 | n++; | ||
3061 | mutex_unlock(&mdsc->mutex); | ||
3062 | return n == 0; | ||
3063 | } | ||
3024 | 3064 | ||
3025 | /* | 3065 | /* |
3026 | * called after sb is ro. | 3066 | * called after sb is ro. |
@@ -3029,45 +3069,32 @@ void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc) | |||
3029 | { | 3069 | { |
3030 | struct ceph_mds_session *session; | 3070 | struct ceph_mds_session *session; |
3031 | int i; | 3071 | int i; |
3032 | int n; | ||
3033 | struct ceph_client *client = mdsc->client; | 3072 | struct ceph_client *client = mdsc->client; |
3034 | unsigned long started, timeout = client->mount_args->mount_timeout * HZ; | 3073 | unsigned long timeout = client->mount_args->mount_timeout * HZ; |
3035 | 3074 | ||
3036 | dout("close_sessions\n"); | 3075 | dout("close_sessions\n"); |
3037 | 3076 | ||
3038 | mutex_lock(&mdsc->mutex); | ||
3039 | |||
3040 | /* close sessions */ | 3077 | /* close sessions */ |
3041 | started = jiffies; | 3078 | mutex_lock(&mdsc->mutex); |
3042 | while (time_before(jiffies, started + timeout)) { | 3079 | for (i = 0; i < mdsc->max_sessions; i++) { |
3043 | dout("closing sessions\n"); | 3080 | session = __ceph_lookup_mds_session(mdsc, i); |
3044 | n = 0; | 3081 | if (!session) |
3045 | for (i = 0; i < mdsc->max_sessions; i++) { | 3082 | continue; |
3046 | session = __ceph_lookup_mds_session(mdsc, i); | ||
3047 | if (!session) | ||
3048 | continue; | ||
3049 | mutex_unlock(&mdsc->mutex); | ||
3050 | mutex_lock(&session->s_mutex); | ||
3051 | __close_session(mdsc, session); | ||
3052 | mutex_unlock(&session->s_mutex); | ||
3053 | ceph_put_mds_session(session); | ||
3054 | mutex_lock(&mdsc->mutex); | ||
3055 | n++; | ||
3056 | } | ||
3057 | if (n == 0) | ||
3058 | break; | ||
3059 | |||
3060 | if (client->mount_state == CEPH_MOUNT_SHUTDOWN) | ||
3061 | break; | ||
3062 | |||
3063 | dout("waiting for sessions to close\n"); | ||
3064 | mutex_unlock(&mdsc->mutex); | 3083 | mutex_unlock(&mdsc->mutex); |
3065 | wait_for_completion_timeout(&mdsc->session_close_waiters, | 3084 | mutex_lock(&session->s_mutex); |
3066 | timeout); | 3085 | __close_session(mdsc, session); |
3086 | mutex_unlock(&session->s_mutex); | ||
3087 | ceph_put_mds_session(session); | ||
3067 | mutex_lock(&mdsc->mutex); | 3088 | mutex_lock(&mdsc->mutex); |
3068 | } | 3089 | } |
3090 | mutex_unlock(&mdsc->mutex); | ||
3091 | |||
3092 | dout("waiting for sessions to close\n"); | ||
3093 | wait_event_timeout(mdsc->session_close_wq, done_closing_sessions(mdsc), | ||
3094 | timeout); | ||
3069 | 3095 | ||
3070 | /* tear down remaining sessions */ | 3096 | /* tear down remaining sessions */ |
3097 | mutex_lock(&mdsc->mutex); | ||
3071 | for (i = 0; i < mdsc->max_sessions; i++) { | 3098 | for (i = 0; i < mdsc->max_sessions; i++) { |
3072 | if (mdsc->sessions[i]) { | 3099 | if (mdsc->sessions[i]) { |
3073 | session = get_session(mdsc->sessions[i]); | 3100 | session = get_session(mdsc->sessions[i]); |
@@ -3080,9 +3107,7 @@ void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc) | |||
3080 | mutex_lock(&mdsc->mutex); | 3107 | mutex_lock(&mdsc->mutex); |
3081 | } | 3108 | } |
3082 | } | 3109 | } |
3083 | |||
3084 | WARN_ON(!list_empty(&mdsc->cap_delay_list)); | 3110 | WARN_ON(!list_empty(&mdsc->cap_delay_list)); |
3085 | |||
3086 | mutex_unlock(&mdsc->mutex); | 3111 | mutex_unlock(&mdsc->mutex); |
3087 | 3112 | ||
3088 | ceph_cleanup_empty_realms(mdsc); | 3113 | ceph_cleanup_empty_realms(mdsc); |
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index ab7e89f5e34..c98267ce6d2 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h | |||
@@ -234,7 +234,8 @@ struct ceph_mds_client { | |||
234 | struct mutex mutex; /* all nested structures */ | 234 | struct mutex mutex; /* all nested structures */ |
235 | 235 | ||
236 | struct ceph_mdsmap *mdsmap; | 236 | struct ceph_mdsmap *mdsmap; |
237 | struct completion safe_umount_waiters, session_close_waiters; | 237 | struct completion safe_umount_waiters; |
238 | wait_queue_head_t session_close_wq; | ||
238 | struct list_head waiting_for_map; | 239 | struct list_head waiting_for_map; |
239 | 240 | ||
240 | struct ceph_mds_session **sessions; /* NULL for mds if no session */ | 241 | struct ceph_mds_session **sessions; /* NULL for mds if no session */ |
diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index bed6391e52c..dfced1dacbc 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c | |||
@@ -661,7 +661,7 @@ static int __send_request(struct ceph_osd_client *osdc, | |||
661 | reqhead->reassert_version = req->r_reassert_version; | 661 | reqhead->reassert_version = req->r_reassert_version; |
662 | 662 | ||
663 | req->r_stamp = jiffies; | 663 | req->r_stamp = jiffies; |
664 | list_move_tail(&osdc->req_lru, &req->r_req_lru_item); | 664 | list_move_tail(&req->r_req_lru_item, &osdc->req_lru); |
665 | 665 | ||
666 | ceph_msg_get(req->r_request); /* send consumes a ref */ | 666 | ceph_msg_get(req->r_request); /* send consumes a ref */ |
667 | ceph_con_send(&req->r_osd->o_con, req->r_request); | 667 | ceph_con_send(&req->r_osd->o_con, req->r_request); |
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index c0b26b6badb..4868b9dcac5 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c | |||
@@ -435,7 +435,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) | |||
435 | { | 435 | { |
436 | struct inode *inode = &ci->vfs_inode; | 436 | struct inode *inode = &ci->vfs_inode; |
437 | struct ceph_cap_snap *capsnap; | 437 | struct ceph_cap_snap *capsnap; |
438 | int used; | 438 | int used, dirty; |
439 | 439 | ||
440 | capsnap = kzalloc(sizeof(*capsnap), GFP_NOFS); | 440 | capsnap = kzalloc(sizeof(*capsnap), GFP_NOFS); |
441 | if (!capsnap) { | 441 | if (!capsnap) { |
@@ -445,6 +445,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) | |||
445 | 445 | ||
446 | spin_lock(&inode->i_lock); | 446 | spin_lock(&inode->i_lock); |
447 | used = __ceph_caps_used(ci); | 447 | used = __ceph_caps_used(ci); |
448 | dirty = __ceph_caps_dirty(ci); | ||
448 | if (__ceph_have_pending_cap_snap(ci)) { | 449 | if (__ceph_have_pending_cap_snap(ci)) { |
449 | /* there is no point in queuing multiple "pending" cap_snaps, | 450 | /* there is no point in queuing multiple "pending" cap_snaps, |
450 | as no new writes are allowed to start when pending, so any | 451 | as no new writes are allowed to start when pending, so any |
@@ -452,11 +453,15 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) | |||
452 | cap_snap. lucky us. */ | 453 | cap_snap. lucky us. */ |
453 | dout("queue_cap_snap %p already pending\n", inode); | 454 | dout("queue_cap_snap %p already pending\n", inode); |
454 | kfree(capsnap); | 455 | kfree(capsnap); |
455 | } else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR)) { | 456 | } else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR) || |
457 | (dirty & (CEPH_CAP_AUTH_EXCL|CEPH_CAP_XATTR_EXCL| | ||
458 | CEPH_CAP_FILE_EXCL|CEPH_CAP_FILE_WR))) { | ||
456 | struct ceph_snap_context *snapc = ci->i_head_snapc; | 459 | struct ceph_snap_context *snapc = ci->i_head_snapc; |
457 | 460 | ||
461 | dout("queue_cap_snap %p cap_snap %p queuing under %p\n", inode, | ||
462 | capsnap, snapc); | ||
458 | igrab(inode); | 463 | igrab(inode); |
459 | 464 | ||
460 | atomic_set(&capsnap->nref, 1); | 465 | atomic_set(&capsnap->nref, 1); |
461 | capsnap->ci = ci; | 466 | capsnap->ci = ci; |
462 | INIT_LIST_HEAD(&capsnap->ci_item); | 467 | INIT_LIST_HEAD(&capsnap->ci_item); |
@@ -464,15 +469,21 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) | |||
464 | 469 | ||
465 | capsnap->follows = snapc->seq - 1; | 470 | capsnap->follows = snapc->seq - 1; |
466 | capsnap->issued = __ceph_caps_issued(ci, NULL); | 471 | capsnap->issued = __ceph_caps_issued(ci, NULL); |
467 | capsnap->dirty = __ceph_caps_dirty(ci); | 472 | capsnap->dirty = dirty; |
468 | 473 | ||
469 | capsnap->mode = inode->i_mode; | 474 | capsnap->mode = inode->i_mode; |
470 | capsnap->uid = inode->i_uid; | 475 | capsnap->uid = inode->i_uid; |
471 | capsnap->gid = inode->i_gid; | 476 | capsnap->gid = inode->i_gid; |
472 | 477 | ||
473 | /* fixme? */ | 478 | if (dirty & CEPH_CAP_XATTR_EXCL) { |
474 | capsnap->xattr_blob = NULL; | 479 | __ceph_build_xattrs_blob(ci); |
475 | capsnap->xattr_len = 0; | 480 | capsnap->xattr_blob = |
481 | ceph_buffer_get(ci->i_xattrs.blob); | ||
482 | capsnap->xattr_version = ci->i_xattrs.version; | ||
483 | } else { | ||
484 | capsnap->xattr_blob = NULL; | ||
485 | capsnap->xattr_version = 0; | ||
486 | } | ||
476 | 487 | ||
477 | /* dirty page count moved from _head to this cap_snap; | 488 | /* dirty page count moved from _head to this cap_snap; |
478 | all subsequent writes page dirties occur _after_ this | 489 | all subsequent writes page dirties occur _after_ this |
@@ -480,7 +491,9 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) | |||
480 | capsnap->dirty_pages = ci->i_wrbuffer_ref_head; | 491 | capsnap->dirty_pages = ci->i_wrbuffer_ref_head; |
481 | ci->i_wrbuffer_ref_head = 0; | 492 | ci->i_wrbuffer_ref_head = 0; |
482 | capsnap->context = snapc; | 493 | capsnap->context = snapc; |
483 | ci->i_head_snapc = NULL; | 494 | ci->i_head_snapc = |
495 | ceph_get_snap_context(ci->i_snap_realm->cached_context); | ||
496 | dout(" new snapc is %p\n", ci->i_head_snapc); | ||
484 | list_add_tail(&capsnap->ci_item, &ci->i_cap_snaps); | 497 | list_add_tail(&capsnap->ci_item, &ci->i_cap_snaps); |
485 | 498 | ||
486 | if (used & CEPH_CAP_FILE_WR) { | 499 | if (used & CEPH_CAP_FILE_WR) { |
@@ -539,6 +552,41 @@ int __ceph_finish_cap_snap(struct ceph_inode_info *ci, | |||
539 | return 1; /* caller may want to ceph_flush_snaps */ | 552 | return 1; /* caller may want to ceph_flush_snaps */ |
540 | } | 553 | } |
541 | 554 | ||
555 | /* | ||
556 | * Queue cap_snaps for snap writeback for this realm and its children. | ||
557 | * Called under snap_rwsem, so realm topology won't change. | ||
558 | */ | ||
559 | static void queue_realm_cap_snaps(struct ceph_snap_realm *realm) | ||
560 | { | ||
561 | struct ceph_inode_info *ci; | ||
562 | struct inode *lastinode = NULL; | ||
563 | struct ceph_snap_realm *child; | ||
564 | |||
565 | dout("queue_realm_cap_snaps %p %llx inodes\n", realm, realm->ino); | ||
566 | |||
567 | spin_lock(&realm->inodes_with_caps_lock); | ||
568 | list_for_each_entry(ci, &realm->inodes_with_caps, | ||
569 | i_snap_realm_item) { | ||
570 | struct inode *inode = igrab(&ci->vfs_inode); | ||
571 | if (!inode) | ||
572 | continue; | ||
573 | spin_unlock(&realm->inodes_with_caps_lock); | ||
574 | if (lastinode) | ||
575 | iput(lastinode); | ||
576 | lastinode = inode; | ||
577 | ceph_queue_cap_snap(ci); | ||
578 | spin_lock(&realm->inodes_with_caps_lock); | ||
579 | } | ||
580 | spin_unlock(&realm->inodes_with_caps_lock); | ||
581 | if (lastinode) | ||
582 | iput(lastinode); | ||
583 | |||
584 | dout("queue_realm_cap_snaps %p %llx children\n", realm, realm->ino); | ||
585 | list_for_each_entry(child, &realm->children, child_item) | ||
586 | queue_realm_cap_snaps(child); | ||
587 | |||
588 | dout("queue_realm_cap_snaps %p %llx done\n", realm, realm->ino); | ||
589 | } | ||
542 | 590 | ||
543 | /* | 591 | /* |
544 | * Parse and apply a snapblob "snap trace" from the MDS. This specifies | 592 | * Parse and apply a snapblob "snap trace" from the MDS. This specifies |
@@ -589,29 +637,8 @@ more: | |||
589 | * | 637 | * |
590 | * ...unless it's a snap deletion! | 638 | * ...unless it's a snap deletion! |
591 | */ | 639 | */ |
592 | if (!deletion) { | 640 | if (!deletion) |
593 | struct ceph_inode_info *ci; | 641 | queue_realm_cap_snaps(realm); |
594 | struct inode *lastinode = NULL; | ||
595 | |||
596 | spin_lock(&realm->inodes_with_caps_lock); | ||
597 | list_for_each_entry(ci, &realm->inodes_with_caps, | ||
598 | i_snap_realm_item) { | ||
599 | struct inode *inode = igrab(&ci->vfs_inode); | ||
600 | if (!inode) | ||
601 | continue; | ||
602 | spin_unlock(&realm->inodes_with_caps_lock); | ||
603 | if (lastinode) | ||
604 | iput(lastinode); | ||
605 | lastinode = inode; | ||
606 | ceph_queue_cap_snap(ci); | ||
607 | spin_lock(&realm->inodes_with_caps_lock); | ||
608 | } | ||
609 | spin_unlock(&realm->inodes_with_caps_lock); | ||
610 | if (lastinode) | ||
611 | iput(lastinode); | ||
612 | dout("update_snap_trace cap_snaps queued\n"); | ||
613 | } | ||
614 | |||
615 | } else { | 642 | } else { |
616 | dout("update_snap_trace %llx %p seq %lld unchanged\n", | 643 | dout("update_snap_trace %llx %p seq %lld unchanged\n", |
617 | realm->ino, realm, realm->seq); | 644 | realm->ino, realm, realm->seq); |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 2482d696f0d..c33897ae572 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -216,8 +216,7 @@ struct ceph_cap_snap { | |||
216 | uid_t uid; | 216 | uid_t uid; |
217 | gid_t gid; | 217 | gid_t gid; |
218 | 218 | ||
219 | void *xattr_blob; | 219 | struct ceph_buffer *xattr_blob; |
220 | int xattr_len; | ||
221 | u64 xattr_version; | 220 | u64 xattr_version; |
222 | 221 | ||
223 | u64 size; | 222 | u64 size; |
@@ -229,8 +228,11 @@ struct ceph_cap_snap { | |||
229 | 228 | ||
230 | static inline void ceph_put_cap_snap(struct ceph_cap_snap *capsnap) | 229 | static inline void ceph_put_cap_snap(struct ceph_cap_snap *capsnap) |
231 | { | 230 | { |
232 | if (atomic_dec_and_test(&capsnap->nref)) | 231 | if (atomic_dec_and_test(&capsnap->nref)) { |
232 | if (capsnap->xattr_blob) | ||
233 | ceph_buffer_put(capsnap->xattr_blob); | ||
233 | kfree(capsnap); | 234 | kfree(capsnap); |
235 | } | ||
234 | } | 236 | } |
235 | 237 | ||
236 | /* | 238 | /* |
@@ -342,7 +344,8 @@ struct ceph_inode_info { | |||
342 | unsigned i_cap_exporting_issued; | 344 | unsigned i_cap_exporting_issued; |
343 | struct ceph_cap_reservation i_cap_migration_resv; | 345 | struct ceph_cap_reservation i_cap_migration_resv; |
344 | struct list_head i_cap_snaps; /* snapped state pending flush to mds */ | 346 | struct list_head i_cap_snaps; /* snapped state pending flush to mds */ |
345 | struct ceph_snap_context *i_head_snapc; /* set if wr_buffer_head > 0 */ | 347 | struct ceph_snap_context *i_head_snapc; /* set if wr_buffer_head > 0 or |
348 | dirty|flushing caps */ | ||
346 | unsigned i_snap_caps; /* cap bits for snapped files */ | 349 | unsigned i_snap_caps; /* cap bits for snapped files */ |
347 | 350 | ||
348 | int i_nr_by_mode[CEPH_FILE_MODE_NUM]; /* open file counts */ | 351 | int i_nr_by_mode[CEPH_FILE_MODE_NUM]; /* open file counts */ |
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 097a2654c00..9578af610b7 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c | |||
@@ -485,6 +485,7 @@ void __ceph_build_xattrs_blob(struct ceph_inode_info *ci) | |||
485 | ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob; | 485 | ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob; |
486 | ci->i_xattrs.prealloc_blob = NULL; | 486 | ci->i_xattrs.prealloc_blob = NULL; |
487 | ci->i_xattrs.dirty = false; | 487 | ci->i_xattrs.dirty = false; |
488 | ci->i_xattrs.version++; | ||
488 | } | 489 | } |
489 | } | 490 | } |
490 | 491 | ||
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig index 917b7d449bb..0da1debd499 100644 --- a/fs/cifs/Kconfig +++ b/fs/cifs/Kconfig | |||
@@ -2,6 +2,8 @@ config CIFS | |||
2 | tristate "CIFS support (advanced network filesystem, SMBFS successor)" | 2 | tristate "CIFS support (advanced network filesystem, SMBFS successor)" |
3 | depends on INET | 3 | depends on INET |
4 | select NLS | 4 | select NLS |
5 | select CRYPTO_MD5 | ||
6 | select CRYPTO_ARC4 | ||
5 | help | 7 | help |
6 | This is the client VFS module for the Common Internet File System | 8 | This is the client VFS module for the Common Internet File System |
7 | (CIFS) protocol which is the successor to the Server Message Block | 9 | (CIFS) protocol which is the successor to the Server Message Block |
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c index cfd1ce34e0b..21f0fbd8698 100644 --- a/fs/cifs/asn1.c +++ b/fs/cifs/asn1.c | |||
@@ -597,13 +597,13 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
597 | if (compare_oid(oid, oidlen, MSKRB5_OID, | 597 | if (compare_oid(oid, oidlen, MSKRB5_OID, |
598 | MSKRB5_OID_LEN)) | 598 | MSKRB5_OID_LEN)) |
599 | server->sec_mskerberos = true; | 599 | server->sec_mskerberos = true; |
600 | else if (compare_oid(oid, oidlen, KRB5U2U_OID, | 600 | if (compare_oid(oid, oidlen, KRB5U2U_OID, |
601 | KRB5U2U_OID_LEN)) | 601 | KRB5U2U_OID_LEN)) |
602 | server->sec_kerberosu2u = true; | 602 | server->sec_kerberosu2u = true; |
603 | else if (compare_oid(oid, oidlen, KRB5_OID, | 603 | if (compare_oid(oid, oidlen, KRB5_OID, |
604 | KRB5_OID_LEN)) | 604 | KRB5_OID_LEN)) |
605 | server->sec_kerberos = true; | 605 | server->sec_kerberos = true; |
606 | else if (compare_oid(oid, oidlen, NTLMSSP_OID, | 606 | if (compare_oid(oid, oidlen, NTLMSSP_OID, |
607 | NTLMSSP_OID_LEN)) | 607 | NTLMSSP_OID_LEN)) |
608 | server->sec_ntlmssp = true; | 608 | server->sec_ntlmssp = true; |
609 | 609 | ||
diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h index 650638275a6..7fe6b52df50 100644 --- a/fs/cifs/cifs_unicode.h +++ b/fs/cifs/cifs_unicode.h | |||
@@ -30,6 +30,8 @@ | |||
30 | * This is a compressed table of upper and lower case conversion. | 30 | * This is a compressed table of upper and lower case conversion. |
31 | * | 31 | * |
32 | */ | 32 | */ |
33 | #ifndef _CIFS_UNICODE_H | ||
34 | #define _CIFS_UNICODE_H | ||
33 | 35 | ||
34 | #include <asm/byteorder.h> | 36 | #include <asm/byteorder.h> |
35 | #include <linux/types.h> | 37 | #include <linux/types.h> |
@@ -67,8 +69,8 @@ extern const struct UniCaseRange CifsUniUpperRange[]; | |||
67 | #endif /* UNIUPR_NOUPPER */ | 69 | #endif /* UNIUPR_NOUPPER */ |
68 | 70 | ||
69 | #ifndef UNIUPR_NOLOWER | 71 | #ifndef UNIUPR_NOLOWER |
70 | extern signed char UniLowerTable[512]; | 72 | extern signed char CifsUniLowerTable[512]; |
71 | extern struct UniCaseRange UniLowerRange[]; | 73 | extern const struct UniCaseRange CifsUniLowerRange[]; |
72 | #endif /* UNIUPR_NOLOWER */ | 74 | #endif /* UNIUPR_NOLOWER */ |
73 | 75 | ||
74 | #ifdef __KERNEL__ | 76 | #ifdef __KERNEL__ |
@@ -337,15 +339,15 @@ UniStrupr(register wchar_t *upin) | |||
337 | * UniTolower: Convert a unicode character to lower case | 339 | * UniTolower: Convert a unicode character to lower case |
338 | */ | 340 | */ |
339 | static inline wchar_t | 341 | static inline wchar_t |
340 | UniTolower(wchar_t uc) | 342 | UniTolower(register wchar_t uc) |
341 | { | 343 | { |
342 | register struct UniCaseRange *rp; | 344 | register const struct UniCaseRange *rp; |
343 | 345 | ||
344 | if (uc < sizeof(UniLowerTable)) { | 346 | if (uc < sizeof(CifsUniLowerTable)) { |
345 | /* Latin characters */ | 347 | /* Latin characters */ |
346 | return uc + UniLowerTable[uc]; /* Use base tables */ | 348 | return uc + CifsUniLowerTable[uc]; /* Use base tables */ |
347 | } else { | 349 | } else { |
348 | rp = UniLowerRange; /* Use range tables */ | 350 | rp = CifsUniLowerRange; /* Use range tables */ |
349 | while (rp->start) { | 351 | while (rp->start) { |
350 | if (uc < rp->start) /* Before start of range */ | 352 | if (uc < rp->start) /* Before start of range */ |
351 | return uc; /* Uppercase = input */ | 353 | return uc; /* Uppercase = input */ |
@@ -374,3 +376,5 @@ UniStrlwr(register wchar_t *upin) | |||
374 | } | 376 | } |
375 | 377 | ||
376 | #endif | 378 | #endif |
379 | |||
380 | #endif /* _CIFS_UNICODE_H */ | ||
diff --git a/fs/cifs/cifs_uniupr.h b/fs/cifs/cifs_uniupr.h index 18a9d978e51..0ac7c5a8633 100644 --- a/fs/cifs/cifs_uniupr.h +++ b/fs/cifs/cifs_uniupr.h | |||
@@ -140,7 +140,7 @@ const struct UniCaseRange CifsUniUpperRange[] = { | |||
140 | /* | 140 | /* |
141 | * Latin lower case | 141 | * Latin lower case |
142 | */ | 142 | */ |
143 | static signed char CifsUniLowerTable[512] = { | 143 | signed char CifsUniLowerTable[512] = { |
144 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 000-00f */ | 144 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 000-00f */ |
145 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 010-01f */ | 145 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 010-01f */ |
146 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 020-02f */ | 146 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 020-02f */ |
@@ -242,12 +242,12 @@ static signed char UniCaseRangeLff20[27] = { | |||
242 | /* | 242 | /* |
243 | * Lower Case Range | 243 | * Lower Case Range |
244 | */ | 244 | */ |
245 | static const struct UniCaseRange CifsUniLowerRange[] = { | 245 | const struct UniCaseRange CifsUniLowerRange[] = { |
246 | 0x0380, 0x03ab, UniCaseRangeL0380, | 246 | {0x0380, 0x03ab, UniCaseRangeL0380}, |
247 | 0x0400, 0x042f, UniCaseRangeL0400, | 247 | {0x0400, 0x042f, UniCaseRangeL0400}, |
248 | 0x0490, 0x04cb, UniCaseRangeL0490, | 248 | {0x0490, 0x04cb, UniCaseRangeL0490}, |
249 | 0x1e00, 0x1ff7, UniCaseRangeL1e00, | 249 | {0x1e00, 0x1ff7, UniCaseRangeL1e00}, |
250 | 0xff20, 0xff3a, UniCaseRangeLff20, | 250 | {0xff20, 0xff3a, UniCaseRangeLff20}, |
251 | 0, 0, 0 | 251 | {0} |
252 | }; | 252 | }; |
253 | #endif | 253 | #endif |
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 847628dfdc4..709f2296bdb 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "md5.h" | 27 | #include "md5.h" |
28 | #include "cifs_unicode.h" | 28 | #include "cifs_unicode.h" |
29 | #include "cifsproto.h" | 29 | #include "cifsproto.h" |
30 | #include "ntlmssp.h" | ||
30 | #include <linux/ctype.h> | 31 | #include <linux/ctype.h> |
31 | #include <linux/random.h> | 32 | #include <linux/random.h> |
32 | 33 | ||
@@ -42,21 +43,43 @@ extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8, | |||
42 | unsigned char *p24); | 43 | unsigned char *p24); |
43 | 44 | ||
44 | static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, | 45 | static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, |
45 | const struct mac_key *key, char *signature) | 46 | struct TCP_Server_Info *server, char *signature) |
46 | { | 47 | { |
47 | struct MD5Context context; | 48 | int rc; |
48 | 49 | ||
49 | if ((cifs_pdu == NULL) || (signature == NULL) || (key == NULL)) | 50 | if (cifs_pdu == NULL || server == NULL || signature == NULL) |
50 | return -EINVAL; | 51 | return -EINVAL; |
51 | 52 | ||
52 | cifs_MD5_init(&context); | 53 | if (!server->ntlmssp.sdescmd5) { |
53 | cifs_MD5_update(&context, (char *)&key->data, key->len); | 54 | cERROR(1, |
54 | cifs_MD5_update(&context, cifs_pdu->Protocol, cifs_pdu->smb_buf_length); | 55 | "cifs_calculate_signature: can't generate signature\n"); |
56 | return -1; | ||
57 | } | ||
55 | 58 | ||
56 | cifs_MD5_final(signature, &context); | 59 | rc = crypto_shash_init(&server->ntlmssp.sdescmd5->shash); |
57 | return 0; | 60 | if (rc) { |
61 | cERROR(1, "cifs_calculate_signature: oould not init md5\n"); | ||
62 | return rc; | ||
63 | } | ||
64 | |||
65 | if (server->secType == RawNTLMSSP) | ||
66 | crypto_shash_update(&server->ntlmssp.sdescmd5->shash, | ||
67 | server->session_key.data.ntlmv2.key, | ||
68 | CIFS_NTLMV2_SESSKEY_SIZE); | ||
69 | else | ||
70 | crypto_shash_update(&server->ntlmssp.sdescmd5->shash, | ||
71 | (char *)&server->session_key.data, | ||
72 | server->session_key.len); | ||
73 | |||
74 | crypto_shash_update(&server->ntlmssp.sdescmd5->shash, | ||
75 | cifs_pdu->Protocol, cifs_pdu->smb_buf_length); | ||
76 | |||
77 | rc = crypto_shash_final(&server->ntlmssp.sdescmd5->shash, signature); | ||
78 | |||
79 | return rc; | ||
58 | } | 80 | } |
59 | 81 | ||
82 | |||
60 | int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, | 83 | int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, |
61 | __u32 *pexpected_response_sequence_number) | 84 | __u32 *pexpected_response_sequence_number) |
62 | { | 85 | { |
@@ -78,8 +101,7 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, | |||
78 | server->sequence_number++; | 101 | server->sequence_number++; |
79 | spin_unlock(&GlobalMid_Lock); | 102 | spin_unlock(&GlobalMid_Lock); |
80 | 103 | ||
81 | rc = cifs_calculate_signature(cifs_pdu, &server->mac_signing_key, | 104 | rc = cifs_calculate_signature(cifs_pdu, server, smb_signature); |
82 | smb_signature); | ||
83 | if (rc) | 105 | if (rc) |
84 | memset(cifs_pdu->Signature.SecuritySignature, 0, 8); | 106 | memset(cifs_pdu->Signature.SecuritySignature, 0, 8); |
85 | else | 107 | else |
@@ -89,21 +111,39 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, | |||
89 | } | 111 | } |
90 | 112 | ||
91 | static int cifs_calc_signature2(const struct kvec *iov, int n_vec, | 113 | static int cifs_calc_signature2(const struct kvec *iov, int n_vec, |
92 | const struct mac_key *key, char *signature) | 114 | struct TCP_Server_Info *server, char *signature) |
93 | { | 115 | { |
94 | struct MD5Context context; | ||
95 | int i; | 116 | int i; |
117 | int rc; | ||
96 | 118 | ||
97 | if ((iov == NULL) || (signature == NULL) || (key == NULL)) | 119 | if (iov == NULL || server == NULL || signature == NULL) |
98 | return -EINVAL; | 120 | return -EINVAL; |
99 | 121 | ||
100 | cifs_MD5_init(&context); | 122 | if (!server->ntlmssp.sdescmd5) { |
101 | cifs_MD5_update(&context, (char *)&key->data, key->len); | 123 | cERROR(1, "cifs_calc_signature2: can't generate signature\n"); |
124 | return -1; | ||
125 | } | ||
126 | |||
127 | rc = crypto_shash_init(&server->ntlmssp.sdescmd5->shash); | ||
128 | if (rc) { | ||
129 | cERROR(1, "cifs_calc_signature2: oould not init md5\n"); | ||
130 | return rc; | ||
131 | } | ||
132 | |||
133 | if (server->secType == RawNTLMSSP) | ||
134 | crypto_shash_update(&server->ntlmssp.sdescmd5->shash, | ||
135 | server->session_key.data.ntlmv2.key, | ||
136 | CIFS_NTLMV2_SESSKEY_SIZE); | ||
137 | else | ||
138 | crypto_shash_update(&server->ntlmssp.sdescmd5->shash, | ||
139 | (char *)&server->session_key.data, | ||
140 | server->session_key.len); | ||
141 | |||
102 | for (i = 0; i < n_vec; i++) { | 142 | for (i = 0; i < n_vec; i++) { |
103 | if (iov[i].iov_len == 0) | 143 | if (iov[i].iov_len == 0) |
104 | continue; | 144 | continue; |
105 | if (iov[i].iov_base == NULL) { | 145 | if (iov[i].iov_base == NULL) { |
106 | cERROR(1, "null iovec entry"); | 146 | cERROR(1, "cifs_calc_signature2: null iovec entry"); |
107 | return -EIO; | 147 | return -EIO; |
108 | } | 148 | } |
109 | /* The first entry includes a length field (which does not get | 149 | /* The first entry includes a length field (which does not get |
@@ -111,18 +151,18 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec, | |||
111 | if (i == 0) { | 151 | if (i == 0) { |
112 | if (iov[0].iov_len <= 8) /* cmd field at offset 9 */ | 152 | if (iov[0].iov_len <= 8) /* cmd field at offset 9 */ |
113 | break; /* nothing to sign or corrupt header */ | 153 | break; /* nothing to sign or corrupt header */ |
114 | cifs_MD5_update(&context, iov[0].iov_base+4, | 154 | crypto_shash_update(&server->ntlmssp.sdescmd5->shash, |
115 | iov[0].iov_len-4); | 155 | iov[i].iov_base + 4, iov[i].iov_len - 4); |
116 | } else | 156 | } else |
117 | cifs_MD5_update(&context, iov[i].iov_base, iov[i].iov_len); | 157 | crypto_shash_update(&server->ntlmssp.sdescmd5->shash, |
158 | iov[i].iov_base, iov[i].iov_len); | ||
118 | } | 159 | } |
119 | 160 | ||
120 | cifs_MD5_final(signature, &context); | 161 | rc = crypto_shash_final(&server->ntlmssp.sdescmd5->shash, signature); |
121 | 162 | ||
122 | return 0; | 163 | return rc; |
123 | } | 164 | } |
124 | 165 | ||
125 | |||
126 | int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, | 166 | int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, |
127 | __u32 *pexpected_response_sequence_number) | 167 | __u32 *pexpected_response_sequence_number) |
128 | { | 168 | { |
@@ -145,8 +185,7 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, | |||
145 | server->sequence_number++; | 185 | server->sequence_number++; |
146 | spin_unlock(&GlobalMid_Lock); | 186 | spin_unlock(&GlobalMid_Lock); |
147 | 187 | ||
148 | rc = cifs_calc_signature2(iov, n_vec, &server->mac_signing_key, | 188 | rc = cifs_calc_signature2(iov, n_vec, server, smb_signature); |
149 | smb_signature); | ||
150 | if (rc) | 189 | if (rc) |
151 | memset(cifs_pdu->Signature.SecuritySignature, 0, 8); | 190 | memset(cifs_pdu->Signature.SecuritySignature, 0, 8); |
152 | else | 191 | else |
@@ -156,14 +195,14 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, | |||
156 | } | 195 | } |
157 | 196 | ||
158 | int cifs_verify_signature(struct smb_hdr *cifs_pdu, | 197 | int cifs_verify_signature(struct smb_hdr *cifs_pdu, |
159 | const struct mac_key *mac_key, | 198 | struct TCP_Server_Info *server, |
160 | __u32 expected_sequence_number) | 199 | __u32 expected_sequence_number) |
161 | { | 200 | { |
162 | unsigned int rc; | 201 | int rc; |
163 | char server_response_sig[8]; | 202 | char server_response_sig[8]; |
164 | char what_we_think_sig_should_be[20]; | 203 | char what_we_think_sig_should_be[20]; |
165 | 204 | ||
166 | if ((cifs_pdu == NULL) || (mac_key == NULL)) | 205 | if (cifs_pdu == NULL || server == NULL) |
167 | return -EINVAL; | 206 | return -EINVAL; |
168 | 207 | ||
169 | if (cifs_pdu->Command == SMB_COM_NEGOTIATE) | 208 | if (cifs_pdu->Command == SMB_COM_NEGOTIATE) |
@@ -192,7 +231,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, | |||
192 | cpu_to_le32(expected_sequence_number); | 231 | cpu_to_le32(expected_sequence_number); |
193 | cifs_pdu->Signature.Sequence.Reserved = 0; | 232 | cifs_pdu->Signature.Sequence.Reserved = 0; |
194 | 233 | ||
195 | rc = cifs_calculate_signature(cifs_pdu, mac_key, | 234 | rc = cifs_calculate_signature(cifs_pdu, server, |
196 | what_we_think_sig_should_be); | 235 | what_we_think_sig_should_be); |
197 | 236 | ||
198 | if (rc) | 237 | if (rc) |
@@ -209,7 +248,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, | |||
209 | } | 248 | } |
210 | 249 | ||
211 | /* We fill in key by putting in 40 byte array which was allocated by caller */ | 250 | /* We fill in key by putting in 40 byte array which was allocated by caller */ |
212 | int cifs_calculate_mac_key(struct mac_key *key, const char *rn, | 251 | int cifs_calculate_session_key(struct session_key *key, const char *rn, |
213 | const char *password) | 252 | const char *password) |
214 | { | 253 | { |
215 | char temp_key[16]; | 254 | char temp_key[16]; |
@@ -223,63 +262,6 @@ int cifs_calculate_mac_key(struct mac_key *key, const char *rn, | |||
223 | return 0; | 262 | return 0; |
224 | } | 263 | } |
225 | 264 | ||
226 | int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *ses, | ||
227 | const struct nls_table *nls_info) | ||
228 | { | ||
229 | char temp_hash[16]; | ||
230 | struct HMACMD5Context ctx; | ||
231 | char *ucase_buf; | ||
232 | __le16 *unicode_buf; | ||
233 | unsigned int i, user_name_len, dom_name_len; | ||
234 | |||
235 | if (ses == NULL) | ||
236 | return -EINVAL; | ||
237 | |||
238 | E_md4hash(ses->password, temp_hash); | ||
239 | |||
240 | hmac_md5_init_limK_to_64(temp_hash, 16, &ctx); | ||
241 | user_name_len = strlen(ses->userName); | ||
242 | if (user_name_len > MAX_USERNAME_SIZE) | ||
243 | return -EINVAL; | ||
244 | if (ses->domainName == NULL) | ||
245 | return -EINVAL; /* BB should we use CIFS_LINUX_DOM */ | ||
246 | dom_name_len = strlen(ses->domainName); | ||
247 | if (dom_name_len > MAX_USERNAME_SIZE) | ||
248 | return -EINVAL; | ||
249 | |||
250 | ucase_buf = kmalloc((MAX_USERNAME_SIZE+1), GFP_KERNEL); | ||
251 | if (ucase_buf == NULL) | ||
252 | return -ENOMEM; | ||
253 | unicode_buf = kmalloc((MAX_USERNAME_SIZE+1)*4, GFP_KERNEL); | ||
254 | if (unicode_buf == NULL) { | ||
255 | kfree(ucase_buf); | ||
256 | return -ENOMEM; | ||
257 | } | ||
258 | |||
259 | for (i = 0; i < user_name_len; i++) | ||
260 | ucase_buf[i] = nls_info->charset2upper[(int)ses->userName[i]]; | ||
261 | ucase_buf[i] = 0; | ||
262 | user_name_len = cifs_strtoUCS(unicode_buf, ucase_buf, | ||
263 | MAX_USERNAME_SIZE*2, nls_info); | ||
264 | unicode_buf[user_name_len] = 0; | ||
265 | user_name_len++; | ||
266 | |||
267 | for (i = 0; i < dom_name_len; i++) | ||
268 | ucase_buf[i] = nls_info->charset2upper[(int)ses->domainName[i]]; | ||
269 | ucase_buf[i] = 0; | ||
270 | dom_name_len = cifs_strtoUCS(unicode_buf+user_name_len, ucase_buf, | ||
271 | MAX_USERNAME_SIZE*2, nls_info); | ||
272 | |||
273 | unicode_buf[user_name_len + dom_name_len] = 0; | ||
274 | hmac_md5_update((const unsigned char *) unicode_buf, | ||
275 | (user_name_len+dom_name_len)*2, &ctx); | ||
276 | |||
277 | hmac_md5_final(ses->server->ntlmv2_hash, &ctx); | ||
278 | kfree(ucase_buf); | ||
279 | kfree(unicode_buf); | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | 265 | #ifdef CONFIG_CIFS_WEAK_PW_HASH |
284 | void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt, | 266 | void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt, |
285 | char *lnm_session_key) | 267 | char *lnm_session_key) |
@@ -324,38 +306,52 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses, | |||
324 | { | 306 | { |
325 | int rc = 0; | 307 | int rc = 0; |
326 | int len; | 308 | int len; |
327 | char nt_hash[16]; | 309 | char nt_hash[CIFS_NTHASH_SIZE]; |
328 | struct HMACMD5Context *pctxt; | ||
329 | wchar_t *user; | 310 | wchar_t *user; |
330 | wchar_t *domain; | 311 | wchar_t *domain; |
312 | wchar_t *server; | ||
331 | 313 | ||
332 | pctxt = kmalloc(sizeof(struct HMACMD5Context), GFP_KERNEL); | 314 | if (!ses->server->ntlmssp.sdeschmacmd5) { |
333 | 315 | cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n"); | |
334 | if (pctxt == NULL) | 316 | return -1; |
335 | return -ENOMEM; | 317 | } |
336 | 318 | ||
337 | /* calculate md4 hash of password */ | 319 | /* calculate md4 hash of password */ |
338 | E_md4hash(ses->password, nt_hash); | 320 | E_md4hash(ses->password, nt_hash); |
339 | 321 | ||
340 | /* convert Domainname to unicode and uppercase */ | 322 | crypto_shash_setkey(ses->server->ntlmssp.hmacmd5, nt_hash, |
341 | hmac_md5_init_limK_to_64(nt_hash, 16, pctxt); | 323 | CIFS_NTHASH_SIZE); |
324 | |||
325 | rc = crypto_shash_init(&ses->server->ntlmssp.sdeschmacmd5->shash); | ||
326 | if (rc) { | ||
327 | cERROR(1, "calc_ntlmv2_hash: could not init hmacmd5\n"); | ||
328 | return rc; | ||
329 | } | ||
342 | 330 | ||
343 | /* convert ses->userName to unicode and uppercase */ | 331 | /* convert ses->userName to unicode and uppercase */ |
344 | len = strlen(ses->userName); | 332 | len = strlen(ses->userName); |
345 | user = kmalloc(2 + (len * 2), GFP_KERNEL); | 333 | user = kmalloc(2 + (len * 2), GFP_KERNEL); |
346 | if (user == NULL) | 334 | if (user == NULL) { |
335 | cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n"); | ||
336 | rc = -ENOMEM; | ||
347 | goto calc_exit_2; | 337 | goto calc_exit_2; |
338 | } | ||
348 | len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp); | 339 | len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp); |
349 | UniStrupr(user); | 340 | UniStrupr(user); |
350 | hmac_md5_update((char *)user, 2*len, pctxt); | 341 | |
342 | crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash, | ||
343 | (char *)user, 2 * len); | ||
351 | 344 | ||
352 | /* convert ses->domainName to unicode and uppercase */ | 345 | /* convert ses->domainName to unicode and uppercase */ |
353 | if (ses->domainName) { | 346 | if (ses->domainName) { |
354 | len = strlen(ses->domainName); | 347 | len = strlen(ses->domainName); |
355 | 348 | ||
356 | domain = kmalloc(2 + (len * 2), GFP_KERNEL); | 349 | domain = kmalloc(2 + (len * 2), GFP_KERNEL); |
357 | if (domain == NULL) | 350 | if (domain == NULL) { |
351 | cERROR(1, "calc_ntlmv2_hash: domain mem alloc failure"); | ||
352 | rc = -ENOMEM; | ||
358 | goto calc_exit_1; | 353 | goto calc_exit_1; |
354 | } | ||
359 | len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len, | 355 | len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len, |
360 | nls_cp); | 356 | nls_cp); |
361 | /* the following line was removed since it didn't work well | 357 | /* the following line was removed since it didn't work well |
@@ -363,65 +359,292 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses, | |||
363 | Maybe converting the domain name earlier makes sense */ | 359 | Maybe converting the domain name earlier makes sense */ |
364 | /* UniStrupr(domain); */ | 360 | /* UniStrupr(domain); */ |
365 | 361 | ||
366 | hmac_md5_update((char *)domain, 2*len, pctxt); | 362 | crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash, |
363 | (char *)domain, 2 * len); | ||
367 | 364 | ||
368 | kfree(domain); | 365 | kfree(domain); |
366 | } else if (ses->serverName) { | ||
367 | len = strlen(ses->serverName); | ||
368 | |||
369 | server = kmalloc(2 + (len * 2), GFP_KERNEL); | ||
370 | if (server == NULL) { | ||
371 | cERROR(1, "calc_ntlmv2_hash: server mem alloc failure"); | ||
372 | rc = -ENOMEM; | ||
373 | goto calc_exit_1; | ||
374 | } | ||
375 | len = cifs_strtoUCS((__le16 *)server, ses->serverName, len, | ||
376 | nls_cp); | ||
377 | /* the following line was removed since it didn't work well | ||
378 | with lower cased domain name that passed as an option. | ||
379 | Maybe converting the domain name earlier makes sense */ | ||
380 | /* UniStrupr(domain); */ | ||
381 | |||
382 | crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash, | ||
383 | (char *)server, 2 * len); | ||
384 | |||
385 | kfree(server); | ||
369 | } | 386 | } |
387 | |||
388 | rc = crypto_shash_final(&ses->server->ntlmssp.sdeschmacmd5->shash, | ||
389 | ses->server->ntlmv2_hash); | ||
390 | |||
370 | calc_exit_1: | 391 | calc_exit_1: |
371 | kfree(user); | 392 | kfree(user); |
372 | calc_exit_2: | 393 | calc_exit_2: |
373 | /* BB FIXME what about bytes 24 through 40 of the signing key? | 394 | /* BB FIXME what about bytes 24 through 40 of the signing key? |
374 | compare with the NTLM example */ | 395 | compare with the NTLM example */ |
375 | hmac_md5_final(ses->server->ntlmv2_hash, pctxt); | ||
376 | 396 | ||
377 | kfree(pctxt); | ||
378 | return rc; | 397 | return rc; |
379 | } | 398 | } |
380 | 399 | ||
381 | void setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf, | 400 | static int |
382 | const struct nls_table *nls_cp) | 401 | find_domain_name(struct cifsSesInfo *ses) |
402 | { | ||
403 | int rc = 0; | ||
404 | unsigned int attrsize; | ||
405 | unsigned int type; | ||
406 | unsigned char *blobptr; | ||
407 | struct ntlmssp2_name *attrptr; | ||
408 | |||
409 | if (ses->server->tiblob) { | ||
410 | blobptr = ses->server->tiblob; | ||
411 | attrptr = (struct ntlmssp2_name *) blobptr; | ||
412 | |||
413 | while ((type = attrptr->type) != 0) { | ||
414 | blobptr += 2; /* advance attr type */ | ||
415 | attrsize = attrptr->length; | ||
416 | blobptr += 2; /* advance attr size */ | ||
417 | if (type == NTLMSSP_AV_NB_DOMAIN_NAME) { | ||
418 | if (!ses->domainName) { | ||
419 | ses->domainName = | ||
420 | kmalloc(attrptr->length + 1, | ||
421 | GFP_KERNEL); | ||
422 | if (!ses->domainName) | ||
423 | return -ENOMEM; | ||
424 | cifs_from_ucs2(ses->domainName, | ||
425 | (__le16 *)blobptr, | ||
426 | attrptr->length, | ||
427 | attrptr->length, | ||
428 | load_nls_default(), false); | ||
429 | } | ||
430 | } | ||
431 | blobptr += attrsize; /* advance attr value */ | ||
432 | attrptr = (struct ntlmssp2_name *) blobptr; | ||
433 | } | ||
434 | } else { | ||
435 | ses->server->tilen = 2 * sizeof(struct ntlmssp2_name); | ||
436 | ses->server->tiblob = kmalloc(ses->server->tilen, GFP_KERNEL); | ||
437 | if (!ses->server->tiblob) { | ||
438 | ses->server->tilen = 0; | ||
439 | cERROR(1, "Challenge target info allocation failure"); | ||
440 | return -ENOMEM; | ||
441 | } | ||
442 | memset(ses->server->tiblob, 0x0, ses->server->tilen); | ||
443 | attrptr = (struct ntlmssp2_name *) ses->server->tiblob; | ||
444 | attrptr->type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE); | ||
445 | } | ||
446 | |||
447 | return rc; | ||
448 | } | ||
449 | |||
450 | static int | ||
451 | CalcNTLMv2_response(const struct TCP_Server_Info *server, | ||
452 | char *v2_session_response) | ||
383 | { | 453 | { |
384 | int rc; | 454 | int rc; |
455 | |||
456 | if (!server->ntlmssp.sdeschmacmd5) { | ||
457 | cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n"); | ||
458 | return -1; | ||
459 | } | ||
460 | |||
461 | crypto_shash_setkey(server->ntlmssp.hmacmd5, server->ntlmv2_hash, | ||
462 | CIFS_HMAC_MD5_HASH_SIZE); | ||
463 | |||
464 | rc = crypto_shash_init(&server->ntlmssp.sdeschmacmd5->shash); | ||
465 | if (rc) { | ||
466 | cERROR(1, "CalcNTLMv2_response: could not init hmacmd5"); | ||
467 | return rc; | ||
468 | } | ||
469 | |||
470 | memcpy(v2_session_response + CIFS_SERVER_CHALLENGE_SIZE, | ||
471 | server->cryptKey, CIFS_SERVER_CHALLENGE_SIZE); | ||
472 | crypto_shash_update(&server->ntlmssp.sdeschmacmd5->shash, | ||
473 | v2_session_response + CIFS_SERVER_CHALLENGE_SIZE, | ||
474 | sizeof(struct ntlmv2_resp) - CIFS_SERVER_CHALLENGE_SIZE); | ||
475 | |||
476 | if (server->tilen) | ||
477 | crypto_shash_update(&server->ntlmssp.sdeschmacmd5->shash, | ||
478 | server->tiblob, server->tilen); | ||
479 | |||
480 | rc = crypto_shash_final(&server->ntlmssp.sdeschmacmd5->shash, | ||
481 | v2_session_response); | ||
482 | |||
483 | return rc; | ||
484 | } | ||
485 | |||
486 | int | ||
487 | setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf, | ||
488 | const struct nls_table *nls_cp) | ||
489 | { | ||
490 | int rc = 0; | ||
385 | struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf; | 491 | struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf; |
386 | struct HMACMD5Context context; | ||
387 | 492 | ||
388 | buf->blob_signature = cpu_to_le32(0x00000101); | 493 | buf->blob_signature = cpu_to_le32(0x00000101); |
389 | buf->reserved = 0; | 494 | buf->reserved = 0; |
390 | buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); | 495 | buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); |
391 | get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); | 496 | get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); |
392 | buf->reserved2 = 0; | 497 | buf->reserved2 = 0; |
393 | buf->names[0].type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE); | 498 | |
394 | buf->names[0].length = 0; | 499 | if (!ses->domainName) { |
395 | buf->names[1].type = 0; | 500 | rc = find_domain_name(ses); |
396 | buf->names[1].length = 0; | 501 | if (rc) { |
502 | cERROR(1, "could not get domain/server name rc %d", rc); | ||
503 | return rc; | ||
504 | } | ||
505 | } | ||
397 | 506 | ||
398 | /* calculate buf->ntlmv2_hash */ | 507 | /* calculate buf->ntlmv2_hash */ |
399 | rc = calc_ntlmv2_hash(ses, nls_cp); | 508 | rc = calc_ntlmv2_hash(ses, nls_cp); |
400 | if (rc) | 509 | if (rc) { |
401 | cERROR(1, "could not get v2 hash rc %d", rc); | 510 | cERROR(1, "could not get v2 hash rc %d", rc); |
402 | CalcNTLMv2_response(ses, resp_buf); | 511 | return rc; |
512 | } | ||
513 | rc = CalcNTLMv2_response(ses->server, resp_buf); | ||
514 | if (rc) { | ||
515 | cERROR(1, "could not get v2 hash rc %d", rc); | ||
516 | return rc; | ||
517 | } | ||
403 | 518 | ||
404 | /* now calculate the MAC key for NTLMv2 */ | 519 | if (!ses->server->ntlmssp.sdeschmacmd5) { |
405 | hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context); | 520 | cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n"); |
406 | hmac_md5_update(resp_buf, 16, &context); | 521 | return -1; |
407 | hmac_md5_final(ses->server->mac_signing_key.data.ntlmv2.key, &context); | 522 | } |
408 | 523 | ||
409 | memcpy(&ses->server->mac_signing_key.data.ntlmv2.resp, resp_buf, | 524 | crypto_shash_setkey(ses->server->ntlmssp.hmacmd5, |
410 | sizeof(struct ntlmv2_resp)); | 525 | ses->server->ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); |
411 | ses->server->mac_signing_key.len = 16 + sizeof(struct ntlmv2_resp); | 526 | |
527 | rc = crypto_shash_init(&ses->server->ntlmssp.sdeschmacmd5->shash); | ||
528 | if (rc) { | ||
529 | cERROR(1, "setup_ntlmv2_rsp: could not init hmacmd5\n"); | ||
530 | return rc; | ||
531 | } | ||
532 | |||
533 | crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash, | ||
534 | resp_buf, CIFS_HMAC_MD5_HASH_SIZE); | ||
535 | |||
536 | rc = crypto_shash_final(&ses->server->ntlmssp.sdeschmacmd5->shash, | ||
537 | ses->server->session_key.data.ntlmv2.key); | ||
538 | |||
539 | memcpy(&ses->server->session_key.data.ntlmv2.resp, resp_buf, | ||
540 | sizeof(struct ntlmv2_resp)); | ||
541 | ses->server->session_key.len = 16 + sizeof(struct ntlmv2_resp); | ||
542 | |||
543 | return rc; | ||
412 | } | 544 | } |
413 | 545 | ||
414 | void CalcNTLMv2_response(const struct cifsSesInfo *ses, | 546 | int |
415 | char *v2_session_response) | 547 | calc_seckey(struct TCP_Server_Info *server) |
416 | { | 548 | { |
417 | struct HMACMD5Context context; | 549 | int rc; |
418 | /* rest of v2 struct already generated */ | 550 | unsigned char sec_key[CIFS_NTLMV2_SESSKEY_SIZE]; |
419 | memcpy(v2_session_response + 8, ses->server->cryptKey, 8); | 551 | struct crypto_blkcipher *tfm_arc4; |
420 | hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context); | 552 | struct scatterlist sgin, sgout; |
553 | struct blkcipher_desc desc; | ||
554 | |||
555 | get_random_bytes(sec_key, CIFS_NTLMV2_SESSKEY_SIZE); | ||
556 | |||
557 | tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", | ||
558 | 0, CRYPTO_ALG_ASYNC); | ||
559 | if (!tfm_arc4 || IS_ERR(tfm_arc4)) { | ||
560 | cERROR(1, "could not allocate " "master crypto API arc4\n"); | ||
561 | return 1; | ||
562 | } | ||
563 | |||
564 | desc.tfm = tfm_arc4; | ||
565 | |||
566 | crypto_blkcipher_setkey(tfm_arc4, | ||
567 | server->session_key.data.ntlmv2.key, CIFS_CPHTXT_SIZE); | ||
568 | sg_init_one(&sgin, sec_key, CIFS_CPHTXT_SIZE); | ||
569 | sg_init_one(&sgout, server->ntlmssp.ciphertext, CIFS_CPHTXT_SIZE); | ||
570 | rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, CIFS_CPHTXT_SIZE); | ||
421 | 571 | ||
422 | hmac_md5_update(v2_session_response+8, | 572 | if (!rc) |
423 | sizeof(struct ntlmv2_resp) - 8, &context); | 573 | memcpy(server->session_key.data.ntlmv2.key, |
574 | sec_key, CIFS_NTLMV2_SESSKEY_SIZE); | ||
575 | |||
576 | crypto_free_blkcipher(tfm_arc4); | ||
577 | |||
578 | return 0; | ||
579 | } | ||
424 | 580 | ||
425 | hmac_md5_final(v2_session_response, &context); | 581 | void |
426 | /* cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */ | 582 | cifs_crypto_shash_release(struct TCP_Server_Info *server) |
583 | { | ||
584 | if (server->ntlmssp.md5) | ||
585 | crypto_free_shash(server->ntlmssp.md5); | ||
586 | |||
587 | if (server->ntlmssp.hmacmd5) | ||
588 | crypto_free_shash(server->ntlmssp.hmacmd5); | ||
589 | |||
590 | kfree(server->ntlmssp.sdeschmacmd5); | ||
591 | |||
592 | kfree(server->ntlmssp.sdescmd5); | ||
593 | } | ||
594 | |||
595 | int | ||
596 | cifs_crypto_shash_allocate(struct TCP_Server_Info *server) | ||
597 | { | ||
598 | int rc; | ||
599 | unsigned int size; | ||
600 | |||
601 | server->ntlmssp.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0); | ||
602 | if (!server->ntlmssp.hmacmd5 || | ||
603 | IS_ERR(server->ntlmssp.hmacmd5)) { | ||
604 | cERROR(1, "could not allocate crypto hmacmd5\n"); | ||
605 | return 1; | ||
606 | } | ||
607 | |||
608 | server->ntlmssp.md5 = crypto_alloc_shash("md5", 0, 0); | ||
609 | if (!server->ntlmssp.md5 || IS_ERR(server->ntlmssp.md5)) { | ||
610 | cERROR(1, "could not allocate crypto md5\n"); | ||
611 | rc = 1; | ||
612 | goto cifs_crypto_shash_allocate_ret1; | ||
613 | } | ||
614 | |||
615 | size = sizeof(struct shash_desc) + | ||
616 | crypto_shash_descsize(server->ntlmssp.hmacmd5); | ||
617 | server->ntlmssp.sdeschmacmd5 = kmalloc(size, GFP_KERNEL); | ||
618 | if (!server->ntlmssp.sdeschmacmd5) { | ||
619 | cERROR(1, "cifs_crypto_shash_allocate: can't alloc hmacmd5\n"); | ||
620 | rc = -ENOMEM; | ||
621 | goto cifs_crypto_shash_allocate_ret2; | ||
622 | } | ||
623 | server->ntlmssp.sdeschmacmd5->shash.tfm = server->ntlmssp.hmacmd5; | ||
624 | server->ntlmssp.sdeschmacmd5->shash.flags = 0x0; | ||
625 | |||
626 | |||
627 | size = sizeof(struct shash_desc) + | ||
628 | crypto_shash_descsize(server->ntlmssp.md5); | ||
629 | server->ntlmssp.sdescmd5 = kmalloc(size, GFP_KERNEL); | ||
630 | if (!server->ntlmssp.sdescmd5) { | ||
631 | cERROR(1, "cifs_crypto_shash_allocate: can't alloc md5\n"); | ||
632 | rc = -ENOMEM; | ||
633 | goto cifs_crypto_shash_allocate_ret3; | ||
634 | } | ||
635 | server->ntlmssp.sdescmd5->shash.tfm = server->ntlmssp.md5; | ||
636 | server->ntlmssp.sdescmd5->shash.flags = 0x0; | ||
637 | |||
638 | return 0; | ||
639 | |||
640 | cifs_crypto_shash_allocate_ret3: | ||
641 | kfree(server->ntlmssp.sdeschmacmd5); | ||
642 | |||
643 | cifs_crypto_shash_allocate_ret2: | ||
644 | crypto_free_shash(server->ntlmssp.md5); | ||
645 | |||
646 | cifs_crypto_shash_allocate_ret1: | ||
647 | crypto_free_shash(server->ntlmssp.hmacmd5); | ||
648 | |||
649 | return rc; | ||
427 | } | 650 | } |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 0cdfb8c32ac..c9d0cfc086e 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -25,6 +25,9 @@ | |||
25 | #include <linux/workqueue.h> | 25 | #include <linux/workqueue.h> |
26 | #include "cifs_fs_sb.h" | 26 | #include "cifs_fs_sb.h" |
27 | #include "cifsacl.h" | 27 | #include "cifsacl.h" |
28 | #include <crypto/internal/hash.h> | ||
29 | #include <linux/scatterlist.h> | ||
30 | |||
28 | /* | 31 | /* |
29 | * The sizes of various internal tables and strings | 32 | * The sizes of various internal tables and strings |
30 | */ | 33 | */ |
@@ -97,7 +100,7 @@ enum protocolEnum { | |||
97 | /* Netbios frames protocol not supported at this time */ | 100 | /* Netbios frames protocol not supported at this time */ |
98 | }; | 101 | }; |
99 | 102 | ||
100 | struct mac_key { | 103 | struct session_key { |
101 | unsigned int len; | 104 | unsigned int len; |
102 | union { | 105 | union { |
103 | char ntlm[CIFS_SESS_KEY_SIZE + 16]; | 106 | char ntlm[CIFS_SESS_KEY_SIZE + 16]; |
@@ -120,6 +123,21 @@ struct cifs_cred { | |||
120 | struct cifs_ace *aces; | 123 | struct cifs_ace *aces; |
121 | }; | 124 | }; |
122 | 125 | ||
126 | struct sdesc { | ||
127 | struct shash_desc shash; | ||
128 | char ctx[]; | ||
129 | }; | ||
130 | |||
131 | struct ntlmssp_auth { | ||
132 | __u32 client_flags; | ||
133 | __u32 server_flags; | ||
134 | unsigned char ciphertext[CIFS_CPHTXT_SIZE]; | ||
135 | struct crypto_shash *hmacmd5; | ||
136 | struct crypto_shash *md5; | ||
137 | struct sdesc *sdeschmacmd5; | ||
138 | struct sdesc *sdescmd5; | ||
139 | }; | ||
140 | |||
123 | /* | 141 | /* |
124 | ***************************************************************** | 142 | ***************************************************************** |
125 | * Except the CIFS PDUs themselves all the | 143 | * Except the CIFS PDUs themselves all the |
@@ -182,11 +200,14 @@ struct TCP_Server_Info { | |||
182 | /* 16th byte of RFC1001 workstation name is always null */ | 200 | /* 16th byte of RFC1001 workstation name is always null */ |
183 | char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; | 201 | char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; |
184 | __u32 sequence_number; /* needed for CIFS PDU signature */ | 202 | __u32 sequence_number; /* needed for CIFS PDU signature */ |
185 | struct mac_key mac_signing_key; | 203 | struct session_key session_key; |
186 | char ntlmv2_hash[16]; | 204 | char ntlmv2_hash[16]; |
187 | unsigned long lstrp; /* when we got last response from this server */ | 205 | unsigned long lstrp; /* when we got last response from this server */ |
188 | u16 dialect; /* dialect index that server chose */ | 206 | u16 dialect; /* dialect index that server chose */ |
189 | /* extended security flavors that server supports */ | 207 | /* extended security flavors that server supports */ |
208 | unsigned int tilen; /* length of the target info blob */ | ||
209 | unsigned char *tiblob; /* target info blob in challenge response */ | ||
210 | struct ntlmssp_auth ntlmssp; /* various keys, ciphers, flags */ | ||
190 | bool sec_kerberos; /* supports plain Kerberos */ | 211 | bool sec_kerberos; /* supports plain Kerberos */ |
191 | bool sec_mskerberos; /* supports legacy MS Kerberos */ | 212 | bool sec_mskerberos; /* supports legacy MS Kerberos */ |
192 | bool sec_kerberosu2u; /* supports U2U Kerberos */ | 213 | bool sec_kerberosu2u; /* supports U2U Kerberos */ |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 14d036d8db1..320e0fd0ba7 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
@@ -134,6 +134,12 @@ | |||
134 | * Size of the session key (crypto key encrypted with the password | 134 | * Size of the session key (crypto key encrypted with the password |
135 | */ | 135 | */ |
136 | #define CIFS_SESS_KEY_SIZE (24) | 136 | #define CIFS_SESS_KEY_SIZE (24) |
137 | #define CIFS_CLIENT_CHALLENGE_SIZE (8) | ||
138 | #define CIFS_SERVER_CHALLENGE_SIZE (8) | ||
139 | #define CIFS_HMAC_MD5_HASH_SIZE (16) | ||
140 | #define CIFS_CPHTXT_SIZE (16) | ||
141 | #define CIFS_NTLMV2_SESSKEY_SIZE (16) | ||
142 | #define CIFS_NTHASH_SIZE (16) | ||
137 | 143 | ||
138 | /* | 144 | /* |
139 | * Maximum user name length | 145 | * Maximum user name length |
@@ -663,7 +669,6 @@ struct ntlmv2_resp { | |||
663 | __le64 time; | 669 | __le64 time; |
664 | __u64 client_chal; /* random */ | 670 | __u64 client_chal; /* random */ |
665 | __u32 reserved2; | 671 | __u32 reserved2; |
666 | struct ntlmssp2_name names[2]; | ||
667 | /* array of name entries could follow ending in minimum 4 byte struct */ | 672 | /* array of name entries could follow ending in minimum 4 byte struct */ |
668 | } __attribute__((packed)); | 673 | } __attribute__((packed)); |
669 | 674 | ||
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 1f545081408..1378d913384 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -361,15 +361,15 @@ extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *); | |||
361 | extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, | 361 | extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, |
362 | __u32 *); | 362 | __u32 *); |
363 | extern int cifs_verify_signature(struct smb_hdr *, | 363 | extern int cifs_verify_signature(struct smb_hdr *, |
364 | const struct mac_key *mac_key, | 364 | struct TCP_Server_Info *server, |
365 | __u32 expected_sequence_number); | 365 | __u32 expected_sequence_number); |
366 | extern int cifs_calculate_mac_key(struct mac_key *key, const char *rn, | 366 | extern int cifs_calculate_session_key(struct session_key *key, const char *rn, |
367 | const char *pass); | 367 | const char *pass); |
368 | extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, | 368 | extern int setup_ntlmv2_rsp(struct cifsSesInfo *, char *, |
369 | const struct nls_table *); | ||
370 | extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *); | ||
371 | extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *, | ||
372 | const struct nls_table *); | 369 | const struct nls_table *); |
370 | extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); | ||
371 | extern void cifs_crypto_shash_release(struct TCP_Server_Info *); | ||
372 | extern int calc_seckey(struct TCP_Server_Info *); | ||
373 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | 373 | #ifdef CONFIG_CIFS_WEAK_PW_HASH |
374 | extern void calc_lanman_hash(const char *password, const char *cryptkey, | 374 | extern void calc_lanman_hash(const char *password, const char *cryptkey, |
375 | bool encrypt, char *lnm_session_key); | 375 | bool encrypt, char *lnm_session_key); |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index c65c3419dd3..4bda920d1f7 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -604,11 +604,14 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
604 | else | 604 | else |
605 | rc = -EINVAL; | 605 | rc = -EINVAL; |
606 | 606 | ||
607 | if (server->sec_kerberos || server->sec_mskerberos) | 607 | if (server->secType == Kerberos) { |
608 | server->secType = Kerberos; | 608 | if (!server->sec_kerberos && |
609 | else if (server->sec_ntlmssp) | 609 | !server->sec_mskerberos) |
610 | server->secType = RawNTLMSSP; | 610 | rc = -EOPNOTSUPP; |
611 | else | 611 | } else if (server->secType == RawNTLMSSP) { |
612 | if (!server->sec_ntlmssp) | ||
613 | rc = -EOPNOTSUPP; | ||
614 | } else | ||
612 | rc = -EOPNOTSUPP; | 615 | rc = -EOPNOTSUPP; |
613 | } | 616 | } |
614 | } else | 617 | } else |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 95c2ea67edf..ec0ea4a43bd 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -1673,7 +1673,9 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol) | |||
1673 | MAX_USERNAME_SIZE)) | 1673 | MAX_USERNAME_SIZE)) |
1674 | continue; | 1674 | continue; |
1675 | if (strlen(vol->username) != 0 && | 1675 | if (strlen(vol->username) != 0 && |
1676 | strncmp(ses->password, vol->password, | 1676 | ses->password != NULL && |
1677 | strncmp(ses->password, | ||
1678 | vol->password ? vol->password : "", | ||
1677 | MAX_PASSWORD_SIZE)) | 1679 | MAX_PASSWORD_SIZE)) |
1678 | continue; | 1680 | continue; |
1679 | } | 1681 | } |
@@ -1706,6 +1708,7 @@ cifs_put_smb_ses(struct cifsSesInfo *ses) | |||
1706 | CIFSSMBLogoff(xid, ses); | 1708 | CIFSSMBLogoff(xid, ses); |
1707 | _FreeXid(xid); | 1709 | _FreeXid(xid); |
1708 | } | 1710 | } |
1711 | cifs_crypto_shash_release(server); | ||
1709 | sesInfoFree(ses); | 1712 | sesInfoFree(ses); |
1710 | cifs_put_tcp_session(server); | 1713 | cifs_put_tcp_session(server); |
1711 | } | 1714 | } |
@@ -1785,13 +1788,23 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) | |||
1785 | ses->linux_uid = volume_info->linux_uid; | 1788 | ses->linux_uid = volume_info->linux_uid; |
1786 | ses->overrideSecFlg = volume_info->secFlg; | 1789 | ses->overrideSecFlg = volume_info->secFlg; |
1787 | 1790 | ||
1791 | rc = cifs_crypto_shash_allocate(server); | ||
1792 | if (rc) { | ||
1793 | cERROR(1, "could not setup hash structures rc %d", rc); | ||
1794 | goto get_ses_fail; | ||
1795 | } | ||
1796 | server->tilen = 0; | ||
1797 | server->tiblob = NULL; | ||
1798 | |||
1788 | mutex_lock(&ses->session_mutex); | 1799 | mutex_lock(&ses->session_mutex); |
1789 | rc = cifs_negotiate_protocol(xid, ses); | 1800 | rc = cifs_negotiate_protocol(xid, ses); |
1790 | if (!rc) | 1801 | if (!rc) |
1791 | rc = cifs_setup_session(xid, ses, volume_info->local_nls); | 1802 | rc = cifs_setup_session(xid, ses, volume_info->local_nls); |
1792 | mutex_unlock(&ses->session_mutex); | 1803 | mutex_unlock(&ses->session_mutex); |
1793 | if (rc) | 1804 | if (rc) { |
1805 | cifs_crypto_shash_release(ses->server); | ||
1794 | goto get_ses_fail; | 1806 | goto get_ses_fail; |
1807 | } | ||
1795 | 1808 | ||
1796 | /* success, put it on the list */ | 1809 | /* success, put it on the list */ |
1797 | write_lock(&cifs_tcp_ses_lock); | 1810 | write_lock(&cifs_tcp_ses_lock); |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 578d88c5b46..f9ed0751cc1 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -305,8 +305,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
305 | full_path = build_path_from_dentry(direntry); | 305 | full_path = build_path_from_dentry(direntry); |
306 | if (full_path == NULL) { | 306 | if (full_path == NULL) { |
307 | rc = -ENOMEM; | 307 | rc = -ENOMEM; |
308 | FreeXid(xid); | 308 | goto cifs_create_out; |
309 | return rc; | ||
310 | } | 309 | } |
311 | 310 | ||
312 | if (oplockEnabled) | 311 | if (oplockEnabled) |
@@ -365,9 +364,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
365 | 364 | ||
366 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); | 365 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
367 | if (buf == NULL) { | 366 | if (buf == NULL) { |
368 | kfree(full_path); | 367 | rc = -ENOMEM; |
369 | FreeXid(xid); | 368 | goto cifs_create_out; |
370 | return -ENOMEM; | ||
371 | } | 369 | } |
372 | 370 | ||
373 | /* | 371 | /* |
@@ -496,6 +494,11 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
496 | struct cifsTconInfo *pTcon; | 494 | struct cifsTconInfo *pTcon; |
497 | char *full_path = NULL; | 495 | char *full_path = NULL; |
498 | struct inode *newinode = NULL; | 496 | struct inode *newinode = NULL; |
497 | int oplock = 0; | ||
498 | u16 fileHandle; | ||
499 | FILE_ALL_INFO *buf = NULL; | ||
500 | unsigned int bytes_written; | ||
501 | struct win_dev *pdev; | ||
499 | 502 | ||
500 | if (!old_valid_dev(device_number)) | 503 | if (!old_valid_dev(device_number)) |
501 | return -EINVAL; | 504 | return -EINVAL; |
@@ -506,9 +509,12 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
506 | pTcon = cifs_sb->tcon; | 509 | pTcon = cifs_sb->tcon; |
507 | 510 | ||
508 | full_path = build_path_from_dentry(direntry); | 511 | full_path = build_path_from_dentry(direntry); |
509 | if (full_path == NULL) | 512 | if (full_path == NULL) { |
510 | rc = -ENOMEM; | 513 | rc = -ENOMEM; |
511 | else if (pTcon->unix_ext) { | 514 | goto mknod_out; |
515 | } | ||
516 | |||
517 | if (pTcon->unix_ext) { | ||
512 | struct cifs_unix_set_info_args args = { | 518 | struct cifs_unix_set_info_args args = { |
513 | .mode = mode & ~current_umask(), | 519 | .mode = mode & ~current_umask(), |
514 | .ctime = NO_CHANGE_64, | 520 | .ctime = NO_CHANGE_64, |
@@ -527,87 +533,78 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
527 | cifs_sb->local_nls, | 533 | cifs_sb->local_nls, |
528 | cifs_sb->mnt_cifs_flags & | 534 | cifs_sb->mnt_cifs_flags & |
529 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 535 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
536 | if (rc) | ||
537 | goto mknod_out; | ||
530 | 538 | ||
531 | if (!rc) { | 539 | rc = cifs_get_inode_info_unix(&newinode, full_path, |
532 | rc = cifs_get_inode_info_unix(&newinode, full_path, | ||
533 | inode->i_sb, xid); | 540 | inode->i_sb, xid); |
534 | if (pTcon->nocase) | 541 | if (pTcon->nocase) |
535 | direntry->d_op = &cifs_ci_dentry_ops; | 542 | direntry->d_op = &cifs_ci_dentry_ops; |
536 | else | 543 | else |
537 | direntry->d_op = &cifs_dentry_ops; | 544 | direntry->d_op = &cifs_dentry_ops; |
538 | if (rc == 0) | ||
539 | d_instantiate(direntry, newinode); | ||
540 | } | ||
541 | } else { | ||
542 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { | ||
543 | int oplock = 0; | ||
544 | u16 fileHandle; | ||
545 | FILE_ALL_INFO *buf; | ||
546 | 545 | ||
547 | cFYI(1, "sfu compat create special file"); | 546 | if (rc == 0) |
547 | d_instantiate(direntry, newinode); | ||
548 | goto mknod_out; | ||
549 | } | ||
548 | 550 | ||
549 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); | 551 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) |
550 | if (buf == NULL) { | 552 | goto mknod_out; |
551 | kfree(full_path); | ||
552 | rc = -ENOMEM; | ||
553 | FreeXid(xid); | ||
554 | return rc; | ||
555 | } | ||
556 | 553 | ||
557 | rc = CIFSSMBOpen(xid, pTcon, full_path, | 554 | |
558 | FILE_CREATE, /* fail if exists */ | 555 | cFYI(1, "sfu compat create special file"); |
559 | GENERIC_WRITE /* BB would | 556 | |
560 | WRITE_OWNER | WRITE_DAC be better? */, | 557 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
561 | /* Create a file and set the | 558 | if (buf == NULL) { |
562 | file attribute to SYSTEM */ | 559 | kfree(full_path); |
563 | CREATE_NOT_DIR | CREATE_OPTION_SPECIAL, | 560 | rc = -ENOMEM; |
564 | &fileHandle, &oplock, buf, | 561 | FreeXid(xid); |
565 | cifs_sb->local_nls, | 562 | return rc; |
566 | cifs_sb->mnt_cifs_flags & | ||
567 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
568 | |||
569 | /* BB FIXME - add handling for backlevel servers | ||
570 | which need legacy open and check for all | ||
571 | calls to SMBOpen for fallback to SMBLeagcyOpen */ | ||
572 | if (!rc) { | ||
573 | /* BB Do not bother to decode buf since no | ||
574 | local inode yet to put timestamps in, | ||
575 | but we can reuse it safely */ | ||
576 | unsigned int bytes_written; | ||
577 | struct win_dev *pdev; | ||
578 | pdev = (struct win_dev *)buf; | ||
579 | if (S_ISCHR(mode)) { | ||
580 | memcpy(pdev->type, "IntxCHR", 8); | ||
581 | pdev->major = | ||
582 | cpu_to_le64(MAJOR(device_number)); | ||
583 | pdev->minor = | ||
584 | cpu_to_le64(MINOR(device_number)); | ||
585 | rc = CIFSSMBWrite(xid, pTcon, | ||
586 | fileHandle, | ||
587 | sizeof(struct win_dev), | ||
588 | 0, &bytes_written, (char *)pdev, | ||
589 | NULL, 0); | ||
590 | } else if (S_ISBLK(mode)) { | ||
591 | memcpy(pdev->type, "IntxBLK", 8); | ||
592 | pdev->major = | ||
593 | cpu_to_le64(MAJOR(device_number)); | ||
594 | pdev->minor = | ||
595 | cpu_to_le64(MINOR(device_number)); | ||
596 | rc = CIFSSMBWrite(xid, pTcon, | ||
597 | fileHandle, | ||
598 | sizeof(struct win_dev), | ||
599 | 0, &bytes_written, (char *)pdev, | ||
600 | NULL, 0); | ||
601 | } /* else if(S_ISFIFO */ | ||
602 | CIFSSMBClose(xid, pTcon, fileHandle); | ||
603 | d_drop(direntry); | ||
604 | } | ||
605 | kfree(buf); | ||
606 | /* add code here to set EAs */ | ||
607 | } | ||
608 | } | 563 | } |
609 | 564 | ||
565 | /* FIXME: would WRITE_OWNER | WRITE_DAC be better? */ | ||
566 | rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE, | ||
567 | GENERIC_WRITE, CREATE_NOT_DIR | CREATE_OPTION_SPECIAL, | ||
568 | &fileHandle, &oplock, buf, cifs_sb->local_nls, | ||
569 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
570 | if (rc) | ||
571 | goto mknod_out; | ||
572 | |||
573 | /* BB Do not bother to decode buf since no local inode yet to put | ||
574 | * timestamps in, but we can reuse it safely */ | ||
575 | |||
576 | pdev = (struct win_dev *)buf; | ||
577 | if (S_ISCHR(mode)) { | ||
578 | memcpy(pdev->type, "IntxCHR", 8); | ||
579 | pdev->major = | ||
580 | cpu_to_le64(MAJOR(device_number)); | ||
581 | pdev->minor = | ||
582 | cpu_to_le64(MINOR(device_number)); | ||
583 | rc = CIFSSMBWrite(xid, pTcon, | ||
584 | fileHandle, | ||
585 | sizeof(struct win_dev), | ||
586 | 0, &bytes_written, (char *)pdev, | ||
587 | NULL, 0); | ||
588 | } else if (S_ISBLK(mode)) { | ||
589 | memcpy(pdev->type, "IntxBLK", 8); | ||
590 | pdev->major = | ||
591 | cpu_to_le64(MAJOR(device_number)); | ||
592 | pdev->minor = | ||
593 | cpu_to_le64(MINOR(device_number)); | ||
594 | rc = CIFSSMBWrite(xid, pTcon, | ||
595 | fileHandle, | ||
596 | sizeof(struct win_dev), | ||
597 | 0, &bytes_written, (char *)pdev, | ||
598 | NULL, 0); | ||
599 | } /* else if (S_ISFIFO) */ | ||
600 | CIFSSMBClose(xid, pTcon, fileHandle); | ||
601 | d_drop(direntry); | ||
602 | |||
603 | /* FIXME: add code here to set EAs */ | ||
604 | |||
605 | mknod_out: | ||
610 | kfree(full_path); | 606 | kfree(full_path); |
607 | kfree(buf); | ||
611 | FreeXid(xid); | 608 | FreeXid(xid); |
612 | return rc; | 609 | return rc; |
613 | } | 610 | } |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index db11fdef0e9..de748c652d1 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -242,8 +242,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
242 | full_path = build_path_from_dentry(file->f_path.dentry); | 242 | full_path = build_path_from_dentry(file->f_path.dentry); |
243 | if (full_path == NULL) { | 243 | if (full_path == NULL) { |
244 | rc = -ENOMEM; | 244 | rc = -ENOMEM; |
245 | FreeXid(xid); | 245 | goto out; |
246 | return rc; | ||
247 | } | 246 | } |
248 | 247 | ||
249 | cFYI(1, "inode = 0x%p file flags are 0x%x for %s", | 248 | cFYI(1, "inode = 0x%p file flags are 0x%x for %s", |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 4bc47e5b5f2..86a164f08a7 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -834,7 +834,7 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) | |||
834 | xid, NULL); | 834 | xid, NULL); |
835 | 835 | ||
836 | if (!inode) | 836 | if (!inode) |
837 | return ERR_PTR(-ENOMEM); | 837 | return ERR_PTR(rc); |
838 | 838 | ||
839 | #ifdef CONFIG_CIFS_FSCACHE | 839 | #ifdef CONFIG_CIFS_FSCACHE |
840 | /* populate tcon->resource_id */ | 840 | /* populate tcon->resource_id */ |
diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h index 49c9a4e7531..1db0f0746a5 100644 --- a/fs/cifs/ntlmssp.h +++ b/fs/cifs/ntlmssp.h | |||
@@ -61,6 +61,19 @@ | |||
61 | #define NTLMSSP_NEGOTIATE_KEY_XCH 0x40000000 | 61 | #define NTLMSSP_NEGOTIATE_KEY_XCH 0x40000000 |
62 | #define NTLMSSP_NEGOTIATE_56 0x80000000 | 62 | #define NTLMSSP_NEGOTIATE_56 0x80000000 |
63 | 63 | ||
64 | /* Define AV Pair Field IDs */ | ||
65 | #define NTLMSSP_AV_EOL 0 | ||
66 | #define NTLMSSP_AV_NB_COMPUTER_NAME 1 | ||
67 | #define NTLMSSP_AV_NB_DOMAIN_NAME 2 | ||
68 | #define NTLMSSP_AV_DNS_COMPUTER_NAME 3 | ||
69 | #define NTLMSSP_AV_DNS_DOMAIN_NAME 4 | ||
70 | #define NTLMSSP_AV_DNS_TREE_NAME 5 | ||
71 | #define NTLMSSP_AV_FLAGS 6 | ||
72 | #define NTLMSSP_AV_TIMESTAMP 7 | ||
73 | #define NTLMSSP_AV_RESTRICTION 8 | ||
74 | #define NTLMSSP_AV_TARGET_NAME 9 | ||
75 | #define NTLMSSP_AV_CHANNEL_BINDINGS 10 | ||
76 | |||
64 | /* Although typedefs are not commonly used for structure definitions */ | 77 | /* Although typedefs are not commonly used for structure definitions */ |
65 | /* in the Linux kernel, in this particular case they are useful */ | 78 | /* in the Linux kernel, in this particular case they are useful */ |
66 | /* to more closely match the standards document for NTLMSSP from */ | 79 | /* to more closely match the standards document for NTLMSSP from */ |
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 0a57cb7db5d..795095f4eac 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
@@ -383,6 +383,9 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft, | |||
383 | static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, | 383 | static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, |
384 | struct cifsSesInfo *ses) | 384 | struct cifsSesInfo *ses) |
385 | { | 385 | { |
386 | unsigned int tioffset; /* challeng message target info area */ | ||
387 | unsigned int tilen; /* challeng message target info area length */ | ||
388 | |||
386 | CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr; | 389 | CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr; |
387 | 390 | ||
388 | if (blob_len < sizeof(CHALLENGE_MESSAGE)) { | 391 | if (blob_len < sizeof(CHALLENGE_MESSAGE)) { |
@@ -405,6 +408,20 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, | |||
405 | /* BB spec says that if AvId field of MsvAvTimestamp is populated then | 408 | /* BB spec says that if AvId field of MsvAvTimestamp is populated then |
406 | we must set the MIC field of the AUTHENTICATE_MESSAGE */ | 409 | we must set the MIC field of the AUTHENTICATE_MESSAGE */ |
407 | 410 | ||
411 | ses->server->ntlmssp.server_flags = le32_to_cpu(pblob->NegotiateFlags); | ||
412 | |||
413 | tioffset = cpu_to_le16(pblob->TargetInfoArray.BufferOffset); | ||
414 | tilen = cpu_to_le16(pblob->TargetInfoArray.Length); | ||
415 | ses->server->tilen = tilen; | ||
416 | if (tilen) { | ||
417 | ses->server->tiblob = kmalloc(tilen, GFP_KERNEL); | ||
418 | if (!ses->server->tiblob) { | ||
419 | cERROR(1, "Challenge target info allocation failure"); | ||
420 | return -ENOMEM; | ||
421 | } | ||
422 | memcpy(ses->server->tiblob, bcc_ptr + tioffset, tilen); | ||
423 | } | ||
424 | |||
408 | return 0; | 425 | return 0; |
409 | } | 426 | } |
410 | 427 | ||
@@ -425,12 +442,13 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, | |||
425 | /* BB is NTLMV2 session security format easier to use here? */ | 442 | /* BB is NTLMV2 session security format easier to use here? */ |
426 | flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET | | 443 | flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET | |
427 | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | | 444 | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | |
428 | NTLMSSP_NEGOTIATE_NT_ONLY | NTLMSSP_NEGOTIATE_NTLM; | 445 | NTLMSSP_NEGOTIATE_NTLM; |
429 | if (ses->server->secMode & | 446 | if (ses->server->secMode & |
430 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) | 447 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { |
431 | flags |= NTLMSSP_NEGOTIATE_SIGN; | 448 | flags |= NTLMSSP_NEGOTIATE_SIGN | |
432 | if (ses->server->secMode & SECMODE_SIGN_REQUIRED) | 449 | NTLMSSP_NEGOTIATE_KEY_XCH | |
433 | flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; | 450 | NTLMSSP_NEGOTIATE_EXTENDED_SEC; |
451 | } | ||
434 | 452 | ||
435 | sec_blob->NegotiateFlags |= cpu_to_le32(flags); | 453 | sec_blob->NegotiateFlags |= cpu_to_le32(flags); |
436 | 454 | ||
@@ -451,10 +469,12 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, | |||
451 | struct cifsSesInfo *ses, | 469 | struct cifsSesInfo *ses, |
452 | const struct nls_table *nls_cp, bool first) | 470 | const struct nls_table *nls_cp, bool first) |
453 | { | 471 | { |
472 | int rc; | ||
473 | unsigned int size; | ||
454 | AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer; | 474 | AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer; |
455 | __u32 flags; | 475 | __u32 flags; |
456 | unsigned char *tmp; | 476 | unsigned char *tmp; |
457 | char ntlm_session_key[CIFS_SESS_KEY_SIZE]; | 477 | struct ntlmv2_resp ntlmv2_response = {}; |
458 | 478 | ||
459 | memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); | 479 | memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); |
460 | sec_blob->MessageType = NtLmAuthenticate; | 480 | sec_blob->MessageType = NtLmAuthenticate; |
@@ -477,19 +497,25 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, | |||
477 | sec_blob->LmChallengeResponse.Length = 0; | 497 | sec_blob->LmChallengeResponse.Length = 0; |
478 | sec_blob->LmChallengeResponse.MaximumLength = 0; | 498 | sec_blob->LmChallengeResponse.MaximumLength = 0; |
479 | 499 | ||
480 | /* calculate session key, BB what about adding similar ntlmv2 path? */ | ||
481 | SMBNTencrypt(ses->password, ses->server->cryptKey, ntlm_session_key); | ||
482 | if (first) | ||
483 | cifs_calculate_mac_key(&ses->server->mac_signing_key, | ||
484 | ntlm_session_key, ses->password); | ||
485 | |||
486 | memcpy(tmp, ntlm_session_key, CIFS_SESS_KEY_SIZE); | ||
487 | sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer); | 500 | sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer); |
488 | sec_blob->NtChallengeResponse.Length = cpu_to_le16(CIFS_SESS_KEY_SIZE); | 501 | rc = setup_ntlmv2_rsp(ses, (char *)&ntlmv2_response, nls_cp); |
489 | sec_blob->NtChallengeResponse.MaximumLength = | 502 | if (rc) { |
490 | cpu_to_le16(CIFS_SESS_KEY_SIZE); | 503 | cERROR(1, "error rc: %d during ntlmssp ntlmv2 setup", rc); |
504 | goto setup_ntlmv2_ret; | ||
505 | } | ||
506 | size = sizeof(struct ntlmv2_resp); | ||
507 | memcpy(tmp, (char *)&ntlmv2_response, size); | ||
508 | tmp += size; | ||
509 | if (ses->server->tilen > 0) { | ||
510 | memcpy(tmp, ses->server->tiblob, ses->server->tilen); | ||
511 | tmp += ses->server->tilen; | ||
512 | } else | ||
513 | ses->server->tilen = 0; | ||
491 | 514 | ||
492 | tmp += CIFS_SESS_KEY_SIZE; | 515 | sec_blob->NtChallengeResponse.Length = cpu_to_le16(size + |
516 | ses->server->tilen); | ||
517 | sec_blob->NtChallengeResponse.MaximumLength = | ||
518 | cpu_to_le16(size + ses->server->tilen); | ||
493 | 519 | ||
494 | if (ses->domainName == NULL) { | 520 | if (ses->domainName == NULL) { |
495 | sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); | 521 | sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); |
@@ -501,7 +527,6 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, | |||
501 | len = cifs_strtoUCS((__le16 *)tmp, ses->domainName, | 527 | len = cifs_strtoUCS((__le16 *)tmp, ses->domainName, |
502 | MAX_USERNAME_SIZE, nls_cp); | 528 | MAX_USERNAME_SIZE, nls_cp); |
503 | len *= 2; /* unicode is 2 bytes each */ | 529 | len *= 2; /* unicode is 2 bytes each */ |
504 | len += 2; /* trailing null */ | ||
505 | sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); | 530 | sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); |
506 | sec_blob->DomainName.Length = cpu_to_le16(len); | 531 | sec_blob->DomainName.Length = cpu_to_le16(len); |
507 | sec_blob->DomainName.MaximumLength = cpu_to_le16(len); | 532 | sec_blob->DomainName.MaximumLength = cpu_to_le16(len); |
@@ -518,7 +543,6 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, | |||
518 | len = cifs_strtoUCS((__le16 *)tmp, ses->userName, | 543 | len = cifs_strtoUCS((__le16 *)tmp, ses->userName, |
519 | MAX_USERNAME_SIZE, nls_cp); | 544 | MAX_USERNAME_SIZE, nls_cp); |
520 | len *= 2; /* unicode is 2 bytes each */ | 545 | len *= 2; /* unicode is 2 bytes each */ |
521 | len += 2; /* trailing null */ | ||
522 | sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer); | 546 | sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer); |
523 | sec_blob->UserName.Length = cpu_to_le16(len); | 547 | sec_blob->UserName.Length = cpu_to_le16(len); |
524 | sec_blob->UserName.MaximumLength = cpu_to_le16(len); | 548 | sec_blob->UserName.MaximumLength = cpu_to_le16(len); |
@@ -530,9 +554,26 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, | |||
530 | sec_blob->WorkstationName.MaximumLength = 0; | 554 | sec_blob->WorkstationName.MaximumLength = 0; |
531 | tmp += 2; | 555 | tmp += 2; |
532 | 556 | ||
533 | sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); | 557 | if ((ses->server->ntlmssp.server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) && |
534 | sec_blob->SessionKey.Length = 0; | 558 | !calc_seckey(ses->server)) { |
535 | sec_blob->SessionKey.MaximumLength = 0; | 559 | memcpy(tmp, ses->server->ntlmssp.ciphertext, CIFS_CPHTXT_SIZE); |
560 | sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); | ||
561 | sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE); | ||
562 | sec_blob->SessionKey.MaximumLength = | ||
563 | cpu_to_le16(CIFS_CPHTXT_SIZE); | ||
564 | tmp += CIFS_CPHTXT_SIZE; | ||
565 | } else { | ||
566 | sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); | ||
567 | sec_blob->SessionKey.Length = 0; | ||
568 | sec_blob->SessionKey.MaximumLength = 0; | ||
569 | } | ||
570 | |||
571 | ses->server->sequence_number = 0; | ||
572 | |||
573 | setup_ntlmv2_ret: | ||
574 | if (ses->server->tilen > 0) | ||
575 | kfree(ses->server->tiblob); | ||
576 | |||
536 | return tmp - pbuffer; | 577 | return tmp - pbuffer; |
537 | } | 578 | } |
538 | 579 | ||
@@ -546,15 +587,14 @@ static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB, | |||
546 | return; | 587 | return; |
547 | } | 588 | } |
548 | 589 | ||
549 | static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB, | 590 | static int setup_ntlmssp_auth_req(char *ntlmsspblob, |
550 | struct cifsSesInfo *ses, | 591 | struct cifsSesInfo *ses, |
551 | const struct nls_table *nls, bool first_time) | 592 | const struct nls_table *nls, bool first_time) |
552 | { | 593 | { |
553 | int bloblen; | 594 | int bloblen; |
554 | 595 | ||
555 | bloblen = build_ntlmssp_auth_blob(&pSMB->req.SecurityBlob[0], ses, nls, | 596 | bloblen = build_ntlmssp_auth_blob(ntlmsspblob, ses, nls, |
556 | first_time); | 597 | first_time); |
557 | pSMB->req.SecurityBlobLength = cpu_to_le16(bloblen); | ||
558 | 598 | ||
559 | return bloblen; | 599 | return bloblen; |
560 | } | 600 | } |
@@ -690,7 +730,7 @@ ssetup_ntlmssp_authenticate: | |||
690 | 730 | ||
691 | if (first_time) /* should this be moved into common code | 731 | if (first_time) /* should this be moved into common code |
692 | with similar ntlmv2 path? */ | 732 | with similar ntlmv2 path? */ |
693 | cifs_calculate_mac_key(&ses->server->mac_signing_key, | 733 | cifs_calculate_session_key(&ses->server->session_key, |
694 | ntlm_session_key, ses->password); | 734 | ntlm_session_key, ses->password); |
695 | /* copy session key */ | 735 | /* copy session key */ |
696 | 736 | ||
@@ -729,12 +769,21 @@ ssetup_ntlmssp_authenticate: | |||
729 | cpu_to_le16(sizeof(struct ntlmv2_resp)); | 769 | cpu_to_le16(sizeof(struct ntlmv2_resp)); |
730 | 770 | ||
731 | /* calculate session key */ | 771 | /* calculate session key */ |
732 | setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); | 772 | rc = setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); |
773 | if (rc) { | ||
774 | kfree(v2_sess_key); | ||
775 | goto ssetup_exit; | ||
776 | } | ||
733 | /* FIXME: calculate MAC key */ | 777 | /* FIXME: calculate MAC key */ |
734 | memcpy(bcc_ptr, (char *)v2_sess_key, | 778 | memcpy(bcc_ptr, (char *)v2_sess_key, |
735 | sizeof(struct ntlmv2_resp)); | 779 | sizeof(struct ntlmv2_resp)); |
736 | bcc_ptr += sizeof(struct ntlmv2_resp); | 780 | bcc_ptr += sizeof(struct ntlmv2_resp); |
737 | kfree(v2_sess_key); | 781 | kfree(v2_sess_key); |
782 | if (ses->server->tilen > 0) { | ||
783 | memcpy(bcc_ptr, ses->server->tiblob, | ||
784 | ses->server->tilen); | ||
785 | bcc_ptr += ses->server->tilen; | ||
786 | } | ||
738 | if (ses->capabilities & CAP_UNICODE) { | 787 | if (ses->capabilities & CAP_UNICODE) { |
739 | if (iov[0].iov_len % 2) { | 788 | if (iov[0].iov_len % 2) { |
740 | *bcc_ptr = 0; | 789 | *bcc_ptr = 0; |
@@ -765,15 +814,15 @@ ssetup_ntlmssp_authenticate: | |||
765 | } | 814 | } |
766 | /* bail out if key is too long */ | 815 | /* bail out if key is too long */ |
767 | if (msg->sesskey_len > | 816 | if (msg->sesskey_len > |
768 | sizeof(ses->server->mac_signing_key.data.krb5)) { | 817 | sizeof(ses->server->session_key.data.krb5)) { |
769 | cERROR(1, "Kerberos signing key too long (%u bytes)", | 818 | cERROR(1, "Kerberos signing key too long (%u bytes)", |
770 | msg->sesskey_len); | 819 | msg->sesskey_len); |
771 | rc = -EOVERFLOW; | 820 | rc = -EOVERFLOW; |
772 | goto ssetup_exit; | 821 | goto ssetup_exit; |
773 | } | 822 | } |
774 | if (first_time) { | 823 | if (first_time) { |
775 | ses->server->mac_signing_key.len = msg->sesskey_len; | 824 | ses->server->session_key.len = msg->sesskey_len; |
776 | memcpy(ses->server->mac_signing_key.data.krb5, | 825 | memcpy(ses->server->session_key.data.krb5, |
777 | msg->data, msg->sesskey_len); | 826 | msg->data, msg->sesskey_len); |
778 | } | 827 | } |
779 | pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; | 828 | pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; |
@@ -815,12 +864,28 @@ ssetup_ntlmssp_authenticate: | |||
815 | if (phase == NtLmNegotiate) { | 864 | if (phase == NtLmNegotiate) { |
816 | setup_ntlmssp_neg_req(pSMB, ses); | 865 | setup_ntlmssp_neg_req(pSMB, ses); |
817 | iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE); | 866 | iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE); |
867 | iov[1].iov_base = &pSMB->req.SecurityBlob[0]; | ||
818 | } else if (phase == NtLmAuthenticate) { | 868 | } else if (phase == NtLmAuthenticate) { |
819 | int blob_len; | 869 | int blob_len; |
820 | blob_len = setup_ntlmssp_auth_req(pSMB, ses, | 870 | char *ntlmsspblob; |
821 | nls_cp, | 871 | |
822 | first_time); | 872 | ntlmsspblob = kmalloc(5 * |
873 | sizeof(struct _AUTHENTICATE_MESSAGE), | ||
874 | GFP_KERNEL); | ||
875 | if (!ntlmsspblob) { | ||
876 | cERROR(1, "Can't allocate NTLMSSP"); | ||
877 | rc = -ENOMEM; | ||
878 | goto ssetup_exit; | ||
879 | } | ||
880 | |||
881 | blob_len = setup_ntlmssp_auth_req(ntlmsspblob, | ||
882 | ses, | ||
883 | nls_cp, | ||
884 | first_time); | ||
823 | iov[1].iov_len = blob_len; | 885 | iov[1].iov_len = blob_len; |
886 | iov[1].iov_base = ntlmsspblob; | ||
887 | pSMB->req.SecurityBlobLength = | ||
888 | cpu_to_le16(blob_len); | ||
824 | /* Make sure that we tell the server that we | 889 | /* Make sure that we tell the server that we |
825 | are using the uid that it just gave us back | 890 | are using the uid that it just gave us back |
826 | on the response (challenge) */ | 891 | on the response (challenge) */ |
@@ -830,7 +895,6 @@ ssetup_ntlmssp_authenticate: | |||
830 | rc = -ENOSYS; | 895 | rc = -ENOSYS; |
831 | goto ssetup_exit; | 896 | goto ssetup_exit; |
832 | } | 897 | } |
833 | iov[1].iov_base = &pSMB->req.SecurityBlob[0]; | ||
834 | /* unicode strings must be word aligned */ | 898 | /* unicode strings must be word aligned */ |
835 | if ((iov[0].iov_len + iov[1].iov_len) % 2) { | 899 | if ((iov[0].iov_len + iov[1].iov_len) % 2) { |
836 | *bcc_ptr = 0; | 900 | *bcc_ptr = 0; |
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 82f78c4d697..e0588cdf4cc 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
@@ -543,7 +543,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
543 | (ses->server->secMode & (SECMODE_SIGN_REQUIRED | | 543 | (ses->server->secMode & (SECMODE_SIGN_REQUIRED | |
544 | SECMODE_SIGN_ENABLED))) { | 544 | SECMODE_SIGN_ENABLED))) { |
545 | rc = cifs_verify_signature(midQ->resp_buf, | 545 | rc = cifs_verify_signature(midQ->resp_buf, |
546 | &ses->server->mac_signing_key, | 546 | ses->server, |
547 | midQ->sequence_number+1); | 547 | midQ->sequence_number+1); |
548 | if (rc) { | 548 | if (rc) { |
549 | cERROR(1, "Unexpected SMB signature"); | 549 | cERROR(1, "Unexpected SMB signature"); |
@@ -731,7 +731,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
731 | (ses->server->secMode & (SECMODE_SIGN_REQUIRED | | 731 | (ses->server->secMode & (SECMODE_SIGN_REQUIRED | |
732 | SECMODE_SIGN_ENABLED))) { | 732 | SECMODE_SIGN_ENABLED))) { |
733 | rc = cifs_verify_signature(out_buf, | 733 | rc = cifs_verify_signature(out_buf, |
734 | &ses->server->mac_signing_key, | 734 | ses->server, |
735 | midQ->sequence_number+1); | 735 | midQ->sequence_number+1); |
736 | if (rc) { | 736 | if (rc) { |
737 | cERROR(1, "Unexpected SMB signature"); | 737 | cERROR(1, "Unexpected SMB signature"); |
@@ -981,7 +981,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, | |||
981 | (ses->server->secMode & (SECMODE_SIGN_REQUIRED | | 981 | (ses->server->secMode & (SECMODE_SIGN_REQUIRED | |
982 | SECMODE_SIGN_ENABLED))) { | 982 | SECMODE_SIGN_ENABLED))) { |
983 | rc = cifs_verify_signature(out_buf, | 983 | rc = cifs_verify_signature(out_buf, |
984 | &ses->server->mac_signing_key, | 984 | ses->server, |
985 | midQ->sequence_number+1); | 985 | midQ->sequence_number+1); |
986 | if (rc) { | 986 | if (rc) { |
987 | cERROR(1, "Unexpected SMB signature"); | 987 | cERROR(1, "Unexpected SMB signature"); |
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index a53b130b366..1e7a33028d3 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c | |||
@@ -80,7 +80,7 @@ static struct inode *get_cramfs_inode(struct super_block *sb, | |||
80 | } | 80 | } |
81 | } else { | 81 | } else { |
82 | inode = iget_locked(sb, CRAMINO(cramfs_inode)); | 82 | inode = iget_locked(sb, CRAMINO(cramfs_inode)); |
83 | if (inode) { | 83 | if (inode && (inode->i_state & I_NEW)) { |
84 | setup_inode(inode, cramfs_inode); | 84 | setup_inode(inode, cramfs_inode); |
85 | unlock_new_inode(inode); | 85 | unlock_new_inode(inode); |
86 | } | 86 | } |
diff --git a/fs/dcache.c b/fs/dcache.c index 4d13bf50b7b..83293be4814 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1332,31 +1332,13 @@ EXPORT_SYMBOL(d_add_ci); | |||
1332 | * d_lookup - search for a dentry | 1332 | * d_lookup - search for a dentry |
1333 | * @parent: parent dentry | 1333 | * @parent: parent dentry |
1334 | * @name: qstr of name we wish to find | 1334 | * @name: qstr of name we wish to find |
1335 | * Returns: dentry, or NULL | ||
1335 | * | 1336 | * |
1336 | * Searches the children of the parent dentry for the name in question. If | 1337 | * d_lookup searches the children of the parent dentry for the name in |
1337 | * the dentry is found its reference count is incremented and the dentry | 1338 | * question. If the dentry is found its reference count is incremented and the |
1338 | * is returned. The caller must use dput to free the entry when it has | 1339 | * dentry is returned. The caller must use dput to free the entry when it has |
1339 | * finished using it. %NULL is returned on failure. | 1340 | * finished using it. %NULL is returned if the dentry does not exist. |
1340 | * | ||
1341 | * __d_lookup is dcache_lock free. The hash list is protected using RCU. | ||
1342 | * Memory barriers are used while updating and doing lockless traversal. | ||
1343 | * To avoid races with d_move while rename is happening, d_lock is used. | ||
1344 | * | ||
1345 | * Overflows in memcmp(), while d_move, are avoided by keeping the length | ||
1346 | * and name pointer in one structure pointed by d_qstr. | ||
1347 | * | ||
1348 | * rcu_read_lock() and rcu_read_unlock() are used to disable preemption while | ||
1349 | * lookup is going on. | ||
1350 | * | ||
1351 | * The dentry unused LRU is not updated even if lookup finds the required dentry | ||
1352 | * in there. It is updated in places such as prune_dcache, shrink_dcache_sb, | ||
1353 | * select_parent and __dget_locked. This laziness saves lookup from dcache_lock | ||
1354 | * acquisition. | ||
1355 | * | ||
1356 | * d_lookup() is protected against the concurrent renames in some unrelated | ||
1357 | * directory using the seqlockt_t rename_lock. | ||
1358 | */ | 1341 | */ |
1359 | |||
1360 | struct dentry * d_lookup(struct dentry * parent, struct qstr * name) | 1342 | struct dentry * d_lookup(struct dentry * parent, struct qstr * name) |
1361 | { | 1343 | { |
1362 | struct dentry * dentry = NULL; | 1344 | struct dentry * dentry = NULL; |
@@ -1372,6 +1354,21 @@ struct dentry * d_lookup(struct dentry * parent, struct qstr * name) | |||
1372 | } | 1354 | } |
1373 | EXPORT_SYMBOL(d_lookup); | 1355 | EXPORT_SYMBOL(d_lookup); |
1374 | 1356 | ||
1357 | /* | ||
1358 | * __d_lookup - search for a dentry (racy) | ||
1359 | * @parent: parent dentry | ||
1360 | * @name: qstr of name we wish to find | ||
1361 | * Returns: dentry, or NULL | ||
1362 | * | ||
1363 | * __d_lookup is like d_lookup, however it may (rarely) return a | ||
1364 | * false-negative result due to unrelated rename activity. | ||
1365 | * | ||
1366 | * __d_lookup is slightly faster by avoiding rename_lock read seqlock, | ||
1367 | * however it must be used carefully, eg. with a following d_lookup in | ||
1368 | * the case of failure. | ||
1369 | * | ||
1370 | * __d_lookup callers must be commented. | ||
1371 | */ | ||
1375 | struct dentry * __d_lookup(struct dentry * parent, struct qstr * name) | 1372 | struct dentry * __d_lookup(struct dentry * parent, struct qstr * name) |
1376 | { | 1373 | { |
1377 | unsigned int len = name->len; | 1374 | unsigned int len = name->len; |
@@ -1382,6 +1379,19 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name) | |||
1382 | struct hlist_node *node; | 1379 | struct hlist_node *node; |
1383 | struct dentry *dentry; | 1380 | struct dentry *dentry; |
1384 | 1381 | ||
1382 | /* | ||
1383 | * The hash list is protected using RCU. | ||
1384 | * | ||
1385 | * Take d_lock when comparing a candidate dentry, to avoid races | ||
1386 | * with d_move(). | ||
1387 | * | ||
1388 | * It is possible that concurrent renames can mess up our list | ||
1389 | * walk here and result in missing our dentry, resulting in the | ||
1390 | * false-negative result. d_lookup() protects against concurrent | ||
1391 | * renames using rename_lock seqlock. | ||
1392 | * | ||
1393 | * See Documentation/vfs/dcache-locking.txt for more details. | ||
1394 | */ | ||
1385 | rcu_read_lock(); | 1395 | rcu_read_lock(); |
1386 | 1396 | ||
1387 | hlist_for_each_entry_rcu(dentry, node, head, d_hash) { | 1397 | hlist_for_each_entry_rcu(dentry, node, head, d_hash) { |
@@ -1396,8 +1406,8 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name) | |||
1396 | 1406 | ||
1397 | /* | 1407 | /* |
1398 | * Recheck the dentry after taking the lock - d_move may have | 1408 | * Recheck the dentry after taking the lock - d_move may have |
1399 | * changed things. Don't bother checking the hash because we're | 1409 | * changed things. Don't bother checking the hash because |
1400 | * about to compare the whole name anyway. | 1410 | * we're about to compare the whole name anyway. |
1401 | */ | 1411 | */ |
1402 | if (dentry->d_parent != parent) | 1412 | if (dentry->d_parent != parent) |
1403 | goto next; | 1413 | goto next; |
@@ -1925,7 +1935,7 @@ static int prepend_path(const struct path *path, struct path *root, | |||
1925 | bool slash = false; | 1935 | bool slash = false; |
1926 | int error = 0; | 1936 | int error = 0; |
1927 | 1937 | ||
1928 | spin_lock(&vfsmount_lock); | 1938 | br_read_lock(vfsmount_lock); |
1929 | while (dentry != root->dentry || vfsmnt != root->mnt) { | 1939 | while (dentry != root->dentry || vfsmnt != root->mnt) { |
1930 | struct dentry * parent; | 1940 | struct dentry * parent; |
1931 | 1941 | ||
@@ -1954,7 +1964,7 @@ out: | |||
1954 | if (!error && !slash) | 1964 | if (!error && !slash) |
1955 | error = prepend(buffer, buflen, "/", 1); | 1965 | error = prepend(buffer, buflen, "/", 1); |
1956 | 1966 | ||
1957 | spin_unlock(&vfsmount_lock); | 1967 | br_read_unlock(vfsmount_lock); |
1958 | return error; | 1968 | return error; |
1959 | 1969 | ||
1960 | global_root: | 1970 | global_root: |
@@ -2292,11 +2302,12 @@ int path_is_under(struct path *path1, struct path *path2) | |||
2292 | struct vfsmount *mnt = path1->mnt; | 2302 | struct vfsmount *mnt = path1->mnt; |
2293 | struct dentry *dentry = path1->dentry; | 2303 | struct dentry *dentry = path1->dentry; |
2294 | int res; | 2304 | int res; |
2295 | spin_lock(&vfsmount_lock); | 2305 | |
2306 | br_read_lock(vfsmount_lock); | ||
2296 | if (mnt != path2->mnt) { | 2307 | if (mnt != path2->mnt) { |
2297 | for (;;) { | 2308 | for (;;) { |
2298 | if (mnt->mnt_parent == mnt) { | 2309 | if (mnt->mnt_parent == mnt) { |
2299 | spin_unlock(&vfsmount_lock); | 2310 | br_read_unlock(vfsmount_lock); |
2300 | return 0; | 2311 | return 0; |
2301 | } | 2312 | } |
2302 | if (mnt->mnt_parent == path2->mnt) | 2313 | if (mnt->mnt_parent == path2->mnt) |
@@ -2306,7 +2317,7 @@ int path_is_under(struct path *path1, struct path *path2) | |||
2306 | dentry = mnt->mnt_mountpoint; | 2317 | dentry = mnt->mnt_mountpoint; |
2307 | } | 2318 | } |
2308 | res = is_subdir(dentry, path2->dentry); | 2319 | res = is_subdir(dentry, path2->dentry); |
2309 | spin_unlock(&vfsmount_lock); | 2320 | br_read_unlock(vfsmount_lock); |
2310 | return res; | 2321 | return res; |
2311 | } | 2322 | } |
2312 | EXPORT_SYMBOL(path_is_under); | 2323 | EXPORT_SYMBOL(path_is_under); |
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index a2e3b562e65..cbadc1bee6e 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -1793,7 +1793,7 @@ struct kmem_cache *ecryptfs_key_tfm_cache; | |||
1793 | static struct list_head key_tfm_list; | 1793 | static struct list_head key_tfm_list; |
1794 | struct mutex key_tfm_list_mutex; | 1794 | struct mutex key_tfm_list_mutex; |
1795 | 1795 | ||
1796 | int ecryptfs_init_crypto(void) | 1796 | int __init ecryptfs_init_crypto(void) |
1797 | { | 1797 | { |
1798 | mutex_init(&key_tfm_list_mutex); | 1798 | mutex_init(&key_tfm_list_mutex); |
1799 | INIT_LIST_HEAD(&key_tfm_list); | 1799 | INIT_LIST_HEAD(&key_tfm_list); |
@@ -2169,7 +2169,6 @@ int ecryptfs_encrypt_and_encode_filename( | |||
2169 | (ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE | 2169 | (ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE |
2170 | + encoded_name_no_prefix_size); | 2170 | + encoded_name_no_prefix_size); |
2171 | (*encoded_name)[(*encoded_name_size)] = '\0'; | 2171 | (*encoded_name)[(*encoded_name_size)] = '\0'; |
2172 | (*encoded_name_size)++; | ||
2173 | } else { | 2172 | } else { |
2174 | rc = -EOPNOTSUPP; | 2173 | rc = -EOPNOTSUPP; |
2175 | } | 2174 | } |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 6c55113e722..3fbc9420338 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -349,7 +349,7 @@ out: | |||
349 | 349 | ||
350 | /** | 350 | /** |
351 | * ecryptfs_new_lower_dentry | 351 | * ecryptfs_new_lower_dentry |
352 | * @ename: The name of the new dentry. | 352 | * @name: The name of the new dentry. |
353 | * @lower_dir_dentry: Parent directory of the new dentry. | 353 | * @lower_dir_dentry: Parent directory of the new dentry. |
354 | * @nd: nameidata from last lookup. | 354 | * @nd: nameidata from last lookup. |
355 | * | 355 | * |
@@ -386,20 +386,19 @@ ecryptfs_new_lower_dentry(struct qstr *name, struct dentry *lower_dir_dentry, | |||
386 | * ecryptfs_lookup_one_lower | 386 | * ecryptfs_lookup_one_lower |
387 | * @ecryptfs_dentry: The eCryptfs dentry that we are looking up | 387 | * @ecryptfs_dentry: The eCryptfs dentry that we are looking up |
388 | * @lower_dir_dentry: lower parent directory | 388 | * @lower_dir_dentry: lower parent directory |
389 | * @name: lower file name | ||
389 | * | 390 | * |
390 | * Get the lower dentry from vfs. If lower dentry does not exist yet, | 391 | * Get the lower dentry from vfs. If lower dentry does not exist yet, |
391 | * create it. | 392 | * create it. |
392 | */ | 393 | */ |
393 | static struct dentry * | 394 | static struct dentry * |
394 | ecryptfs_lookup_one_lower(struct dentry *ecryptfs_dentry, | 395 | ecryptfs_lookup_one_lower(struct dentry *ecryptfs_dentry, |
395 | struct dentry *lower_dir_dentry) | 396 | struct dentry *lower_dir_dentry, struct qstr *name) |
396 | { | 397 | { |
397 | struct nameidata nd; | 398 | struct nameidata nd; |
398 | struct vfsmount *lower_mnt; | 399 | struct vfsmount *lower_mnt; |
399 | struct qstr *name; | ||
400 | int err; | 400 | int err; |
401 | 401 | ||
402 | name = &ecryptfs_dentry->d_name; | ||
403 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( | 402 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( |
404 | ecryptfs_dentry->d_parent)); | 403 | ecryptfs_dentry->d_parent)); |
405 | err = vfs_path_lookup(lower_dir_dentry, lower_mnt, name->name , 0, &nd); | 404 | err = vfs_path_lookup(lower_dir_dentry, lower_mnt, name->name , 0, &nd); |
@@ -434,6 +433,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
434 | size_t encrypted_and_encoded_name_size; | 433 | size_t encrypted_and_encoded_name_size; |
435 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; | 434 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; |
436 | struct dentry *lower_dir_dentry, *lower_dentry; | 435 | struct dentry *lower_dir_dentry, *lower_dentry; |
436 | struct qstr lower_name; | ||
437 | int rc = 0; | 437 | int rc = 0; |
438 | 438 | ||
439 | ecryptfs_dentry->d_op = &ecryptfs_dops; | 439 | ecryptfs_dentry->d_op = &ecryptfs_dops; |
@@ -444,9 +444,17 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
444 | goto out_d_drop; | 444 | goto out_d_drop; |
445 | } | 445 | } |
446 | lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent); | 446 | lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent); |
447 | 447 | lower_name.name = ecryptfs_dentry->d_name.name; | |
448 | lower_name.len = ecryptfs_dentry->d_name.len; | ||
449 | lower_name.hash = ecryptfs_dentry->d_name.hash; | ||
450 | if (lower_dir_dentry->d_op && lower_dir_dentry->d_op->d_hash) { | ||
451 | rc = lower_dir_dentry->d_op->d_hash(lower_dir_dentry, | ||
452 | &lower_name); | ||
453 | if (rc < 0) | ||
454 | goto out_d_drop; | ||
455 | } | ||
448 | lower_dentry = ecryptfs_lookup_one_lower(ecryptfs_dentry, | 456 | lower_dentry = ecryptfs_lookup_one_lower(ecryptfs_dentry, |
449 | lower_dir_dentry); | 457 | lower_dir_dentry, &lower_name); |
450 | if (IS_ERR(lower_dentry)) { | 458 | if (IS_ERR(lower_dentry)) { |
451 | rc = PTR_ERR(lower_dentry); | 459 | rc = PTR_ERR(lower_dentry); |
452 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_lower() returned " | 460 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_lower() returned " |
@@ -471,8 +479,17 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
471 | "filename; rc = [%d]\n", __func__, rc); | 479 | "filename; rc = [%d]\n", __func__, rc); |
472 | goto out_d_drop; | 480 | goto out_d_drop; |
473 | } | 481 | } |
482 | lower_name.name = encrypted_and_encoded_name; | ||
483 | lower_name.len = encrypted_and_encoded_name_size; | ||
484 | lower_name.hash = full_name_hash(lower_name.name, lower_name.len); | ||
485 | if (lower_dir_dentry->d_op && lower_dir_dentry->d_op->d_hash) { | ||
486 | rc = lower_dir_dentry->d_op->d_hash(lower_dir_dentry, | ||
487 | &lower_name); | ||
488 | if (rc < 0) | ||
489 | goto out_d_drop; | ||
490 | } | ||
474 | lower_dentry = ecryptfs_lookup_one_lower(ecryptfs_dentry, | 491 | lower_dentry = ecryptfs_lookup_one_lower(ecryptfs_dentry, |
475 | lower_dir_dentry); | 492 | lower_dir_dentry, &lower_name); |
476 | if (IS_ERR(lower_dentry)) { | 493 | if (IS_ERR(lower_dentry)) { |
477 | rc = PTR_ERR(lower_dentry); | 494 | rc = PTR_ERR(lower_dentry); |
478 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_lower() returned " | 495 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_lower() returned " |
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 89c5476506e..73811cfa2ea 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
@@ -515,6 +515,7 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, | |||
515 | if (!s) { | 515 | if (!s) { |
516 | printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " | 516 | printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " |
517 | "[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); | 517 | "[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); |
518 | rc = -ENOMEM; | ||
518 | goto out; | 519 | goto out; |
519 | } | 520 | } |
520 | s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | 521 | s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; |
@@ -806,6 +807,7 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, | |||
806 | if (!s) { | 807 | if (!s) { |
807 | printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " | 808 | printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " |
808 | "[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); | 809 | "[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); |
810 | rc = -ENOMEM; | ||
809 | goto out; | 811 | goto out; |
810 | } | 812 | } |
811 | s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | 813 | s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; |
diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c index d8c3a373aaf..0851ab6980f 100644 --- a/fs/ecryptfs/kthread.c +++ b/fs/ecryptfs/kthread.c | |||
@@ -86,7 +86,7 @@ out: | |||
86 | return 0; | 86 | return 0; |
87 | } | 87 | } |
88 | 88 | ||
89 | int ecryptfs_init_kthread(void) | 89 | int __init ecryptfs_init_kthread(void) |
90 | { | 90 | { |
91 | int rc = 0; | 91 | int rc = 0; |
92 | 92 | ||
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c index bcb68c0cb1f..ab224809051 100644 --- a/fs/ecryptfs/messaging.c +++ b/fs/ecryptfs/messaging.c | |||
@@ -473,7 +473,7 @@ sleep: | |||
473 | return rc; | 473 | return rc; |
474 | } | 474 | } |
475 | 475 | ||
476 | int ecryptfs_init_messaging(void) | 476 | int __init ecryptfs_init_messaging(void) |
477 | { | 477 | { |
478 | int i; | 478 | int i; |
479 | int rc = 0; | 479 | int rc = 0; |
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c index 3745f612bcd..00208c3d7e9 100644 --- a/fs/ecryptfs/miscdev.c +++ b/fs/ecryptfs/miscdev.c | |||
@@ -500,7 +500,7 @@ static struct miscdevice ecryptfs_miscdev = { | |||
500 | * | 500 | * |
501 | * Returns zero on success; non-zero otherwise | 501 | * Returns zero on success; non-zero otherwise |
502 | */ | 502 | */ |
503 | int ecryptfs_init_ecryptfs_miscdev(void) | 503 | int __init ecryptfs_init_ecryptfs_miscdev(void) |
504 | { | 504 | { |
505 | int rc; | 505 | int rc; |
506 | 506 | ||
@@ -361,13 +361,13 @@ err: | |||
361 | /* | 361 | /* |
362 | * count() counts the number of strings in array ARGV. | 362 | * count() counts the number of strings in array ARGV. |
363 | */ | 363 | */ |
364 | static int count(char __user * __user * argv, int max) | 364 | static int count(const char __user * const __user * argv, int max) |
365 | { | 365 | { |
366 | int i = 0; | 366 | int i = 0; |
367 | 367 | ||
368 | if (argv != NULL) { | 368 | if (argv != NULL) { |
369 | for (;;) { | 369 | for (;;) { |
370 | char __user * p; | 370 | const char __user * p; |
371 | 371 | ||
372 | if (get_user(p, argv)) | 372 | if (get_user(p, argv)) |
373 | return -EFAULT; | 373 | return -EFAULT; |
@@ -387,7 +387,7 @@ static int count(char __user * __user * argv, int max) | |||
387 | * processes's memory to the new process's stack. The call to get_user_pages() | 387 | * processes's memory to the new process's stack. The call to get_user_pages() |
388 | * ensures the destination page is created and not swapped out. | 388 | * ensures the destination page is created and not swapped out. |
389 | */ | 389 | */ |
390 | static int copy_strings(int argc, char __user * __user * argv, | 390 | static int copy_strings(int argc, const char __user *const __user *argv, |
391 | struct linux_binprm *bprm) | 391 | struct linux_binprm *bprm) |
392 | { | 392 | { |
393 | struct page *kmapped_page = NULL; | 393 | struct page *kmapped_page = NULL; |
@@ -396,7 +396,7 @@ static int copy_strings(int argc, char __user * __user * argv, | |||
396 | int ret; | 396 | int ret; |
397 | 397 | ||
398 | while (argc-- > 0) { | 398 | while (argc-- > 0) { |
399 | char __user *str; | 399 | const char __user *str; |
400 | int len; | 400 | int len; |
401 | unsigned long pos; | 401 | unsigned long pos; |
402 | 402 | ||
@@ -470,12 +470,13 @@ out: | |||
470 | /* | 470 | /* |
471 | * Like copy_strings, but get argv and its values from kernel memory. | 471 | * Like copy_strings, but get argv and its values from kernel memory. |
472 | */ | 472 | */ |
473 | int copy_strings_kernel(int argc,char ** argv, struct linux_binprm *bprm) | 473 | int copy_strings_kernel(int argc, const char *const *argv, |
474 | struct linux_binprm *bprm) | ||
474 | { | 475 | { |
475 | int r; | 476 | int r; |
476 | mm_segment_t oldfs = get_fs(); | 477 | mm_segment_t oldfs = get_fs(); |
477 | set_fs(KERNEL_DS); | 478 | set_fs(KERNEL_DS); |
478 | r = copy_strings(argc, (char __user * __user *)argv, bprm); | 479 | r = copy_strings(argc, (const char __user *const __user *)argv, bprm); |
479 | set_fs(oldfs); | 480 | set_fs(oldfs); |
480 | return r; | 481 | return r; |
481 | } | 482 | } |
@@ -997,7 +998,7 @@ EXPORT_SYMBOL(flush_old_exec); | |||
997 | void setup_new_exec(struct linux_binprm * bprm) | 998 | void setup_new_exec(struct linux_binprm * bprm) |
998 | { | 999 | { |
999 | int i, ch; | 1000 | int i, ch; |
1000 | char * name; | 1001 | const char *name; |
1001 | char tcomm[sizeof(current->comm)]; | 1002 | char tcomm[sizeof(current->comm)]; |
1002 | 1003 | ||
1003 | arch_pick_mmap_layout(current->mm); | 1004 | arch_pick_mmap_layout(current->mm); |
@@ -1117,7 +1118,7 @@ int check_unsafe_exec(struct linux_binprm *bprm) | |||
1117 | bprm->unsafe = tracehook_unsafe_exec(p); | 1118 | bprm->unsafe = tracehook_unsafe_exec(p); |
1118 | 1119 | ||
1119 | n_fs = 1; | 1120 | n_fs = 1; |
1120 | write_lock(&p->fs->lock); | 1121 | spin_lock(&p->fs->lock); |
1121 | rcu_read_lock(); | 1122 | rcu_read_lock(); |
1122 | for (t = next_thread(p); t != p; t = next_thread(t)) { | 1123 | for (t = next_thread(p); t != p; t = next_thread(t)) { |
1123 | if (t->fs == p->fs) | 1124 | if (t->fs == p->fs) |
@@ -1134,7 +1135,7 @@ int check_unsafe_exec(struct linux_binprm *bprm) | |||
1134 | res = 1; | 1135 | res = 1; |
1135 | } | 1136 | } |
1136 | } | 1137 | } |
1137 | write_unlock(&p->fs->lock); | 1138 | spin_unlock(&p->fs->lock); |
1138 | 1139 | ||
1139 | return res; | 1140 | return res; |
1140 | } | 1141 | } |
@@ -1316,9 +1317,9 @@ EXPORT_SYMBOL(search_binary_handler); | |||
1316 | /* | 1317 | /* |
1317 | * sys_execve() executes a new program. | 1318 | * sys_execve() executes a new program. |
1318 | */ | 1319 | */ |
1319 | int do_execve(char * filename, | 1320 | int do_execve(const char * filename, |
1320 | char __user *__user *argv, | 1321 | const char __user *const __user *argv, |
1321 | char __user *__user *envp, | 1322 | const char __user *const __user *envp, |
1322 | struct pt_regs * regs) | 1323 | struct pt_regs * regs) |
1323 | { | 1324 | { |
1324 | struct linux_binprm *bprm; | 1325 | struct linux_binprm *bprm; |
diff --git a/fs/fat/misc.c b/fs/fat/misc.c index 1fa23f6ffba..1736f235638 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c | |||
@@ -250,7 +250,9 @@ int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs) | |||
250 | { | 250 | { |
251 | int i, err = 0; | 251 | int i, err = 0; |
252 | 252 | ||
253 | ll_rw_block(SWRITE, nr_bhs, bhs); | 253 | for (i = 0; i < nr_bhs; i++) |
254 | write_dirty_buffer(bhs[i], WRITE); | ||
255 | |||
254 | for (i = 0; i < nr_bhs; i++) { | 256 | for (i = 0; i < nr_bhs; i++) { |
255 | wait_on_buffer(bhs[i]); | 257 | wait_on_buffer(bhs[i]); |
256 | if (buffer_eopnotsupp(bhs[i])) { | 258 | if (buffer_eopnotsupp(bhs[i])) { |
diff --git a/fs/file_table.c b/fs/file_table.c index edecd36fed9..a04bdd81c11 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -20,7 +20,9 @@ | |||
20 | #include <linux/cdev.h> | 20 | #include <linux/cdev.h> |
21 | #include <linux/fsnotify.h> | 21 | #include <linux/fsnotify.h> |
22 | #include <linux/sysctl.h> | 22 | #include <linux/sysctl.h> |
23 | #include <linux/lglock.h> | ||
23 | #include <linux/percpu_counter.h> | 24 | #include <linux/percpu_counter.h> |
25 | #include <linux/percpu.h> | ||
24 | #include <linux/ima.h> | 26 | #include <linux/ima.h> |
25 | 27 | ||
26 | #include <asm/atomic.h> | 28 | #include <asm/atomic.h> |
@@ -32,8 +34,8 @@ struct files_stat_struct files_stat = { | |||
32 | .max_files = NR_FILE | 34 | .max_files = NR_FILE |
33 | }; | 35 | }; |
34 | 36 | ||
35 | /* public. Not pretty! */ | 37 | DECLARE_LGLOCK(files_lglock); |
36 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(files_lock); | 38 | DEFINE_LGLOCK(files_lglock); |
37 | 39 | ||
38 | /* SLAB cache for file structures */ | 40 | /* SLAB cache for file structures */ |
39 | static struct kmem_cache *filp_cachep __read_mostly; | 41 | static struct kmem_cache *filp_cachep __read_mostly; |
@@ -249,7 +251,7 @@ static void __fput(struct file *file) | |||
249 | cdev_put(inode->i_cdev); | 251 | cdev_put(inode->i_cdev); |
250 | fops_put(file->f_op); | 252 | fops_put(file->f_op); |
251 | put_pid(file->f_owner.pid); | 253 | put_pid(file->f_owner.pid); |
252 | file_kill(file); | 254 | file_sb_list_del(file); |
253 | if (file->f_mode & FMODE_WRITE) | 255 | if (file->f_mode & FMODE_WRITE) |
254 | drop_file_write_access(file); | 256 | drop_file_write_access(file); |
255 | file->f_path.dentry = NULL; | 257 | file->f_path.dentry = NULL; |
@@ -328,41 +330,107 @@ struct file *fget_light(unsigned int fd, int *fput_needed) | |||
328 | return file; | 330 | return file; |
329 | } | 331 | } |
330 | 332 | ||
331 | |||
332 | void put_filp(struct file *file) | 333 | void put_filp(struct file *file) |
333 | { | 334 | { |
334 | if (atomic_long_dec_and_test(&file->f_count)) { | 335 | if (atomic_long_dec_and_test(&file->f_count)) { |
335 | security_file_free(file); | 336 | security_file_free(file); |
336 | file_kill(file); | 337 | file_sb_list_del(file); |
337 | file_free(file); | 338 | file_free(file); |
338 | } | 339 | } |
339 | } | 340 | } |
340 | 341 | ||
341 | void file_move(struct file *file, struct list_head *list) | 342 | static inline int file_list_cpu(struct file *file) |
342 | { | 343 | { |
343 | if (!list) | 344 | #ifdef CONFIG_SMP |
344 | return; | 345 | return file->f_sb_list_cpu; |
345 | file_list_lock(); | 346 | #else |
346 | list_move(&file->f_u.fu_list, list); | 347 | return smp_processor_id(); |
347 | file_list_unlock(); | 348 | #endif |
349 | } | ||
350 | |||
351 | /* helper for file_sb_list_add to reduce ifdefs */ | ||
352 | static inline void __file_sb_list_add(struct file *file, struct super_block *sb) | ||
353 | { | ||
354 | struct list_head *list; | ||
355 | #ifdef CONFIG_SMP | ||
356 | int cpu; | ||
357 | cpu = smp_processor_id(); | ||
358 | file->f_sb_list_cpu = cpu; | ||
359 | list = per_cpu_ptr(sb->s_files, cpu); | ||
360 | #else | ||
361 | list = &sb->s_files; | ||
362 | #endif | ||
363 | list_add(&file->f_u.fu_list, list); | ||
348 | } | 364 | } |
349 | 365 | ||
350 | void file_kill(struct file *file) | 366 | /** |
367 | * file_sb_list_add - add a file to the sb's file list | ||
368 | * @file: file to add | ||
369 | * @sb: sb to add it to | ||
370 | * | ||
371 | * Use this function to associate a file with the superblock of the inode it | ||
372 | * refers to. | ||
373 | */ | ||
374 | void file_sb_list_add(struct file *file, struct super_block *sb) | ||
375 | { | ||
376 | lg_local_lock(files_lglock); | ||
377 | __file_sb_list_add(file, sb); | ||
378 | lg_local_unlock(files_lglock); | ||
379 | } | ||
380 | |||
381 | /** | ||
382 | * file_sb_list_del - remove a file from the sb's file list | ||
383 | * @file: file to remove | ||
384 | * @sb: sb to remove it from | ||
385 | * | ||
386 | * Use this function to remove a file from its superblock. | ||
387 | */ | ||
388 | void file_sb_list_del(struct file *file) | ||
351 | { | 389 | { |
352 | if (!list_empty(&file->f_u.fu_list)) { | 390 | if (!list_empty(&file->f_u.fu_list)) { |
353 | file_list_lock(); | 391 | lg_local_lock_cpu(files_lglock, file_list_cpu(file)); |
354 | list_del_init(&file->f_u.fu_list); | 392 | list_del_init(&file->f_u.fu_list); |
355 | file_list_unlock(); | 393 | lg_local_unlock_cpu(files_lglock, file_list_cpu(file)); |
356 | } | 394 | } |
357 | } | 395 | } |
358 | 396 | ||
397 | #ifdef CONFIG_SMP | ||
398 | |||
399 | /* | ||
400 | * These macros iterate all files on all CPUs for a given superblock. | ||
401 | * files_lglock must be held globally. | ||
402 | */ | ||
403 | #define do_file_list_for_each_entry(__sb, __file) \ | ||
404 | { \ | ||
405 | int i; \ | ||
406 | for_each_possible_cpu(i) { \ | ||
407 | struct list_head *list; \ | ||
408 | list = per_cpu_ptr((__sb)->s_files, i); \ | ||
409 | list_for_each_entry((__file), list, f_u.fu_list) | ||
410 | |||
411 | #define while_file_list_for_each_entry \ | ||
412 | } \ | ||
413 | } | ||
414 | |||
415 | #else | ||
416 | |||
417 | #define do_file_list_for_each_entry(__sb, __file) \ | ||
418 | { \ | ||
419 | struct list_head *list; \ | ||
420 | list = &(sb)->s_files; \ | ||
421 | list_for_each_entry((__file), list, f_u.fu_list) | ||
422 | |||
423 | #define while_file_list_for_each_entry \ | ||
424 | } | ||
425 | |||
426 | #endif | ||
427 | |||
359 | int fs_may_remount_ro(struct super_block *sb) | 428 | int fs_may_remount_ro(struct super_block *sb) |
360 | { | 429 | { |
361 | struct file *file; | 430 | struct file *file; |
362 | |||
363 | /* Check that no files are currently opened for writing. */ | 431 | /* Check that no files are currently opened for writing. */ |
364 | file_list_lock(); | 432 | lg_global_lock(files_lglock); |
365 | list_for_each_entry(file, &sb->s_files, f_u.fu_list) { | 433 | do_file_list_for_each_entry(sb, file) { |
366 | struct inode *inode = file->f_path.dentry->d_inode; | 434 | struct inode *inode = file->f_path.dentry->d_inode; |
367 | 435 | ||
368 | /* File with pending delete? */ | 436 | /* File with pending delete? */ |
@@ -372,11 +440,11 @@ int fs_may_remount_ro(struct super_block *sb) | |||
372 | /* Writeable file? */ | 440 | /* Writeable file? */ |
373 | if (S_ISREG(inode->i_mode) && (file->f_mode & FMODE_WRITE)) | 441 | if (S_ISREG(inode->i_mode) && (file->f_mode & FMODE_WRITE)) |
374 | goto too_bad; | 442 | goto too_bad; |
375 | } | 443 | } while_file_list_for_each_entry; |
376 | file_list_unlock(); | 444 | lg_global_unlock(files_lglock); |
377 | return 1; /* Tis' cool bro. */ | 445 | return 1; /* Tis' cool bro. */ |
378 | too_bad: | 446 | too_bad: |
379 | file_list_unlock(); | 447 | lg_global_unlock(files_lglock); |
380 | return 0; | 448 | return 0; |
381 | } | 449 | } |
382 | 450 | ||
@@ -392,8 +460,8 @@ void mark_files_ro(struct super_block *sb) | |||
392 | struct file *f; | 460 | struct file *f; |
393 | 461 | ||
394 | retry: | 462 | retry: |
395 | file_list_lock(); | 463 | lg_global_lock(files_lglock); |
396 | list_for_each_entry(f, &sb->s_files, f_u.fu_list) { | 464 | do_file_list_for_each_entry(sb, f) { |
397 | struct vfsmount *mnt; | 465 | struct vfsmount *mnt; |
398 | if (!S_ISREG(f->f_path.dentry->d_inode->i_mode)) | 466 | if (!S_ISREG(f->f_path.dentry->d_inode->i_mode)) |
399 | continue; | 467 | continue; |
@@ -408,16 +476,13 @@ retry: | |||
408 | continue; | 476 | continue; |
409 | file_release_write(f); | 477 | file_release_write(f); |
410 | mnt = mntget(f->f_path.mnt); | 478 | mnt = mntget(f->f_path.mnt); |
411 | file_list_unlock(); | 479 | /* This can sleep, so we can't hold the spinlock. */ |
412 | /* | 480 | lg_global_unlock(files_lglock); |
413 | * This can sleep, so we can't hold | ||
414 | * the file_list_lock() spinlock. | ||
415 | */ | ||
416 | mnt_drop_write(mnt); | 481 | mnt_drop_write(mnt); |
417 | mntput(mnt); | 482 | mntput(mnt); |
418 | goto retry; | 483 | goto retry; |
419 | } | 484 | } while_file_list_for_each_entry; |
420 | file_list_unlock(); | 485 | lg_global_unlock(files_lglock); |
421 | } | 486 | } |
422 | 487 | ||
423 | void __init files_init(unsigned long mempages) | 488 | void __init files_init(unsigned long mempages) |
@@ -437,5 +502,6 @@ void __init files_init(unsigned long mempages) | |||
437 | if (files_stat.max_files < NR_FILE) | 502 | if (files_stat.max_files < NR_FILE) |
438 | files_stat.max_files = NR_FILE; | 503 | files_stat.max_files = NR_FILE; |
439 | files_defer_init(); | 504 | files_defer_init(); |
505 | lg_lock_init(files_lglock); | ||
440 | percpu_counter_init(&nr_files, 0); | 506 | percpu_counter_init(&nr_files, 0); |
441 | } | 507 | } |
diff --git a/fs/fs_struct.c b/fs/fs_struct.c index 1ee40eb9a2c..ed45a9cf5f3 100644 --- a/fs/fs_struct.c +++ b/fs/fs_struct.c | |||
@@ -13,11 +13,11 @@ void set_fs_root(struct fs_struct *fs, struct path *path) | |||
13 | { | 13 | { |
14 | struct path old_root; | 14 | struct path old_root; |
15 | 15 | ||
16 | write_lock(&fs->lock); | 16 | spin_lock(&fs->lock); |
17 | old_root = fs->root; | 17 | old_root = fs->root; |
18 | fs->root = *path; | 18 | fs->root = *path; |
19 | path_get(path); | 19 | path_get(path); |
20 | write_unlock(&fs->lock); | 20 | spin_unlock(&fs->lock); |
21 | if (old_root.dentry) | 21 | if (old_root.dentry) |
22 | path_put(&old_root); | 22 | path_put(&old_root); |
23 | } | 23 | } |
@@ -30,11 +30,11 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path) | |||
30 | { | 30 | { |
31 | struct path old_pwd; | 31 | struct path old_pwd; |
32 | 32 | ||
33 | write_lock(&fs->lock); | 33 | spin_lock(&fs->lock); |
34 | old_pwd = fs->pwd; | 34 | old_pwd = fs->pwd; |
35 | fs->pwd = *path; | 35 | fs->pwd = *path; |
36 | path_get(path); | 36 | path_get(path); |
37 | write_unlock(&fs->lock); | 37 | spin_unlock(&fs->lock); |
38 | 38 | ||
39 | if (old_pwd.dentry) | 39 | if (old_pwd.dentry) |
40 | path_put(&old_pwd); | 40 | path_put(&old_pwd); |
@@ -51,7 +51,7 @@ void chroot_fs_refs(struct path *old_root, struct path *new_root) | |||
51 | task_lock(p); | 51 | task_lock(p); |
52 | fs = p->fs; | 52 | fs = p->fs; |
53 | if (fs) { | 53 | if (fs) { |
54 | write_lock(&fs->lock); | 54 | spin_lock(&fs->lock); |
55 | if (fs->root.dentry == old_root->dentry | 55 | if (fs->root.dentry == old_root->dentry |
56 | && fs->root.mnt == old_root->mnt) { | 56 | && fs->root.mnt == old_root->mnt) { |
57 | path_get(new_root); | 57 | path_get(new_root); |
@@ -64,7 +64,7 @@ void chroot_fs_refs(struct path *old_root, struct path *new_root) | |||
64 | fs->pwd = *new_root; | 64 | fs->pwd = *new_root; |
65 | count++; | 65 | count++; |
66 | } | 66 | } |
67 | write_unlock(&fs->lock); | 67 | spin_unlock(&fs->lock); |
68 | } | 68 | } |
69 | task_unlock(p); | 69 | task_unlock(p); |
70 | } while_each_thread(g, p); | 70 | } while_each_thread(g, p); |
@@ -87,10 +87,10 @@ void exit_fs(struct task_struct *tsk) | |||
87 | if (fs) { | 87 | if (fs) { |
88 | int kill; | 88 | int kill; |
89 | task_lock(tsk); | 89 | task_lock(tsk); |
90 | write_lock(&fs->lock); | 90 | spin_lock(&fs->lock); |
91 | tsk->fs = NULL; | 91 | tsk->fs = NULL; |
92 | kill = !--fs->users; | 92 | kill = !--fs->users; |
93 | write_unlock(&fs->lock); | 93 | spin_unlock(&fs->lock); |
94 | task_unlock(tsk); | 94 | task_unlock(tsk); |
95 | if (kill) | 95 | if (kill) |
96 | free_fs_struct(fs); | 96 | free_fs_struct(fs); |
@@ -104,7 +104,7 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old) | |||
104 | if (fs) { | 104 | if (fs) { |
105 | fs->users = 1; | 105 | fs->users = 1; |
106 | fs->in_exec = 0; | 106 | fs->in_exec = 0; |
107 | rwlock_init(&fs->lock); | 107 | spin_lock_init(&fs->lock); |
108 | fs->umask = old->umask; | 108 | fs->umask = old->umask; |
109 | get_fs_root_and_pwd(old, &fs->root, &fs->pwd); | 109 | get_fs_root_and_pwd(old, &fs->root, &fs->pwd); |
110 | } | 110 | } |
@@ -121,10 +121,10 @@ int unshare_fs_struct(void) | |||
121 | return -ENOMEM; | 121 | return -ENOMEM; |
122 | 122 | ||
123 | task_lock(current); | 123 | task_lock(current); |
124 | write_lock(&fs->lock); | 124 | spin_lock(&fs->lock); |
125 | kill = !--fs->users; | 125 | kill = !--fs->users; |
126 | current->fs = new_fs; | 126 | current->fs = new_fs; |
127 | write_unlock(&fs->lock); | 127 | spin_unlock(&fs->lock); |
128 | task_unlock(current); | 128 | task_unlock(current); |
129 | 129 | ||
130 | if (kill) | 130 | if (kill) |
@@ -143,7 +143,7 @@ EXPORT_SYMBOL(current_umask); | |||
143 | /* to be mentioned only in INIT_TASK */ | 143 | /* to be mentioned only in INIT_TASK */ |
144 | struct fs_struct init_fs = { | 144 | struct fs_struct init_fs = { |
145 | .users = 1, | 145 | .users = 1, |
146 | .lock = __RW_LOCK_UNLOCKED(init_fs.lock), | 146 | .lock = __SPIN_LOCK_UNLOCKED(init_fs.lock), |
147 | .umask = 0022, | 147 | .umask = 0022, |
148 | }; | 148 | }; |
149 | 149 | ||
@@ -156,14 +156,14 @@ void daemonize_fs_struct(void) | |||
156 | 156 | ||
157 | task_lock(current); | 157 | task_lock(current); |
158 | 158 | ||
159 | write_lock(&init_fs.lock); | 159 | spin_lock(&init_fs.lock); |
160 | init_fs.users++; | 160 | init_fs.users++; |
161 | write_unlock(&init_fs.lock); | 161 | spin_unlock(&init_fs.lock); |
162 | 162 | ||
163 | write_lock(&fs->lock); | 163 | spin_lock(&fs->lock); |
164 | current->fs = &init_fs; | 164 | current->fs = &init_fs; |
165 | kill = !--fs->users; | 165 | kill = !--fs->users; |
166 | write_unlock(&fs->lock); | 166 | spin_unlock(&fs->lock); |
167 | 167 | ||
168 | task_unlock(current); | 168 | task_unlock(current); |
169 | if (kill) | 169 | if (kill) |
diff --git a/fs/generic_acl.c b/fs/generic_acl.c index 99800e56415..6bc9e3a5a69 100644 --- a/fs/generic_acl.c +++ b/fs/generic_acl.c | |||
@@ -94,6 +94,7 @@ generic_acl_set(struct dentry *dentry, const char *name, const void *value, | |||
94 | if (error < 0) | 94 | if (error < 0) |
95 | goto failed; | 95 | goto failed; |
96 | inode->i_mode = mode; | 96 | inode->i_mode = mode; |
97 | inode->i_ctime = CURRENT_TIME; | ||
97 | if (error == 0) { | 98 | if (error == 0) { |
98 | posix_acl_release(acl); | 99 | posix_acl_release(acl); |
99 | acl = NULL; | 100 | acl = NULL; |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index dd1e55535a4..f7dc9b5f9ef 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -104,7 +104,7 @@ static char *__dentry_name(struct dentry *dentry, char *name) | |||
104 | __putname(name); | 104 | __putname(name); |
105 | return NULL; | 105 | return NULL; |
106 | } | 106 | } |
107 | strncpy(name, root, PATH_MAX); | 107 | strlcpy(name, root, PATH_MAX); |
108 | if (len > p - name) { | 108 | if (len > p - name) { |
109 | __putname(name); | 109 | __putname(name); |
110 | return NULL; | 110 | return NULL; |
@@ -876,7 +876,7 @@ static void *hostfs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
876 | char *path = dentry_name(dentry); | 876 | char *path = dentry_name(dentry); |
877 | int err = -ENOMEM; | 877 | int err = -ENOMEM; |
878 | if (path) { | 878 | if (path) { |
879 | int err = hostfs_do_readlink(path, link, PATH_MAX); | 879 | err = hostfs_do_readlink(path, link, PATH_MAX); |
880 | if (err == PATH_MAX) | 880 | if (err == PATH_MAX) |
881 | err = -E2BIG; | 881 | err = -E2BIG; |
882 | __putname(path); | 882 | __putname(path); |
diff --git a/fs/internal.h b/fs/internal.h index 6b706bc60a6..a6910e91cee 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
@@ -9,6 +9,8 @@ | |||
9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/lglock.h> | ||
13 | |||
12 | struct super_block; | 14 | struct super_block; |
13 | struct linux_binprm; | 15 | struct linux_binprm; |
14 | struct path; | 16 | struct path; |
@@ -70,7 +72,8 @@ extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int); | |||
70 | 72 | ||
71 | extern void __init mnt_init(void); | 73 | extern void __init mnt_init(void); |
72 | 74 | ||
73 | extern spinlock_t vfsmount_lock; | 75 | DECLARE_BRLOCK(vfsmount_lock); |
76 | |||
74 | 77 | ||
75 | /* | 78 | /* |
76 | * fs_struct.c | 79 | * fs_struct.c |
@@ -80,6 +83,8 @@ extern void chroot_fs_refs(struct path *, struct path *); | |||
80 | /* | 83 | /* |
81 | * file_table.c | 84 | * file_table.c |
82 | */ | 85 | */ |
86 | extern void file_sb_list_add(struct file *f, struct super_block *sb); | ||
87 | extern void file_sb_list_del(struct file *f); | ||
83 | extern void mark_files_ro(struct super_block *); | 88 | extern void mark_files_ro(struct super_block *); |
84 | extern struct file *get_empty_filp(void); | 89 | extern struct file *get_empty_filp(void); |
85 | 90 | ||
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c index b0435dd0654..05a38b9c4c0 100644 --- a/fs/jbd/checkpoint.c +++ b/fs/jbd/checkpoint.c | |||
@@ -254,7 +254,9 @@ __flush_batch(journal_t *journal, struct buffer_head **bhs, int *batch_count) | |||
254 | { | 254 | { |
255 | int i; | 255 | int i; |
256 | 256 | ||
257 | ll_rw_block(SWRITE, *batch_count, bhs); | 257 | for (i = 0; i < *batch_count; i++) |
258 | write_dirty_buffer(bhs[i], WRITE); | ||
259 | |||
258 | for (i = 0; i < *batch_count; i++) { | 260 | for (i = 0; i < *batch_count; i++) { |
259 | struct buffer_head *bh = bhs[i]; | 261 | struct buffer_head *bh = bhs[i]; |
260 | clear_buffer_jwrite(bh); | 262 | clear_buffer_jwrite(bh); |
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c index 28a9ddaa0c4..95d8c11c929 100644 --- a/fs/jbd/commit.c +++ b/fs/jbd/commit.c | |||
@@ -119,7 +119,6 @@ static int journal_write_commit_record(journal_t *journal, | |||
119 | struct buffer_head *bh; | 119 | struct buffer_head *bh; |
120 | journal_header_t *header; | 120 | journal_header_t *header; |
121 | int ret; | 121 | int ret; |
122 | int barrier_done = 0; | ||
123 | 122 | ||
124 | if (is_journal_aborted(journal)) | 123 | if (is_journal_aborted(journal)) |
125 | return 0; | 124 | return 0; |
@@ -137,34 +136,36 @@ static int journal_write_commit_record(journal_t *journal, | |||
137 | 136 | ||
138 | JBUFFER_TRACE(descriptor, "write commit block"); | 137 | JBUFFER_TRACE(descriptor, "write commit block"); |
139 | set_buffer_dirty(bh); | 138 | set_buffer_dirty(bh); |
139 | |||
140 | if (journal->j_flags & JFS_BARRIER) { | 140 | if (journal->j_flags & JFS_BARRIER) { |
141 | set_buffer_ordered(bh); | 141 | ret = __sync_dirty_buffer(bh, WRITE_SYNC | WRITE_BARRIER); |
142 | barrier_done = 1; | ||
143 | } | ||
144 | ret = sync_dirty_buffer(bh); | ||
145 | if (barrier_done) | ||
146 | clear_buffer_ordered(bh); | ||
147 | /* is it possible for another commit to fail at roughly | ||
148 | * the same time as this one? If so, we don't want to | ||
149 | * trust the barrier flag in the super, but instead want | ||
150 | * to remember if we sent a barrier request | ||
151 | */ | ||
152 | if (ret == -EOPNOTSUPP && barrier_done) { | ||
153 | char b[BDEVNAME_SIZE]; | ||
154 | 142 | ||
155 | printk(KERN_WARNING | 143 | /* |
156 | "JBD: barrier-based sync failed on %s - " | 144 | * Is it possible for another commit to fail at roughly |
157 | "disabling barriers\n", | 145 | * the same time as this one? If so, we don't want to |
158 | bdevname(journal->j_dev, b)); | 146 | * trust the barrier flag in the super, but instead want |
159 | spin_lock(&journal->j_state_lock); | 147 | * to remember if we sent a barrier request |
160 | journal->j_flags &= ~JFS_BARRIER; | 148 | */ |
161 | spin_unlock(&journal->j_state_lock); | 149 | if (ret == -EOPNOTSUPP) { |
150 | char b[BDEVNAME_SIZE]; | ||
162 | 151 | ||
163 | /* And try again, without the barrier */ | 152 | printk(KERN_WARNING |
164 | set_buffer_uptodate(bh); | 153 | "JBD: barrier-based sync failed on %s - " |
165 | set_buffer_dirty(bh); | 154 | "disabling barriers\n", |
155 | bdevname(journal->j_dev, b)); | ||
156 | spin_lock(&journal->j_state_lock); | ||
157 | journal->j_flags &= ~JFS_BARRIER; | ||
158 | spin_unlock(&journal->j_state_lock); | ||
159 | |||
160 | /* And try again, without the barrier */ | ||
161 | set_buffer_uptodate(bh); | ||
162 | set_buffer_dirty(bh); | ||
163 | ret = sync_dirty_buffer(bh); | ||
164 | } | ||
165 | } else { | ||
166 | ret = sync_dirty_buffer(bh); | 166 | ret = sync_dirty_buffer(bh); |
167 | } | 167 | } |
168 | |||
168 | put_bh(bh); /* One for getblk() */ | 169 | put_bh(bh); /* One for getblk() */ |
169 | journal_put_journal_head(descriptor); | 170 | journal_put_journal_head(descriptor); |
170 | 171 | ||
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index f19ce94693d..2c4b1f109da 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c | |||
@@ -1024,7 +1024,7 @@ void journal_update_superblock(journal_t *journal, int wait) | |||
1024 | if (wait) | 1024 | if (wait) |
1025 | sync_dirty_buffer(bh); | 1025 | sync_dirty_buffer(bh); |
1026 | else | 1026 | else |
1027 | ll_rw_block(SWRITE, 1, &bh); | 1027 | write_dirty_buffer(bh, WRITE); |
1028 | 1028 | ||
1029 | out: | 1029 | out: |
1030 | /* If we have just flushed the log (by marking s_start==0), then | 1030 | /* If we have just flushed the log (by marking s_start==0), then |
diff --git a/fs/jbd/revoke.c b/fs/jbd/revoke.c index ad717328343..d29018307e2 100644 --- a/fs/jbd/revoke.c +++ b/fs/jbd/revoke.c | |||
@@ -617,7 +617,7 @@ static void flush_descriptor(journal_t *journal, | |||
617 | set_buffer_jwrite(bh); | 617 | set_buffer_jwrite(bh); |
618 | BUFFER_TRACE(bh, "write"); | 618 | BUFFER_TRACE(bh, "write"); |
619 | set_buffer_dirty(bh); | 619 | set_buffer_dirty(bh); |
620 | ll_rw_block((write_op == WRITE) ? SWRITE : SWRITE_SYNC_PLUG, 1, &bh); | 620 | write_dirty_buffer(bh, write_op); |
621 | } | 621 | } |
622 | #endif | 622 | #endif |
623 | 623 | ||
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index 1c23a0f4e8a..5247e7ffdcb 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c | |||
@@ -255,7 +255,9 @@ __flush_batch(journal_t *journal, int *batch_count) | |||
255 | { | 255 | { |
256 | int i; | 256 | int i; |
257 | 257 | ||
258 | ll_rw_block(SWRITE, *batch_count, journal->j_chkpt_bhs); | 258 | for (i = 0; i < *batch_count; i++) |
259 | write_dirty_buffer(journal->j_chkpt_bhs[i], WRITE); | ||
260 | |||
259 | for (i = 0; i < *batch_count; i++) { | 261 | for (i = 0; i < *batch_count; i++) { |
260 | struct buffer_head *bh = journal->j_chkpt_bhs[i]; | 262 | struct buffer_head *bh = journal->j_chkpt_bhs[i]; |
261 | clear_buffer_jwrite(bh); | 263 | clear_buffer_jwrite(bh); |
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index f52e5e8049f..7c068c189d8 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -101,7 +101,6 @@ static int journal_submit_commit_record(journal_t *journal, | |||
101 | struct commit_header *tmp; | 101 | struct commit_header *tmp; |
102 | struct buffer_head *bh; | 102 | struct buffer_head *bh; |
103 | int ret; | 103 | int ret; |
104 | int barrier_done = 0; | ||
105 | struct timespec now = current_kernel_time(); | 104 | struct timespec now = current_kernel_time(); |
106 | 105 | ||
107 | if (is_journal_aborted(journal)) | 106 | if (is_journal_aborted(journal)) |
@@ -136,30 +135,22 @@ static int journal_submit_commit_record(journal_t *journal, | |||
136 | if (journal->j_flags & JBD2_BARRIER && | 135 | if (journal->j_flags & JBD2_BARRIER && |
137 | !JBD2_HAS_INCOMPAT_FEATURE(journal, | 136 | !JBD2_HAS_INCOMPAT_FEATURE(journal, |
138 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { | 137 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { |
139 | set_buffer_ordered(bh); | 138 | ret = submit_bh(WRITE_SYNC_PLUG | WRITE_BARRIER, bh); |
140 | barrier_done = 1; | 139 | if (ret == -EOPNOTSUPP) { |
141 | } | 140 | printk(KERN_WARNING |
142 | ret = submit_bh(WRITE_SYNC_PLUG, bh); | 141 | "JBD2: Disabling barriers on %s, " |
143 | if (barrier_done) | 142 | "not supported by device\n", journal->j_devname); |
144 | clear_buffer_ordered(bh); | 143 | write_lock(&journal->j_state_lock); |
145 | 144 | journal->j_flags &= ~JBD2_BARRIER; | |
146 | /* is it possible for another commit to fail at roughly | 145 | write_unlock(&journal->j_state_lock); |
147 | * the same time as this one? If so, we don't want to | ||
148 | * trust the barrier flag in the super, but instead want | ||
149 | * to remember if we sent a barrier request | ||
150 | */ | ||
151 | if (ret == -EOPNOTSUPP && barrier_done) { | ||
152 | printk(KERN_WARNING | ||
153 | "JBD2: Disabling barriers on %s, " | ||
154 | "not supported by device\n", journal->j_devname); | ||
155 | write_lock(&journal->j_state_lock); | ||
156 | journal->j_flags &= ~JBD2_BARRIER; | ||
157 | write_unlock(&journal->j_state_lock); | ||
158 | 146 | ||
159 | /* And try again, without the barrier */ | 147 | /* And try again, without the barrier */ |
160 | lock_buffer(bh); | 148 | lock_buffer(bh); |
161 | set_buffer_uptodate(bh); | 149 | set_buffer_uptodate(bh); |
162 | clear_buffer_dirty(bh); | 150 | clear_buffer_dirty(bh); |
151 | ret = submit_bh(WRITE_SYNC_PLUG, bh); | ||
152 | } | ||
153 | } else { | ||
163 | ret = submit_bh(WRITE_SYNC_PLUG, bh); | 154 | ret = submit_bh(WRITE_SYNC_PLUG, bh); |
164 | } | 155 | } |
165 | *cbh = bh; | 156 | *cbh = bh; |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index ad5866aaf0f..0e8014ea6b9 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -1124,7 +1124,7 @@ void jbd2_journal_update_superblock(journal_t *journal, int wait) | |||
1124 | set_buffer_uptodate(bh); | 1124 | set_buffer_uptodate(bh); |
1125 | } | 1125 | } |
1126 | } else | 1126 | } else |
1127 | ll_rw_block(SWRITE, 1, &bh); | 1127 | write_dirty_buffer(bh, WRITE); |
1128 | 1128 | ||
1129 | out: | 1129 | out: |
1130 | /* If we have just flushed the log (by marking s_start==0), then | 1130 | /* If we have just flushed the log (by marking s_start==0), then |
diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c index a360b06af2e..9ad321fd63f 100644 --- a/fs/jbd2/revoke.c +++ b/fs/jbd2/revoke.c | |||
@@ -625,7 +625,7 @@ static void flush_descriptor(journal_t *journal, | |||
625 | set_buffer_jwrite(bh); | 625 | set_buffer_jwrite(bh); |
626 | BUFFER_TRACE(bh, "write"); | 626 | BUFFER_TRACE(bh, "write"); |
627 | set_buffer_dirty(bh); | 627 | set_buffer_dirty(bh); |
628 | ll_rw_block((write_op == WRITE) ? SWRITE : SWRITE_SYNC_PLUG, 1, &bh); | 628 | write_dirty_buffer(bh, write_op); |
629 | } | 629 | } |
630 | #endif | 630 | #endif |
631 | 631 | ||
diff --git a/fs/mbcache.c b/fs/mbcache.c index cf4e6cdfd15..93444747237 100644 --- a/fs/mbcache.c +++ b/fs/mbcache.c | |||
@@ -80,6 +80,7 @@ struct mb_cache { | |||
80 | struct list_head c_cache_list; | 80 | struct list_head c_cache_list; |
81 | const char *c_name; | 81 | const char *c_name; |
82 | atomic_t c_entry_count; | 82 | atomic_t c_entry_count; |
83 | int c_max_entries; | ||
83 | int c_bucket_bits; | 84 | int c_bucket_bits; |
84 | struct kmem_cache *c_entry_cache; | 85 | struct kmem_cache *c_entry_cache; |
85 | struct list_head *c_block_hash; | 86 | struct list_head *c_block_hash; |
@@ -243,6 +244,12 @@ mb_cache_create(const char *name, int bucket_bits) | |||
243 | if (!cache->c_entry_cache) | 244 | if (!cache->c_entry_cache) |
244 | goto fail2; | 245 | goto fail2; |
245 | 246 | ||
247 | /* | ||
248 | * Set an upper limit on the number of cache entries so that the hash | ||
249 | * chains won't grow too long. | ||
250 | */ | ||
251 | cache->c_max_entries = bucket_count << 4; | ||
252 | |||
246 | spin_lock(&mb_cache_spinlock); | 253 | spin_lock(&mb_cache_spinlock); |
247 | list_add(&cache->c_cache_list, &mb_cache_list); | 254 | list_add(&cache->c_cache_list, &mb_cache_list); |
248 | spin_unlock(&mb_cache_spinlock); | 255 | spin_unlock(&mb_cache_spinlock); |
@@ -333,7 +340,6 @@ mb_cache_destroy(struct mb_cache *cache) | |||
333 | kfree(cache); | 340 | kfree(cache); |
334 | } | 341 | } |
335 | 342 | ||
336 | |||
337 | /* | 343 | /* |
338 | * mb_cache_entry_alloc() | 344 | * mb_cache_entry_alloc() |
339 | * | 345 | * |
@@ -345,17 +351,29 @@ mb_cache_destroy(struct mb_cache *cache) | |||
345 | struct mb_cache_entry * | 351 | struct mb_cache_entry * |
346 | mb_cache_entry_alloc(struct mb_cache *cache, gfp_t gfp_flags) | 352 | mb_cache_entry_alloc(struct mb_cache *cache, gfp_t gfp_flags) |
347 | { | 353 | { |
348 | struct mb_cache_entry *ce; | 354 | struct mb_cache_entry *ce = NULL; |
349 | 355 | ||
350 | ce = kmem_cache_alloc(cache->c_entry_cache, gfp_flags); | 356 | if (atomic_read(&cache->c_entry_count) >= cache->c_max_entries) { |
351 | if (ce) { | 357 | spin_lock(&mb_cache_spinlock); |
358 | if (!list_empty(&mb_cache_lru_list)) { | ||
359 | ce = list_entry(mb_cache_lru_list.next, | ||
360 | struct mb_cache_entry, e_lru_list); | ||
361 | list_del_init(&ce->e_lru_list); | ||
362 | __mb_cache_entry_unhash(ce); | ||
363 | } | ||
364 | spin_unlock(&mb_cache_spinlock); | ||
365 | } | ||
366 | if (!ce) { | ||
367 | ce = kmem_cache_alloc(cache->c_entry_cache, gfp_flags); | ||
368 | if (!ce) | ||
369 | return NULL; | ||
352 | atomic_inc(&cache->c_entry_count); | 370 | atomic_inc(&cache->c_entry_count); |
353 | INIT_LIST_HEAD(&ce->e_lru_list); | 371 | INIT_LIST_HEAD(&ce->e_lru_list); |
354 | INIT_LIST_HEAD(&ce->e_block_list); | 372 | INIT_LIST_HEAD(&ce->e_block_list); |
355 | ce->e_cache = cache; | 373 | ce->e_cache = cache; |
356 | ce->e_used = 1 + MB_CACHE_WRITER; | ||
357 | ce->e_queued = 0; | 374 | ce->e_queued = 0; |
358 | } | 375 | } |
376 | ce->e_used = 1 + MB_CACHE_WRITER; | ||
359 | return ce; | 377 | return ce; |
360 | } | 378 | } |
361 | 379 | ||
diff --git a/fs/namei.c b/fs/namei.c index 17ea76bf2fb..24896e83356 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -595,15 +595,16 @@ int follow_up(struct path *path) | |||
595 | { | 595 | { |
596 | struct vfsmount *parent; | 596 | struct vfsmount *parent; |
597 | struct dentry *mountpoint; | 597 | struct dentry *mountpoint; |
598 | spin_lock(&vfsmount_lock); | 598 | |
599 | br_read_lock(vfsmount_lock); | ||
599 | parent = path->mnt->mnt_parent; | 600 | parent = path->mnt->mnt_parent; |
600 | if (parent == path->mnt) { | 601 | if (parent == path->mnt) { |
601 | spin_unlock(&vfsmount_lock); | 602 | br_read_unlock(vfsmount_lock); |
602 | return 0; | 603 | return 0; |
603 | } | 604 | } |
604 | mntget(parent); | 605 | mntget(parent); |
605 | mountpoint = dget(path->mnt->mnt_mountpoint); | 606 | mountpoint = dget(path->mnt->mnt_mountpoint); |
606 | spin_unlock(&vfsmount_lock); | 607 | br_read_unlock(vfsmount_lock); |
607 | dput(path->dentry); | 608 | dput(path->dentry); |
608 | path->dentry = mountpoint; | 609 | path->dentry = mountpoint; |
609 | mntput(path->mnt); | 610 | mntput(path->mnt); |
@@ -686,6 +687,35 @@ static __always_inline void follow_dotdot(struct nameidata *nd) | |||
686 | } | 687 | } |
687 | 688 | ||
688 | /* | 689 | /* |
690 | * Allocate a dentry with name and parent, and perform a parent | ||
691 | * directory ->lookup on it. Returns the new dentry, or ERR_PTR | ||
692 | * on error. parent->d_inode->i_mutex must be held. d_lookup must | ||
693 | * have verified that no child exists while under i_mutex. | ||
694 | */ | ||
695 | static struct dentry *d_alloc_and_lookup(struct dentry *parent, | ||
696 | struct qstr *name, struct nameidata *nd) | ||
697 | { | ||
698 | struct inode *inode = parent->d_inode; | ||
699 | struct dentry *dentry; | ||
700 | struct dentry *old; | ||
701 | |||
702 | /* Don't create child dentry for a dead directory. */ | ||
703 | if (unlikely(IS_DEADDIR(inode))) | ||
704 | return ERR_PTR(-ENOENT); | ||
705 | |||
706 | dentry = d_alloc(parent, name); | ||
707 | if (unlikely(!dentry)) | ||
708 | return ERR_PTR(-ENOMEM); | ||
709 | |||
710 | old = inode->i_op->lookup(inode, dentry, nd); | ||
711 | if (unlikely(old)) { | ||
712 | dput(dentry); | ||
713 | dentry = old; | ||
714 | } | ||
715 | return dentry; | ||
716 | } | ||
717 | |||
718 | /* | ||
689 | * It's more convoluted than I'd like it to be, but... it's still fairly | 719 | * It's more convoluted than I'd like it to be, but... it's still fairly |
690 | * small and for now I'd prefer to have fast path as straight as possible. | 720 | * small and for now I'd prefer to have fast path as straight as possible. |
691 | * It _is_ time-critical. | 721 | * It _is_ time-critical. |
@@ -706,9 +736,15 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, | |||
706 | return err; | 736 | return err; |
707 | } | 737 | } |
708 | 738 | ||
739 | /* | ||
740 | * Rename seqlock is not required here because in the off chance | ||
741 | * of a false negative due to a concurrent rename, we're going to | ||
742 | * do the non-racy lookup, below. | ||
743 | */ | ||
709 | dentry = __d_lookup(nd->path.dentry, name); | 744 | dentry = __d_lookup(nd->path.dentry, name); |
710 | if (!dentry) | 745 | if (!dentry) |
711 | goto need_lookup; | 746 | goto need_lookup; |
747 | found: | ||
712 | if (dentry->d_op && dentry->d_op->d_revalidate) | 748 | if (dentry->d_op && dentry->d_op->d_revalidate) |
713 | goto need_revalidate; | 749 | goto need_revalidate; |
714 | done: | 750 | done: |
@@ -724,56 +760,28 @@ need_lookup: | |||
724 | mutex_lock(&dir->i_mutex); | 760 | mutex_lock(&dir->i_mutex); |
725 | /* | 761 | /* |
726 | * First re-do the cached lookup just in case it was created | 762 | * First re-do the cached lookup just in case it was created |
727 | * while we waited for the directory semaphore.. | 763 | * while we waited for the directory semaphore, or the first |
764 | * lookup failed due to an unrelated rename. | ||
728 | * | 765 | * |
729 | * FIXME! This could use version numbering or similar to | 766 | * This could use version numbering or similar to avoid unnecessary |
730 | * avoid unnecessary cache lookups. | 767 | * cache lookups, but then we'd have to do the first lookup in the |
731 | * | 768 | * non-racy way. However in the common case here, everything should |
732 | * The "dcache_lock" is purely to protect the RCU list walker | 769 | * be hot in cache, so would it be a big win? |
733 | * from concurrent renames at this point (we mustn't get false | ||
734 | * negatives from the RCU list walk here, unlike the optimistic | ||
735 | * fast walk). | ||
736 | * | ||
737 | * so doing d_lookup() (with seqlock), instead of lockfree __d_lookup | ||
738 | */ | 770 | */ |
739 | dentry = d_lookup(parent, name); | 771 | dentry = d_lookup(parent, name); |
740 | if (!dentry) { | 772 | if (likely(!dentry)) { |
741 | struct dentry *new; | 773 | dentry = d_alloc_and_lookup(parent, name, nd); |
742 | |||
743 | /* Don't create child dentry for a dead directory. */ | ||
744 | dentry = ERR_PTR(-ENOENT); | ||
745 | if (IS_DEADDIR(dir)) | ||
746 | goto out_unlock; | ||
747 | |||
748 | new = d_alloc(parent, name); | ||
749 | dentry = ERR_PTR(-ENOMEM); | ||
750 | if (new) { | ||
751 | dentry = dir->i_op->lookup(dir, new, nd); | ||
752 | if (dentry) | ||
753 | dput(new); | ||
754 | else | ||
755 | dentry = new; | ||
756 | } | ||
757 | out_unlock: | ||
758 | mutex_unlock(&dir->i_mutex); | 774 | mutex_unlock(&dir->i_mutex); |
759 | if (IS_ERR(dentry)) | 775 | if (IS_ERR(dentry)) |
760 | goto fail; | 776 | goto fail; |
761 | goto done; | 777 | goto done; |
762 | } | 778 | } |
763 | |||
764 | /* | 779 | /* |
765 | * Uhhuh! Nasty case: the cache was re-populated while | 780 | * Uhhuh! Nasty case: the cache was re-populated while |
766 | * we waited on the semaphore. Need to revalidate. | 781 | * we waited on the semaphore. Need to revalidate. |
767 | */ | 782 | */ |
768 | mutex_unlock(&dir->i_mutex); | 783 | mutex_unlock(&dir->i_mutex); |
769 | if (dentry->d_op && dentry->d_op->d_revalidate) { | 784 | goto found; |
770 | dentry = do_revalidate(dentry, nd); | ||
771 | if (!dentry) | ||
772 | dentry = ERR_PTR(-ENOENT); | ||
773 | } | ||
774 | if (IS_ERR(dentry)) | ||
775 | goto fail; | ||
776 | goto done; | ||
777 | 785 | ||
778 | need_revalidate: | 786 | need_revalidate: |
779 | dentry = do_revalidate(dentry, nd); | 787 | dentry = do_revalidate(dentry, nd); |
@@ -1130,35 +1138,18 @@ static struct dentry *__lookup_hash(struct qstr *name, | |||
1130 | goto out; | 1138 | goto out; |
1131 | } | 1139 | } |
1132 | 1140 | ||
1133 | dentry = __d_lookup(base, name); | 1141 | /* |
1134 | 1142 | * Don't bother with __d_lookup: callers are for creat as | |
1135 | /* lockess __d_lookup may fail due to concurrent d_move() | 1143 | * well as unlink, so a lot of the time it would cost |
1136 | * in some unrelated directory, so try with d_lookup | 1144 | * a double lookup. |
1137 | */ | 1145 | */ |
1138 | if (!dentry) | 1146 | dentry = d_lookup(base, name); |
1139 | dentry = d_lookup(base, name); | ||
1140 | 1147 | ||
1141 | if (dentry && dentry->d_op && dentry->d_op->d_revalidate) | 1148 | if (dentry && dentry->d_op && dentry->d_op->d_revalidate) |
1142 | dentry = do_revalidate(dentry, nd); | 1149 | dentry = do_revalidate(dentry, nd); |
1143 | 1150 | ||
1144 | if (!dentry) { | 1151 | if (!dentry) |
1145 | struct dentry *new; | 1152 | dentry = d_alloc_and_lookup(base, name, nd); |
1146 | |||
1147 | /* Don't create child dentry for a dead directory. */ | ||
1148 | dentry = ERR_PTR(-ENOENT); | ||
1149 | if (IS_DEADDIR(inode)) | ||
1150 | goto out; | ||
1151 | |||
1152 | new = d_alloc(base, name); | ||
1153 | dentry = ERR_PTR(-ENOMEM); | ||
1154 | if (!new) | ||
1155 | goto out; | ||
1156 | dentry = inode->i_op->lookup(inode, new, nd); | ||
1157 | if (!dentry) | ||
1158 | dentry = new; | ||
1159 | else | ||
1160 | dput(new); | ||
1161 | } | ||
1162 | out: | 1153 | out: |
1163 | return dentry; | 1154 | return dentry; |
1164 | } | 1155 | } |
diff --git a/fs/namespace.c b/fs/namespace.c index 2e10cb19c5b..a72eaabfe8f 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -11,6 +11,8 @@ | |||
11 | #include <linux/syscalls.h> | 11 | #include <linux/syscalls.h> |
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
14 | #include <linux/spinlock.h> | ||
15 | #include <linux/percpu.h> | ||
14 | #include <linux/smp_lock.h> | 16 | #include <linux/smp_lock.h> |
15 | #include <linux/init.h> | 17 | #include <linux/init.h> |
16 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
@@ -38,12 +40,10 @@ | |||
38 | #define HASH_SHIFT ilog2(PAGE_SIZE / sizeof(struct list_head)) | 40 | #define HASH_SHIFT ilog2(PAGE_SIZE / sizeof(struct list_head)) |
39 | #define HASH_SIZE (1UL << HASH_SHIFT) | 41 | #define HASH_SIZE (1UL << HASH_SHIFT) |
40 | 42 | ||
41 | /* spinlock for vfsmount related operations, inplace of dcache_lock */ | ||
42 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock); | ||
43 | |||
44 | static int event; | 43 | static int event; |
45 | static DEFINE_IDA(mnt_id_ida); | 44 | static DEFINE_IDA(mnt_id_ida); |
46 | static DEFINE_IDA(mnt_group_ida); | 45 | static DEFINE_IDA(mnt_group_ida); |
46 | static DEFINE_SPINLOCK(mnt_id_lock); | ||
47 | static int mnt_id_start = 0; | 47 | static int mnt_id_start = 0; |
48 | static int mnt_group_start = 1; | 48 | static int mnt_group_start = 1; |
49 | 49 | ||
@@ -55,6 +55,16 @@ static struct rw_semaphore namespace_sem; | |||
55 | struct kobject *fs_kobj; | 55 | struct kobject *fs_kobj; |
56 | EXPORT_SYMBOL_GPL(fs_kobj); | 56 | EXPORT_SYMBOL_GPL(fs_kobj); |
57 | 57 | ||
58 | /* | ||
59 | * vfsmount lock may be taken for read to prevent changes to the | ||
60 | * vfsmount hash, ie. during mountpoint lookups or walking back | ||
61 | * up the tree. | ||
62 | * | ||
63 | * It should be taken for write in all cases where the vfsmount | ||
64 | * tree or hash is modified or when a vfsmount structure is modified. | ||
65 | */ | ||
66 | DEFINE_BRLOCK(vfsmount_lock); | ||
67 | |||
58 | static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry) | 68 | static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry) |
59 | { | 69 | { |
60 | unsigned long tmp = ((unsigned long)mnt / L1_CACHE_BYTES); | 70 | unsigned long tmp = ((unsigned long)mnt / L1_CACHE_BYTES); |
@@ -65,18 +75,21 @@ static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry) | |||
65 | 75 | ||
66 | #define MNT_WRITER_UNDERFLOW_LIMIT -(1<<16) | 76 | #define MNT_WRITER_UNDERFLOW_LIMIT -(1<<16) |
67 | 77 | ||
68 | /* allocation is serialized by namespace_sem */ | 78 | /* |
79 | * allocation is serialized by namespace_sem, but we need the spinlock to | ||
80 | * serialize with freeing. | ||
81 | */ | ||
69 | static int mnt_alloc_id(struct vfsmount *mnt) | 82 | static int mnt_alloc_id(struct vfsmount *mnt) |
70 | { | 83 | { |
71 | int res; | 84 | int res; |
72 | 85 | ||
73 | retry: | 86 | retry: |
74 | ida_pre_get(&mnt_id_ida, GFP_KERNEL); | 87 | ida_pre_get(&mnt_id_ida, GFP_KERNEL); |
75 | spin_lock(&vfsmount_lock); | 88 | spin_lock(&mnt_id_lock); |
76 | res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id); | 89 | res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id); |
77 | if (!res) | 90 | if (!res) |
78 | mnt_id_start = mnt->mnt_id + 1; | 91 | mnt_id_start = mnt->mnt_id + 1; |
79 | spin_unlock(&vfsmount_lock); | 92 | spin_unlock(&mnt_id_lock); |
80 | if (res == -EAGAIN) | 93 | if (res == -EAGAIN) |
81 | goto retry; | 94 | goto retry; |
82 | 95 | ||
@@ -86,11 +99,11 @@ retry: | |||
86 | static void mnt_free_id(struct vfsmount *mnt) | 99 | static void mnt_free_id(struct vfsmount *mnt) |
87 | { | 100 | { |
88 | int id = mnt->mnt_id; | 101 | int id = mnt->mnt_id; |
89 | spin_lock(&vfsmount_lock); | 102 | spin_lock(&mnt_id_lock); |
90 | ida_remove(&mnt_id_ida, id); | 103 | ida_remove(&mnt_id_ida, id); |
91 | if (mnt_id_start > id) | 104 | if (mnt_id_start > id) |
92 | mnt_id_start = id; | 105 | mnt_id_start = id; |
93 | spin_unlock(&vfsmount_lock); | 106 | spin_unlock(&mnt_id_lock); |
94 | } | 107 | } |
95 | 108 | ||
96 | /* | 109 | /* |
@@ -348,7 +361,7 @@ static int mnt_make_readonly(struct vfsmount *mnt) | |||
348 | { | 361 | { |
349 | int ret = 0; | 362 | int ret = 0; |
350 | 363 | ||
351 | spin_lock(&vfsmount_lock); | 364 | br_write_lock(vfsmount_lock); |
352 | mnt->mnt_flags |= MNT_WRITE_HOLD; | 365 | mnt->mnt_flags |= MNT_WRITE_HOLD; |
353 | /* | 366 | /* |
354 | * After storing MNT_WRITE_HOLD, we'll read the counters. This store | 367 | * After storing MNT_WRITE_HOLD, we'll read the counters. This store |
@@ -382,15 +395,15 @@ static int mnt_make_readonly(struct vfsmount *mnt) | |||
382 | */ | 395 | */ |
383 | smp_wmb(); | 396 | smp_wmb(); |
384 | mnt->mnt_flags &= ~MNT_WRITE_HOLD; | 397 | mnt->mnt_flags &= ~MNT_WRITE_HOLD; |
385 | spin_unlock(&vfsmount_lock); | 398 | br_write_unlock(vfsmount_lock); |
386 | return ret; | 399 | return ret; |
387 | } | 400 | } |
388 | 401 | ||
389 | static void __mnt_unmake_readonly(struct vfsmount *mnt) | 402 | static void __mnt_unmake_readonly(struct vfsmount *mnt) |
390 | { | 403 | { |
391 | spin_lock(&vfsmount_lock); | 404 | br_write_lock(vfsmount_lock); |
392 | mnt->mnt_flags &= ~MNT_READONLY; | 405 | mnt->mnt_flags &= ~MNT_READONLY; |
393 | spin_unlock(&vfsmount_lock); | 406 | br_write_unlock(vfsmount_lock); |
394 | } | 407 | } |
395 | 408 | ||
396 | void simple_set_mnt(struct vfsmount *mnt, struct super_block *sb) | 409 | void simple_set_mnt(struct vfsmount *mnt, struct super_block *sb) |
@@ -414,6 +427,7 @@ void free_vfsmnt(struct vfsmount *mnt) | |||
414 | /* | 427 | /* |
415 | * find the first or last mount at @dentry on vfsmount @mnt depending on | 428 | * find the first or last mount at @dentry on vfsmount @mnt depending on |
416 | * @dir. If @dir is set return the first mount else return the last mount. | 429 | * @dir. If @dir is set return the first mount else return the last mount. |
430 | * vfsmount_lock must be held for read or write. | ||
417 | */ | 431 | */ |
418 | struct vfsmount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry, | 432 | struct vfsmount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry, |
419 | int dir) | 433 | int dir) |
@@ -443,10 +457,11 @@ struct vfsmount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry, | |||
443 | struct vfsmount *lookup_mnt(struct path *path) | 457 | struct vfsmount *lookup_mnt(struct path *path) |
444 | { | 458 | { |
445 | struct vfsmount *child_mnt; | 459 | struct vfsmount *child_mnt; |
446 | spin_lock(&vfsmount_lock); | 460 | |
461 | br_read_lock(vfsmount_lock); | ||
447 | if ((child_mnt = __lookup_mnt(path->mnt, path->dentry, 1))) | 462 | if ((child_mnt = __lookup_mnt(path->mnt, path->dentry, 1))) |
448 | mntget(child_mnt); | 463 | mntget(child_mnt); |
449 | spin_unlock(&vfsmount_lock); | 464 | br_read_unlock(vfsmount_lock); |
450 | return child_mnt; | 465 | return child_mnt; |
451 | } | 466 | } |
452 | 467 | ||
@@ -455,6 +470,9 @@ static inline int check_mnt(struct vfsmount *mnt) | |||
455 | return mnt->mnt_ns == current->nsproxy->mnt_ns; | 470 | return mnt->mnt_ns == current->nsproxy->mnt_ns; |
456 | } | 471 | } |
457 | 472 | ||
473 | /* | ||
474 | * vfsmount lock must be held for write | ||
475 | */ | ||
458 | static void touch_mnt_namespace(struct mnt_namespace *ns) | 476 | static void touch_mnt_namespace(struct mnt_namespace *ns) |
459 | { | 477 | { |
460 | if (ns) { | 478 | if (ns) { |
@@ -463,6 +481,9 @@ static void touch_mnt_namespace(struct mnt_namespace *ns) | |||
463 | } | 481 | } |
464 | } | 482 | } |
465 | 483 | ||
484 | /* | ||
485 | * vfsmount lock must be held for write | ||
486 | */ | ||
466 | static void __touch_mnt_namespace(struct mnt_namespace *ns) | 487 | static void __touch_mnt_namespace(struct mnt_namespace *ns) |
467 | { | 488 | { |
468 | if (ns && ns->event != event) { | 489 | if (ns && ns->event != event) { |
@@ -471,6 +492,9 @@ static void __touch_mnt_namespace(struct mnt_namespace *ns) | |||
471 | } | 492 | } |
472 | } | 493 | } |
473 | 494 | ||
495 | /* | ||
496 | * vfsmount lock must be held for write | ||
497 | */ | ||
474 | static void detach_mnt(struct vfsmount *mnt, struct path *old_path) | 498 | static void detach_mnt(struct vfsmount *mnt, struct path *old_path) |
475 | { | 499 | { |
476 | old_path->dentry = mnt->mnt_mountpoint; | 500 | old_path->dentry = mnt->mnt_mountpoint; |
@@ -482,6 +506,9 @@ static void detach_mnt(struct vfsmount *mnt, struct path *old_path) | |||
482 | old_path->dentry->d_mounted--; | 506 | old_path->dentry->d_mounted--; |
483 | } | 507 | } |
484 | 508 | ||
509 | /* | ||
510 | * vfsmount lock must be held for write | ||
511 | */ | ||
485 | void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry, | 512 | void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry, |
486 | struct vfsmount *child_mnt) | 513 | struct vfsmount *child_mnt) |
487 | { | 514 | { |
@@ -490,6 +517,9 @@ void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry, | |||
490 | dentry->d_mounted++; | 517 | dentry->d_mounted++; |
491 | } | 518 | } |
492 | 519 | ||
520 | /* | ||
521 | * vfsmount lock must be held for write | ||
522 | */ | ||
493 | static void attach_mnt(struct vfsmount *mnt, struct path *path) | 523 | static void attach_mnt(struct vfsmount *mnt, struct path *path) |
494 | { | 524 | { |
495 | mnt_set_mountpoint(path->mnt, path->dentry, mnt); | 525 | mnt_set_mountpoint(path->mnt, path->dentry, mnt); |
@@ -499,7 +529,7 @@ static void attach_mnt(struct vfsmount *mnt, struct path *path) | |||
499 | } | 529 | } |
500 | 530 | ||
501 | /* | 531 | /* |
502 | * the caller must hold vfsmount_lock | 532 | * vfsmount lock must be held for write |
503 | */ | 533 | */ |
504 | static void commit_tree(struct vfsmount *mnt) | 534 | static void commit_tree(struct vfsmount *mnt) |
505 | { | 535 | { |
@@ -623,39 +653,43 @@ static inline void __mntput(struct vfsmount *mnt) | |||
623 | void mntput_no_expire(struct vfsmount *mnt) | 653 | void mntput_no_expire(struct vfsmount *mnt) |
624 | { | 654 | { |
625 | repeat: | 655 | repeat: |
626 | if (atomic_dec_and_lock(&mnt->mnt_count, &vfsmount_lock)) { | 656 | if (atomic_add_unless(&mnt->mnt_count, -1, 1)) |
627 | if (likely(!mnt->mnt_pinned)) { | 657 | return; |
628 | spin_unlock(&vfsmount_lock); | 658 | br_write_lock(vfsmount_lock); |
629 | __mntput(mnt); | 659 | if (!atomic_dec_and_test(&mnt->mnt_count)) { |
630 | return; | 660 | br_write_unlock(vfsmount_lock); |
631 | } | 661 | return; |
632 | atomic_add(mnt->mnt_pinned + 1, &mnt->mnt_count); | ||
633 | mnt->mnt_pinned = 0; | ||
634 | spin_unlock(&vfsmount_lock); | ||
635 | acct_auto_close_mnt(mnt); | ||
636 | goto repeat; | ||
637 | } | 662 | } |
663 | if (likely(!mnt->mnt_pinned)) { | ||
664 | br_write_unlock(vfsmount_lock); | ||
665 | __mntput(mnt); | ||
666 | return; | ||
667 | } | ||
668 | atomic_add(mnt->mnt_pinned + 1, &mnt->mnt_count); | ||
669 | mnt->mnt_pinned = 0; | ||
670 | br_write_unlock(vfsmount_lock); | ||
671 | acct_auto_close_mnt(mnt); | ||
672 | goto repeat; | ||
638 | } | 673 | } |
639 | |||
640 | EXPORT_SYMBOL(mntput_no_expire); | 674 | EXPORT_SYMBOL(mntput_no_expire); |
641 | 675 | ||
642 | void mnt_pin(struct vfsmount *mnt) | 676 | void mnt_pin(struct vfsmount *mnt) |
643 | { | 677 | { |
644 | spin_lock(&vfsmount_lock); | 678 | br_write_lock(vfsmount_lock); |
645 | mnt->mnt_pinned++; | 679 | mnt->mnt_pinned++; |
646 | spin_unlock(&vfsmount_lock); | 680 | br_write_unlock(vfsmount_lock); |
647 | } | 681 | } |
648 | 682 | ||
649 | EXPORT_SYMBOL(mnt_pin); | 683 | EXPORT_SYMBOL(mnt_pin); |
650 | 684 | ||
651 | void mnt_unpin(struct vfsmount *mnt) | 685 | void mnt_unpin(struct vfsmount *mnt) |
652 | { | 686 | { |
653 | spin_lock(&vfsmount_lock); | 687 | br_write_lock(vfsmount_lock); |
654 | if (mnt->mnt_pinned) { | 688 | if (mnt->mnt_pinned) { |
655 | atomic_inc(&mnt->mnt_count); | 689 | atomic_inc(&mnt->mnt_count); |
656 | mnt->mnt_pinned--; | 690 | mnt->mnt_pinned--; |
657 | } | 691 | } |
658 | spin_unlock(&vfsmount_lock); | 692 | br_write_unlock(vfsmount_lock); |
659 | } | 693 | } |
660 | 694 | ||
661 | EXPORT_SYMBOL(mnt_unpin); | 695 | EXPORT_SYMBOL(mnt_unpin); |
@@ -746,12 +780,12 @@ int mnt_had_events(struct proc_mounts *p) | |||
746 | struct mnt_namespace *ns = p->ns; | 780 | struct mnt_namespace *ns = p->ns; |
747 | int res = 0; | 781 | int res = 0; |
748 | 782 | ||
749 | spin_lock(&vfsmount_lock); | 783 | br_read_lock(vfsmount_lock); |
750 | if (p->event != ns->event) { | 784 | if (p->event != ns->event) { |
751 | p->event = ns->event; | 785 | p->event = ns->event; |
752 | res = 1; | 786 | res = 1; |
753 | } | 787 | } |
754 | spin_unlock(&vfsmount_lock); | 788 | br_read_unlock(vfsmount_lock); |
755 | 789 | ||
756 | return res; | 790 | return res; |
757 | } | 791 | } |
@@ -952,12 +986,12 @@ int may_umount_tree(struct vfsmount *mnt) | |||
952 | int minimum_refs = 0; | 986 | int minimum_refs = 0; |
953 | struct vfsmount *p; | 987 | struct vfsmount *p; |
954 | 988 | ||
955 | spin_lock(&vfsmount_lock); | 989 | br_read_lock(vfsmount_lock); |
956 | for (p = mnt; p; p = next_mnt(p, mnt)) { | 990 | for (p = mnt; p; p = next_mnt(p, mnt)) { |
957 | actual_refs += atomic_read(&p->mnt_count); | 991 | actual_refs += atomic_read(&p->mnt_count); |
958 | minimum_refs += 2; | 992 | minimum_refs += 2; |
959 | } | 993 | } |
960 | spin_unlock(&vfsmount_lock); | 994 | br_read_unlock(vfsmount_lock); |
961 | 995 | ||
962 | if (actual_refs > minimum_refs) | 996 | if (actual_refs > minimum_refs) |
963 | return 0; | 997 | return 0; |
@@ -984,10 +1018,10 @@ int may_umount(struct vfsmount *mnt) | |||
984 | { | 1018 | { |
985 | int ret = 1; | 1019 | int ret = 1; |
986 | down_read(&namespace_sem); | 1020 | down_read(&namespace_sem); |
987 | spin_lock(&vfsmount_lock); | 1021 | br_read_lock(vfsmount_lock); |
988 | if (propagate_mount_busy(mnt, 2)) | 1022 | if (propagate_mount_busy(mnt, 2)) |
989 | ret = 0; | 1023 | ret = 0; |
990 | spin_unlock(&vfsmount_lock); | 1024 | br_read_unlock(vfsmount_lock); |
991 | up_read(&namespace_sem); | 1025 | up_read(&namespace_sem); |
992 | return ret; | 1026 | return ret; |
993 | } | 1027 | } |
@@ -1003,13 +1037,14 @@ void release_mounts(struct list_head *head) | |||
1003 | if (mnt->mnt_parent != mnt) { | 1037 | if (mnt->mnt_parent != mnt) { |
1004 | struct dentry *dentry; | 1038 | struct dentry *dentry; |
1005 | struct vfsmount *m; | 1039 | struct vfsmount *m; |
1006 | spin_lock(&vfsmount_lock); | 1040 | |
1041 | br_write_lock(vfsmount_lock); | ||
1007 | dentry = mnt->mnt_mountpoint; | 1042 | dentry = mnt->mnt_mountpoint; |
1008 | m = mnt->mnt_parent; | 1043 | m = mnt->mnt_parent; |
1009 | mnt->mnt_mountpoint = mnt->mnt_root; | 1044 | mnt->mnt_mountpoint = mnt->mnt_root; |
1010 | mnt->mnt_parent = mnt; | 1045 | mnt->mnt_parent = mnt; |
1011 | m->mnt_ghosts--; | 1046 | m->mnt_ghosts--; |
1012 | spin_unlock(&vfsmount_lock); | 1047 | br_write_unlock(vfsmount_lock); |
1013 | dput(dentry); | 1048 | dput(dentry); |
1014 | mntput(m); | 1049 | mntput(m); |
1015 | } | 1050 | } |
@@ -1017,6 +1052,10 @@ void release_mounts(struct list_head *head) | |||
1017 | } | 1052 | } |
1018 | } | 1053 | } |
1019 | 1054 | ||
1055 | /* | ||
1056 | * vfsmount lock must be held for write | ||
1057 | * namespace_sem must be held for write | ||
1058 | */ | ||
1020 | void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill) | 1059 | void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill) |
1021 | { | 1060 | { |
1022 | struct vfsmount *p; | 1061 | struct vfsmount *p; |
@@ -1107,7 +1146,7 @@ static int do_umount(struct vfsmount *mnt, int flags) | |||
1107 | } | 1146 | } |
1108 | 1147 | ||
1109 | down_write(&namespace_sem); | 1148 | down_write(&namespace_sem); |
1110 | spin_lock(&vfsmount_lock); | 1149 | br_write_lock(vfsmount_lock); |
1111 | event++; | 1150 | event++; |
1112 | 1151 | ||
1113 | if (!(flags & MNT_DETACH)) | 1152 | if (!(flags & MNT_DETACH)) |
@@ -1119,7 +1158,7 @@ static int do_umount(struct vfsmount *mnt, int flags) | |||
1119 | umount_tree(mnt, 1, &umount_list); | 1158 | umount_tree(mnt, 1, &umount_list); |
1120 | retval = 0; | 1159 | retval = 0; |
1121 | } | 1160 | } |
1122 | spin_unlock(&vfsmount_lock); | 1161 | br_write_unlock(vfsmount_lock); |
1123 | up_write(&namespace_sem); | 1162 | up_write(&namespace_sem); |
1124 | release_mounts(&umount_list); | 1163 | release_mounts(&umount_list); |
1125 | return retval; | 1164 | return retval; |
@@ -1231,19 +1270,19 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry, | |||
1231 | q = clone_mnt(p, p->mnt_root, flag); | 1270 | q = clone_mnt(p, p->mnt_root, flag); |
1232 | if (!q) | 1271 | if (!q) |
1233 | goto Enomem; | 1272 | goto Enomem; |
1234 | spin_lock(&vfsmount_lock); | 1273 | br_write_lock(vfsmount_lock); |
1235 | list_add_tail(&q->mnt_list, &res->mnt_list); | 1274 | list_add_tail(&q->mnt_list, &res->mnt_list); |
1236 | attach_mnt(q, &path); | 1275 | attach_mnt(q, &path); |
1237 | spin_unlock(&vfsmount_lock); | 1276 | br_write_unlock(vfsmount_lock); |
1238 | } | 1277 | } |
1239 | } | 1278 | } |
1240 | return res; | 1279 | return res; |
1241 | Enomem: | 1280 | Enomem: |
1242 | if (res) { | 1281 | if (res) { |
1243 | LIST_HEAD(umount_list); | 1282 | LIST_HEAD(umount_list); |
1244 | spin_lock(&vfsmount_lock); | 1283 | br_write_lock(vfsmount_lock); |
1245 | umount_tree(res, 0, &umount_list); | 1284 | umount_tree(res, 0, &umount_list); |
1246 | spin_unlock(&vfsmount_lock); | 1285 | br_write_unlock(vfsmount_lock); |
1247 | release_mounts(&umount_list); | 1286 | release_mounts(&umount_list); |
1248 | } | 1287 | } |
1249 | return NULL; | 1288 | return NULL; |
@@ -1262,9 +1301,9 @@ void drop_collected_mounts(struct vfsmount *mnt) | |||
1262 | { | 1301 | { |
1263 | LIST_HEAD(umount_list); | 1302 | LIST_HEAD(umount_list); |
1264 | down_write(&namespace_sem); | 1303 | down_write(&namespace_sem); |
1265 | spin_lock(&vfsmount_lock); | 1304 | br_write_lock(vfsmount_lock); |
1266 | umount_tree(mnt, 0, &umount_list); | 1305 | umount_tree(mnt, 0, &umount_list); |
1267 | spin_unlock(&vfsmount_lock); | 1306 | br_write_unlock(vfsmount_lock); |
1268 | up_write(&namespace_sem); | 1307 | up_write(&namespace_sem); |
1269 | release_mounts(&umount_list); | 1308 | release_mounts(&umount_list); |
1270 | } | 1309 | } |
@@ -1392,7 +1431,7 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt, | |||
1392 | if (err) | 1431 | if (err) |
1393 | goto out_cleanup_ids; | 1432 | goto out_cleanup_ids; |
1394 | 1433 | ||
1395 | spin_lock(&vfsmount_lock); | 1434 | br_write_lock(vfsmount_lock); |
1396 | 1435 | ||
1397 | if (IS_MNT_SHARED(dest_mnt)) { | 1436 | if (IS_MNT_SHARED(dest_mnt)) { |
1398 | for (p = source_mnt; p; p = next_mnt(p, source_mnt)) | 1437 | for (p = source_mnt; p; p = next_mnt(p, source_mnt)) |
@@ -1411,7 +1450,8 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt, | |||
1411 | list_del_init(&child->mnt_hash); | 1450 | list_del_init(&child->mnt_hash); |
1412 | commit_tree(child); | 1451 | commit_tree(child); |
1413 | } | 1452 | } |
1414 | spin_unlock(&vfsmount_lock); | 1453 | br_write_unlock(vfsmount_lock); |
1454 | |||
1415 | return 0; | 1455 | return 0; |
1416 | 1456 | ||
1417 | out_cleanup_ids: | 1457 | out_cleanup_ids: |
@@ -1444,13 +1484,30 @@ out_unlock: | |||
1444 | } | 1484 | } |
1445 | 1485 | ||
1446 | /* | 1486 | /* |
1487 | * Sanity check the flags to change_mnt_propagation. | ||
1488 | */ | ||
1489 | |||
1490 | static int flags_to_propagation_type(int flags) | ||
1491 | { | ||
1492 | int type = flags & ~MS_REC; | ||
1493 | |||
1494 | /* Fail if any non-propagation flags are set */ | ||
1495 | if (type & ~(MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) | ||
1496 | return 0; | ||
1497 | /* Only one propagation flag should be set */ | ||
1498 | if (!is_power_of_2(type)) | ||
1499 | return 0; | ||
1500 | return type; | ||
1501 | } | ||
1502 | |||
1503 | /* | ||
1447 | * recursively change the type of the mountpoint. | 1504 | * recursively change the type of the mountpoint. |
1448 | */ | 1505 | */ |
1449 | static int do_change_type(struct path *path, int flag) | 1506 | static int do_change_type(struct path *path, int flag) |
1450 | { | 1507 | { |
1451 | struct vfsmount *m, *mnt = path->mnt; | 1508 | struct vfsmount *m, *mnt = path->mnt; |
1452 | int recurse = flag & MS_REC; | 1509 | int recurse = flag & MS_REC; |
1453 | int type = flag & ~MS_REC; | 1510 | int type; |
1454 | int err = 0; | 1511 | int err = 0; |
1455 | 1512 | ||
1456 | if (!capable(CAP_SYS_ADMIN)) | 1513 | if (!capable(CAP_SYS_ADMIN)) |
@@ -1459,6 +1516,10 @@ static int do_change_type(struct path *path, int flag) | |||
1459 | if (path->dentry != path->mnt->mnt_root) | 1516 | if (path->dentry != path->mnt->mnt_root) |
1460 | return -EINVAL; | 1517 | return -EINVAL; |
1461 | 1518 | ||
1519 | type = flags_to_propagation_type(flag); | ||
1520 | if (!type) | ||
1521 | return -EINVAL; | ||
1522 | |||
1462 | down_write(&namespace_sem); | 1523 | down_write(&namespace_sem); |
1463 | if (type == MS_SHARED) { | 1524 | if (type == MS_SHARED) { |
1464 | err = invent_group_ids(mnt, recurse); | 1525 | err = invent_group_ids(mnt, recurse); |
@@ -1466,10 +1527,10 @@ static int do_change_type(struct path *path, int flag) | |||
1466 | goto out_unlock; | 1527 | goto out_unlock; |
1467 | } | 1528 | } |
1468 | 1529 | ||
1469 | spin_lock(&vfsmount_lock); | 1530 | br_write_lock(vfsmount_lock); |
1470 | for (m = mnt; m; m = (recurse ? next_mnt(m, mnt) : NULL)) | 1531 | for (m = mnt; m; m = (recurse ? next_mnt(m, mnt) : NULL)) |
1471 | change_mnt_propagation(m, type); | 1532 | change_mnt_propagation(m, type); |
1472 | spin_unlock(&vfsmount_lock); | 1533 | br_write_unlock(vfsmount_lock); |
1473 | 1534 | ||
1474 | out_unlock: | 1535 | out_unlock: |
1475 | up_write(&namespace_sem); | 1536 | up_write(&namespace_sem); |
@@ -1513,9 +1574,10 @@ static int do_loopback(struct path *path, char *old_name, | |||
1513 | err = graft_tree(mnt, path); | 1574 | err = graft_tree(mnt, path); |
1514 | if (err) { | 1575 | if (err) { |
1515 | LIST_HEAD(umount_list); | 1576 | LIST_HEAD(umount_list); |
1516 | spin_lock(&vfsmount_lock); | 1577 | |
1578 | br_write_lock(vfsmount_lock); | ||
1517 | umount_tree(mnt, 0, &umount_list); | 1579 | umount_tree(mnt, 0, &umount_list); |
1518 | spin_unlock(&vfsmount_lock); | 1580 | br_write_unlock(vfsmount_lock); |
1519 | release_mounts(&umount_list); | 1581 | release_mounts(&umount_list); |
1520 | } | 1582 | } |
1521 | 1583 | ||
@@ -1568,16 +1630,16 @@ static int do_remount(struct path *path, int flags, int mnt_flags, | |||
1568 | else | 1630 | else |
1569 | err = do_remount_sb(sb, flags, data, 0); | 1631 | err = do_remount_sb(sb, flags, data, 0); |
1570 | if (!err) { | 1632 | if (!err) { |
1571 | spin_lock(&vfsmount_lock); | 1633 | br_write_lock(vfsmount_lock); |
1572 | mnt_flags |= path->mnt->mnt_flags & MNT_PROPAGATION_MASK; | 1634 | mnt_flags |= path->mnt->mnt_flags & MNT_PROPAGATION_MASK; |
1573 | path->mnt->mnt_flags = mnt_flags; | 1635 | path->mnt->mnt_flags = mnt_flags; |
1574 | spin_unlock(&vfsmount_lock); | 1636 | br_write_unlock(vfsmount_lock); |
1575 | } | 1637 | } |
1576 | up_write(&sb->s_umount); | 1638 | up_write(&sb->s_umount); |
1577 | if (!err) { | 1639 | if (!err) { |
1578 | spin_lock(&vfsmount_lock); | 1640 | br_write_lock(vfsmount_lock); |
1579 | touch_mnt_namespace(path->mnt->mnt_ns); | 1641 | touch_mnt_namespace(path->mnt->mnt_ns); |
1580 | spin_unlock(&vfsmount_lock); | 1642 | br_write_unlock(vfsmount_lock); |
1581 | } | 1643 | } |
1582 | return err; | 1644 | return err; |
1583 | } | 1645 | } |
@@ -1754,7 +1816,7 @@ void mark_mounts_for_expiry(struct list_head *mounts) | |||
1754 | return; | 1816 | return; |
1755 | 1817 | ||
1756 | down_write(&namespace_sem); | 1818 | down_write(&namespace_sem); |
1757 | spin_lock(&vfsmount_lock); | 1819 | br_write_lock(vfsmount_lock); |
1758 | 1820 | ||
1759 | /* extract from the expiration list every vfsmount that matches the | 1821 | /* extract from the expiration list every vfsmount that matches the |
1760 | * following criteria: | 1822 | * following criteria: |
@@ -1773,7 +1835,7 @@ void mark_mounts_for_expiry(struct list_head *mounts) | |||
1773 | touch_mnt_namespace(mnt->mnt_ns); | 1835 | touch_mnt_namespace(mnt->mnt_ns); |
1774 | umount_tree(mnt, 1, &umounts); | 1836 | umount_tree(mnt, 1, &umounts); |
1775 | } | 1837 | } |
1776 | spin_unlock(&vfsmount_lock); | 1838 | br_write_unlock(vfsmount_lock); |
1777 | up_write(&namespace_sem); | 1839 | up_write(&namespace_sem); |
1778 | 1840 | ||
1779 | release_mounts(&umounts); | 1841 | release_mounts(&umounts); |
@@ -1830,6 +1892,8 @@ resume: | |||
1830 | /* | 1892 | /* |
1831 | * process a list of expirable mountpoints with the intent of discarding any | 1893 | * process a list of expirable mountpoints with the intent of discarding any |
1832 | * submounts of a specific parent mountpoint | 1894 | * submounts of a specific parent mountpoint |
1895 | * | ||
1896 | * vfsmount_lock must be held for write | ||
1833 | */ | 1897 | */ |
1834 | static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts) | 1898 | static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts) |
1835 | { | 1899 | { |
@@ -2048,9 +2112,9 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, | |||
2048 | kfree(new_ns); | 2112 | kfree(new_ns); |
2049 | return ERR_PTR(-ENOMEM); | 2113 | return ERR_PTR(-ENOMEM); |
2050 | } | 2114 | } |
2051 | spin_lock(&vfsmount_lock); | 2115 | br_write_lock(vfsmount_lock); |
2052 | list_add_tail(&new_ns->list, &new_ns->root->mnt_list); | 2116 | list_add_tail(&new_ns->list, &new_ns->root->mnt_list); |
2053 | spin_unlock(&vfsmount_lock); | 2117 | br_write_unlock(vfsmount_lock); |
2054 | 2118 | ||
2055 | /* | 2119 | /* |
2056 | * Second pass: switch the tsk->fs->* elements and mark new vfsmounts | 2120 | * Second pass: switch the tsk->fs->* elements and mark new vfsmounts |
@@ -2244,7 +2308,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, | |||
2244 | goto out2; /* not attached */ | 2308 | goto out2; /* not attached */ |
2245 | /* make sure we can reach put_old from new_root */ | 2309 | /* make sure we can reach put_old from new_root */ |
2246 | tmp = old.mnt; | 2310 | tmp = old.mnt; |
2247 | spin_lock(&vfsmount_lock); | 2311 | br_write_lock(vfsmount_lock); |
2248 | if (tmp != new.mnt) { | 2312 | if (tmp != new.mnt) { |
2249 | for (;;) { | 2313 | for (;;) { |
2250 | if (tmp->mnt_parent == tmp) | 2314 | if (tmp->mnt_parent == tmp) |
@@ -2264,7 +2328,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, | |||
2264 | /* mount new_root on / */ | 2328 | /* mount new_root on / */ |
2265 | attach_mnt(new.mnt, &root_parent); | 2329 | attach_mnt(new.mnt, &root_parent); |
2266 | touch_mnt_namespace(current->nsproxy->mnt_ns); | 2330 | touch_mnt_namespace(current->nsproxy->mnt_ns); |
2267 | spin_unlock(&vfsmount_lock); | 2331 | br_write_unlock(vfsmount_lock); |
2268 | chroot_fs_refs(&root, &new); | 2332 | chroot_fs_refs(&root, &new); |
2269 | error = 0; | 2333 | error = 0; |
2270 | path_put(&root_parent); | 2334 | path_put(&root_parent); |
@@ -2279,7 +2343,7 @@ out1: | |||
2279 | out0: | 2343 | out0: |
2280 | return error; | 2344 | return error; |
2281 | out3: | 2345 | out3: |
2282 | spin_unlock(&vfsmount_lock); | 2346 | br_write_unlock(vfsmount_lock); |
2283 | goto out2; | 2347 | goto out2; |
2284 | } | 2348 | } |
2285 | 2349 | ||
@@ -2326,6 +2390,8 @@ void __init mnt_init(void) | |||
2326 | for (u = 0; u < HASH_SIZE; u++) | 2390 | for (u = 0; u < HASH_SIZE; u++) |
2327 | INIT_LIST_HEAD(&mount_hashtable[u]); | 2391 | INIT_LIST_HEAD(&mount_hashtable[u]); |
2328 | 2392 | ||
2393 | br_lock_init(vfsmount_lock); | ||
2394 | |||
2329 | err = sysfs_init(); | 2395 | err = sysfs_init(); |
2330 | if (err) | 2396 | if (err) |
2331 | printk(KERN_WARNING "%s: sysfs_init error: %d\n", | 2397 | printk(KERN_WARNING "%s: sysfs_init error: %d\n", |
@@ -2344,9 +2410,9 @@ void put_mnt_ns(struct mnt_namespace *ns) | |||
2344 | if (!atomic_dec_and_test(&ns->count)) | 2410 | if (!atomic_dec_and_test(&ns->count)) |
2345 | return; | 2411 | return; |
2346 | down_write(&namespace_sem); | 2412 | down_write(&namespace_sem); |
2347 | spin_lock(&vfsmount_lock); | 2413 | br_write_lock(vfsmount_lock); |
2348 | umount_tree(ns->root, 0, &umount_list); | 2414 | umount_tree(ns->root, 0, &umount_list); |
2349 | spin_unlock(&vfsmount_lock); | 2415 | br_write_unlock(vfsmount_lock); |
2350 | up_write(&namespace_sem); | 2416 | up_write(&namespace_sem); |
2351 | release_mounts(&umount_list); | 2417 | release_mounts(&umount_list); |
2352 | kfree(ns); | 2418 | kfree(ns); |
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig index 26a510a7be0..6c2aad49d73 100644 --- a/fs/nfs/Kconfig +++ b/fs/nfs/Kconfig | |||
@@ -63,7 +63,6 @@ config NFS_V3_ACL | |||
63 | config NFS_V4 | 63 | config NFS_V4 |
64 | bool "NFS client support for NFS version 4" | 64 | bool "NFS client support for NFS version 4" |
65 | depends on NFS_FS | 65 | depends on NFS_FS |
66 | select RPCSEC_GSS_KRB5 | ||
67 | help | 66 | help |
68 | This option enables support for version 4 of the NFS protocol | 67 | This option enables support for version 4 of the NFS protocol |
69 | (RFC 3530) in the kernel's NFS client. | 68 | (RFC 3530) in the kernel's NFS client. |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 29539ceeb74..e257172d438 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -140,6 +140,13 @@ nfs_opendir(struct inode *inode, struct file *filp) | |||
140 | 140 | ||
141 | /* Call generic open code in order to cache credentials */ | 141 | /* Call generic open code in order to cache credentials */ |
142 | res = nfs_open(inode, filp); | 142 | res = nfs_open(inode, filp); |
143 | if (filp->f_path.dentry == filp->f_path.mnt->mnt_root) { | ||
144 | /* This is a mountpoint, so d_revalidate will never | ||
145 | * have been called, so we need to refresh the | ||
146 | * inode (for close-open consistency) ourselves. | ||
147 | */ | ||
148 | __nfs_revalidate_inode(NFS_SERVER(inode), inode); | ||
149 | } | ||
143 | return res; | 150 | return res; |
144 | } | 151 | } |
145 | 152 | ||
@@ -1103,7 +1110,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
1103 | if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) | 1110 | if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) |
1104 | goto no_open_dput; | 1111 | goto no_open_dput; |
1105 | /* We can't create new files, or truncate existing ones here */ | 1112 | /* We can't create new files, or truncate existing ones here */ |
1106 | openflags &= ~(O_CREAT|O_TRUNC); | 1113 | openflags &= ~(O_CREAT|O_EXCL|O_TRUNC); |
1107 | 1114 | ||
1108 | /* | 1115 | /* |
1109 | * Note: we're not holding inode->i_mutex and so may be racing with | 1116 | * Note: we're not holding inode->i_mutex and so may be racing with |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 2d141a74ae8..eb51bd6201d 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -323,7 +323,7 @@ nfs_file_fsync(struct file *file, int datasync) | |||
323 | have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags); | 323 | have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags); |
324 | if (have_error) | 324 | if (have_error) |
325 | ret = xchg(&ctx->error, 0); | 325 | ret = xchg(&ctx->error, 0); |
326 | if (!ret) | 326 | if (!ret && status < 0) |
327 | ret = status; | 327 | ret = status; |
328 | return ret; | 328 | return ret; |
329 | } | 329 | } |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 7ffbb98ddec..089da5b5d20 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -2036,7 +2036,8 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
2036 | struct rpc_cred *cred; | 2036 | struct rpc_cred *cred; |
2037 | struct nfs4_state *state; | 2037 | struct nfs4_state *state; |
2038 | struct dentry *res; | 2038 | struct dentry *res; |
2039 | fmode_t fmode = nd->intent.open.flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC); | 2039 | int open_flags = nd->intent.open.flags; |
2040 | fmode_t fmode = open_flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC); | ||
2040 | 2041 | ||
2041 | if (nd->flags & LOOKUP_CREATE) { | 2042 | if (nd->flags & LOOKUP_CREATE) { |
2042 | attr.ia_mode = nd->intent.open.create_mode; | 2043 | attr.ia_mode = nd->intent.open.create_mode; |
@@ -2044,8 +2045,9 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
2044 | if (!IS_POSIXACL(dir)) | 2045 | if (!IS_POSIXACL(dir)) |
2045 | attr.ia_mode &= ~current_umask(); | 2046 | attr.ia_mode &= ~current_umask(); |
2046 | } else { | 2047 | } else { |
2048 | open_flags &= ~O_EXCL; | ||
2047 | attr.ia_valid = 0; | 2049 | attr.ia_valid = 0; |
2048 | BUG_ON(nd->intent.open.flags & O_CREAT); | 2050 | BUG_ON(open_flags & O_CREAT); |
2049 | } | 2051 | } |
2050 | 2052 | ||
2051 | cred = rpc_lookup_cred(); | 2053 | cred = rpc_lookup_cred(); |
@@ -2054,7 +2056,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
2054 | parent = dentry->d_parent; | 2056 | parent = dentry->d_parent; |
2055 | /* Protect against concurrent sillydeletes */ | 2057 | /* Protect against concurrent sillydeletes */ |
2056 | nfs_block_sillyrename(parent); | 2058 | nfs_block_sillyrename(parent); |
2057 | state = nfs4_do_open(dir, &path, fmode, nd->intent.open.flags, &attr, cred); | 2059 | state = nfs4_do_open(dir, &path, fmode, open_flags, &attr, cred); |
2058 | put_rpccred(cred); | 2060 | put_rpccred(cred); |
2059 | if (IS_ERR(state)) { | 2061 | if (IS_ERR(state)) { |
2060 | if (PTR_ERR(state) == -ENOENT) { | 2062 | if (PTR_ERR(state) == -ENOENT) { |
@@ -2273,8 +2275,7 @@ static int nfs4_get_referral(struct inode *dir, const struct qstr *name, struct | |||
2273 | out: | 2275 | out: |
2274 | if (page) | 2276 | if (page) |
2275 | __free_page(page); | 2277 | __free_page(page); |
2276 | if (locations) | 2278 | kfree(locations); |
2277 | kfree(locations); | ||
2278 | return status; | 2279 | return status; |
2279 | } | 2280 | } |
2280 | 2281 | ||
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index ee26316ad1f..ec3966e4706 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -655,6 +655,13 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, | |||
655 | 655 | ||
656 | if (nfss->options & NFS_OPTION_FSCACHE) | 656 | if (nfss->options & NFS_OPTION_FSCACHE) |
657 | seq_printf(m, ",fsc"); | 657 | seq_printf(m, ",fsc"); |
658 | |||
659 | if (nfss->flags & NFS_MOUNT_LOOKUP_CACHE_NONEG) { | ||
660 | if (nfss->flags & NFS_MOUNT_LOOKUP_CACHE_NONE) | ||
661 | seq_printf(m, ",lookupcache=none"); | ||
662 | else | ||
663 | seq_printf(m, ",lookupcache=pos"); | ||
664 | } | ||
658 | } | 665 | } |
659 | 666 | ||
660 | /* | 667 | /* |
diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig index 503b9da159a..95932f523ae 100644 --- a/fs/nfsd/Kconfig +++ b/fs/nfsd/Kconfig | |||
@@ -69,7 +69,6 @@ config NFSD_V4 | |||
69 | depends on NFSD && PROC_FS && EXPERIMENTAL | 69 | depends on NFSD && PROC_FS && EXPERIMENTAL |
70 | select NFSD_V3 | 70 | select NFSD_V3 |
71 | select FS_POSIX_ACL | 71 | select FS_POSIX_ACL |
72 | select RPCSEC_GSS_KRB5 | ||
73 | help | 72 | help |
74 | This option enables support in your system's NFS server for | 73 | This option enables support in your system's NFS server for |
75 | version 4 of the NFS protocol (RFC 3530). | 74 | version 4 of the NFS protocol (RFC 3530). |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 2e7357104cf..3dfef062396 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -2450,14 +2450,13 @@ nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh, | |||
2450 | static __be32 | 2450 | static __be32 |
2451 | nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open) | 2451 | nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open) |
2452 | { | 2452 | { |
2453 | u32 op_share_access, new_access; | 2453 | u32 op_share_access = open->op_share_access & ~NFS4_SHARE_WANT_MASK; |
2454 | bool new_access; | ||
2454 | __be32 status; | 2455 | __be32 status; |
2455 | 2456 | ||
2456 | set_access(&new_access, stp->st_access_bmap); | 2457 | new_access = !test_bit(op_share_access, &stp->st_access_bmap); |
2457 | new_access = (~new_access) & open->op_share_access & ~NFS4_SHARE_WANT_MASK; | ||
2458 | |||
2459 | if (new_access) { | 2458 | if (new_access) { |
2460 | status = nfs4_get_vfs_file(rqstp, fp, cur_fh, new_access); | 2459 | status = nfs4_get_vfs_file(rqstp, fp, cur_fh, op_share_access); |
2461 | if (status) | 2460 | if (status) |
2462 | return status; | 2461 | return status; |
2463 | } | 2462 | } |
@@ -2470,7 +2469,6 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *c | |||
2470 | return status; | 2469 | return status; |
2471 | } | 2470 | } |
2472 | /* remember the open */ | 2471 | /* remember the open */ |
2473 | op_share_access = open->op_share_access & ~NFS4_SHARE_WANT_MASK; | ||
2474 | __set_bit(op_share_access, &stp->st_access_bmap); | 2472 | __set_bit(op_share_access, &stp->st_access_bmap); |
2475 | __set_bit(open->op_share_deny, &stp->st_deny_bmap); | 2473 | __set_bit(open->op_share_deny, &stp->st_deny_bmap); |
2476 | 2474 | ||
@@ -2983,7 +2981,6 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate, | |||
2983 | *filpp = find_readable_file(stp->st_file); | 2981 | *filpp = find_readable_file(stp->st_file); |
2984 | else | 2982 | else |
2985 | *filpp = find_writeable_file(stp->st_file); | 2983 | *filpp = find_writeable_file(stp->st_file); |
2986 | BUG_ON(!*filpp); /* assured by check_openmode */ | ||
2987 | } | 2984 | } |
2988 | } | 2985 | } |
2989 | status = nfs_ok; | 2986 | status = nfs_ok; |
@@ -3561,7 +3558,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3561 | struct nfs4_stateowner *open_sop = NULL; | 3558 | struct nfs4_stateowner *open_sop = NULL; |
3562 | struct nfs4_stateowner *lock_sop = NULL; | 3559 | struct nfs4_stateowner *lock_sop = NULL; |
3563 | struct nfs4_stateid *lock_stp; | 3560 | struct nfs4_stateid *lock_stp; |
3564 | struct file *filp; | 3561 | struct nfs4_file *fp; |
3562 | struct file *filp = NULL; | ||
3565 | struct file_lock file_lock; | 3563 | struct file_lock file_lock; |
3566 | struct file_lock conflock; | 3564 | struct file_lock conflock; |
3567 | __be32 status = 0; | 3565 | __be32 status = 0; |
@@ -3591,7 +3589,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3591 | * lock stateid. | 3589 | * lock stateid. |
3592 | */ | 3590 | */ |
3593 | struct nfs4_stateid *open_stp = NULL; | 3591 | struct nfs4_stateid *open_stp = NULL; |
3594 | struct nfs4_file *fp; | ||
3595 | 3592 | ||
3596 | status = nfserr_stale_clientid; | 3593 | status = nfserr_stale_clientid; |
3597 | if (!nfsd4_has_session(cstate) && | 3594 | if (!nfsd4_has_session(cstate) && |
@@ -3634,6 +3631,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3634 | if (status) | 3631 | if (status) |
3635 | goto out; | 3632 | goto out; |
3636 | lock_sop = lock->lk_replay_owner; | 3633 | lock_sop = lock->lk_replay_owner; |
3634 | fp = lock_stp->st_file; | ||
3637 | } | 3635 | } |
3638 | /* lock->lk_replay_owner and lock_stp have been created or found */ | 3636 | /* lock->lk_replay_owner and lock_stp have been created or found */ |
3639 | 3637 | ||
@@ -3648,13 +3646,19 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3648 | switch (lock->lk_type) { | 3646 | switch (lock->lk_type) { |
3649 | case NFS4_READ_LT: | 3647 | case NFS4_READ_LT: |
3650 | case NFS4_READW_LT: | 3648 | case NFS4_READW_LT: |
3651 | filp = find_readable_file(lock_stp->st_file); | 3649 | if (find_readable_file(lock_stp->st_file)) { |
3650 | nfs4_get_vfs_file(rqstp, fp, &cstate->current_fh, NFS4_SHARE_ACCESS_READ); | ||
3651 | filp = find_readable_file(lock_stp->st_file); | ||
3652 | } | ||
3652 | file_lock.fl_type = F_RDLCK; | 3653 | file_lock.fl_type = F_RDLCK; |
3653 | cmd = F_SETLK; | 3654 | cmd = F_SETLK; |
3654 | break; | 3655 | break; |
3655 | case NFS4_WRITE_LT: | 3656 | case NFS4_WRITE_LT: |
3656 | case NFS4_WRITEW_LT: | 3657 | case NFS4_WRITEW_LT: |
3657 | filp = find_writeable_file(lock_stp->st_file); | 3658 | if (find_writeable_file(lock_stp->st_file)) { |
3659 | nfs4_get_vfs_file(rqstp, fp, &cstate->current_fh, NFS4_SHARE_ACCESS_WRITE); | ||
3660 | filp = find_writeable_file(lock_stp->st_file); | ||
3661 | } | ||
3658 | file_lock.fl_type = F_WRLCK; | 3662 | file_lock.fl_type = F_WRLCK; |
3659 | cmd = F_SETLK; | 3663 | cmd = F_SETLK; |
3660 | break; | 3664 | break; |
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 7731a75971d..322518c88e4 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h | |||
@@ -363,23 +363,23 @@ struct nfs4_file { | |||
363 | * at all? */ | 363 | * at all? */ |
364 | static inline struct file *find_writeable_file(struct nfs4_file *f) | 364 | static inline struct file *find_writeable_file(struct nfs4_file *f) |
365 | { | 365 | { |
366 | if (f->fi_fds[O_RDWR]) | 366 | if (f->fi_fds[O_WRONLY]) |
367 | return f->fi_fds[O_RDWR]; | 367 | return f->fi_fds[O_WRONLY]; |
368 | return f->fi_fds[O_WRONLY]; | 368 | return f->fi_fds[O_RDWR]; |
369 | } | 369 | } |
370 | 370 | ||
371 | static inline struct file *find_readable_file(struct nfs4_file *f) | 371 | static inline struct file *find_readable_file(struct nfs4_file *f) |
372 | { | 372 | { |
373 | if (f->fi_fds[O_RDWR]) | 373 | if (f->fi_fds[O_RDONLY]) |
374 | return f->fi_fds[O_RDWR]; | 374 | return f->fi_fds[O_RDONLY]; |
375 | return f->fi_fds[O_RDONLY]; | 375 | return f->fi_fds[O_RDWR]; |
376 | } | 376 | } |
377 | 377 | ||
378 | static inline struct file *find_any_file(struct nfs4_file *f) | 378 | static inline struct file *find_any_file(struct nfs4_file *f) |
379 | { | 379 | { |
380 | if (f->fi_fds[O_RDWR]) | 380 | if (f->fi_fds[O_RDWR]) |
381 | return f->fi_fds[O_RDWR]; | 381 | return f->fi_fds[O_RDWR]; |
382 | else if (f->fi_fds[O_RDWR]) | 382 | else if (f->fi_fds[O_WRONLY]) |
383 | return f->fi_fds[O_WRONLY]; | 383 | return f->fi_fds[O_WRONLY]; |
384 | else | 384 | else |
385 | return f->fi_fds[O_RDONLY]; | 385 | return f->fi_fds[O_RDONLY]; |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 96360a83cb9..661a6cf8e82 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -2033,15 +2033,17 @@ out: | |||
2033 | __be32 | 2033 | __be32 |
2034 | nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat, int access) | 2034 | nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat, int access) |
2035 | { | 2035 | { |
2036 | struct path path = { | ||
2037 | .mnt = fhp->fh_export->ex_path.mnt, | ||
2038 | .dentry = fhp->fh_dentry, | ||
2039 | }; | ||
2040 | __be32 err; | 2036 | __be32 err; |
2041 | 2037 | ||
2042 | err = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP | access); | 2038 | err = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP | access); |
2043 | if (!err && vfs_statfs(&path, stat)) | 2039 | if (!err) { |
2044 | err = nfserr_io; | 2040 | struct path path = { |
2041 | .mnt = fhp->fh_export->ex_path.mnt, | ||
2042 | .dentry = fhp->fh_dentry, | ||
2043 | }; | ||
2044 | if (vfs_statfs(&path, stat)) | ||
2045 | err = nfserr_io; | ||
2046 | } | ||
2045 | return err; | 2047 | return err; |
2046 | } | 2048 | } |
2047 | 2049 | ||
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 1fa86b9df73..922263393c7 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -175,24 +175,24 @@ static int nilfs_sync_super(struct nilfs_sb_info *sbi, int flag) | |||
175 | { | 175 | { |
176 | struct the_nilfs *nilfs = sbi->s_nilfs; | 176 | struct the_nilfs *nilfs = sbi->s_nilfs; |
177 | int err; | 177 | int err; |
178 | int barrier_done = 0; | ||
179 | 178 | ||
180 | if (nilfs_test_opt(sbi, BARRIER)) { | ||
181 | set_buffer_ordered(nilfs->ns_sbh[0]); | ||
182 | barrier_done = 1; | ||
183 | } | ||
184 | retry: | 179 | retry: |
185 | set_buffer_dirty(nilfs->ns_sbh[0]); | 180 | set_buffer_dirty(nilfs->ns_sbh[0]); |
186 | err = sync_dirty_buffer(nilfs->ns_sbh[0]); | 181 | |
187 | if (err == -EOPNOTSUPP && barrier_done) { | 182 | if (nilfs_test_opt(sbi, BARRIER)) { |
188 | nilfs_warning(sbi->s_super, __func__, | 183 | err = __sync_dirty_buffer(nilfs->ns_sbh[0], |
189 | "barrier-based sync failed. " | 184 | WRITE_SYNC | WRITE_BARRIER); |
190 | "disabling barriers\n"); | 185 | if (err == -EOPNOTSUPP) { |
191 | nilfs_clear_opt(sbi, BARRIER); | 186 | nilfs_warning(sbi->s_super, __func__, |
192 | barrier_done = 0; | 187 | "barrier-based sync failed. " |
193 | clear_buffer_ordered(nilfs->ns_sbh[0]); | 188 | "disabling barriers\n"); |
194 | goto retry; | 189 | nilfs_clear_opt(sbi, BARRIER); |
190 | goto retry; | ||
191 | } | ||
192 | } else { | ||
193 | err = sync_dirty_buffer(nilfs->ns_sbh[0]); | ||
195 | } | 194 | } |
195 | |||
196 | if (unlikely(err)) { | 196 | if (unlikely(err)) { |
197 | printk(KERN_ERR | 197 | printk(KERN_ERR |
198 | "NILFS: unable to write superblock (err=%d)\n", err); | 198 | "NILFS: unable to write superblock (err=%d)\n", err); |
@@ -400,9 +400,10 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno) | |||
400 | list_add(&sbi->s_list, &nilfs->ns_supers); | 400 | list_add(&sbi->s_list, &nilfs->ns_supers); |
401 | up_write(&nilfs->ns_super_sem); | 401 | up_write(&nilfs->ns_super_sem); |
402 | 402 | ||
403 | err = -ENOMEM; | ||
403 | sbi->s_ifile = nilfs_ifile_new(sbi, nilfs->ns_inode_size); | 404 | sbi->s_ifile = nilfs_ifile_new(sbi, nilfs->ns_inode_size); |
404 | if (!sbi->s_ifile) | 405 | if (!sbi->s_ifile) |
405 | return -ENOMEM; | 406 | goto delist; |
406 | 407 | ||
407 | down_read(&nilfs->ns_segctor_sem); | 408 | down_read(&nilfs->ns_segctor_sem); |
408 | err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp, | 409 | err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp, |
@@ -433,6 +434,7 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno) | |||
433 | nilfs_mdt_destroy(sbi->s_ifile); | 434 | nilfs_mdt_destroy(sbi->s_ifile); |
434 | sbi->s_ifile = NULL; | 435 | sbi->s_ifile = NULL; |
435 | 436 | ||
437 | delist: | ||
436 | down_write(&nilfs->ns_super_sem); | 438 | down_write(&nilfs->ns_super_sem); |
437 | list_del_init(&sbi->s_list); | 439 | list_del_init(&sbi->s_list); |
438 | up_write(&nilfs->ns_super_sem); | 440 | up_write(&nilfs->ns_super_sem); |
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index 37de1f062d8..ba7c10c917f 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c | |||
@@ -446,6 +446,7 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) | |||
446 | nilfs_mdt_destroy(nilfs->ns_cpfile); | 446 | nilfs_mdt_destroy(nilfs->ns_cpfile); |
447 | nilfs_mdt_destroy(nilfs->ns_sufile); | 447 | nilfs_mdt_destroy(nilfs->ns_sufile); |
448 | nilfs_mdt_destroy(nilfs->ns_dat); | 448 | nilfs_mdt_destroy(nilfs->ns_dat); |
449 | nilfs_mdt_destroy(nilfs->ns_gc_dat); | ||
449 | 450 | ||
450 | failed: | 451 | failed: |
451 | nilfs_clear_recovery_info(&ri); | 452 | nilfs_clear_recovery_info(&ri); |
@@ -608,11 +609,11 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs, | |||
608 | return -EINVAL; | 609 | return -EINVAL; |
609 | } | 610 | } |
610 | 611 | ||
611 | if (swp) { | 612 | if (!valid[!swp]) |
612 | printk(KERN_WARNING "NILFS warning: broken superblock. " | 613 | printk(KERN_WARNING "NILFS warning: broken superblock. " |
613 | "using spare superblock.\n"); | 614 | "using spare superblock.\n"); |
615 | if (swp) | ||
614 | nilfs_swap_super_block(nilfs); | 616 | nilfs_swap_super_block(nilfs); |
615 | } | ||
616 | 617 | ||
617 | nilfs->ns_sbwcount = 0; | 618 | nilfs->ns_sbwcount = 0; |
618 | nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime); | 619 | nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime); |
@@ -775,6 +776,7 @@ int nilfs_discard_segments(struct the_nilfs *nilfs, __u64 *segnump, | |||
775 | start * sects_per_block, | 776 | start * sects_per_block, |
776 | nblocks * sects_per_block, | 777 | nblocks * sects_per_block, |
777 | GFP_NOFS, | 778 | GFP_NOFS, |
779 | BLKDEV_IFL_WAIT | | ||
778 | BLKDEV_IFL_BARRIER); | 780 | BLKDEV_IFL_BARRIER); |
779 | if (ret < 0) | 781 | if (ret < 0) |
780 | return ret; | 782 | return ret; |
@@ -785,7 +787,8 @@ int nilfs_discard_segments(struct the_nilfs *nilfs, __u64 *segnump, | |||
785 | ret = blkdev_issue_discard(nilfs->ns_bdev, | 787 | ret = blkdev_issue_discard(nilfs->ns_bdev, |
786 | start * sects_per_block, | 788 | start * sects_per_block, |
787 | nblocks * sects_per_block, | 789 | nblocks * sects_per_block, |
788 | GFP_NOFS, BLKDEV_IFL_BARRIER); | 790 | GFP_NOFS, |
791 | BLKDEV_IFL_WAIT | BLKDEV_IFL_BARRIER); | ||
789 | return ret; | 792 | return ret; |
790 | } | 793 | } |
791 | 794 | ||
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 756566fe844..85366c78cc3 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c | |||
@@ -165,9 +165,6 @@ static bool fanotify_should_send_event(struct fsnotify_group *group, | |||
165 | "mask=%x data=%p data_type=%d\n", __func__, group, to_tell, | 165 | "mask=%x data=%p data_type=%d\n", __func__, group, to_tell, |
166 | inode_mark, vfsmnt_mark, event_mask, data, data_type); | 166 | inode_mark, vfsmnt_mark, event_mask, data, data_type); |
167 | 167 | ||
168 | pr_debug("%s: group=%p vfsmount_mark=%p inode_mark=%p mask=%x\n", | ||
169 | __func__, group, vfsmnt_mark, inode_mark, event_mask); | ||
170 | |||
171 | /* sorry, fanotify only gives a damn about files and dirs */ | 168 | /* sorry, fanotify only gives a damn about files and dirs */ |
172 | if (!S_ISREG(to_tell->i_mode) && | 169 | if (!S_ISREG(to_tell->i_mode) && |
173 | !S_ISDIR(to_tell->i_mode)) | 170 | !S_ISDIR(to_tell->i_mode)) |
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 032b837fcd1..5ed8e58d7bf 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -195,6 +195,14 @@ static int prepare_for_access_response(struct fsnotify_group *group, | |||
195 | re->fd = fd; | 195 | re->fd = fd; |
196 | 196 | ||
197 | mutex_lock(&group->fanotify_data.access_mutex); | 197 | mutex_lock(&group->fanotify_data.access_mutex); |
198 | |||
199 | if (group->fanotify_data.bypass_perm) { | ||
200 | mutex_unlock(&group->fanotify_data.access_mutex); | ||
201 | kmem_cache_free(fanotify_response_event_cache, re); | ||
202 | event->response = FAN_ALLOW; | ||
203 | return 0; | ||
204 | } | ||
205 | |||
198 | list_add_tail(&re->list, &group->fanotify_data.access_list); | 206 | list_add_tail(&re->list, &group->fanotify_data.access_list); |
199 | mutex_unlock(&group->fanotify_data.access_mutex); | 207 | mutex_unlock(&group->fanotify_data.access_mutex); |
200 | 208 | ||
@@ -364,9 +372,28 @@ static ssize_t fanotify_write(struct file *file, const char __user *buf, size_t | |||
364 | static int fanotify_release(struct inode *ignored, struct file *file) | 372 | static int fanotify_release(struct inode *ignored, struct file *file) |
365 | { | 373 | { |
366 | struct fsnotify_group *group = file->private_data; | 374 | struct fsnotify_group *group = file->private_data; |
375 | struct fanotify_response_event *re, *lre; | ||
367 | 376 | ||
368 | pr_debug("%s: file=%p group=%p\n", __func__, file, group); | 377 | pr_debug("%s: file=%p group=%p\n", __func__, file, group); |
369 | 378 | ||
379 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS | ||
380 | mutex_lock(&group->fanotify_data.access_mutex); | ||
381 | |||
382 | group->fanotify_data.bypass_perm = true; | ||
383 | |||
384 | list_for_each_entry_safe(re, lre, &group->fanotify_data.access_list, list) { | ||
385 | pr_debug("%s: found group=%p re=%p event=%p\n", __func__, group, | ||
386 | re, re->event); | ||
387 | |||
388 | list_del_init(&re->list); | ||
389 | re->event->response = FAN_ALLOW; | ||
390 | |||
391 | kmem_cache_free(fanotify_response_event_cache, re); | ||
392 | } | ||
393 | mutex_unlock(&group->fanotify_data.access_mutex); | ||
394 | |||
395 | wake_up(&group->fanotify_data.access_waitq); | ||
396 | #endif | ||
370 | /* matches the fanotify_init->fsnotify_alloc_group */ | 397 | /* matches the fanotify_init->fsnotify_alloc_group */ |
371 | fsnotify_put_group(group); | 398 | fsnotify_put_group(group); |
372 | 399 | ||
@@ -614,7 +641,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) | |||
614 | __func__, flags, event_f_flags); | 641 | __func__, flags, event_f_flags); |
615 | 642 | ||
616 | if (!capable(CAP_SYS_ADMIN)) | 643 | if (!capable(CAP_SYS_ADMIN)) |
617 | return -EACCES; | 644 | return -EPERM; |
618 | 645 | ||
619 | if (flags & ~FAN_ALL_INIT_FLAGS) | 646 | if (flags & ~FAN_ALL_INIT_FLAGS) |
620 | return -EINVAL; | 647 | return -EINVAL; |
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 3970392b272..36802420d69 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c | |||
@@ -148,13 +148,14 @@ static int send_to_group(struct inode *to_tell, struct vfsmount *mnt, | |||
148 | const unsigned char *file_name, | 148 | const unsigned char *file_name, |
149 | struct fsnotify_event **event) | 149 | struct fsnotify_event **event) |
150 | { | 150 | { |
151 | struct fsnotify_group *group = inode_mark->group; | 151 | struct fsnotify_group *group = NULL; |
152 | __u32 inode_test_mask = (mask & ~FS_EVENT_ON_CHILD); | 152 | __u32 inode_test_mask = 0; |
153 | __u32 vfsmount_test_mask = (mask & ~FS_EVENT_ON_CHILD); | 153 | __u32 vfsmount_test_mask = 0; |
154 | 154 | ||
155 | pr_debug("%s: group=%p to_tell=%p mnt=%p mark=%p mask=%x data=%p" | 155 | if (unlikely(!inode_mark && !vfsmount_mark)) { |
156 | " data_is=%d cookie=%d event=%p\n", __func__, group, to_tell, | 156 | BUG(); |
157 | mnt, inode_mark, mask, data, data_is, cookie, *event); | 157 | return 0; |
158 | } | ||
158 | 159 | ||
159 | /* clear ignored on inode modification */ | 160 | /* clear ignored on inode modification */ |
160 | if (mask & FS_MODIFY) { | 161 | if (mask & FS_MODIFY) { |
@@ -168,18 +169,29 @@ static int send_to_group(struct inode *to_tell, struct vfsmount *mnt, | |||
168 | 169 | ||
169 | /* does the inode mark tell us to do something? */ | 170 | /* does the inode mark tell us to do something? */ |
170 | if (inode_mark) { | 171 | if (inode_mark) { |
172 | group = inode_mark->group; | ||
173 | inode_test_mask = (mask & ~FS_EVENT_ON_CHILD); | ||
171 | inode_test_mask &= inode_mark->mask; | 174 | inode_test_mask &= inode_mark->mask; |
172 | inode_test_mask &= ~inode_mark->ignored_mask; | 175 | inode_test_mask &= ~inode_mark->ignored_mask; |
173 | } | 176 | } |
174 | 177 | ||
175 | /* does the vfsmount_mark tell us to do something? */ | 178 | /* does the vfsmount_mark tell us to do something? */ |
176 | if (vfsmount_mark) { | 179 | if (vfsmount_mark) { |
180 | vfsmount_test_mask = (mask & ~FS_EVENT_ON_CHILD); | ||
181 | group = vfsmount_mark->group; | ||
177 | vfsmount_test_mask &= vfsmount_mark->mask; | 182 | vfsmount_test_mask &= vfsmount_mark->mask; |
178 | vfsmount_test_mask &= ~vfsmount_mark->ignored_mask; | 183 | vfsmount_test_mask &= ~vfsmount_mark->ignored_mask; |
179 | if (inode_mark) | 184 | if (inode_mark) |
180 | vfsmount_test_mask &= ~inode_mark->ignored_mask; | 185 | vfsmount_test_mask &= ~inode_mark->ignored_mask; |
181 | } | 186 | } |
182 | 187 | ||
188 | pr_debug("%s: group=%p to_tell=%p mnt=%p mask=%x inode_mark=%p" | ||
189 | " inode_test_mask=%x vfsmount_mark=%p vfsmount_test_mask=%x" | ||
190 | " data=%p data_is=%d cookie=%d event=%p\n", | ||
191 | __func__, group, to_tell, mnt, mask, inode_mark, | ||
192 | inode_test_mask, vfsmount_mark, vfsmount_test_mask, data, | ||
193 | data_is, cookie, *event); | ||
194 | |||
183 | if (!inode_test_mask && !vfsmount_test_mask) | 195 | if (!inode_test_mask && !vfsmount_test_mask) |
184 | return 0; | 196 | return 0; |
185 | 197 | ||
@@ -207,13 +219,12 @@ static int send_to_group(struct inode *to_tell, struct vfsmount *mnt, | |||
207 | int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, | 219 | int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, |
208 | const unsigned char *file_name, u32 cookie) | 220 | const unsigned char *file_name, u32 cookie) |
209 | { | 221 | { |
210 | struct hlist_node *inode_node, *vfsmount_node; | 222 | struct hlist_node *inode_node = NULL, *vfsmount_node = NULL; |
211 | struct fsnotify_mark *inode_mark = NULL, *vfsmount_mark = NULL; | 223 | struct fsnotify_mark *inode_mark = NULL, *vfsmount_mark = NULL; |
212 | struct fsnotify_group *inode_group, *vfsmount_group; | 224 | struct fsnotify_group *inode_group, *vfsmount_group; |
213 | struct fsnotify_event *event = NULL; | 225 | struct fsnotify_event *event = NULL; |
214 | struct vfsmount *mnt; | 226 | struct vfsmount *mnt; |
215 | int idx, ret = 0; | 227 | int idx, ret = 0; |
216 | bool used_inode = false, used_vfsmount = false; | ||
217 | /* global tests shouldn't care about events on child only the specific event */ | 228 | /* global tests shouldn't care about events on child only the specific event */ |
218 | __u32 test_mask = (mask & ~FS_EVENT_ON_CHILD); | 229 | __u32 test_mask = (mask & ~FS_EVENT_ON_CHILD); |
219 | 230 | ||
@@ -238,57 +249,50 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, | |||
238 | (test_mask & to_tell->i_fsnotify_mask)) | 249 | (test_mask & to_tell->i_fsnotify_mask)) |
239 | inode_node = srcu_dereference(to_tell->i_fsnotify_marks.first, | 250 | inode_node = srcu_dereference(to_tell->i_fsnotify_marks.first, |
240 | &fsnotify_mark_srcu); | 251 | &fsnotify_mark_srcu); |
241 | else | ||
242 | inode_node = NULL; | ||
243 | 252 | ||
244 | if (mnt) { | 253 | if (mnt && ((mask & FS_MODIFY) || |
245 | if ((mask & FS_MODIFY) || | 254 | (test_mask & mnt->mnt_fsnotify_mask))) { |
246 | (test_mask & mnt->mnt_fsnotify_mask)) | 255 | vfsmount_node = srcu_dereference(mnt->mnt_fsnotify_marks.first, |
247 | vfsmount_node = srcu_dereference(mnt->mnt_fsnotify_marks.first, | 256 | &fsnotify_mark_srcu); |
248 | &fsnotify_mark_srcu); | 257 | inode_node = srcu_dereference(to_tell->i_fsnotify_marks.first, |
249 | else | 258 | &fsnotify_mark_srcu); |
250 | vfsmount_node = NULL; | ||
251 | } else { | ||
252 | mnt = NULL; | ||
253 | vfsmount_node = NULL; | ||
254 | } | 259 | } |
255 | 260 | ||
256 | while (inode_node || vfsmount_node) { | 261 | while (inode_node || vfsmount_node) { |
262 | inode_group = vfsmount_group = NULL; | ||
263 | |||
257 | if (inode_node) { | 264 | if (inode_node) { |
258 | inode_mark = hlist_entry(srcu_dereference(inode_node, &fsnotify_mark_srcu), | 265 | inode_mark = hlist_entry(srcu_dereference(inode_node, &fsnotify_mark_srcu), |
259 | struct fsnotify_mark, i.i_list); | 266 | struct fsnotify_mark, i.i_list); |
260 | inode_group = inode_mark->group; | 267 | inode_group = inode_mark->group; |
261 | } else | 268 | } |
262 | inode_group = (void *)-1; | ||
263 | 269 | ||
264 | if (vfsmount_node) { | 270 | if (vfsmount_node) { |
265 | vfsmount_mark = hlist_entry(srcu_dereference(vfsmount_node, &fsnotify_mark_srcu), | 271 | vfsmount_mark = hlist_entry(srcu_dereference(vfsmount_node, &fsnotify_mark_srcu), |
266 | struct fsnotify_mark, m.m_list); | 272 | struct fsnotify_mark, m.m_list); |
267 | vfsmount_group = vfsmount_mark->group; | 273 | vfsmount_group = vfsmount_mark->group; |
268 | } else | 274 | } |
269 | vfsmount_group = (void *)-1; | ||
270 | 275 | ||
271 | if (inode_group < vfsmount_group) { | 276 | if (inode_group > vfsmount_group) { |
272 | /* handle inode */ | 277 | /* handle inode */ |
273 | send_to_group(to_tell, NULL, inode_mark, NULL, mask, data, | 278 | send_to_group(to_tell, NULL, inode_mark, NULL, mask, data, |
274 | data_is, cookie, file_name, &event); | 279 | data_is, cookie, file_name, &event); |
275 | used_inode = true; | 280 | /* we didn't use the vfsmount_mark */ |
276 | } else if (vfsmount_group < inode_group) { | 281 | vfsmount_group = NULL; |
282 | } else if (vfsmount_group > inode_group) { | ||
277 | send_to_group(to_tell, mnt, NULL, vfsmount_mark, mask, data, | 283 | send_to_group(to_tell, mnt, NULL, vfsmount_mark, mask, data, |
278 | data_is, cookie, file_name, &event); | 284 | data_is, cookie, file_name, &event); |
279 | used_vfsmount = true; | 285 | inode_group = NULL; |
280 | } else { | 286 | } else { |
281 | send_to_group(to_tell, mnt, inode_mark, vfsmount_mark, | 287 | send_to_group(to_tell, mnt, inode_mark, vfsmount_mark, |
282 | mask, data, data_is, cookie, file_name, | 288 | mask, data, data_is, cookie, file_name, |
283 | &event); | 289 | &event); |
284 | used_vfsmount = true; | ||
285 | used_inode = true; | ||
286 | } | 290 | } |
287 | 291 | ||
288 | if (used_inode) | 292 | if (inode_group) |
289 | inode_node = srcu_dereference(inode_node->next, | 293 | inode_node = srcu_dereference(inode_node->next, |
290 | &fsnotify_mark_srcu); | 294 | &fsnotify_mark_srcu); |
291 | if (used_vfsmount) | 295 | if (vfsmount_group) |
292 | vfsmount_node = srcu_dereference(vfsmount_node->next, | 296 | vfsmount_node = srcu_dereference(vfsmount_node->next, |
293 | &fsnotify_mark_srcu); | 297 | &fsnotify_mark_srcu); |
294 | } | 298 | } |
@@ -675,7 +675,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, | |||
675 | f->f_path.mnt = mnt; | 675 | f->f_path.mnt = mnt; |
676 | f->f_pos = 0; | 676 | f->f_pos = 0; |
677 | f->f_op = fops_get(inode->i_fop); | 677 | f->f_op = fops_get(inode->i_fop); |
678 | file_move(f, &inode->i_sb->s_files); | 678 | file_sb_list_add(f, inode->i_sb); |
679 | 679 | ||
680 | error = security_dentry_open(f, cred); | 680 | error = security_dentry_open(f, cred); |
681 | if (error) | 681 | if (error) |
@@ -721,7 +721,7 @@ cleanup_all: | |||
721 | mnt_drop_write(mnt); | 721 | mnt_drop_write(mnt); |
722 | } | 722 | } |
723 | } | 723 | } |
724 | file_kill(f); | 724 | file_sb_list_del(f); |
725 | f->f_path.dentry = NULL; | 725 | f->f_path.dentry = NULL; |
726 | f->f_path.mnt = NULL; | 726 | f->f_path.mnt = NULL; |
727 | cleanup_file: | 727 | cleanup_file: |
diff --git a/fs/pnode.c b/fs/pnode.c index 5cc564a8314..8066b8dd748 100644 --- a/fs/pnode.c +++ b/fs/pnode.c | |||
@@ -126,6 +126,9 @@ static int do_make_slave(struct vfsmount *mnt) | |||
126 | return 0; | 126 | return 0; |
127 | } | 127 | } |
128 | 128 | ||
129 | /* | ||
130 | * vfsmount lock must be held for write | ||
131 | */ | ||
129 | void change_mnt_propagation(struct vfsmount *mnt, int type) | 132 | void change_mnt_propagation(struct vfsmount *mnt, int type) |
130 | { | 133 | { |
131 | if (type == MS_SHARED) { | 134 | if (type == MS_SHARED) { |
@@ -270,12 +273,12 @@ int propagate_mnt(struct vfsmount *dest_mnt, struct dentry *dest_dentry, | |||
270 | prev_src_mnt = child; | 273 | prev_src_mnt = child; |
271 | } | 274 | } |
272 | out: | 275 | out: |
273 | spin_lock(&vfsmount_lock); | 276 | br_write_lock(vfsmount_lock); |
274 | while (!list_empty(&tmp_list)) { | 277 | while (!list_empty(&tmp_list)) { |
275 | child = list_first_entry(&tmp_list, struct vfsmount, mnt_hash); | 278 | child = list_first_entry(&tmp_list, struct vfsmount, mnt_hash); |
276 | umount_tree(child, 0, &umount_list); | 279 | umount_tree(child, 0, &umount_list); |
277 | } | 280 | } |
278 | spin_unlock(&vfsmount_lock); | 281 | br_write_unlock(vfsmount_lock); |
279 | release_mounts(&umount_list); | 282 | release_mounts(&umount_list); |
280 | return ret; | 283 | return ret; |
281 | } | 284 | } |
@@ -296,6 +299,8 @@ static inline int do_refcount_check(struct vfsmount *mnt, int count) | |||
296 | * other mounts its parent propagates to. | 299 | * other mounts its parent propagates to. |
297 | * Check if any of these mounts that **do not have submounts** | 300 | * Check if any of these mounts that **do not have submounts** |
298 | * have more references than 'refcnt'. If so return busy. | 301 | * have more references than 'refcnt'. If so return busy. |
302 | * | ||
303 | * vfsmount lock must be held for read or write | ||
299 | */ | 304 | */ |
300 | int propagate_mount_busy(struct vfsmount *mnt, int refcnt) | 305 | int propagate_mount_busy(struct vfsmount *mnt, int refcnt) |
301 | { | 306 | { |
@@ -353,6 +358,8 @@ static void __propagate_umount(struct vfsmount *mnt) | |||
353 | * collect all mounts that receive propagation from the mount in @list, | 358 | * collect all mounts that receive propagation from the mount in @list, |
354 | * and return these additional mounts in the same list. | 359 | * and return these additional mounts in the same list. |
355 | * @list: the list of mounts to be unmounted. | 360 | * @list: the list of mounts to be unmounted. |
361 | * | ||
362 | * vfsmount lock must be held for write | ||
356 | */ | 363 | */ |
357 | int propagate_umount(struct list_head *list) | 364 | int propagate_umount(struct list_head *list) |
358 | { | 365 | { |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index ae35413dcbe..caa758377d6 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -83,6 +83,7 @@ void reiserfs_evict_inode(struct inode *inode) | |||
83 | dquot_drop(inode); | 83 | dquot_drop(inode); |
84 | inode->i_blocks = 0; | 84 | inode->i_blocks = 0; |
85 | reiserfs_write_unlock_once(inode->i_sb, depth); | 85 | reiserfs_write_unlock_once(inode->i_sb, depth); |
86 | return; | ||
86 | 87 | ||
87 | no_delete: | 88 | no_delete: |
88 | end_writeback(inode); | 89 | end_writeback(inode); |
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 1ec952b1f03..812e2c05aa2 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
@@ -2311,7 +2311,7 @@ static int journal_read_transaction(struct super_block *sb, | |||
2311 | /* flush out the real blocks */ | 2311 | /* flush out the real blocks */ |
2312 | for (i = 0; i < get_desc_trans_len(desc); i++) { | 2312 | for (i = 0; i < get_desc_trans_len(desc); i++) { |
2313 | set_buffer_dirty(real_blocks[i]); | 2313 | set_buffer_dirty(real_blocks[i]); |
2314 | ll_rw_block(SWRITE, 1, real_blocks + i); | 2314 | write_dirty_buffer(real_blocks[i], WRITE); |
2315 | } | 2315 | } |
2316 | for (i = 0; i < get_desc_trans_len(desc); i++) { | 2316 | for (i = 0; i < get_desc_trans_len(desc); i++) { |
2317 | wait_on_buffer(real_blocks[i]); | 2317 | wait_on_buffer(real_blocks[i]); |
diff --git a/fs/super.c b/fs/super.c index 9674ab2c871..8819e3a7ff2 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -54,7 +54,22 @@ static struct super_block *alloc_super(struct file_system_type *type) | |||
54 | s = NULL; | 54 | s = NULL; |
55 | goto out; | 55 | goto out; |
56 | } | 56 | } |
57 | #ifdef CONFIG_SMP | ||
58 | s->s_files = alloc_percpu(struct list_head); | ||
59 | if (!s->s_files) { | ||
60 | security_sb_free(s); | ||
61 | kfree(s); | ||
62 | s = NULL; | ||
63 | goto out; | ||
64 | } else { | ||
65 | int i; | ||
66 | |||
67 | for_each_possible_cpu(i) | ||
68 | INIT_LIST_HEAD(per_cpu_ptr(s->s_files, i)); | ||
69 | } | ||
70 | #else | ||
57 | INIT_LIST_HEAD(&s->s_files); | 71 | INIT_LIST_HEAD(&s->s_files); |
72 | #endif | ||
58 | INIT_LIST_HEAD(&s->s_instances); | 73 | INIT_LIST_HEAD(&s->s_instances); |
59 | INIT_HLIST_HEAD(&s->s_anon); | 74 | INIT_HLIST_HEAD(&s->s_anon); |
60 | INIT_LIST_HEAD(&s->s_inodes); | 75 | INIT_LIST_HEAD(&s->s_inodes); |
@@ -108,6 +123,9 @@ out: | |||
108 | */ | 123 | */ |
109 | static inline void destroy_super(struct super_block *s) | 124 | static inline void destroy_super(struct super_block *s) |
110 | { | 125 | { |
126 | #ifdef CONFIG_SMP | ||
127 | free_percpu(s->s_files); | ||
128 | #endif | ||
111 | security_sb_free(s); | 129 | security_sb_free(s); |
112 | kfree(s->s_subtype); | 130 | kfree(s->s_subtype); |
113 | kfree(s->s_options); | 131 | kfree(s->s_options); |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 1b27b5688f6..da3fefe91a8 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -340,7 +340,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file) | |||
340 | char *p; | 340 | char *p; |
341 | 341 | ||
342 | p = d_path(&file->f_path, last_sysfs_file, sizeof(last_sysfs_file)); | 342 | p = d_path(&file->f_path, last_sysfs_file, sizeof(last_sysfs_file)); |
343 | if (p) | 343 | if (!IS_ERR(p)) |
344 | memmove(last_sysfs_file, p, strlen(p) + 1); | 344 | memmove(last_sysfs_file, p, strlen(p) + 1); |
345 | 345 | ||
346 | /* need attr_sd for attr and ops, its parent for kobj */ | 346 | /* need attr_sd for attr and ops, its parent for kobj */ |
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index 048484fb10d..46f7a807bbc 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c | |||
@@ -114,10 +114,8 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count) | |||
114 | 114 | ||
115 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); | 115 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); |
116 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); | 116 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
117 | if (sb->s_flags & MS_SYNCHRONOUS) { | 117 | if (sb->s_flags & MS_SYNCHRONOUS) |
118 | ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi)); | 118 | ubh_sync_block(UCPI_UBH(ucpi)); |
119 | ubh_wait_on_buffer (UCPI_UBH(ucpi)); | ||
120 | } | ||
121 | sb->s_dirt = 1; | 119 | sb->s_dirt = 1; |
122 | 120 | ||
123 | unlock_super (sb); | 121 | unlock_super (sb); |
@@ -207,10 +205,8 @@ do_more: | |||
207 | 205 | ||
208 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); | 206 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); |
209 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); | 207 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
210 | if (sb->s_flags & MS_SYNCHRONOUS) { | 208 | if (sb->s_flags & MS_SYNCHRONOUS) |
211 | ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi)); | 209 | ubh_sync_block(UCPI_UBH(ucpi)); |
212 | ubh_wait_on_buffer (UCPI_UBH(ucpi)); | ||
213 | } | ||
214 | 210 | ||
215 | if (overflow) { | 211 | if (overflow) { |
216 | fragment += count; | 212 | fragment += count; |
@@ -558,10 +554,8 @@ static u64 ufs_add_fragments(struct inode *inode, u64 fragment, | |||
558 | 554 | ||
559 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); | 555 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); |
560 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); | 556 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
561 | if (sb->s_flags & MS_SYNCHRONOUS) { | 557 | if (sb->s_flags & MS_SYNCHRONOUS) |
562 | ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi)); | 558 | ubh_sync_block(UCPI_UBH(ucpi)); |
563 | ubh_wait_on_buffer (UCPI_UBH(ucpi)); | ||
564 | } | ||
565 | sb->s_dirt = 1; | 559 | sb->s_dirt = 1; |
566 | 560 | ||
567 | UFSD("EXIT, fragment %llu\n", (unsigned long long)fragment); | 561 | UFSD("EXIT, fragment %llu\n", (unsigned long long)fragment); |
@@ -680,10 +674,8 @@ cg_found: | |||
680 | succed: | 674 | succed: |
681 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); | 675 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); |
682 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); | 676 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
683 | if (sb->s_flags & MS_SYNCHRONOUS) { | 677 | if (sb->s_flags & MS_SYNCHRONOUS) |
684 | ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi)); | 678 | ubh_sync_block(UCPI_UBH(ucpi)); |
685 | ubh_wait_on_buffer (UCPI_UBH(ucpi)); | ||
686 | } | ||
687 | sb->s_dirt = 1; | 679 | sb->s_dirt = 1; |
688 | 680 | ||
689 | result += cgno * uspi->s_fpg; | 681 | result += cgno * uspi->s_fpg; |
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index 428017e018f..2eabf04af3d 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c | |||
@@ -113,10 +113,8 @@ void ufs_free_inode (struct inode * inode) | |||
113 | 113 | ||
114 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); | 114 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); |
115 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); | 115 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
116 | if (sb->s_flags & MS_SYNCHRONOUS) { | 116 | if (sb->s_flags & MS_SYNCHRONOUS) |
117 | ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi)); | 117 | ubh_sync_block(UCPI_UBH(ucpi)); |
118 | ubh_wait_on_buffer (UCPI_UBH(ucpi)); | ||
119 | } | ||
120 | 118 | ||
121 | sb->s_dirt = 1; | 119 | sb->s_dirt = 1; |
122 | unlock_super (sb); | 120 | unlock_super (sb); |
@@ -156,10 +154,8 @@ static void ufs2_init_inodes_chunk(struct super_block *sb, | |||
156 | 154 | ||
157 | fs32_add(sb, &ucg->cg_u.cg_u2.cg_initediblk, uspi->s_inopb); | 155 | fs32_add(sb, &ucg->cg_u.cg_u2.cg_initediblk, uspi->s_inopb); |
158 | ubh_mark_buffer_dirty(UCPI_UBH(ucpi)); | 156 | ubh_mark_buffer_dirty(UCPI_UBH(ucpi)); |
159 | if (sb->s_flags & MS_SYNCHRONOUS) { | 157 | if (sb->s_flags & MS_SYNCHRONOUS) |
160 | ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi)); | 158 | ubh_sync_block(UCPI_UBH(ucpi)); |
161 | ubh_wait_on_buffer(UCPI_UBH(ucpi)); | ||
162 | } | ||
163 | 159 | ||
164 | UFSD("EXIT\n"); | 160 | UFSD("EXIT\n"); |
165 | } | 161 | } |
@@ -290,10 +286,8 @@ cg_found: | |||
290 | } | 286 | } |
291 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); | 287 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); |
292 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); | 288 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
293 | if (sb->s_flags & MS_SYNCHRONOUS) { | 289 | if (sb->s_flags & MS_SYNCHRONOUS) |
294 | ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi)); | 290 | ubh_sync_block(UCPI_UBH(ucpi)); |
295 | ubh_wait_on_buffer (UCPI_UBH(ucpi)); | ||
296 | } | ||
297 | sb->s_dirt = 1; | 291 | sb->s_dirt = 1; |
298 | 292 | ||
299 | inode->i_ino = cg * uspi->s_ipg + bit; | 293 | inode->i_ino = cg * uspi->s_ipg + bit; |
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index 34d5cb13532..a58f9155fc9 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c | |||
@@ -243,10 +243,8 @@ static int ufs_trunc_indirect(struct inode *inode, u64 offset, void *p) | |||
243 | ubh_bforget(ind_ubh); | 243 | ubh_bforget(ind_ubh); |
244 | ind_ubh = NULL; | 244 | ind_ubh = NULL; |
245 | } | 245 | } |
246 | if (IS_SYNC(inode) && ind_ubh && ubh_buffer_dirty(ind_ubh)) { | 246 | if (IS_SYNC(inode) && ind_ubh && ubh_buffer_dirty(ind_ubh)) |
247 | ubh_ll_rw_block(SWRITE, ind_ubh); | 247 | ubh_sync_block(ind_ubh); |
248 | ubh_wait_on_buffer (ind_ubh); | ||
249 | } | ||
250 | ubh_brelse (ind_ubh); | 248 | ubh_brelse (ind_ubh); |
251 | 249 | ||
252 | UFSD("EXIT: ino %lu\n", inode->i_ino); | 250 | UFSD("EXIT: ino %lu\n", inode->i_ino); |
@@ -307,10 +305,8 @@ static int ufs_trunc_dindirect(struct inode *inode, u64 offset, void *p) | |||
307 | ubh_bforget(dind_bh); | 305 | ubh_bforget(dind_bh); |
308 | dind_bh = NULL; | 306 | dind_bh = NULL; |
309 | } | 307 | } |
310 | if (IS_SYNC(inode) && dind_bh && ubh_buffer_dirty(dind_bh)) { | 308 | if (IS_SYNC(inode) && dind_bh && ubh_buffer_dirty(dind_bh)) |
311 | ubh_ll_rw_block(SWRITE, dind_bh); | 309 | ubh_sync_block(dind_bh); |
312 | ubh_wait_on_buffer (dind_bh); | ||
313 | } | ||
314 | ubh_brelse (dind_bh); | 310 | ubh_brelse (dind_bh); |
315 | 311 | ||
316 | UFSD("EXIT: ino %lu\n", inode->i_ino); | 312 | UFSD("EXIT: ino %lu\n", inode->i_ino); |
@@ -367,10 +363,8 @@ static int ufs_trunc_tindirect(struct inode *inode) | |||
367 | ubh_bforget(tind_bh); | 363 | ubh_bforget(tind_bh); |
368 | tind_bh = NULL; | 364 | tind_bh = NULL; |
369 | } | 365 | } |
370 | if (IS_SYNC(inode) && tind_bh && ubh_buffer_dirty(tind_bh)) { | 366 | if (IS_SYNC(inode) && tind_bh && ubh_buffer_dirty(tind_bh)) |
371 | ubh_ll_rw_block(SWRITE, tind_bh); | 367 | ubh_sync_block(tind_bh); |
372 | ubh_wait_on_buffer (tind_bh); | ||
373 | } | ||
374 | ubh_brelse (tind_bh); | 368 | ubh_brelse (tind_bh); |
375 | 369 | ||
376 | UFSD("EXIT: ino %lu\n", inode->i_ino); | 370 | UFSD("EXIT: ino %lu\n", inode->i_ino); |
diff --git a/fs/ufs/util.c b/fs/ufs/util.c index 85a7fc9e4a4..d2c36d53fe6 100644 --- a/fs/ufs/util.c +++ b/fs/ufs/util.c | |||
@@ -113,21 +113,17 @@ void ubh_mark_buffer_uptodate (struct ufs_buffer_head * ubh, int flag) | |||
113 | } | 113 | } |
114 | } | 114 | } |
115 | 115 | ||
116 | void ubh_ll_rw_block(int rw, struct ufs_buffer_head *ubh) | 116 | void ubh_sync_block(struct ufs_buffer_head *ubh) |
117 | { | 117 | { |
118 | if (!ubh) | 118 | if (ubh) { |
119 | return; | 119 | unsigned i; |
120 | 120 | ||
121 | ll_rw_block(rw, ubh->count, ubh->bh); | 121 | for (i = 0; i < ubh->count; i++) |
122 | } | 122 | write_dirty_buffer(ubh->bh[i], WRITE); |
123 | 123 | ||
124 | void ubh_wait_on_buffer (struct ufs_buffer_head * ubh) | 124 | for (i = 0; i < ubh->count; i++) |
125 | { | 125 | wait_on_buffer(ubh->bh[i]); |
126 | unsigned i; | 126 | } |
127 | if (!ubh) | ||
128 | return; | ||
129 | for ( i = 0; i < ubh->count; i++ ) | ||
130 | wait_on_buffer (ubh->bh[i]); | ||
131 | } | 127 | } |
132 | 128 | ||
133 | void ubh_bforget (struct ufs_buffer_head * ubh) | 129 | void ubh_bforget (struct ufs_buffer_head * ubh) |
diff --git a/fs/ufs/util.h b/fs/ufs/util.h index 0466036912f..9f8775ce381 100644 --- a/fs/ufs/util.h +++ b/fs/ufs/util.h | |||
@@ -269,8 +269,7 @@ extern void ubh_brelse (struct ufs_buffer_head *); | |||
269 | extern void ubh_brelse_uspi (struct ufs_sb_private_info *); | 269 | extern void ubh_brelse_uspi (struct ufs_sb_private_info *); |
270 | extern void ubh_mark_buffer_dirty (struct ufs_buffer_head *); | 270 | extern void ubh_mark_buffer_dirty (struct ufs_buffer_head *); |
271 | extern void ubh_mark_buffer_uptodate (struct ufs_buffer_head *, int); | 271 | extern void ubh_mark_buffer_uptodate (struct ufs_buffer_head *, int); |
272 | extern void ubh_ll_rw_block(int, struct ufs_buffer_head *); | 272 | extern void ubh_sync_block(struct ufs_buffer_head *); |
273 | extern void ubh_wait_on_buffer (struct ufs_buffer_head *); | ||
274 | extern void ubh_bforget (struct ufs_buffer_head *); | 273 | extern void ubh_bforget (struct ufs_buffer_head *); |
275 | extern int ubh_buffer_dirty (struct ufs_buffer_head *); | 274 | extern int ubh_buffer_dirty (struct ufs_buffer_head *); |
276 | #define ubh_ubhcpymem(mem,ubh,size) _ubh_ubhcpymem_(uspi,mem,ubh,size) | 275 | #define ubh_ubhcpymem(mem,ubh,size) _ubh_ubhcpymem_(uspi,mem,ubh,size) |
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 15412fe15c3..b552f816de1 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -852,8 +852,8 @@ xfs_convert_page( | |||
852 | SetPageUptodate(page); | 852 | SetPageUptodate(page); |
853 | 853 | ||
854 | if (count) { | 854 | if (count) { |
855 | wbc->nr_to_write--; | 855 | if (--wbc->nr_to_write <= 0 && |
856 | if (wbc->nr_to_write <= 0) | 856 | wbc->sync_mode == WB_SYNC_NONE) |
857 | done = 1; | 857 | done = 1; |
858 | } | 858 | } |
859 | xfs_start_page_writeback(page, !page_dirty, count); | 859 | xfs_start_page_writeback(page, !page_dirty, count); |
@@ -1068,7 +1068,7 @@ xfs_vm_writepage( | |||
1068 | * by themselves. | 1068 | * by themselves. |
1069 | */ | 1069 | */ |
1070 | if ((current->flags & (PF_MEMALLOC|PF_KSWAPD)) == PF_MEMALLOC) | 1070 | if ((current->flags & (PF_MEMALLOC|PF_KSWAPD)) == PF_MEMALLOC) |
1071 | goto out_fail; | 1071 | goto redirty; |
1072 | 1072 | ||
1073 | /* | 1073 | /* |
1074 | * We need a transaction if there are delalloc or unwritten buffers | 1074 | * We need a transaction if there are delalloc or unwritten buffers |
@@ -1080,7 +1080,7 @@ xfs_vm_writepage( | |||
1080 | */ | 1080 | */ |
1081 | xfs_count_page_state(page, &delalloc, &unwritten); | 1081 | xfs_count_page_state(page, &delalloc, &unwritten); |
1082 | if ((current->flags & PF_FSTRANS) && (delalloc || unwritten)) | 1082 | if ((current->flags & PF_FSTRANS) && (delalloc || unwritten)) |
1083 | goto out_fail; | 1083 | goto redirty; |
1084 | 1084 | ||
1085 | /* Is this page beyond the end of the file? */ | 1085 | /* Is this page beyond the end of the file? */ |
1086 | offset = i_size_read(inode); | 1086 | offset = i_size_read(inode); |
@@ -1245,12 +1245,15 @@ error: | |||
1245 | if (iohead) | 1245 | if (iohead) |
1246 | xfs_cancel_ioend(iohead); | 1246 | xfs_cancel_ioend(iohead); |
1247 | 1247 | ||
1248 | if (err == -EAGAIN) | ||
1249 | goto redirty; | ||
1250 | |||
1248 | xfs_aops_discard_page(page); | 1251 | xfs_aops_discard_page(page); |
1249 | ClearPageUptodate(page); | 1252 | ClearPageUptodate(page); |
1250 | unlock_page(page); | 1253 | unlock_page(page); |
1251 | return err; | 1254 | return err; |
1252 | 1255 | ||
1253 | out_fail: | 1256 | redirty: |
1254 | redirty_page_for_writepage(wbc, page); | 1257 | redirty_page_for_writepage(wbc, page); |
1255 | unlock_page(page); | 1258 | unlock_page(page); |
1256 | return 0; | 1259 | return 0; |
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index ea79072f521..d72cf2bb054 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -440,12 +440,7 @@ _xfs_buf_find( | |||
440 | ASSERT(btp == bp->b_target); | 440 | ASSERT(btp == bp->b_target); |
441 | if (bp->b_file_offset == range_base && | 441 | if (bp->b_file_offset == range_base && |
442 | bp->b_buffer_length == range_length) { | 442 | bp->b_buffer_length == range_length) { |
443 | /* | ||
444 | * If we look at something, bring it to the | ||
445 | * front of the list for next time. | ||
446 | */ | ||
447 | atomic_inc(&bp->b_hold); | 443 | atomic_inc(&bp->b_hold); |
448 | list_move(&bp->b_hash_list, &hash->bh_list); | ||
449 | goto found; | 444 | goto found; |
450 | } | 445 | } |
451 | } | 446 | } |
@@ -1443,8 +1438,7 @@ xfs_alloc_bufhash( | |||
1443 | { | 1438 | { |
1444 | unsigned int i; | 1439 | unsigned int i; |
1445 | 1440 | ||
1446 | btp->bt_hashshift = external ? 3 : 8; /* 8 or 256 buckets */ | 1441 | btp->bt_hashshift = external ? 3 : 12; /* 8 or 4096 buckets */ |
1447 | btp->bt_hashmask = (1 << btp->bt_hashshift) - 1; | ||
1448 | btp->bt_hash = kmem_zalloc_large((1 << btp->bt_hashshift) * | 1442 | btp->bt_hash = kmem_zalloc_large((1 << btp->bt_hashshift) * |
1449 | sizeof(xfs_bufhash_t)); | 1443 | sizeof(xfs_bufhash_t)); |
1450 | for (i = 0; i < (1 << btp->bt_hashshift); i++) { | 1444 | for (i = 0; i < (1 << btp->bt_hashshift); i++) { |
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index d072e5ff923..2a05614f0b9 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h | |||
@@ -137,7 +137,6 @@ typedef struct xfs_buftarg { | |||
137 | size_t bt_smask; | 137 | size_t bt_smask; |
138 | 138 | ||
139 | /* per device buffer hash table */ | 139 | /* per device buffer hash table */ |
140 | uint bt_hashmask; | ||
141 | uint bt_hashshift; | 140 | uint bt_hashshift; |
142 | xfs_bufhash_t *bt_hash; | 141 | xfs_bufhash_t *bt_hash; |
143 | 142 | ||
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index 237f5ffb2ee..4fec427b83e 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
@@ -907,6 +907,13 @@ xfs_ioctl_setattr( | |||
907 | return XFS_ERROR(EIO); | 907 | return XFS_ERROR(EIO); |
908 | 908 | ||
909 | /* | 909 | /* |
910 | * Disallow 32bit project ids because on-disk structure | ||
911 | * is 16bit only. | ||
912 | */ | ||
913 | if ((mask & FSX_PROJID) && (fa->fsx_projid > (__uint16_t)-1)) | ||
914 | return XFS_ERROR(EINVAL); | ||
915 | |||
916 | /* | ||
910 | * If disk quotas is on, we make sure that the dquots do exist on disk, | 917 | * If disk quotas is on, we make sure that the dquots do exist on disk, |
911 | * before we start any other transactions. Trying to do this later | 918 | * before we start any other transactions. Trying to do this later |
912 | * is messy. We don't care to take a readlock to look at the ids | 919 | * is messy. We don't care to take a readlock to look at the ids |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 68be25dcd30..b1fc2a6bfe8 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -664,7 +664,7 @@ xfs_vn_fiemap( | |||
664 | fieinfo->fi_extents_max + 1; | 664 | fieinfo->fi_extents_max + 1; |
665 | bm.bmv_count = min_t(__s32, bm.bmv_count, | 665 | bm.bmv_count = min_t(__s32, bm.bmv_count, |
666 | (PAGE_SIZE * 16 / sizeof(struct getbmapx))); | 666 | (PAGE_SIZE * 16 / sizeof(struct getbmapx))); |
667 | bm.bmv_iflags = BMV_IF_PREALLOC; | 667 | bm.bmv_iflags = BMV_IF_PREALLOC | BMV_IF_NO_HOLES; |
668 | if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) | 668 | if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) |
669 | bm.bmv_iflags |= BMV_IF_ATTRFORK; | 669 | bm.bmv_iflags |= BMV_IF_ATTRFORK; |
670 | if (!(fieinfo->fi_flags & FIEMAP_FLAG_SYNC)) | 670 | if (!(fieinfo->fi_flags & FIEMAP_FLAG_SYNC)) |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 15c35b62ff1..a4e07974955 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -1226,6 +1226,7 @@ xfs_fs_statfs( | |||
1226 | struct xfs_inode *ip = XFS_I(dentry->d_inode); | 1226 | struct xfs_inode *ip = XFS_I(dentry->d_inode); |
1227 | __uint64_t fakeinos, id; | 1227 | __uint64_t fakeinos, id; |
1228 | xfs_extlen_t lsize; | 1228 | xfs_extlen_t lsize; |
1229 | __int64_t ffree; | ||
1229 | 1230 | ||
1230 | statp->f_type = XFS_SB_MAGIC; | 1231 | statp->f_type = XFS_SB_MAGIC; |
1231 | statp->f_namelen = MAXNAMELEN - 1; | 1232 | statp->f_namelen = MAXNAMELEN - 1; |
@@ -1249,7 +1250,11 @@ xfs_fs_statfs( | |||
1249 | statp->f_files = min_t(typeof(statp->f_files), | 1250 | statp->f_files = min_t(typeof(statp->f_files), |
1250 | statp->f_files, | 1251 | statp->f_files, |
1251 | mp->m_maxicount); | 1252 | mp->m_maxicount); |
1252 | statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree); | 1253 | |
1254 | /* make sure statp->f_ffree does not underflow */ | ||
1255 | ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree); | ||
1256 | statp->f_ffree = max_t(__int64_t, ffree, 0); | ||
1257 | |||
1253 | spin_unlock(&mp->m_sb_lock); | 1258 | spin_unlock(&mp->m_sb_lock); |
1254 | 1259 | ||
1255 | if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) || | 1260 | if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) || |
@@ -1402,7 +1407,7 @@ xfs_fs_freeze( | |||
1402 | 1407 | ||
1403 | xfs_save_resvblks(mp); | 1408 | xfs_save_resvblks(mp); |
1404 | xfs_quiesce_attr(mp); | 1409 | xfs_quiesce_attr(mp); |
1405 | return -xfs_fs_log_dummy(mp); | 1410 | return -xfs_fs_log_dummy(mp, SYNC_WAIT); |
1406 | } | 1411 | } |
1407 | 1412 | ||
1408 | STATIC int | 1413 | STATIC int |
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index dfcbd98d159..d59c4a65d49 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "xfs_inode_item.h" | 34 | #include "xfs_inode_item.h" |
35 | #include "xfs_quota.h" | 35 | #include "xfs_quota.h" |
36 | #include "xfs_trace.h" | 36 | #include "xfs_trace.h" |
37 | #include "xfs_fsops.h" | ||
37 | 38 | ||
38 | #include <linux/kthread.h> | 39 | #include <linux/kthread.h> |
39 | #include <linux/freezer.h> | 40 | #include <linux/freezer.h> |
@@ -341,38 +342,6 @@ xfs_sync_attr( | |||
341 | } | 342 | } |
342 | 343 | ||
343 | STATIC int | 344 | STATIC int |
344 | xfs_commit_dummy_trans( | ||
345 | struct xfs_mount *mp, | ||
346 | uint flags) | ||
347 | { | ||
348 | struct xfs_inode *ip = mp->m_rootip; | ||
349 | struct xfs_trans *tp; | ||
350 | int error; | ||
351 | |||
352 | /* | ||
353 | * Put a dummy transaction in the log to tell recovery | ||
354 | * that all others are OK. | ||
355 | */ | ||
356 | tp = xfs_trans_alloc(mp, XFS_TRANS_DUMMY1); | ||
357 | error = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0); | ||
358 | if (error) { | ||
359 | xfs_trans_cancel(tp, 0); | ||
360 | return error; | ||
361 | } | ||
362 | |||
363 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
364 | |||
365 | xfs_trans_ijoin(tp, ip); | ||
366 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | ||
367 | error = xfs_trans_commit(tp, 0); | ||
368 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
369 | |||
370 | /* the log force ensures this transaction is pushed to disk */ | ||
371 | xfs_log_force(mp, (flags & SYNC_WAIT) ? XFS_LOG_SYNC : 0); | ||
372 | return error; | ||
373 | } | ||
374 | |||
375 | STATIC int | ||
376 | xfs_sync_fsdata( | 345 | xfs_sync_fsdata( |
377 | struct xfs_mount *mp) | 346 | struct xfs_mount *mp) |
378 | { | 347 | { |
@@ -432,7 +401,7 @@ xfs_quiesce_data( | |||
432 | 401 | ||
433 | /* mark the log as covered if needed */ | 402 | /* mark the log as covered if needed */ |
434 | if (xfs_log_need_covered(mp)) | 403 | if (xfs_log_need_covered(mp)) |
435 | error2 = xfs_commit_dummy_trans(mp, SYNC_WAIT); | 404 | error2 = xfs_fs_log_dummy(mp, SYNC_WAIT); |
436 | 405 | ||
437 | /* flush data-only devices */ | 406 | /* flush data-only devices */ |
438 | if (mp->m_rtdev_targp) | 407 | if (mp->m_rtdev_targp) |
@@ -563,7 +532,7 @@ xfs_flush_inodes( | |||
563 | /* | 532 | /* |
564 | * Every sync period we need to unpin all items, reclaim inodes and sync | 533 | * Every sync period we need to unpin all items, reclaim inodes and sync |
565 | * disk quotas. We might need to cover the log to indicate that the | 534 | * disk quotas. We might need to cover the log to indicate that the |
566 | * filesystem is idle. | 535 | * filesystem is idle and not frozen. |
567 | */ | 536 | */ |
568 | STATIC void | 537 | STATIC void |
569 | xfs_sync_worker( | 538 | xfs_sync_worker( |
@@ -577,8 +546,9 @@ xfs_sync_worker( | |||
577 | xfs_reclaim_inodes(mp, 0); | 546 | xfs_reclaim_inodes(mp, 0); |
578 | /* dgc: errors ignored here */ | 547 | /* dgc: errors ignored here */ |
579 | error = xfs_qm_sync(mp, SYNC_TRYLOCK); | 548 | error = xfs_qm_sync(mp, SYNC_TRYLOCK); |
580 | if (xfs_log_need_covered(mp)) | 549 | if (mp->m_super->s_frozen == SB_UNFROZEN && |
581 | error = xfs_commit_dummy_trans(mp, 0); | 550 | xfs_log_need_covered(mp)) |
551 | error = xfs_fs_log_dummy(mp, 0); | ||
582 | } | 552 | } |
583 | mp->m_sync_seq++; | 553 | mp->m_sync_seq++; |
584 | wake_up(&mp->m_wait_single_sync_task); | 554 | wake_up(&mp->m_wait_single_sync_task); |
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 23f14e595c1..f90dadd5a96 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -5533,12 +5533,24 @@ xfs_getbmap( | |||
5533 | map[i].br_startblock)) | 5533 | map[i].br_startblock)) |
5534 | goto out_free_map; | 5534 | goto out_free_map; |
5535 | 5535 | ||
5536 | nexleft--; | ||
5537 | bmv->bmv_offset = | 5536 | bmv->bmv_offset = |
5538 | out[cur_ext].bmv_offset + | 5537 | out[cur_ext].bmv_offset + |
5539 | out[cur_ext].bmv_length; | 5538 | out[cur_ext].bmv_length; |
5540 | bmv->bmv_length = | 5539 | bmv->bmv_length = |
5541 | max_t(__int64_t, 0, bmvend - bmv->bmv_offset); | 5540 | max_t(__int64_t, 0, bmvend - bmv->bmv_offset); |
5541 | |||
5542 | /* | ||
5543 | * In case we don't want to return the hole, | ||
5544 | * don't increase cur_ext so that we can reuse | ||
5545 | * it in the next loop. | ||
5546 | */ | ||
5547 | if ((iflags & BMV_IF_NO_HOLES) && | ||
5548 | map[i].br_startblock == HOLESTARTBLOCK) { | ||
5549 | memset(&out[cur_ext], 0, sizeof(out[cur_ext])); | ||
5550 | continue; | ||
5551 | } | ||
5552 | |||
5553 | nexleft--; | ||
5542 | bmv->bmv_entries++; | 5554 | bmv->bmv_entries++; |
5543 | cur_ext++; | 5555 | cur_ext++; |
5544 | } | 5556 | } |
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h index 7cf7220e7d5..87c2e9d0228 100644 --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h | |||
@@ -114,8 +114,10 @@ struct getbmapx { | |||
114 | #define BMV_IF_NO_DMAPI_READ 0x2 /* Do not generate DMAPI read event */ | 114 | #define BMV_IF_NO_DMAPI_READ 0x2 /* Do not generate DMAPI read event */ |
115 | #define BMV_IF_PREALLOC 0x4 /* rtn status BMV_OF_PREALLOC if req */ | 115 | #define BMV_IF_PREALLOC 0x4 /* rtn status BMV_OF_PREALLOC if req */ |
116 | #define BMV_IF_DELALLOC 0x8 /* rtn status BMV_OF_DELALLOC if req */ | 116 | #define BMV_IF_DELALLOC 0x8 /* rtn status BMV_OF_DELALLOC if req */ |
117 | #define BMV_IF_NO_HOLES 0x10 /* Do not return holes */ | ||
117 | #define BMV_IF_VALID \ | 118 | #define BMV_IF_VALID \ |
118 | (BMV_IF_ATTRFORK|BMV_IF_NO_DMAPI_READ|BMV_IF_PREALLOC|BMV_IF_DELALLOC) | 119 | (BMV_IF_ATTRFORK|BMV_IF_NO_DMAPI_READ|BMV_IF_PREALLOC| \ |
120 | BMV_IF_DELALLOC|BMV_IF_NO_HOLES) | ||
119 | 121 | ||
120 | /* bmv_oflags values - returned for each non-header segment */ | 122 | /* bmv_oflags values - returned for each non-header segment */ |
121 | #define BMV_OF_PREALLOC 0x1 /* segment = unwritten pre-allocation */ | 123 | #define BMV_OF_PREALLOC 0x1 /* segment = unwritten pre-allocation */ |
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index dbca5f5c37b..43b1d569933 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c | |||
@@ -604,31 +604,36 @@ out: | |||
604 | return 0; | 604 | return 0; |
605 | } | 605 | } |
606 | 606 | ||
607 | /* | ||
608 | * Dump a transaction into the log that contains no real change. This is needed | ||
609 | * to be able to make the log dirty or stamp the current tail LSN into the log | ||
610 | * during the covering operation. | ||
611 | * | ||
612 | * We cannot use an inode here for this - that will push dirty state back up | ||
613 | * into the VFS and then periodic inode flushing will prevent log covering from | ||
614 | * making progress. Hence we log a field in the superblock instead. | ||
615 | */ | ||
607 | int | 616 | int |
608 | xfs_fs_log_dummy( | 617 | xfs_fs_log_dummy( |
609 | xfs_mount_t *mp) | 618 | xfs_mount_t *mp, |
619 | int flags) | ||
610 | { | 620 | { |
611 | xfs_trans_t *tp; | 621 | xfs_trans_t *tp; |
612 | xfs_inode_t *ip; | ||
613 | int error; | 622 | int error; |
614 | 623 | ||
615 | tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1, KM_SLEEP); | 624 | tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1, KM_SLEEP); |
616 | error = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0); | 625 | error = xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0, |
626 | XFS_DEFAULT_LOG_COUNT); | ||
617 | if (error) { | 627 | if (error) { |
618 | xfs_trans_cancel(tp, 0); | 628 | xfs_trans_cancel(tp, 0); |
619 | return error; | 629 | return error; |
620 | } | 630 | } |
621 | 631 | ||
622 | ip = mp->m_rootip; | 632 | /* log the UUID because it is an unchanging field */ |
623 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 633 | xfs_mod_sb(tp, XFS_SB_UUID); |
624 | 634 | if (flags & SYNC_WAIT) | |
625 | xfs_trans_ijoin(tp, ip); | 635 | xfs_trans_set_sync(tp); |
626 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 636 | return xfs_trans_commit(tp, 0); |
627 | xfs_trans_set_sync(tp); | ||
628 | error = xfs_trans_commit(tp, 0); | ||
629 | |||
630 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
631 | return error; | ||
632 | } | 637 | } |
633 | 638 | ||
634 | int | 639 | int |
diff --git a/fs/xfs/xfs_fsops.h b/fs/xfs/xfs_fsops.h index 88435e0a77c..a786c5212c1 100644 --- a/fs/xfs/xfs_fsops.h +++ b/fs/xfs/xfs_fsops.h | |||
@@ -25,6 +25,6 @@ extern int xfs_fs_counts(xfs_mount_t *mp, xfs_fsop_counts_t *cnt); | |||
25 | extern int xfs_reserve_blocks(xfs_mount_t *mp, __uint64_t *inval, | 25 | extern int xfs_reserve_blocks(xfs_mount_t *mp, __uint64_t *inval, |
26 | xfs_fsop_resblks_t *outval); | 26 | xfs_fsop_resblks_t *outval); |
27 | extern int xfs_fs_goingdown(xfs_mount_t *mp, __uint32_t inflags); | 27 | extern int xfs_fs_goingdown(xfs_mount_t *mp, __uint32_t inflags); |
28 | extern int xfs_fs_log_dummy(xfs_mount_t *mp); | 28 | extern int xfs_fs_log_dummy(xfs_mount_t *mp, int flags); |
29 | 29 | ||
30 | #endif /* __XFS_FSOPS_H__ */ | 30 | #endif /* __XFS_FSOPS_H__ */ |
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index abf80ae1e95..5371d2dc360 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
@@ -1213,7 +1213,6 @@ xfs_imap_lookup( | |||
1213 | struct xfs_inobt_rec_incore rec; | 1213 | struct xfs_inobt_rec_incore rec; |
1214 | struct xfs_btree_cur *cur; | 1214 | struct xfs_btree_cur *cur; |
1215 | struct xfs_buf *agbp; | 1215 | struct xfs_buf *agbp; |
1216 | xfs_agino_t startino; | ||
1217 | int error; | 1216 | int error; |
1218 | int i; | 1217 | int i; |
1219 | 1218 | ||
@@ -1227,13 +1226,13 @@ xfs_imap_lookup( | |||
1227 | } | 1226 | } |
1228 | 1227 | ||
1229 | /* | 1228 | /* |
1230 | * derive and lookup the exact inode record for the given agino. If the | 1229 | * Lookup the inode record for the given agino. If the record cannot be |
1231 | * record cannot be found, then it's an invalid inode number and we | 1230 | * found, then it's an invalid inode number and we should abort. Once |
1232 | * should abort. | 1231 | * we have a record, we need to ensure it contains the inode number |
1232 | * we are looking up. | ||
1233 | */ | 1233 | */ |
1234 | cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); | 1234 | cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); |
1235 | startino = agino & ~(XFS_IALLOC_INODES(mp) - 1); | 1235 | error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i); |
1236 | error = xfs_inobt_lookup(cur, startino, XFS_LOOKUP_EQ, &i); | ||
1237 | if (!error) { | 1236 | if (!error) { |
1238 | if (i) | 1237 | if (i) |
1239 | error = xfs_inobt_get_rec(cur, &rec, &i); | 1238 | error = xfs_inobt_get_rec(cur, &rec, &i); |
@@ -1246,6 +1245,11 @@ xfs_imap_lookup( | |||
1246 | if (error) | 1245 | if (error) |
1247 | return error; | 1246 | return error; |
1248 | 1247 | ||
1248 | /* check that the returned record contains the required inode */ | ||
1249 | if (rec.ir_startino > agino || | ||
1250 | rec.ir_startino + XFS_IALLOC_INODES(mp) <= agino) | ||
1251 | return EINVAL; | ||
1252 | |||
1249 | /* for untrusted inodes check it is allocated first */ | 1253 | /* for untrusted inodes check it is allocated first */ |
1250 | if ((flags & XFS_IGET_UNTRUSTED) && | 1254 | if ((flags & XFS_IGET_UNTRUSTED) && |
1251 | (rec.ir_free & XFS_INOBT_MASK(agino - rec.ir_startino))) | 1255 | (rec.ir_free & XFS_INOBT_MASK(agino - rec.ir_startino))) |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 68415cb4f23..34798f391c4 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -1914,6 +1914,11 @@ xfs_iunlink_remove( | |||
1914 | return 0; | 1914 | return 0; |
1915 | } | 1915 | } |
1916 | 1916 | ||
1917 | /* | ||
1918 | * A big issue when freeing the inode cluster is is that we _cannot_ skip any | ||
1919 | * inodes that are in memory - they all must be marked stale and attached to | ||
1920 | * the cluster buffer. | ||
1921 | */ | ||
1917 | STATIC void | 1922 | STATIC void |
1918 | xfs_ifree_cluster( | 1923 | xfs_ifree_cluster( |
1919 | xfs_inode_t *free_ip, | 1924 | xfs_inode_t *free_ip, |
@@ -1945,8 +1950,6 @@ xfs_ifree_cluster( | |||
1945 | } | 1950 | } |
1946 | 1951 | ||
1947 | for (j = 0; j < nbufs; j++, inum += ninodes) { | 1952 | for (j = 0; j < nbufs; j++, inum += ninodes) { |
1948 | int found = 0; | ||
1949 | |||
1950 | blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum), | 1953 | blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum), |
1951 | XFS_INO_TO_AGBNO(mp, inum)); | 1954 | XFS_INO_TO_AGBNO(mp, inum)); |
1952 | 1955 | ||
@@ -1965,7 +1968,9 @@ xfs_ifree_cluster( | |||
1965 | /* | 1968 | /* |
1966 | * Walk the inodes already attached to the buffer and mark them | 1969 | * Walk the inodes already attached to the buffer and mark them |
1967 | * stale. These will all have the flush locks held, so an | 1970 | * stale. These will all have the flush locks held, so an |
1968 | * in-memory inode walk can't lock them. | 1971 | * in-memory inode walk can't lock them. By marking them all |
1972 | * stale first, we will not attempt to lock them in the loop | ||
1973 | * below as the XFS_ISTALE flag will be set. | ||
1969 | */ | 1974 | */ |
1970 | lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *); | 1975 | lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *); |
1971 | while (lip) { | 1976 | while (lip) { |
@@ -1977,11 +1982,11 @@ xfs_ifree_cluster( | |||
1977 | &iip->ili_flush_lsn, | 1982 | &iip->ili_flush_lsn, |
1978 | &iip->ili_item.li_lsn); | 1983 | &iip->ili_item.li_lsn); |
1979 | xfs_iflags_set(iip->ili_inode, XFS_ISTALE); | 1984 | xfs_iflags_set(iip->ili_inode, XFS_ISTALE); |
1980 | found++; | ||
1981 | } | 1985 | } |
1982 | lip = lip->li_bio_list; | 1986 | lip = lip->li_bio_list; |
1983 | } | 1987 | } |
1984 | 1988 | ||
1989 | |||
1985 | /* | 1990 | /* |
1986 | * For each inode in memory attempt to add it to the inode | 1991 | * For each inode in memory attempt to add it to the inode |
1987 | * buffer and set it up for being staled on buffer IO | 1992 | * buffer and set it up for being staled on buffer IO |
@@ -1993,6 +1998,7 @@ xfs_ifree_cluster( | |||
1993 | * even trying to lock them. | 1998 | * even trying to lock them. |
1994 | */ | 1999 | */ |
1995 | for (i = 0; i < ninodes; i++) { | 2000 | for (i = 0; i < ninodes; i++) { |
2001 | retry: | ||
1996 | read_lock(&pag->pag_ici_lock); | 2002 | read_lock(&pag->pag_ici_lock); |
1997 | ip = radix_tree_lookup(&pag->pag_ici_root, | 2003 | ip = radix_tree_lookup(&pag->pag_ici_root, |
1998 | XFS_INO_TO_AGINO(mp, (inum + i))); | 2004 | XFS_INO_TO_AGINO(mp, (inum + i))); |
@@ -2003,38 +2009,36 @@ xfs_ifree_cluster( | |||
2003 | continue; | 2009 | continue; |
2004 | } | 2010 | } |
2005 | 2011 | ||
2006 | /* don't try to lock/unlock the current inode */ | 2012 | /* |
2013 | * Don't try to lock/unlock the current inode, but we | ||
2014 | * _cannot_ skip the other inodes that we did not find | ||
2015 | * in the list attached to the buffer and are not | ||
2016 | * already marked stale. If we can't lock it, back off | ||
2017 | * and retry. | ||
2018 | */ | ||
2007 | if (ip != free_ip && | 2019 | if (ip != free_ip && |
2008 | !xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { | 2020 | !xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { |
2009 | read_unlock(&pag->pag_ici_lock); | 2021 | read_unlock(&pag->pag_ici_lock); |
2010 | continue; | 2022 | delay(1); |
2023 | goto retry; | ||
2011 | } | 2024 | } |
2012 | read_unlock(&pag->pag_ici_lock); | 2025 | read_unlock(&pag->pag_ici_lock); |
2013 | 2026 | ||
2014 | if (!xfs_iflock_nowait(ip)) { | 2027 | xfs_iflock(ip); |
2015 | if (ip != free_ip) | ||
2016 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
2017 | continue; | ||
2018 | } | ||
2019 | |||
2020 | xfs_iflags_set(ip, XFS_ISTALE); | 2028 | xfs_iflags_set(ip, XFS_ISTALE); |
2021 | if (xfs_inode_clean(ip)) { | ||
2022 | ASSERT(ip != free_ip); | ||
2023 | xfs_ifunlock(ip); | ||
2024 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
2025 | continue; | ||
2026 | } | ||
2027 | 2029 | ||
2030 | /* | ||
2031 | * we don't need to attach clean inodes or those only | ||
2032 | * with unlogged changes (which we throw away, anyway). | ||
2033 | */ | ||
2028 | iip = ip->i_itemp; | 2034 | iip = ip->i_itemp; |
2029 | if (!iip) { | 2035 | if (!iip || xfs_inode_clean(ip)) { |
2030 | /* inode with unlogged changes only */ | ||
2031 | ASSERT(ip != free_ip); | 2036 | ASSERT(ip != free_ip); |
2032 | ip->i_update_core = 0; | 2037 | ip->i_update_core = 0; |
2033 | xfs_ifunlock(ip); | 2038 | xfs_ifunlock(ip); |
2034 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 2039 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
2035 | continue; | 2040 | continue; |
2036 | } | 2041 | } |
2037 | found++; | ||
2038 | 2042 | ||
2039 | iip->ili_last_fields = iip->ili_format.ilf_fields; | 2043 | iip->ili_last_fields = iip->ili_format.ilf_fields; |
2040 | iip->ili_format.ilf_fields = 0; | 2044 | iip->ili_format.ilf_fields = 0; |
@@ -2049,8 +2053,7 @@ xfs_ifree_cluster( | |||
2049 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 2053 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
2050 | } | 2054 | } |
2051 | 2055 | ||
2052 | if (found) | 2056 | xfs_trans_stale_inode_buf(tp, bp); |
2053 | xfs_trans_stale_inode_buf(tp, bp); | ||
2054 | xfs_trans_binval(tp, bp); | 2057 | xfs_trans_binval(tp, bp); |
2055 | } | 2058 | } |
2056 | 2059 | ||
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 925d572bf0f..33f718f92a4 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -3015,7 +3015,8 @@ _xfs_log_force( | |||
3015 | 3015 | ||
3016 | XFS_STATS_INC(xs_log_force); | 3016 | XFS_STATS_INC(xs_log_force); |
3017 | 3017 | ||
3018 | xlog_cil_push(log, 1); | 3018 | if (log->l_cilp) |
3019 | xlog_cil_force(log); | ||
3019 | 3020 | ||
3020 | spin_lock(&log->l_icloglock); | 3021 | spin_lock(&log->l_icloglock); |
3021 | 3022 | ||
@@ -3167,7 +3168,7 @@ _xfs_log_force_lsn( | |||
3167 | XFS_STATS_INC(xs_log_force); | 3168 | XFS_STATS_INC(xs_log_force); |
3168 | 3169 | ||
3169 | if (log->l_cilp) { | 3170 | if (log->l_cilp) { |
3170 | lsn = xlog_cil_push_lsn(log, lsn); | 3171 | lsn = xlog_cil_force_lsn(log, lsn); |
3171 | if (lsn == NULLCOMMITLSN) | 3172 | if (lsn == NULLCOMMITLSN) |
3172 | return 0; | 3173 | return 0; |
3173 | } | 3174 | } |
@@ -3724,7 +3725,7 @@ xfs_log_force_umount( | |||
3724 | * call below. | 3725 | * call below. |
3725 | */ | 3726 | */ |
3726 | if (!logerror && (mp->m_flags & XFS_MOUNT_DELAYLOG)) | 3727 | if (!logerror && (mp->m_flags & XFS_MOUNT_DELAYLOG)) |
3727 | xlog_cil_push(log, 1); | 3728 | xlog_cil_force(log); |
3728 | 3729 | ||
3729 | /* | 3730 | /* |
3730 | * We must hold both the GRANT lock and the LOG lock, | 3731 | * We must hold both the GRANT lock and the LOG lock, |
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index 31e4ea2d19a..ed575fb4b49 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c | |||
@@ -68,6 +68,7 @@ xlog_cil_init( | |||
68 | ctx->sequence = 1; | 68 | ctx->sequence = 1; |
69 | ctx->cil = cil; | 69 | ctx->cil = cil; |
70 | cil->xc_ctx = ctx; | 70 | cil->xc_ctx = ctx; |
71 | cil->xc_current_sequence = ctx->sequence; | ||
71 | 72 | ||
72 | cil->xc_log = log; | 73 | cil->xc_log = log; |
73 | log->l_cilp = cil; | 74 | log->l_cilp = cil; |
@@ -269,15 +270,10 @@ xlog_cil_insert( | |||
269 | static void | 270 | static void |
270 | xlog_cil_format_items( | 271 | xlog_cil_format_items( |
271 | struct log *log, | 272 | struct log *log, |
272 | struct xfs_log_vec *log_vector, | 273 | struct xfs_log_vec *log_vector) |
273 | struct xlog_ticket *ticket, | ||
274 | xfs_lsn_t *start_lsn) | ||
275 | { | 274 | { |
276 | struct xfs_log_vec *lv; | 275 | struct xfs_log_vec *lv; |
277 | 276 | ||
278 | if (start_lsn) | ||
279 | *start_lsn = log->l_cilp->xc_ctx->sequence; | ||
280 | |||
281 | ASSERT(log_vector); | 277 | ASSERT(log_vector); |
282 | for (lv = log_vector; lv; lv = lv->lv_next) { | 278 | for (lv = log_vector; lv; lv = lv->lv_next) { |
283 | void *ptr; | 279 | void *ptr; |
@@ -301,9 +297,24 @@ xlog_cil_format_items( | |||
301 | ptr += vec->i_len; | 297 | ptr += vec->i_len; |
302 | } | 298 | } |
303 | ASSERT(ptr == lv->lv_buf + lv->lv_buf_len); | 299 | ASSERT(ptr == lv->lv_buf + lv->lv_buf_len); |
300 | } | ||
301 | } | ||
302 | |||
303 | static void | ||
304 | xlog_cil_insert_items( | ||
305 | struct log *log, | ||
306 | struct xfs_log_vec *log_vector, | ||
307 | struct xlog_ticket *ticket, | ||
308 | xfs_lsn_t *start_lsn) | ||
309 | { | ||
310 | struct xfs_log_vec *lv; | ||
311 | |||
312 | if (start_lsn) | ||
313 | *start_lsn = log->l_cilp->xc_ctx->sequence; | ||
304 | 314 | ||
315 | ASSERT(log_vector); | ||
316 | for (lv = log_vector; lv; lv = lv->lv_next) | ||
305 | xlog_cil_insert(log, ticket, lv->lv_item, lv); | 317 | xlog_cil_insert(log, ticket, lv->lv_item, lv); |
306 | } | ||
307 | } | 318 | } |
308 | 319 | ||
309 | static void | 320 | static void |
@@ -321,80 +332,6 @@ xlog_cil_free_logvec( | |||
321 | } | 332 | } |
322 | 333 | ||
323 | /* | 334 | /* |
324 | * Commit a transaction with the given vector to the Committed Item List. | ||
325 | * | ||
326 | * To do this, we need to format the item, pin it in memory if required and | ||
327 | * account for the space used by the transaction. Once we have done that we | ||
328 | * need to release the unused reservation for the transaction, attach the | ||
329 | * transaction to the checkpoint context so we carry the busy extents through | ||
330 | * to checkpoint completion, and then unlock all the items in the transaction. | ||
331 | * | ||
332 | * For more specific information about the order of operations in | ||
333 | * xfs_log_commit_cil() please refer to the comments in | ||
334 | * xfs_trans_commit_iclog(). | ||
335 | * | ||
336 | * Called with the context lock already held in read mode to lock out | ||
337 | * background commit, returns without it held once background commits are | ||
338 | * allowed again. | ||
339 | */ | ||
340 | int | ||
341 | xfs_log_commit_cil( | ||
342 | struct xfs_mount *mp, | ||
343 | struct xfs_trans *tp, | ||
344 | struct xfs_log_vec *log_vector, | ||
345 | xfs_lsn_t *commit_lsn, | ||
346 | int flags) | ||
347 | { | ||
348 | struct log *log = mp->m_log; | ||
349 | int log_flags = 0; | ||
350 | int push = 0; | ||
351 | |||
352 | if (flags & XFS_TRANS_RELEASE_LOG_RES) | ||
353 | log_flags = XFS_LOG_REL_PERM_RESERV; | ||
354 | |||
355 | if (XLOG_FORCED_SHUTDOWN(log)) { | ||
356 | xlog_cil_free_logvec(log_vector); | ||
357 | return XFS_ERROR(EIO); | ||
358 | } | ||
359 | |||
360 | /* lock out background commit */ | ||
361 | down_read(&log->l_cilp->xc_ctx_lock); | ||
362 | xlog_cil_format_items(log, log_vector, tp->t_ticket, commit_lsn); | ||
363 | |||
364 | /* check we didn't blow the reservation */ | ||
365 | if (tp->t_ticket->t_curr_res < 0) | ||
366 | xlog_print_tic_res(log->l_mp, tp->t_ticket); | ||
367 | |||
368 | /* attach the transaction to the CIL if it has any busy extents */ | ||
369 | if (!list_empty(&tp->t_busy)) { | ||
370 | spin_lock(&log->l_cilp->xc_cil_lock); | ||
371 | list_splice_init(&tp->t_busy, | ||
372 | &log->l_cilp->xc_ctx->busy_extents); | ||
373 | spin_unlock(&log->l_cilp->xc_cil_lock); | ||
374 | } | ||
375 | |||
376 | tp->t_commit_lsn = *commit_lsn; | ||
377 | xfs_log_done(mp, tp->t_ticket, NULL, log_flags); | ||
378 | xfs_trans_unreserve_and_mod_sb(tp); | ||
379 | |||
380 | /* check for background commit before unlock */ | ||
381 | if (log->l_cilp->xc_ctx->space_used > XLOG_CIL_SPACE_LIMIT(log)) | ||
382 | push = 1; | ||
383 | up_read(&log->l_cilp->xc_ctx_lock); | ||
384 | |||
385 | /* | ||
386 | * We need to push CIL every so often so we don't cache more than we | ||
387 | * can fit in the log. The limit really is that a checkpoint can't be | ||
388 | * more than half the log (the current checkpoint is not allowed to | ||
389 | * overwrite the previous checkpoint), but commit latency and memory | ||
390 | * usage limit this to a smaller size in most cases. | ||
391 | */ | ||
392 | if (push) | ||
393 | xlog_cil_push(log, 0); | ||
394 | return 0; | ||
395 | } | ||
396 | |||
397 | /* | ||
398 | * Mark all items committed and clear busy extents. We free the log vector | 335 | * Mark all items committed and clear busy extents. We free the log vector |
399 | * chains in a separate pass so that we unpin the log items as quickly as | 336 | * chains in a separate pass so that we unpin the log items as quickly as |
400 | * possible. | 337 | * possible. |
@@ -427,13 +364,23 @@ xlog_cil_committed( | |||
427 | } | 364 | } |
428 | 365 | ||
429 | /* | 366 | /* |
430 | * Push the Committed Item List to the log. If the push_now flag is not set, | 367 | * Push the Committed Item List to the log. If @push_seq flag is zero, then it |
431 | * then it is a background flush and so we can chose to ignore it. | 368 | * is a background flush and so we can chose to ignore it. Otherwise, if the |
369 | * current sequence is the same as @push_seq we need to do a flush. If | ||
370 | * @push_seq is less than the current sequence, then it has already been | ||
371 | * flushed and we don't need to do anything - the caller will wait for it to | ||
372 | * complete if necessary. | ||
373 | * | ||
374 | * @push_seq is a value rather than a flag because that allows us to do an | ||
375 | * unlocked check of the sequence number for a match. Hence we can allows log | ||
376 | * forces to run racily and not issue pushes for the same sequence twice. If we | ||
377 | * get a race between multiple pushes for the same sequence they will block on | ||
378 | * the first one and then abort, hence avoiding needless pushes. | ||
432 | */ | 379 | */ |
433 | int | 380 | STATIC int |
434 | xlog_cil_push( | 381 | xlog_cil_push( |
435 | struct log *log, | 382 | struct log *log, |
436 | int push_now) | 383 | xfs_lsn_t push_seq) |
437 | { | 384 | { |
438 | struct xfs_cil *cil = log->l_cilp; | 385 | struct xfs_cil *cil = log->l_cilp; |
439 | struct xfs_log_vec *lv; | 386 | struct xfs_log_vec *lv; |
@@ -453,12 +400,14 @@ xlog_cil_push( | |||
453 | if (!cil) | 400 | if (!cil) |
454 | return 0; | 401 | return 0; |
455 | 402 | ||
403 | ASSERT(!push_seq || push_seq <= cil->xc_ctx->sequence); | ||
404 | |||
456 | new_ctx = kmem_zalloc(sizeof(*new_ctx), KM_SLEEP|KM_NOFS); | 405 | new_ctx = kmem_zalloc(sizeof(*new_ctx), KM_SLEEP|KM_NOFS); |
457 | new_ctx->ticket = xlog_cil_ticket_alloc(log); | 406 | new_ctx->ticket = xlog_cil_ticket_alloc(log); |
458 | 407 | ||
459 | /* lock out transaction commit, but don't block on background push */ | 408 | /* lock out transaction commit, but don't block on background push */ |
460 | if (!down_write_trylock(&cil->xc_ctx_lock)) { | 409 | if (!down_write_trylock(&cil->xc_ctx_lock)) { |
461 | if (!push_now) | 410 | if (!push_seq) |
462 | goto out_free_ticket; | 411 | goto out_free_ticket; |
463 | down_write(&cil->xc_ctx_lock); | 412 | down_write(&cil->xc_ctx_lock); |
464 | } | 413 | } |
@@ -469,7 +418,11 @@ xlog_cil_push( | |||
469 | goto out_skip; | 418 | goto out_skip; |
470 | 419 | ||
471 | /* check for spurious background flush */ | 420 | /* check for spurious background flush */ |
472 | if (!push_now && cil->xc_ctx->space_used < XLOG_CIL_SPACE_LIMIT(log)) | 421 | if (!push_seq && cil->xc_ctx->space_used < XLOG_CIL_SPACE_LIMIT(log)) |
422 | goto out_skip; | ||
423 | |||
424 | /* check for a previously pushed seqeunce */ | ||
425 | if (push_seq < cil->xc_ctx->sequence) | ||
473 | goto out_skip; | 426 | goto out_skip; |
474 | 427 | ||
475 | /* | 428 | /* |
@@ -515,6 +468,13 @@ xlog_cil_push( | |||
515 | cil->xc_ctx = new_ctx; | 468 | cil->xc_ctx = new_ctx; |
516 | 469 | ||
517 | /* | 470 | /* |
471 | * mirror the new sequence into the cil structure so that we can do | ||
472 | * unlocked checks against the current sequence in log forces without | ||
473 | * risking deferencing a freed context pointer. | ||
474 | */ | ||
475 | cil->xc_current_sequence = new_ctx->sequence; | ||
476 | |||
477 | /* | ||
518 | * The switch is now done, so we can drop the context lock and move out | 478 | * The switch is now done, so we can drop the context lock and move out |
519 | * of a shared context. We can't just go straight to the commit record, | 479 | * of a shared context. We can't just go straight to the commit record, |
520 | * though - we need to synchronise with previous and future commits so | 480 | * though - we need to synchronise with previous and future commits so |
@@ -626,6 +586,102 @@ out_abort: | |||
626 | } | 586 | } |
627 | 587 | ||
628 | /* | 588 | /* |
589 | * Commit a transaction with the given vector to the Committed Item List. | ||
590 | * | ||
591 | * To do this, we need to format the item, pin it in memory if required and | ||
592 | * account for the space used by the transaction. Once we have done that we | ||
593 | * need to release the unused reservation for the transaction, attach the | ||
594 | * transaction to the checkpoint context so we carry the busy extents through | ||
595 | * to checkpoint completion, and then unlock all the items in the transaction. | ||
596 | * | ||
597 | * For more specific information about the order of operations in | ||
598 | * xfs_log_commit_cil() please refer to the comments in | ||
599 | * xfs_trans_commit_iclog(). | ||
600 | * | ||
601 | * Called with the context lock already held in read mode to lock out | ||
602 | * background commit, returns without it held once background commits are | ||
603 | * allowed again. | ||
604 | */ | ||
605 | int | ||
606 | xfs_log_commit_cil( | ||
607 | struct xfs_mount *mp, | ||
608 | struct xfs_trans *tp, | ||
609 | struct xfs_log_vec *log_vector, | ||
610 | xfs_lsn_t *commit_lsn, | ||
611 | int flags) | ||
612 | { | ||
613 | struct log *log = mp->m_log; | ||
614 | int log_flags = 0; | ||
615 | int push = 0; | ||
616 | |||
617 | if (flags & XFS_TRANS_RELEASE_LOG_RES) | ||
618 | log_flags = XFS_LOG_REL_PERM_RESERV; | ||
619 | |||
620 | if (XLOG_FORCED_SHUTDOWN(log)) { | ||
621 | xlog_cil_free_logvec(log_vector); | ||
622 | return XFS_ERROR(EIO); | ||
623 | } | ||
624 | |||
625 | /* | ||
626 | * do all the hard work of formatting items (including memory | ||
627 | * allocation) outside the CIL context lock. This prevents stalling CIL | ||
628 | * pushes when we are low on memory and a transaction commit spends a | ||
629 | * lot of time in memory reclaim. | ||
630 | */ | ||
631 | xlog_cil_format_items(log, log_vector); | ||
632 | |||
633 | /* lock out background commit */ | ||
634 | down_read(&log->l_cilp->xc_ctx_lock); | ||
635 | xlog_cil_insert_items(log, log_vector, tp->t_ticket, commit_lsn); | ||
636 | |||
637 | /* check we didn't blow the reservation */ | ||
638 | if (tp->t_ticket->t_curr_res < 0) | ||
639 | xlog_print_tic_res(log->l_mp, tp->t_ticket); | ||
640 | |||
641 | /* attach the transaction to the CIL if it has any busy extents */ | ||
642 | if (!list_empty(&tp->t_busy)) { | ||
643 | spin_lock(&log->l_cilp->xc_cil_lock); | ||
644 | list_splice_init(&tp->t_busy, | ||
645 | &log->l_cilp->xc_ctx->busy_extents); | ||
646 | spin_unlock(&log->l_cilp->xc_cil_lock); | ||
647 | } | ||
648 | |||
649 | tp->t_commit_lsn = *commit_lsn; | ||
650 | xfs_log_done(mp, tp->t_ticket, NULL, log_flags); | ||
651 | xfs_trans_unreserve_and_mod_sb(tp); | ||
652 | |||
653 | /* | ||
654 | * Once all the items of the transaction have been copied to the CIL, | ||
655 | * the items can be unlocked and freed. | ||
656 | * | ||
657 | * This needs to be done before we drop the CIL context lock because we | ||
658 | * have to update state in the log items and unlock them before they go | ||
659 | * to disk. If we don't, then the CIL checkpoint can race with us and | ||
660 | * we can run checkpoint completion before we've updated and unlocked | ||
661 | * the log items. This affects (at least) processing of stale buffers, | ||
662 | * inodes and EFIs. | ||
663 | */ | ||
664 | xfs_trans_free_items(tp, *commit_lsn, 0); | ||
665 | |||
666 | /* check for background commit before unlock */ | ||
667 | if (log->l_cilp->xc_ctx->space_used > XLOG_CIL_SPACE_LIMIT(log)) | ||
668 | push = 1; | ||
669 | |||
670 | up_read(&log->l_cilp->xc_ctx_lock); | ||
671 | |||
672 | /* | ||
673 | * We need to push CIL every so often so we don't cache more than we | ||
674 | * can fit in the log. The limit really is that a checkpoint can't be | ||
675 | * more than half the log (the current checkpoint is not allowed to | ||
676 | * overwrite the previous checkpoint), but commit latency and memory | ||
677 | * usage limit this to a smaller size in most cases. | ||
678 | */ | ||
679 | if (push) | ||
680 | xlog_cil_push(log, 0); | ||
681 | return 0; | ||
682 | } | ||
683 | |||
684 | /* | ||
629 | * Conditionally push the CIL based on the sequence passed in. | 685 | * Conditionally push the CIL based on the sequence passed in. |
630 | * | 686 | * |
631 | * We only need to push if we haven't already pushed the sequence | 687 | * We only need to push if we haven't already pushed the sequence |
@@ -639,39 +695,34 @@ out_abort: | |||
639 | * commit lsn is there. It'll be empty, so this is broken for now. | 695 | * commit lsn is there. It'll be empty, so this is broken for now. |
640 | */ | 696 | */ |
641 | xfs_lsn_t | 697 | xfs_lsn_t |
642 | xlog_cil_push_lsn( | 698 | xlog_cil_force_lsn( |
643 | struct log *log, | 699 | struct log *log, |
644 | xfs_lsn_t push_seq) | 700 | xfs_lsn_t sequence) |
645 | { | 701 | { |
646 | struct xfs_cil *cil = log->l_cilp; | 702 | struct xfs_cil *cil = log->l_cilp; |
647 | struct xfs_cil_ctx *ctx; | 703 | struct xfs_cil_ctx *ctx; |
648 | xfs_lsn_t commit_lsn = NULLCOMMITLSN; | 704 | xfs_lsn_t commit_lsn = NULLCOMMITLSN; |
649 | 705 | ||
650 | restart: | 706 | ASSERT(sequence <= cil->xc_current_sequence); |
651 | down_write(&cil->xc_ctx_lock); | 707 | |
652 | ASSERT(push_seq <= cil->xc_ctx->sequence); | 708 | /* |
653 | 709 | * check to see if we need to force out the current context. | |
654 | /* check to see if we need to force out the current context */ | 710 | * xlog_cil_push() handles racing pushes for the same sequence, |
655 | if (push_seq == cil->xc_ctx->sequence) { | 711 | * so no need to deal with it here. |
656 | up_write(&cil->xc_ctx_lock); | 712 | */ |
657 | xlog_cil_push(log, 1); | 713 | if (sequence == cil->xc_current_sequence) |
658 | goto restart; | 714 | xlog_cil_push(log, sequence); |
659 | } | ||
660 | 715 | ||
661 | /* | 716 | /* |
662 | * See if we can find a previous sequence still committing. | 717 | * See if we can find a previous sequence still committing. |
663 | * We can drop the flush lock as soon as we have the cil lock | ||
664 | * because we are now only comparing contexts protected by | ||
665 | * the cil lock. | ||
666 | * | ||
667 | * We need to wait for all previous sequence commits to complete | 718 | * We need to wait for all previous sequence commits to complete |
668 | * before allowing the force of push_seq to go ahead. Hence block | 719 | * before allowing the force of push_seq to go ahead. Hence block |
669 | * on commits for those as well. | 720 | * on commits for those as well. |
670 | */ | 721 | */ |
722 | restart: | ||
671 | spin_lock(&cil->xc_cil_lock); | 723 | spin_lock(&cil->xc_cil_lock); |
672 | up_write(&cil->xc_ctx_lock); | ||
673 | list_for_each_entry(ctx, &cil->xc_committing, committing) { | 724 | list_for_each_entry(ctx, &cil->xc_committing, committing) { |
674 | if (ctx->sequence > push_seq) | 725 | if (ctx->sequence > sequence) |
675 | continue; | 726 | continue; |
676 | if (!ctx->commit_lsn) { | 727 | if (!ctx->commit_lsn) { |
677 | /* | 728 | /* |
@@ -681,7 +732,7 @@ restart: | |||
681 | sv_wait(&cil->xc_commit_wait, 0, &cil->xc_cil_lock, 0); | 732 | sv_wait(&cil->xc_commit_wait, 0, &cil->xc_cil_lock, 0); |
682 | goto restart; | 733 | goto restart; |
683 | } | 734 | } |
684 | if (ctx->sequence != push_seq) | 735 | if (ctx->sequence != sequence) |
685 | continue; | 736 | continue; |
686 | /* found it! */ | 737 | /* found it! */ |
687 | commit_lsn = ctx->commit_lsn; | 738 | commit_lsn = ctx->commit_lsn; |
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 8c072618965..ced52b98b32 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h | |||
@@ -422,6 +422,7 @@ struct xfs_cil { | |||
422 | struct rw_semaphore xc_ctx_lock; | 422 | struct rw_semaphore xc_ctx_lock; |
423 | struct list_head xc_committing; | 423 | struct list_head xc_committing; |
424 | sv_t xc_commit_wait; | 424 | sv_t xc_commit_wait; |
425 | xfs_lsn_t xc_current_sequence; | ||
425 | }; | 426 | }; |
426 | 427 | ||
427 | /* | 428 | /* |
@@ -562,8 +563,16 @@ int xlog_cil_init(struct log *log); | |||
562 | void xlog_cil_init_post_recovery(struct log *log); | 563 | void xlog_cil_init_post_recovery(struct log *log); |
563 | void xlog_cil_destroy(struct log *log); | 564 | void xlog_cil_destroy(struct log *log); |
564 | 565 | ||
565 | int xlog_cil_push(struct log *log, int push_now); | 566 | /* |
566 | xfs_lsn_t xlog_cil_push_lsn(struct log *log, xfs_lsn_t push_sequence); | 567 | * CIL force routines |
568 | */ | ||
569 | xfs_lsn_t xlog_cil_force_lsn(struct log *log, xfs_lsn_t sequence); | ||
570 | |||
571 | static inline void | ||
572 | xlog_cil_force(struct log *log) | ||
573 | { | ||
574 | xlog_cil_force_lsn(log, log->l_cilp->xc_current_sequence); | ||
575 | } | ||
567 | 576 | ||
568 | /* | 577 | /* |
569 | * Unmount record type is used as a pseudo transaction type for the ticket. | 578 | * Unmount record type is used as a pseudo transaction type for the ticket. |
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index fdca7416c75..1c47edaea0d 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -1167,7 +1167,7 @@ xfs_trans_del_item( | |||
1167 | * Unlock all of the items of a transaction and free all the descriptors | 1167 | * Unlock all of the items of a transaction and free all the descriptors |
1168 | * of that transaction. | 1168 | * of that transaction. |
1169 | */ | 1169 | */ |
1170 | STATIC void | 1170 | void |
1171 | xfs_trans_free_items( | 1171 | xfs_trans_free_items( |
1172 | struct xfs_trans *tp, | 1172 | struct xfs_trans *tp, |
1173 | xfs_lsn_t commit_lsn, | 1173 | xfs_lsn_t commit_lsn, |
@@ -1653,9 +1653,6 @@ xfs_trans_commit_cil( | |||
1653 | return error; | 1653 | return error; |
1654 | 1654 | ||
1655 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); | 1655 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); |
1656 | |||
1657 | /* xfs_trans_free_items() unlocks them first */ | ||
1658 | xfs_trans_free_items(tp, *commit_lsn, 0); | ||
1659 | xfs_trans_free(tp); | 1656 | xfs_trans_free(tp); |
1660 | return 0; | 1657 | return 0; |
1661 | } | 1658 | } |
diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h index e2d93d8ead7..62da86c90de 100644 --- a/fs/xfs/xfs_trans_priv.h +++ b/fs/xfs/xfs_trans_priv.h | |||
@@ -25,7 +25,8 @@ struct xfs_trans; | |||
25 | 25 | ||
26 | void xfs_trans_add_item(struct xfs_trans *, struct xfs_log_item *); | 26 | void xfs_trans_add_item(struct xfs_trans *, struct xfs_log_item *); |
27 | void xfs_trans_del_item(struct xfs_log_item *); | 27 | void xfs_trans_del_item(struct xfs_log_item *); |
28 | 28 | void xfs_trans_free_items(struct xfs_trans *tp, xfs_lsn_t commit_lsn, | |
29 | int flags); | ||
29 | void xfs_trans_item_committed(struct xfs_log_item *lip, | 30 | void xfs_trans_item_committed(struct xfs_log_item *lip, |
30 | xfs_lsn_t commit_lsn, int aborted); | 31 | xfs_lsn_t commit_lsn, int aborted); |
31 | void xfs_trans_unreserve_and_mod_sb(struct xfs_trans *tp); | 32 | void xfs_trans_unreserve_and_mod_sb(struct xfs_trans *tp); |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 66d585c6917..4c7c7bfb2b2 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -2299,15 +2299,22 @@ xfs_alloc_file_space( | |||
2299 | e = allocatesize_fsb; | 2299 | e = allocatesize_fsb; |
2300 | } | 2300 | } |
2301 | 2301 | ||
2302 | /* | ||
2303 | * The transaction reservation is limited to a 32-bit block | ||
2304 | * count, hence we need to limit the number of blocks we are | ||
2305 | * trying to reserve to avoid an overflow. We can't allocate | ||
2306 | * more than @nimaps extents, and an extent is limited on disk | ||
2307 | * to MAXEXTLEN (21 bits), so use that to enforce the limit. | ||
2308 | */ | ||
2309 | resblks = min_t(xfs_fileoff_t, (e - s), (MAXEXTLEN * nimaps)); | ||
2302 | if (unlikely(rt)) { | 2310 | if (unlikely(rt)) { |
2303 | resrtextents = qblocks = (uint)(e - s); | 2311 | resrtextents = qblocks = resblks; |
2304 | resrtextents /= mp->m_sb.sb_rextsize; | 2312 | resrtextents /= mp->m_sb.sb_rextsize; |
2305 | resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0); | 2313 | resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0); |
2306 | quota_flag = XFS_QMOPT_RES_RTBLKS; | 2314 | quota_flag = XFS_QMOPT_RES_RTBLKS; |
2307 | } else { | 2315 | } else { |
2308 | resrtextents = 0; | 2316 | resrtextents = 0; |
2309 | resblks = qblocks = \ | 2317 | resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, resblks); |
2310 | XFS_DIOSTRAT_SPACE_RES(mp, (uint)(e - s)); | ||
2311 | quota_flag = XFS_QMOPT_RES_REGBLKS; | 2318 | quota_flag = XFS_QMOPT_RES_REGBLKS; |
2312 | } | 2319 | } |
2313 | 2320 | ||
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index baacd98e7cc..4de84ce3a92 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -377,9 +377,6 @@ struct acpi_pci_root { | |||
377 | 377 | ||
378 | u32 osc_support_set; /* _OSC state of support bits */ | 378 | u32 osc_support_set; /* _OSC state of support bits */ |
379 | u32 osc_control_set; /* _OSC state of control bits */ | 379 | u32 osc_control_set; /* _OSC state of control bits */ |
380 | u32 osc_control_qry; /* the latest _OSC query result */ | ||
381 | |||
382 | u32 osc_queried:1; /* has _OSC control been queried? */ | ||
383 | }; | 380 | }; |
384 | 381 | ||
385 | /* helper */ | 382 | /* helper */ |
diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h index b5043a9890d..08923b68476 100644 --- a/include/asm-generic/percpu.h +++ b/include/asm-generic/percpu.h | |||
@@ -70,11 +70,16 @@ extern void setup_per_cpu_areas(void); | |||
70 | 70 | ||
71 | #else /* ! SMP */ | 71 | #else /* ! SMP */ |
72 | 72 | ||
73 | #define per_cpu(var, cpu) (*((void)(cpu), &(var))) | 73 | #define VERIFY_PERCPU_PTR(__p) ({ \ |
74 | #define __get_cpu_var(var) (var) | 74 | __verify_pcpu_ptr((__p)); \ |
75 | #define __raw_get_cpu_var(var) (var) | 75 | (typeof(*(__p)) __kernel __force *)(__p); \ |
76 | #define this_cpu_ptr(ptr) per_cpu_ptr(ptr, 0) | 76 | }) |
77 | #define __this_cpu_ptr(ptr) this_cpu_ptr(ptr) | 77 | |
78 | #define per_cpu(var, cpu) (*((void)(cpu), VERIFY_PERCPU_PTR(&(var)))) | ||
79 | #define __get_cpu_var(var) (*VERIFY_PERCPU_PTR(&(var))) | ||
80 | #define __raw_get_cpu_var(var) (*VERIFY_PERCPU_PTR(&(var))) | ||
81 | #define this_cpu_ptr(ptr) per_cpu_ptr(ptr, 0) | ||
82 | #define __this_cpu_ptr(ptr) this_cpu_ptr(ptr) | ||
78 | 83 | ||
79 | #endif /* SMP */ | 84 | #endif /* SMP */ |
80 | 85 | ||
diff --git a/include/asm-generic/syscalls.h b/include/asm-generic/syscalls.h index df84e3b0455..d89dec864d4 100644 --- a/include/asm-generic/syscalls.h +++ b/include/asm-generic/syscalls.h | |||
@@ -23,8 +23,10 @@ asmlinkage long sys_vfork(struct pt_regs *regs); | |||
23 | #endif | 23 | #endif |
24 | 24 | ||
25 | #ifndef sys_execve | 25 | #ifndef sys_execve |
26 | asmlinkage long sys_execve(char __user *filename, char __user * __user *argv, | 26 | asmlinkage long sys_execve(const char __user *filename, |
27 | char __user * __user *envp, struct pt_regs *regs); | 27 | const char __user *const __user *argv, |
28 | const char __user *const __user *envp, | ||
29 | struct pt_regs *regs); | ||
28 | #endif | 30 | #endif |
29 | 31 | ||
30 | #ifndef sys_mmap2 | 32 | #ifndef sys_mmap2 |
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 2a512bc0d4a..7809d230ade 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
@@ -305,14 +305,16 @@ struct drm_ioctl_desc { | |||
305 | unsigned int cmd; | 305 | unsigned int cmd; |
306 | int flags; | 306 | int flags; |
307 | drm_ioctl_t *func; | 307 | drm_ioctl_t *func; |
308 | unsigned int cmd_drv; | ||
308 | }; | 309 | }; |
309 | 310 | ||
310 | /** | 311 | /** |
311 | * Creates a driver or general drm_ioctl_desc array entry for the given | 312 | * Creates a driver or general drm_ioctl_desc array entry for the given |
312 | * ioctl, for use by drm_ioctl(). | 313 | * ioctl, for use by drm_ioctl(). |
313 | */ | 314 | */ |
314 | #define DRM_IOCTL_DEF(ioctl, _func, _flags) \ | 315 | |
315 | [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags} | 316 | #define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \ |
317 | [DRM_IOCTL_NR(DRM_##ioctl)] = {.cmd = DRM_##ioctl, .func = _func, .flags = _flags, .cmd_drv = DRM_IOCTL_##ioctl} | ||
316 | 318 | ||
317 | struct drm_magic_entry { | 319 | struct drm_magic_entry { |
318 | struct list_head head; | 320 | struct list_head head; |
diff --git a/include/drm/i830_drm.h b/include/drm/i830_drm.h index 4b00d2dd4f6..61315c29b8f 100644 --- a/include/drm/i830_drm.h +++ b/include/drm/i830_drm.h | |||
@@ -264,20 +264,20 @@ typedef struct _drm_i830_sarea { | |||
264 | #define DRM_I830_GETPARAM 0x0c | 264 | #define DRM_I830_GETPARAM 0x0c |
265 | #define DRM_I830_SETPARAM 0x0d | 265 | #define DRM_I830_SETPARAM 0x0d |
266 | 266 | ||
267 | #define DRM_IOCTL_I830_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_INIT, drm_i830_init_t) | 267 | #define DRM_IOCTL_I830_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I830_INIT, drm_i830_init_t) |
268 | #define DRM_IOCTL_I830_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_VERTEX, drm_i830_vertex_t) | 268 | #define DRM_IOCTL_I830_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_I830_VERTEX, drm_i830_vertex_t) |
269 | #define DRM_IOCTL_I830_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_CLEAR, drm_i830_clear_t) | 269 | #define DRM_IOCTL_I830_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_I830_CLEAR, drm_i830_clear_t) |
270 | #define DRM_IOCTL_I830_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_FLUSH) | 270 | #define DRM_IOCTL_I830_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I830_FLUSH) |
271 | #define DRM_IOCTL_I830_GETAGE DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_GETAGE) | 271 | #define DRM_IOCTL_I830_GETAGE DRM_IO ( DRM_COMMAND_BASE + DRM_I830_GETAGE) |
272 | #define DRM_IOCTL_I830_GETBUF DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_GETBUF, drm_i830_dma_t) | 272 | #define DRM_IOCTL_I830_GETBUF DRM_IOWR(DRM_COMMAND_BASE + DRM_I830_GETBUF, drm_i830_dma_t) |
273 | #define DRM_IOCTL_I830_SWAP DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_SWAP) | 273 | #define DRM_IOCTL_I830_SWAP DRM_IO ( DRM_COMMAND_BASE + DRM_I830_SWAP) |
274 | #define DRM_IOCTL_I830_COPY DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_COPY, drm_i830_copy_t) | 274 | #define DRM_IOCTL_I830_COPY DRM_IOW( DRM_COMMAND_BASE + DRM_I830_COPY, drm_i830_copy_t) |
275 | #define DRM_IOCTL_I830_DOCOPY DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_DOCOPY) | 275 | #define DRM_IOCTL_I830_DOCOPY DRM_IO ( DRM_COMMAND_BASE + DRM_I830_DOCOPY) |
276 | #define DRM_IOCTL_I830_FLIP DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_FLIP) | 276 | #define DRM_IOCTL_I830_FLIP DRM_IO ( DRM_COMMAND_BASE + DRM_I830_FLIP) |
277 | #define DRM_IOCTL_I830_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_IRQ_EMIT, drm_i830_irq_emit_t) | 277 | #define DRM_IOCTL_I830_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I830_IRQ_EMIT, drm_i830_irq_emit_t) |
278 | #define DRM_IOCTL_I830_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_IRQ_WAIT, drm_i830_irq_wait_t) | 278 | #define DRM_IOCTL_I830_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_I830_IRQ_WAIT, drm_i830_irq_wait_t) |
279 | #define DRM_IOCTL_I830_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_GETPARAM, drm_i830_getparam_t) | 279 | #define DRM_IOCTL_I830_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I830_GETPARAM, drm_i830_getparam_t) |
280 | #define DRM_IOCTL_I830_SETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_SETPARAM, drm_i830_setparam_t) | 280 | #define DRM_IOCTL_I830_SETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I830_SETPARAM, drm_i830_setparam_t) |
281 | 281 | ||
282 | typedef struct _drm_i830_clear { | 282 | typedef struct _drm_i830_clear { |
283 | int clear_color; | 283 | int clear_color; |
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 8f8b072c4c7..e41c74facb6 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h | |||
@@ -215,6 +215,7 @@ typedef struct _drm_i915_sarea { | |||
215 | #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t) | 215 | #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t) |
216 | #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) | 216 | #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) |
217 | #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) | 217 | #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) |
218 | #define DRM_IOCTL_I915_HWS_ADDR DRM_IOW(DRM_COMMAND_BASE + DRM_I915_HWS_ADDR, struct drm_i915_gem_init) | ||
218 | #define DRM_IOCTL_I915_GEM_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_INIT, struct drm_i915_gem_init) | 219 | #define DRM_IOCTL_I915_GEM_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_INIT, struct drm_i915_gem_init) |
219 | #define DRM_IOCTL_I915_GEM_EXECBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER, struct drm_i915_gem_execbuffer) | 220 | #define DRM_IOCTL_I915_GEM_EXECBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER, struct drm_i915_gem_execbuffer) |
220 | #define DRM_IOCTL_I915_GEM_EXECBUFFER2 DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2) | 221 | #define DRM_IOCTL_I915_GEM_EXECBUFFER2 DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2) |
diff --git a/include/drm/mga_drm.h b/include/drm/mga_drm.h index 3ffbc4798af..c16097f99be 100644 --- a/include/drm/mga_drm.h +++ b/include/drm/mga_drm.h | |||
@@ -248,7 +248,7 @@ typedef struct _drm_mga_sarea { | |||
248 | #define DRM_MGA_DMA_BOOTSTRAP 0x0c | 248 | #define DRM_MGA_DMA_BOOTSTRAP 0x0c |
249 | 249 | ||
250 | #define DRM_IOCTL_MGA_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t) | 250 | #define DRM_IOCTL_MGA_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t) |
251 | #define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, drm_lock_t) | 251 | #define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, struct drm_lock) |
252 | #define DRM_IOCTL_MGA_RESET DRM_IO( DRM_COMMAND_BASE + DRM_MGA_RESET) | 252 | #define DRM_IOCTL_MGA_RESET DRM_IO( DRM_COMMAND_BASE + DRM_MGA_RESET) |
253 | #define DRM_IOCTL_MGA_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_MGA_SWAP) | 253 | #define DRM_IOCTL_MGA_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_MGA_SWAP) |
254 | #define DRM_IOCTL_MGA_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_CLEAR, drm_mga_clear_t) | 254 | #define DRM_IOCTL_MGA_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_CLEAR, drm_mga_clear_t) |
diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h index fe917dee723..01a71411950 100644 --- a/include/drm/nouveau_drm.h +++ b/include/drm/nouveau_drm.h | |||
@@ -197,4 +197,17 @@ struct drm_nouveau_sarea { | |||
197 | #define DRM_NOUVEAU_GEM_CPU_FINI 0x43 | 197 | #define DRM_NOUVEAU_GEM_CPU_FINI 0x43 |
198 | #define DRM_NOUVEAU_GEM_INFO 0x44 | 198 | #define DRM_NOUVEAU_GEM_INFO 0x44 |
199 | 199 | ||
200 | #define DRM_IOCTL_NOUVEAU_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GETPARAM, struct drm_nouveau_getparam) | ||
201 | #define DRM_IOCTL_NOUVEAU_SETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_SETPARAM, struct drm_nouveau_setparam) | ||
202 | #define DRM_IOCTL_NOUVEAU_CHANNEL_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_CHANNEL_ALLOC, struct drm_nouveau_channel_alloc) | ||
203 | #define DRM_IOCTL_NOUVEAU_CHANNEL_FREE DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_CHANNEL_FREE, struct drm_nouveau_channel_free) | ||
204 | #define DRM_IOCTL_NOUVEAU_GROBJ_ALLOC DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GROBJ_ALLOC, struct drm_nouveau_grobj_alloc) | ||
205 | #define DRM_IOCTL_NOUVEAU_NOTIFIEROBJ_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, struct drm_nouveau_notifierobj_alloc) | ||
206 | #define DRM_IOCTL_NOUVEAU_GPUOBJ_FREE DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GPUOBJ_FREE, struct drm_nouveau_gpuobj_free) | ||
207 | #define DRM_IOCTL_NOUVEAU_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_NEW, struct drm_nouveau_gem_new) | ||
208 | #define DRM_IOCTL_NOUVEAU_GEM_PUSHBUF DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_PUSHBUF, struct drm_nouveau_gem_pushbuf) | ||
209 | #define DRM_IOCTL_NOUVEAU_GEM_CPU_PREP DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_PREP, struct drm_nouveau_gem_cpu_prep) | ||
210 | #define DRM_IOCTL_NOUVEAU_GEM_CPU_FINI DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_FINI, struct drm_nouveau_gem_cpu_fini) | ||
211 | #define DRM_IOCTL_NOUVEAU_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_INFO, struct drm_nouveau_gem_info) | ||
212 | |||
200 | #endif /* __NOUVEAU_DRM_H__ */ | 213 | #endif /* __NOUVEAU_DRM_H__ */ |
diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h index 0acaf8f9143..10f8b53bdd4 100644 --- a/include/drm/radeon_drm.h +++ b/include/drm/radeon_drm.h | |||
@@ -547,8 +547,8 @@ typedef struct { | |||
547 | #define DRM_IOCTL_RADEON_GEM_WAIT_IDLE DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_IDLE, struct drm_radeon_gem_wait_idle) | 547 | #define DRM_IOCTL_RADEON_GEM_WAIT_IDLE DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_IDLE, struct drm_radeon_gem_wait_idle) |
548 | #define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs) | 548 | #define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs) |
549 | #define DRM_IOCTL_RADEON_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_INFO, struct drm_radeon_info) | 549 | #define DRM_IOCTL_RADEON_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_INFO, struct drm_radeon_info) |
550 | #define DRM_IOCTL_RADEON_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_TILING, struct drm_radeon_gem_set_tiling) | 550 | #define DRM_IOCTL_RADEON_GEM_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_TILING, struct drm_radeon_gem_set_tiling) |
551 | #define DRM_IOCTL_RADEON_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_GET_TILING, struct drm_radeon_gem_get_tiling) | 551 | #define DRM_IOCTL_RADEON_GEM_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_GET_TILING, struct drm_radeon_gem_get_tiling) |
552 | #define DRM_IOCTL_RADEON_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_BUSY, struct drm_radeon_gem_busy) | 552 | #define DRM_IOCTL_RADEON_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_BUSY, struct drm_radeon_gem_busy) |
553 | 553 | ||
554 | typedef struct drm_radeon_init { | 554 | typedef struct drm_radeon_init { |
diff --git a/include/drm/savage_drm.h b/include/drm/savage_drm.h index 8a576ef0182..4863cf6bf96 100644 --- a/include/drm/savage_drm.h +++ b/include/drm/savage_drm.h | |||
@@ -63,10 +63,10 @@ typedef struct _drm_savage_sarea { | |||
63 | #define DRM_SAVAGE_BCI_EVENT_EMIT 0x02 | 63 | #define DRM_SAVAGE_BCI_EVENT_EMIT 0x02 |
64 | #define DRM_SAVAGE_BCI_EVENT_WAIT 0x03 | 64 | #define DRM_SAVAGE_BCI_EVENT_WAIT 0x03 |
65 | 65 | ||
66 | #define DRM_IOCTL_SAVAGE_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_INIT, drm_savage_init_t) | 66 | #define DRM_IOCTL_SAVAGE_BCI_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_INIT, drm_savage_init_t) |
67 | #define DRM_IOCTL_SAVAGE_CMDBUF DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_CMDBUF, drm_savage_cmdbuf_t) | 67 | #define DRM_IOCTL_SAVAGE_BCI_CMDBUF DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_CMDBUF, drm_savage_cmdbuf_t) |
68 | #define DRM_IOCTL_SAVAGE_EVENT_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_EMIT, drm_savage_event_emit_t) | 68 | #define DRM_IOCTL_SAVAGE_BCI_EVENT_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_EMIT, drm_savage_event_emit_t) |
69 | #define DRM_IOCTL_SAVAGE_EVENT_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_WAIT, drm_savage_event_wait_t) | 69 | #define DRM_IOCTL_SAVAGE_BCI_EVENT_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_WAIT, drm_savage_event_wait_t) |
70 | 70 | ||
71 | #define SAVAGE_DMA_PCI 1 | 71 | #define SAVAGE_DMA_PCI 1 |
72 | #define SAVAGE_DMA_AGP 3 | 72 | #define SAVAGE_DMA_AGP 3 |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index ccf94dc5acd..c227757feb0 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -304,8 +304,8 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context); | |||
304 | OSC_PCI_EXPRESS_PME_CONTROL | \ | 304 | OSC_PCI_EXPRESS_PME_CONTROL | \ |
305 | OSC_PCI_EXPRESS_AER_CONTROL | \ | 305 | OSC_PCI_EXPRESS_AER_CONTROL | \ |
306 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL) | 306 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL) |
307 | 307 | extern acpi_status acpi_pci_osc_control_set(acpi_handle handle, | |
308 | extern acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags); | 308 | u32 *mask, u32 req); |
309 | extern void acpi_early_init(void); | 309 | extern void acpi_early_init(void); |
310 | 310 | ||
311 | #else /* !CONFIG_ACPI */ | 311 | #else /* !CONFIG_ACPI */ |
diff --git a/include/linux/amba/clcd.h b/include/linux/amba/clcd.h index ca16c3801a1..be33b3affc8 100644 --- a/include/linux/amba/clcd.h +++ b/include/linux/amba/clcd.h | |||
@@ -150,6 +150,7 @@ struct clcd_fb { | |||
150 | u16 off_cntl; | 150 | u16 off_cntl; |
151 | u32 clcd_cntl; | 151 | u32 clcd_cntl; |
152 | u32 cmap[16]; | 152 | u32 cmap[16]; |
153 | bool clk_enabled; | ||
153 | }; | 154 | }; |
154 | 155 | ||
155 | static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs) | 156 | static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs) |
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index c809e286d21..a065612fc92 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h | |||
@@ -50,8 +50,8 @@ struct linux_binprm{ | |||
50 | int unsafe; /* how unsafe this exec is (mask of LSM_UNSAFE_*) */ | 50 | int unsafe; /* how unsafe this exec is (mask of LSM_UNSAFE_*) */ |
51 | unsigned int per_clear; /* bits to clear in current->personality */ | 51 | unsigned int per_clear; /* bits to clear in current->personality */ |
52 | int argc, envc; | 52 | int argc, envc; |
53 | char * filename; /* Name of binary as seen by procps */ | 53 | const char * filename; /* Name of binary as seen by procps */ |
54 | char * interp; /* Name of the binary really executed. Most | 54 | const char * interp; /* Name of the binary really executed. Most |
55 | of the time same as filename, but could be | 55 | of the time same as filename, but could be |
56 | different for binfmt_{misc,script} */ | 56 | different for binfmt_{misc,script} */ |
57 | unsigned interp_flags; | 57 | unsigned interp_flags; |
@@ -126,7 +126,8 @@ extern int setup_arg_pages(struct linux_binprm * bprm, | |||
126 | unsigned long stack_top, | 126 | unsigned long stack_top, |
127 | int executable_stack); | 127 | int executable_stack); |
128 | extern int bprm_mm_init(struct linux_binprm *bprm); | 128 | extern int bprm_mm_init(struct linux_binprm *bprm); |
129 | extern int copy_strings_kernel(int argc,char ** argv,struct linux_binprm *bprm); | 129 | extern int copy_strings_kernel(int argc, const char *const *argv, |
130 | struct linux_binprm *bprm); | ||
130 | extern int prepare_bprm_creds(struct linux_binprm *bprm); | 131 | extern int prepare_bprm_creds(struct linux_binprm *bprm); |
131 | extern void install_exec_creds(struct linux_binprm *bprm); | 132 | extern void install_exec_creds(struct linux_binprm *bprm); |
132 | extern void do_coredump(long signr, int exit_code, struct pt_regs *regs); | 133 | extern void do_coredump(long signr, int exit_code, struct pt_regs *regs); |
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index 43e649a7252..ec94c12f21d 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h | |||
@@ -32,7 +32,6 @@ enum bh_state_bits { | |||
32 | BH_Delay, /* Buffer is not yet allocated on disk */ | 32 | BH_Delay, /* Buffer is not yet allocated on disk */ |
33 | BH_Boundary, /* Block is followed by a discontiguity */ | 33 | BH_Boundary, /* Block is followed by a discontiguity */ |
34 | BH_Write_EIO, /* I/O error on write */ | 34 | BH_Write_EIO, /* I/O error on write */ |
35 | BH_Ordered, /* ordered write */ | ||
36 | BH_Eopnotsupp, /* operation not supported (barrier) */ | 35 | BH_Eopnotsupp, /* operation not supported (barrier) */ |
37 | BH_Unwritten, /* Buffer is allocated on disk but not written */ | 36 | BH_Unwritten, /* Buffer is allocated on disk but not written */ |
38 | BH_Quiet, /* Buffer Error Prinks to be quiet */ | 37 | BH_Quiet, /* Buffer Error Prinks to be quiet */ |
@@ -125,7 +124,6 @@ BUFFER_FNS(Async_Write, async_write) | |||
125 | BUFFER_FNS(Delay, delay) | 124 | BUFFER_FNS(Delay, delay) |
126 | BUFFER_FNS(Boundary, boundary) | 125 | BUFFER_FNS(Boundary, boundary) |
127 | BUFFER_FNS(Write_EIO, write_io_error) | 126 | BUFFER_FNS(Write_EIO, write_io_error) |
128 | BUFFER_FNS(Ordered, ordered) | ||
129 | BUFFER_FNS(Eopnotsupp, eopnotsupp) | 127 | BUFFER_FNS(Eopnotsupp, eopnotsupp) |
130 | BUFFER_FNS(Unwritten, unwritten) | 128 | BUFFER_FNS(Unwritten, unwritten) |
131 | 129 | ||
@@ -183,6 +181,8 @@ void unlock_buffer(struct buffer_head *bh); | |||
183 | void __lock_buffer(struct buffer_head *bh); | 181 | void __lock_buffer(struct buffer_head *bh); |
184 | void ll_rw_block(int, int, struct buffer_head * bh[]); | 182 | void ll_rw_block(int, int, struct buffer_head * bh[]); |
185 | int sync_dirty_buffer(struct buffer_head *bh); | 183 | int sync_dirty_buffer(struct buffer_head *bh); |
184 | int __sync_dirty_buffer(struct buffer_head *bh, int rw); | ||
185 | void write_dirty_buffer(struct buffer_head *bh, int rw); | ||
186 | int submit_bh(int, struct buffer_head *); | 186 | int submit_bh(int, struct buffer_head *); |
187 | void write_boundary_block(struct block_device *bdev, | 187 | void write_boundary_block(struct block_device *bdev, |
188 | sector_t bblock, unsigned blocksize); | 188 | sector_t bblock, unsigned blocksize); |
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index ed3e92e41c6..5a53d8f039a 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
@@ -578,7 +578,11 @@ struct task_struct *cgroup_iter_next(struct cgroup *cgrp, | |||
578 | void cgroup_iter_end(struct cgroup *cgrp, struct cgroup_iter *it); | 578 | void cgroup_iter_end(struct cgroup *cgrp, struct cgroup_iter *it); |
579 | int cgroup_scan_tasks(struct cgroup_scanner *scan); | 579 | int cgroup_scan_tasks(struct cgroup_scanner *scan); |
580 | int cgroup_attach_task(struct cgroup *, struct task_struct *); | 580 | int cgroup_attach_task(struct cgroup *, struct task_struct *); |
581 | int cgroup_attach_task_current_cg(struct task_struct *); | 581 | int cgroup_attach_task_all(struct task_struct *from, struct task_struct *); |
582 | static inline int cgroup_attach_task_current_cg(struct task_struct *tsk) | ||
583 | { | ||
584 | return cgroup_attach_task_all(current, tsk); | ||
585 | } | ||
582 | 586 | ||
583 | /* | 587 | /* |
584 | * CSS ID is ID for cgroup_subsys_state structs under subsys. This only works | 588 | * CSS ID is ID for cgroup_subsys_state structs under subsys. This only works |
@@ -636,6 +640,11 @@ static inline int cgroupstats_build(struct cgroupstats *stats, | |||
636 | } | 640 | } |
637 | 641 | ||
638 | /* No cgroups - nothing to do */ | 642 | /* No cgroups - nothing to do */ |
643 | static inline int cgroup_attach_task_all(struct task_struct *from, | ||
644 | struct task_struct *t) | ||
645 | { | ||
646 | return 0; | ||
647 | } | ||
639 | static inline int cgroup_attach_task_current_cg(struct task_struct *t) | 648 | static inline int cgroup_attach_task_current_cg(struct task_struct *t) |
640 | { | 649 | { |
641 | return 0; | 650 | return 0; |
diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h index f0949a57ca9..63531a6b4d2 100644 --- a/include/linux/fanotify.h +++ b/include/linux/fanotify.h | |||
@@ -65,14 +65,14 @@ | |||
65 | FAN_ALL_PERM_EVENTS |\ | 65 | FAN_ALL_PERM_EVENTS |\ |
66 | FAN_Q_OVERFLOW) | 66 | FAN_Q_OVERFLOW) |
67 | 67 | ||
68 | #define FANOTIFY_METADATA_VERSION 1 | 68 | #define FANOTIFY_METADATA_VERSION 2 |
69 | 69 | ||
70 | struct fanotify_event_metadata { | 70 | struct fanotify_event_metadata { |
71 | __u32 event_len; | 71 | __u32 event_len; |
72 | __u32 vers; | 72 | __u32 vers; |
73 | __s32 fd; | ||
74 | __u64 mask; | 73 | __u64 mask; |
75 | __s64 pid; | 74 | __s32 fd; |
75 | __s32 pid; | ||
76 | } __attribute__ ((packed)); | 76 | } __attribute__ ((packed)); |
77 | 77 | ||
78 | struct fanotify_response { | 78 | struct fanotify_response { |
@@ -95,11 +95,4 @@ struct fanotify_response { | |||
95 | (long)(meta)->event_len >= (long)FAN_EVENT_METADATA_LEN && \ | 95 | (long)(meta)->event_len >= (long)FAN_EVENT_METADATA_LEN && \ |
96 | (long)(meta)->event_len <= (long)(len)) | 96 | (long)(meta)->event_len <= (long)(len)) |
97 | 97 | ||
98 | #ifdef __KERNEL__ | ||
99 | |||
100 | struct fanotify_wait { | ||
101 | struct fsnotify_event *event; | ||
102 | __s32 fd; | ||
103 | }; | ||
104 | #endif /* __KERNEL__ */ | ||
105 | #endif /* _LINUX_FANOTIFY_H */ | 98 | #endif /* _LINUX_FANOTIFY_H */ |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 9a96b4d83fc..76041b61475 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -125,9 +125,6 @@ struct inodes_stat_t { | |||
125 | * block layer could (in theory) choose to ignore this | 125 | * block layer could (in theory) choose to ignore this |
126 | * request if it runs into resource problems. | 126 | * request if it runs into resource problems. |
127 | * WRITE A normal async write. Device will be plugged. | 127 | * WRITE A normal async write. Device will be plugged. |
128 | * SWRITE Like WRITE, but a special case for ll_rw_block() that | ||
129 | * tells it to lock the buffer first. Normally a buffer | ||
130 | * must be locked before doing IO. | ||
131 | * WRITE_SYNC_PLUG Synchronous write. Identical to WRITE, but passes down | 128 | * WRITE_SYNC_PLUG Synchronous write. Identical to WRITE, but passes down |
132 | * the hint that someone will be waiting on this IO | 129 | * the hint that someone will be waiting on this IO |
133 | * shortly. The device must still be unplugged explicitly, | 130 | * shortly. The device must still be unplugged explicitly, |
@@ -138,9 +135,6 @@ struct inodes_stat_t { | |||
138 | * immediately after submission. The write equivalent | 135 | * immediately after submission. The write equivalent |
139 | * of READ_SYNC. | 136 | * of READ_SYNC. |
140 | * WRITE_ODIRECT_PLUG Special case write for O_DIRECT only. | 137 | * WRITE_ODIRECT_PLUG Special case write for O_DIRECT only. |
141 | * SWRITE_SYNC | ||
142 | * SWRITE_SYNC_PLUG Like WRITE_SYNC/WRITE_SYNC_PLUG, but locks the buffer. | ||
143 | * See SWRITE. | ||
144 | * WRITE_BARRIER Like WRITE_SYNC, but tells the block layer that all | 138 | * WRITE_BARRIER Like WRITE_SYNC, but tells the block layer that all |
145 | * previously submitted writes must be safely on storage | 139 | * previously submitted writes must be safely on storage |
146 | * before this one is started. Also guarantees that when | 140 | * before this one is started. Also guarantees that when |
@@ -155,7 +149,6 @@ struct inodes_stat_t { | |||
155 | #define READ 0 | 149 | #define READ 0 |
156 | #define WRITE RW_MASK | 150 | #define WRITE RW_MASK |
157 | #define READA RWA_MASK | 151 | #define READA RWA_MASK |
158 | #define SWRITE (WRITE | READA) | ||
159 | 152 | ||
160 | #define READ_SYNC (READ | REQ_SYNC | REQ_UNPLUG) | 153 | #define READ_SYNC (READ | REQ_SYNC | REQ_UNPLUG) |
161 | #define READ_META (READ | REQ_META) | 154 | #define READ_META (READ | REQ_META) |
@@ -165,8 +158,6 @@ struct inodes_stat_t { | |||
165 | #define WRITE_META (WRITE | REQ_META) | 158 | #define WRITE_META (WRITE | REQ_META) |
166 | #define WRITE_BARRIER (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_UNPLUG | \ | 159 | #define WRITE_BARRIER (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_UNPLUG | \ |
167 | REQ_HARDBARRIER) | 160 | REQ_HARDBARRIER) |
168 | #define SWRITE_SYNC_PLUG (SWRITE | REQ_SYNC | REQ_NOIDLE) | ||
169 | #define SWRITE_SYNC (SWRITE | REQ_SYNC | REQ_NOIDLE | REQ_UNPLUG) | ||
170 | 161 | ||
171 | /* | 162 | /* |
172 | * These aren't really reads or writes, they pass down information about | 163 | * These aren't really reads or writes, they pass down information about |
@@ -929,6 +920,9 @@ struct file { | |||
929 | #define f_vfsmnt f_path.mnt | 920 | #define f_vfsmnt f_path.mnt |
930 | const struct file_operations *f_op; | 921 | const struct file_operations *f_op; |
931 | spinlock_t f_lock; /* f_ep_links, f_flags, no IRQ */ | 922 | spinlock_t f_lock; /* f_ep_links, f_flags, no IRQ */ |
923 | #ifdef CONFIG_SMP | ||
924 | int f_sb_list_cpu; | ||
925 | #endif | ||
932 | atomic_long_t f_count; | 926 | atomic_long_t f_count; |
933 | unsigned int f_flags; | 927 | unsigned int f_flags; |
934 | fmode_t f_mode; | 928 | fmode_t f_mode; |
@@ -953,9 +947,6 @@ struct file { | |||
953 | unsigned long f_mnt_write_state; | 947 | unsigned long f_mnt_write_state; |
954 | #endif | 948 | #endif |
955 | }; | 949 | }; |
956 | extern spinlock_t files_lock; | ||
957 | #define file_list_lock() spin_lock(&files_lock); | ||
958 | #define file_list_unlock() spin_unlock(&files_lock); | ||
959 | 950 | ||
960 | #define get_file(x) atomic_long_inc(&(x)->f_count) | 951 | #define get_file(x) atomic_long_inc(&(x)->f_count) |
961 | #define fput_atomic(x) atomic_long_add_unless(&(x)->f_count, -1, 1) | 952 | #define fput_atomic(x) atomic_long_add_unless(&(x)->f_count, -1, 1) |
@@ -1346,7 +1337,11 @@ struct super_block { | |||
1346 | 1337 | ||
1347 | struct list_head s_inodes; /* all inodes */ | 1338 | struct list_head s_inodes; /* all inodes */ |
1348 | struct hlist_head s_anon; /* anonymous dentries for (nfs) exporting */ | 1339 | struct hlist_head s_anon; /* anonymous dentries for (nfs) exporting */ |
1340 | #ifdef CONFIG_SMP | ||
1341 | struct list_head __percpu *s_files; | ||
1342 | #else | ||
1349 | struct list_head s_files; | 1343 | struct list_head s_files; |
1344 | #endif | ||
1350 | /* s_dentry_lru and s_nr_dentry_unused are protected by dcache_lock */ | 1345 | /* s_dentry_lru and s_nr_dentry_unused are protected by dcache_lock */ |
1351 | struct list_head s_dentry_lru; /* unused dentry lru */ | 1346 | struct list_head s_dentry_lru; /* unused dentry lru */ |
1352 | int s_nr_dentry_unused; /* # of dentry on lru */ | 1347 | int s_nr_dentry_unused; /* # of dentry on lru */ |
@@ -2197,8 +2192,6 @@ static inline void insert_inode_hash(struct inode *inode) { | |||
2197 | __insert_inode_hash(inode, inode->i_ino); | 2192 | __insert_inode_hash(inode, inode->i_ino); |
2198 | } | 2193 | } |
2199 | 2194 | ||
2200 | extern void file_move(struct file *f, struct list_head *list); | ||
2201 | extern void file_kill(struct file *f); | ||
2202 | #ifdef CONFIG_BLOCK | 2195 | #ifdef CONFIG_BLOCK |
2203 | extern void submit_bio(int, struct bio *); | 2196 | extern void submit_bio(int, struct bio *); |
2204 | extern int bdev_read_only(struct block_device *); | 2197 | extern int bdev_read_only(struct block_device *); |
diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h index eca3d520213..a42b5bf02f8 100644 --- a/include/linux/fs_struct.h +++ b/include/linux/fs_struct.h | |||
@@ -5,7 +5,7 @@ | |||
5 | 5 | ||
6 | struct fs_struct { | 6 | struct fs_struct { |
7 | int users; | 7 | int users; |
8 | rwlock_t lock; | 8 | spinlock_t lock; |
9 | int umask; | 9 | int umask; |
10 | int in_exec; | 10 | int in_exec; |
11 | struct path root, pwd; | 11 | struct path root, pwd; |
@@ -23,29 +23,29 @@ extern int unshare_fs_struct(void); | |||
23 | 23 | ||
24 | static inline void get_fs_root(struct fs_struct *fs, struct path *root) | 24 | static inline void get_fs_root(struct fs_struct *fs, struct path *root) |
25 | { | 25 | { |
26 | read_lock(&fs->lock); | 26 | spin_lock(&fs->lock); |
27 | *root = fs->root; | 27 | *root = fs->root; |
28 | path_get(root); | 28 | path_get(root); |
29 | read_unlock(&fs->lock); | 29 | spin_unlock(&fs->lock); |
30 | } | 30 | } |
31 | 31 | ||
32 | static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd) | 32 | static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd) |
33 | { | 33 | { |
34 | read_lock(&fs->lock); | 34 | spin_lock(&fs->lock); |
35 | *pwd = fs->pwd; | 35 | *pwd = fs->pwd; |
36 | path_get(pwd); | 36 | path_get(pwd); |
37 | read_unlock(&fs->lock); | 37 | spin_unlock(&fs->lock); |
38 | } | 38 | } |
39 | 39 | ||
40 | static inline void get_fs_root_and_pwd(struct fs_struct *fs, struct path *root, | 40 | static inline void get_fs_root_and_pwd(struct fs_struct *fs, struct path *root, |
41 | struct path *pwd) | 41 | struct path *pwd) |
42 | { | 42 | { |
43 | read_lock(&fs->lock); | 43 | spin_lock(&fs->lock); |
44 | *root = fs->root; | 44 | *root = fs->root; |
45 | path_get(root); | 45 | path_get(root); |
46 | *pwd = fs->pwd; | 46 | *pwd = fs->pwd; |
47 | path_get(pwd); | 47 | path_get(pwd); |
48 | read_unlock(&fs->lock); | 48 | spin_unlock(&fs->lock); |
49 | } | 49 | } |
50 | 50 | ||
51 | #endif /* _LINUX_FS_STRUCT_H */ | 51 | #endif /* _LINUX_FS_STRUCT_H */ |
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index ed36fb57c42..e40190d1687 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
@@ -156,6 +156,7 @@ struct fsnotify_group { | |||
156 | struct mutex access_mutex; | 156 | struct mutex access_mutex; |
157 | struct list_head access_list; | 157 | struct list_head access_list; |
158 | wait_queue_head_t access_waitq; | 158 | wait_queue_head_t access_waitq; |
159 | bool bypass_perm; /* protected by access_mutex */ | ||
159 | #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */ | 160 | #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */ |
160 | int f_flags; | 161 | int f_flags; |
161 | } fanotify_data; | 162 | } fanotify_data; |
diff --git a/include/linux/intel-gtt.h b/include/linux/intel-gtt.h new file mode 100644 index 00000000000..1d19ab2afa3 --- /dev/null +++ b/include/linux/intel-gtt.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * Common Intel AGPGART and GTT definitions. | ||
3 | */ | ||
4 | #ifndef _INTEL_GTT_H | ||
5 | #define _INTEL_GTT_H | ||
6 | |||
7 | #include <linux/agp_backend.h> | ||
8 | |||
9 | /* This is for Intel only GTT controls. | ||
10 | * | ||
11 | * Sandybridge: AGP_USER_CACHED_MEMORY default to LLC only | ||
12 | */ | ||
13 | |||
14 | #define AGP_USER_CACHED_MEMORY_LLC_MLC (AGP_USER_TYPES + 2) | ||
15 | #define AGP_USER_UNCACHED_MEMORY (AGP_USER_TYPES + 4) | ||
16 | |||
17 | /* flag for GFDT type */ | ||
18 | #define AGP_USER_CACHED_MEMORY_GFDT (1 << 3) | ||
19 | |||
20 | #endif | ||
diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index 311f8753d71..4aa95f203f3 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h | |||
@@ -836,6 +836,8 @@ extern void __kfifo_dma_out_finish_r(struct __kfifo *fifo, size_t recsize); | |||
836 | 836 | ||
837 | extern unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize); | 837 | extern unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize); |
838 | 838 | ||
839 | extern void __kfifo_skip_r(struct __kfifo *fifo, size_t recsize); | ||
840 | |||
839 | extern unsigned int __kfifo_out_peek_r(struct __kfifo *fifo, | 841 | extern unsigned int __kfifo_out_peek_r(struct __kfifo *fifo, |
840 | void *buf, unsigned int len, size_t recsize); | 842 | void *buf, unsigned int len, size_t recsize); |
841 | 843 | ||
diff --git a/include/linux/kobject.h b/include/linux/kobject.h index cf343a85253..7950a37a714 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/compiler.h> | 22 | #include <linux/compiler.h> |
23 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
24 | #include <linux/kref.h> | 24 | #include <linux/kref.h> |
25 | #include <linux/kobject_ns.h> | ||
25 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
26 | #include <linux/wait.h> | 27 | #include <linux/wait.h> |
27 | #include <asm/atomic.h> | 28 | #include <asm/atomic.h> |
@@ -136,42 +137,8 @@ struct kobj_attribute { | |||
136 | 137 | ||
137 | extern const struct sysfs_ops kobj_sysfs_ops; | 138 | extern const struct sysfs_ops kobj_sysfs_ops; |
138 | 139 | ||
139 | /* | ||
140 | * Namespace types which are used to tag kobjects and sysfs entries. | ||
141 | * Network namespace will likely be the first. | ||
142 | */ | ||
143 | enum kobj_ns_type { | ||
144 | KOBJ_NS_TYPE_NONE = 0, | ||
145 | KOBJ_NS_TYPE_NET, | ||
146 | KOBJ_NS_TYPES | ||
147 | }; | ||
148 | |||
149 | struct sock; | 140 | struct sock; |
150 | 141 | ||
151 | /* | ||
152 | * Callbacks so sysfs can determine namespaces | ||
153 | * @current_ns: return calling task's namespace | ||
154 | * @netlink_ns: return namespace to which a sock belongs (right?) | ||
155 | * @initial_ns: return the initial namespace (i.e. init_net_ns) | ||
156 | */ | ||
157 | struct kobj_ns_type_operations { | ||
158 | enum kobj_ns_type type; | ||
159 | const void *(*current_ns)(void); | ||
160 | const void *(*netlink_ns)(struct sock *sk); | ||
161 | const void *(*initial_ns)(void); | ||
162 | }; | ||
163 | |||
164 | int kobj_ns_type_register(const struct kobj_ns_type_operations *ops); | ||
165 | int kobj_ns_type_registered(enum kobj_ns_type type); | ||
166 | const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent); | ||
167 | const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj); | ||
168 | |||
169 | const void *kobj_ns_current(enum kobj_ns_type type); | ||
170 | const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk); | ||
171 | const void *kobj_ns_initial(enum kobj_ns_type type); | ||
172 | void kobj_ns_exit(enum kobj_ns_type type, const void *ns); | ||
173 | |||
174 | |||
175 | /** | 142 | /** |
176 | * struct kset - a set of kobjects of a specific type, belonging to a specific subsystem. | 143 | * struct kset - a set of kobjects of a specific type, belonging to a specific subsystem. |
177 | * | 144 | * |
diff --git a/include/linux/kobject_ns.h b/include/linux/kobject_ns.h new file mode 100644 index 00000000000..82cb5bf461f --- /dev/null +++ b/include/linux/kobject_ns.h | |||
@@ -0,0 +1,56 @@ | |||
1 | /* Kernel object name space definitions | ||
2 | * | ||
3 | * Copyright (c) 2002-2003 Patrick Mochel | ||
4 | * Copyright (c) 2002-2003 Open Source Development Labs | ||
5 | * Copyright (c) 2006-2008 Greg Kroah-Hartman <greg@kroah.com> | ||
6 | * Copyright (c) 2006-2008 Novell Inc. | ||
7 | * | ||
8 | * Split from kobject.h by David Howells (dhowells@redhat.com) | ||
9 | * | ||
10 | * This file is released under the GPLv2. | ||
11 | * | ||
12 | * Please read Documentation/kobject.txt before using the kobject | ||
13 | * interface, ESPECIALLY the parts about reference counts and object | ||
14 | * destructors. | ||
15 | */ | ||
16 | |||
17 | #ifndef _LINUX_KOBJECT_NS_H | ||
18 | #define _LINUX_KOBJECT_NS_H | ||
19 | |||
20 | struct sock; | ||
21 | struct kobject; | ||
22 | |||
23 | /* | ||
24 | * Namespace types which are used to tag kobjects and sysfs entries. | ||
25 | * Network namespace will likely be the first. | ||
26 | */ | ||
27 | enum kobj_ns_type { | ||
28 | KOBJ_NS_TYPE_NONE = 0, | ||
29 | KOBJ_NS_TYPE_NET, | ||
30 | KOBJ_NS_TYPES | ||
31 | }; | ||
32 | |||
33 | /* | ||
34 | * Callbacks so sysfs can determine namespaces | ||
35 | * @current_ns: return calling task's namespace | ||
36 | * @netlink_ns: return namespace to which a sock belongs (right?) | ||
37 | * @initial_ns: return the initial namespace (i.e. init_net_ns) | ||
38 | */ | ||
39 | struct kobj_ns_type_operations { | ||
40 | enum kobj_ns_type type; | ||
41 | const void *(*current_ns)(void); | ||
42 | const void *(*netlink_ns)(struct sock *sk); | ||
43 | const void *(*initial_ns)(void); | ||
44 | }; | ||
45 | |||
46 | int kobj_ns_type_register(const struct kobj_ns_type_operations *ops); | ||
47 | int kobj_ns_type_registered(enum kobj_ns_type type); | ||
48 | const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent); | ||
49 | const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj); | ||
50 | |||
51 | const void *kobj_ns_current(enum kobj_ns_type type); | ||
52 | const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk); | ||
53 | const void *kobj_ns_initial(enum kobj_ns_type type); | ||
54 | void kobj_ns_exit(enum kobj_ns_type type, const void *ns); | ||
55 | |||
56 | #endif /* _LINUX_KOBJECT_NS_H */ | ||
diff --git a/include/linux/lglock.h b/include/linux/lglock.h new file mode 100644 index 00000000000..b288cb713b9 --- /dev/null +++ b/include/linux/lglock.h | |||
@@ -0,0 +1,172 @@ | |||
1 | /* | ||
2 | * Specialised local-global spinlock. Can only be declared as global variables | ||
3 | * to avoid overhead and keep things simple (and we don't want to start using | ||
4 | * these inside dynamically allocated structures). | ||
5 | * | ||
6 | * "local/global locks" (lglocks) can be used to: | ||
7 | * | ||
8 | * - Provide fast exclusive access to per-CPU data, with exclusive access to | ||
9 | * another CPU's data allowed but possibly subject to contention, and to | ||
10 | * provide very slow exclusive access to all per-CPU data. | ||
11 | * - Or to provide very fast and scalable read serialisation, and to provide | ||
12 | * very slow exclusive serialisation of data (not necessarily per-CPU data). | ||
13 | * | ||
14 | * Brlocks are also implemented as a short-hand notation for the latter use | ||
15 | * case. | ||
16 | * | ||
17 | * Copyright 2009, 2010, Nick Piggin, Novell Inc. | ||
18 | */ | ||
19 | #ifndef __LINUX_LGLOCK_H | ||
20 | #define __LINUX_LGLOCK_H | ||
21 | |||
22 | #include <linux/spinlock.h> | ||
23 | #include <linux/lockdep.h> | ||
24 | #include <linux/percpu.h> | ||
25 | |||
26 | /* can make br locks by using local lock for read side, global lock for write */ | ||
27 | #define br_lock_init(name) name##_lock_init() | ||
28 | #define br_read_lock(name) name##_local_lock() | ||
29 | #define br_read_unlock(name) name##_local_unlock() | ||
30 | #define br_write_lock(name) name##_global_lock_online() | ||
31 | #define br_write_unlock(name) name##_global_unlock_online() | ||
32 | |||
33 | #define DECLARE_BRLOCK(name) DECLARE_LGLOCK(name) | ||
34 | #define DEFINE_BRLOCK(name) DEFINE_LGLOCK(name) | ||
35 | |||
36 | |||
37 | #define lg_lock_init(name) name##_lock_init() | ||
38 | #define lg_local_lock(name) name##_local_lock() | ||
39 | #define lg_local_unlock(name) name##_local_unlock() | ||
40 | #define lg_local_lock_cpu(name, cpu) name##_local_lock_cpu(cpu) | ||
41 | #define lg_local_unlock_cpu(name, cpu) name##_local_unlock_cpu(cpu) | ||
42 | #define lg_global_lock(name) name##_global_lock() | ||
43 | #define lg_global_unlock(name) name##_global_unlock() | ||
44 | #define lg_global_lock_online(name) name##_global_lock_online() | ||
45 | #define lg_global_unlock_online(name) name##_global_unlock_online() | ||
46 | |||
47 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
48 | #define LOCKDEP_INIT_MAP lockdep_init_map | ||
49 | |||
50 | #define DEFINE_LGLOCK_LOCKDEP(name) \ | ||
51 | struct lock_class_key name##_lock_key; \ | ||
52 | struct lockdep_map name##_lock_dep_map; \ | ||
53 | EXPORT_SYMBOL(name##_lock_dep_map) | ||
54 | |||
55 | #else | ||
56 | #define LOCKDEP_INIT_MAP(a, b, c, d) | ||
57 | |||
58 | #define DEFINE_LGLOCK_LOCKDEP(name) | ||
59 | #endif | ||
60 | |||
61 | |||
62 | #define DECLARE_LGLOCK(name) \ | ||
63 | extern void name##_lock_init(void); \ | ||
64 | extern void name##_local_lock(void); \ | ||
65 | extern void name##_local_unlock(void); \ | ||
66 | extern void name##_local_lock_cpu(int cpu); \ | ||
67 | extern void name##_local_unlock_cpu(int cpu); \ | ||
68 | extern void name##_global_lock(void); \ | ||
69 | extern void name##_global_unlock(void); \ | ||
70 | extern void name##_global_lock_online(void); \ | ||
71 | extern void name##_global_unlock_online(void); \ | ||
72 | |||
73 | #define DEFINE_LGLOCK(name) \ | ||
74 | \ | ||
75 | DEFINE_PER_CPU(arch_spinlock_t, name##_lock); \ | ||
76 | DEFINE_LGLOCK_LOCKDEP(name); \ | ||
77 | \ | ||
78 | void name##_lock_init(void) { \ | ||
79 | int i; \ | ||
80 | LOCKDEP_INIT_MAP(&name##_lock_dep_map, #name, &name##_lock_key, 0); \ | ||
81 | for_each_possible_cpu(i) { \ | ||
82 | arch_spinlock_t *lock; \ | ||
83 | lock = &per_cpu(name##_lock, i); \ | ||
84 | *lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; \ | ||
85 | } \ | ||
86 | } \ | ||
87 | EXPORT_SYMBOL(name##_lock_init); \ | ||
88 | \ | ||
89 | void name##_local_lock(void) { \ | ||
90 | arch_spinlock_t *lock; \ | ||
91 | preempt_disable(); \ | ||
92 | rwlock_acquire_read(&name##_lock_dep_map, 0, 0, _THIS_IP_); \ | ||
93 | lock = &__get_cpu_var(name##_lock); \ | ||
94 | arch_spin_lock(lock); \ | ||
95 | } \ | ||
96 | EXPORT_SYMBOL(name##_local_lock); \ | ||
97 | \ | ||
98 | void name##_local_unlock(void) { \ | ||
99 | arch_spinlock_t *lock; \ | ||
100 | rwlock_release(&name##_lock_dep_map, 1, _THIS_IP_); \ | ||
101 | lock = &__get_cpu_var(name##_lock); \ | ||
102 | arch_spin_unlock(lock); \ | ||
103 | preempt_enable(); \ | ||
104 | } \ | ||
105 | EXPORT_SYMBOL(name##_local_unlock); \ | ||
106 | \ | ||
107 | void name##_local_lock_cpu(int cpu) { \ | ||
108 | arch_spinlock_t *lock; \ | ||
109 | preempt_disable(); \ | ||
110 | rwlock_acquire_read(&name##_lock_dep_map, 0, 0, _THIS_IP_); \ | ||
111 | lock = &per_cpu(name##_lock, cpu); \ | ||
112 | arch_spin_lock(lock); \ | ||
113 | } \ | ||
114 | EXPORT_SYMBOL(name##_local_lock_cpu); \ | ||
115 | \ | ||
116 | void name##_local_unlock_cpu(int cpu) { \ | ||
117 | arch_spinlock_t *lock; \ | ||
118 | rwlock_release(&name##_lock_dep_map, 1, _THIS_IP_); \ | ||
119 | lock = &per_cpu(name##_lock, cpu); \ | ||
120 | arch_spin_unlock(lock); \ | ||
121 | preempt_enable(); \ | ||
122 | } \ | ||
123 | EXPORT_SYMBOL(name##_local_unlock_cpu); \ | ||
124 | \ | ||
125 | void name##_global_lock_online(void) { \ | ||
126 | int i; \ | ||
127 | preempt_disable(); \ | ||
128 | rwlock_acquire(&name##_lock_dep_map, 0, 0, _RET_IP_); \ | ||
129 | for_each_online_cpu(i) { \ | ||
130 | arch_spinlock_t *lock; \ | ||
131 | lock = &per_cpu(name##_lock, i); \ | ||
132 | arch_spin_lock(lock); \ | ||
133 | } \ | ||
134 | } \ | ||
135 | EXPORT_SYMBOL(name##_global_lock_online); \ | ||
136 | \ | ||
137 | void name##_global_unlock_online(void) { \ | ||
138 | int i; \ | ||
139 | rwlock_release(&name##_lock_dep_map, 1, _RET_IP_); \ | ||
140 | for_each_online_cpu(i) { \ | ||
141 | arch_spinlock_t *lock; \ | ||
142 | lock = &per_cpu(name##_lock, i); \ | ||
143 | arch_spin_unlock(lock); \ | ||
144 | } \ | ||
145 | preempt_enable(); \ | ||
146 | } \ | ||
147 | EXPORT_SYMBOL(name##_global_unlock_online); \ | ||
148 | \ | ||
149 | void name##_global_lock(void) { \ | ||
150 | int i; \ | ||
151 | preempt_disable(); \ | ||
152 | rwlock_acquire(&name##_lock_dep_map, 0, 0, _RET_IP_); \ | ||
153 | for_each_online_cpu(i) { \ | ||
154 | arch_spinlock_t *lock; \ | ||
155 | lock = &per_cpu(name##_lock, i); \ | ||
156 | arch_spin_lock(lock); \ | ||
157 | } \ | ||
158 | } \ | ||
159 | EXPORT_SYMBOL(name##_global_lock); \ | ||
160 | \ | ||
161 | void name##_global_unlock(void) { \ | ||
162 | int i; \ | ||
163 | rwlock_release(&name##_lock_dep_map, 1, _RET_IP_); \ | ||
164 | for_each_online_cpu(i) { \ | ||
165 | arch_spinlock_t *lock; \ | ||
166 | lock = &per_cpu(name##_lock, i); \ | ||
167 | arch_spin_unlock(lock); \ | ||
168 | } \ | ||
169 | preempt_enable(); \ | ||
170 | } \ | ||
171 | EXPORT_SYMBOL(name##_global_unlock); | ||
172 | #endif | ||
diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h index bafffc73790..18fd13028ba 100644 --- a/include/linux/miscdevice.h +++ b/include/linux/miscdevice.h | |||
@@ -33,6 +33,7 @@ | |||
33 | #define MWAVE_MINOR 219 /* ACP/Mwave Modem */ | 33 | #define MWAVE_MINOR 219 /* ACP/Mwave Modem */ |
34 | #define MPT_MINOR 220 | 34 | #define MPT_MINOR 220 |
35 | #define MPT2SAS_MINOR 221 | 35 | #define MPT2SAS_MINOR 221 |
36 | #define UINPUT_MINOR 223 | ||
36 | #define HPET_MINOR 228 | 37 | #define HPET_MINOR 228 |
37 | #define FUSE_MINOR 229 | 38 | #define FUSE_MINOR 229 |
38 | #define KVM_MINOR 232 | 39 | #define KVM_MINOR 232 |
diff --git a/include/linux/mm.h b/include/linux/mm.h index 709f6728fc9..e6b1210772c 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -78,7 +78,11 @@ extern unsigned int kobjsize(const void *objp); | |||
78 | #define VM_MAYSHARE 0x00000080 | 78 | #define VM_MAYSHARE 0x00000080 |
79 | 79 | ||
80 | #define VM_GROWSDOWN 0x00000100 /* general info on the segment */ | 80 | #define VM_GROWSDOWN 0x00000100 /* general info on the segment */ |
81 | #if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64) | ||
81 | #define VM_GROWSUP 0x00000200 | 82 | #define VM_GROWSUP 0x00000200 |
83 | #else | ||
84 | #define VM_GROWSUP 0x00000000 | ||
85 | #endif | ||
82 | #define VM_PFNMAP 0x00000400 /* Page-ranges managed without "struct page", just pure PFN */ | 86 | #define VM_PFNMAP 0x00000400 /* Page-ranges managed without "struct page", just pure PFN */ |
83 | #define VM_DENYWRITE 0x00000800 /* ETXTBSY on write attempts.. */ | 87 | #define VM_DENYWRITE 0x00000800 /* ETXTBSY on write attempts.. */ |
84 | 88 | ||
@@ -1330,8 +1334,10 @@ unsigned long ra_submit(struct file_ra_state *ra, | |||
1330 | 1334 | ||
1331 | /* Do stack extension */ | 1335 | /* Do stack extension */ |
1332 | extern int expand_stack(struct vm_area_struct *vma, unsigned long address); | 1336 | extern int expand_stack(struct vm_area_struct *vma, unsigned long address); |
1333 | #ifdef CONFIG_IA64 | 1337 | #if VM_GROWSUP |
1334 | extern int expand_upwards(struct vm_area_struct *vma, unsigned long address); | 1338 | extern int expand_upwards(struct vm_area_struct *vma, unsigned long address); |
1339 | #else | ||
1340 | #define expand_upwards(vma, address) do { } while (0) | ||
1335 | #endif | 1341 | #endif |
1336 | extern int expand_stack_downwards(struct vm_area_struct *vma, | 1342 | extern int expand_stack_downwards(struct vm_area_struct *vma, |
1337 | unsigned long address); | 1343 | unsigned long address); |
@@ -1357,7 +1363,15 @@ static inline unsigned long vma_pages(struct vm_area_struct *vma) | |||
1357 | return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; | 1363 | return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; |
1358 | } | 1364 | } |
1359 | 1365 | ||
1366 | #ifdef CONFIG_MMU | ||
1360 | pgprot_t vm_get_page_prot(unsigned long vm_flags); | 1367 | pgprot_t vm_get_page_prot(unsigned long vm_flags); |
1368 | #else | ||
1369 | static inline pgprot_t vm_get_page_prot(unsigned long vm_flags) | ||
1370 | { | ||
1371 | return __pgprot(0); | ||
1372 | } | ||
1373 | #endif | ||
1374 | |||
1361 | struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr); | 1375 | struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr); |
1362 | int remap_pfn_range(struct vm_area_struct *, unsigned long addr, | 1376 | int remap_pfn_range(struct vm_area_struct *, unsigned long addr, |
1363 | unsigned long pfn, unsigned long size, pgprot_t); | 1377 | unsigned long pfn, unsigned long size, pgprot_t); |
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index b8bb9a6a1f3..ee7e258627f 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h | |||
@@ -134,7 +134,7 @@ struct vm_area_struct { | |||
134 | within vm_mm. */ | 134 | within vm_mm. */ |
135 | 135 | ||
136 | /* linked list of VM areas per task, sorted by address */ | 136 | /* linked list of VM areas per task, sorted by address */ |
137 | struct vm_area_struct *vm_next; | 137 | struct vm_area_struct *vm_next, *vm_prev; |
138 | 138 | ||
139 | pgprot_t vm_page_prot; /* Access permissions of this VMA. */ | 139 | pgprot_t vm_page_prot; /* Access permissions of this VMA. */ |
140 | unsigned long vm_flags; /* Flags, see mm.h. */ | 140 | unsigned long vm_flags; /* Flags, see mm.h. */ |
diff --git a/include/linux/pci.h b/include/linux/pci.h index b1d17956a15..c8d95e369ff 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -1214,6 +1214,9 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus, | |||
1214 | unsigned int devfn) | 1214 | unsigned int devfn) |
1215 | { return NULL; } | 1215 | { return NULL; } |
1216 | 1216 | ||
1217 | static inline int pci_domain_nr(struct pci_bus *bus) | ||
1218 | { return 0; } | ||
1219 | |||
1217 | #define dev_is_pci(d) (false) | 1220 | #define dev_is_pci(d) (false) |
1218 | #define dev_is_pf(d) (false) | 1221 | #define dev_is_pf(d) (false) |
1219 | #define dev_num_vf(d) (0) | 1222 | #define dev_num_vf(d) (0) |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 1f730de0df0..9438660b46e 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -2303,6 +2303,8 @@ | |||
2303 | #define PCI_DEVICE_ID_P2010 0x0079 | 2303 | #define PCI_DEVICE_ID_P2010 0x0079 |
2304 | #define PCI_DEVICE_ID_P1020E 0x0100 | 2304 | #define PCI_DEVICE_ID_P1020E 0x0100 |
2305 | #define PCI_DEVICE_ID_P1020 0x0101 | 2305 | #define PCI_DEVICE_ID_P1020 0x0101 |
2306 | #define PCI_DEVICE_ID_P1021E 0x0102 | ||
2307 | #define PCI_DEVICE_ID_P1021 0x0103 | ||
2306 | #define PCI_DEVICE_ID_P1011E 0x0108 | 2308 | #define PCI_DEVICE_ID_P1011E 0x0108 |
2307 | #define PCI_DEVICE_ID_P1011 0x0109 | 2309 | #define PCI_DEVICE_ID_P1011 0x0109 |
2308 | #define PCI_DEVICE_ID_P1022E 0x0110 | 2310 | #define PCI_DEVICE_ID_P1022E 0x0110 |
diff --git a/include/linux/percpu.h b/include/linux/percpu.h index b8b9084527b..49466b13c5c 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h | |||
@@ -149,7 +149,7 @@ extern void __init percpu_init_late(void); | |||
149 | 149 | ||
150 | #else /* CONFIG_SMP */ | 150 | #else /* CONFIG_SMP */ |
151 | 151 | ||
152 | #define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); }) | 152 | #define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); VERIFY_PERCPU_PTR((ptr)); }) |
153 | 153 | ||
154 | /* can't distinguish from other static vars, always false */ | 154 | /* can't distinguish from other static vars, always false */ |
155 | static inline bool is_kernel_percpu_address(unsigned long addr) | 155 | static inline bool is_kernel_percpu_address(unsigned long addr) |
diff --git a/include/linux/sched.h b/include/linux/sched.h index ce160d68f5e..1e2a6db2d7d 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -2109,7 +2109,9 @@ extern void daemonize(const char *, ...); | |||
2109 | extern int allow_signal(int); | 2109 | extern int allow_signal(int); |
2110 | extern int disallow_signal(int); | 2110 | extern int disallow_signal(int); |
2111 | 2111 | ||
2112 | extern int do_execve(char *, char __user * __user *, char __user * __user *, struct pt_regs *); | 2112 | extern int do_execve(const char *, |
2113 | const char __user * const __user *, | ||
2114 | const char __user * const __user *, struct pt_regs *); | ||
2113 | extern long do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *); | 2115 | extern long do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *); |
2114 | struct task_struct *fork_idle(int); | 2116 | struct task_struct *fork_idle(int); |
2115 | 2117 | ||
diff --git a/include/linux/serial.h b/include/linux/serial.h index 1ebc694a6d5..ef914061511 100644 --- a/include/linux/serial.h +++ b/include/linux/serial.h | |||
@@ -77,8 +77,7 @@ struct serial_struct { | |||
77 | #define PORT_16654 11 | 77 | #define PORT_16654 11 |
78 | #define PORT_16850 12 | 78 | #define PORT_16850 12 |
79 | #define PORT_RSA 13 /* RSA-DV II/S card */ | 79 | #define PORT_RSA 13 /* RSA-DV II/S card */ |
80 | #define PORT_U6_16550A 14 | 80 | #define PORT_MAX 13 |
81 | #define PORT_MAX 14 | ||
82 | 81 | ||
83 | #define SERIAL_IO_PORT 0 | 82 | #define SERIAL_IO_PORT 0 |
84 | #define SERIAL_IO_HUB6 1 | 83 | #define SERIAL_IO_HUB6 1 |
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 3c2ad99fed3..563e2340091 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h | |||
@@ -44,7 +44,8 @@ | |||
44 | #define PORT_RM9000 16 /* PMC-Sierra RM9xxx internal UART */ | 44 | #define PORT_RM9000 16 /* PMC-Sierra RM9xxx internal UART */ |
45 | #define PORT_OCTEON 17 /* Cavium OCTEON internal UART */ | 45 | #define PORT_OCTEON 17 /* Cavium OCTEON internal UART */ |
46 | #define PORT_AR7 18 /* Texas Instruments AR7 internal UART */ | 46 | #define PORT_AR7 18 /* Texas Instruments AR7 internal UART */ |
47 | #define PORT_MAX_8250 18 /* max port ID */ | 47 | #define PORT_U6_16550A 19 /* ST-Ericsson U6xxx internal UART */ |
48 | #define PORT_MAX_8250 19 /* max port ID */ | ||
48 | 49 | ||
49 | /* | 50 | /* |
50 | * ARM specific type numbers. These are not currently guaranteed | 51 | * ARM specific type numbers. These are not currently guaranteed |
@@ -465,7 +466,7 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) | |||
465 | #ifdef SUPPORT_SYSRQ | 466 | #ifdef SUPPORT_SYSRQ |
466 | if (port->sysrq) { | 467 | if (port->sysrq) { |
467 | if (ch && time_before(jiffies, port->sysrq)) { | 468 | if (ch && time_before(jiffies, port->sysrq)) { |
468 | handle_sysrq(ch, port->state->port.tty); | 469 | handle_sysrq(ch); |
469 | port->sysrq = 0; | 470 | port->sysrq = 0; |
470 | return 1; | 471 | return 1; |
471 | } | 472 | } |
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index 6d14409c4d9..9f63538928c 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h | |||
@@ -68,7 +68,7 @@ struct kmem_cache_order_objects { | |||
68 | * Slab cache management. | 68 | * Slab cache management. |
69 | */ | 69 | */ |
70 | struct kmem_cache { | 70 | struct kmem_cache { |
71 | struct kmem_cache_cpu *cpu_slab; | 71 | struct kmem_cache_cpu __percpu *cpu_slab; |
72 | /* Used for retriving partial slabs etc */ | 72 | /* Used for retriving partial slabs etc */ |
73 | unsigned long flags; | 73 | unsigned long flags; |
74 | int size; /* The size of an object including meta data */ | 74 | int size; /* The size of an object including meta data */ |
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index ae0a5286f55..92e52a1e6af 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h | |||
@@ -213,6 +213,9 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) | |||
213 | * @dma_alignment: SPI controller constraint on DMA buffers alignment. | 213 | * @dma_alignment: SPI controller constraint on DMA buffers alignment. |
214 | * @mode_bits: flags understood by this controller driver | 214 | * @mode_bits: flags understood by this controller driver |
215 | * @flags: other constraints relevant to this driver | 215 | * @flags: other constraints relevant to this driver |
216 | * @bus_lock_spinlock: spinlock for SPI bus locking | ||
217 | * @bus_lock_mutex: mutex for SPI bus locking | ||
218 | * @bus_lock_flag: indicates that the SPI bus is locked for exclusive use | ||
216 | * @setup: updates the device mode and clocking records used by a | 219 | * @setup: updates the device mode and clocking records used by a |
217 | * device's SPI controller; protocol code may call this. This | 220 | * device's SPI controller; protocol code may call this. This |
218 | * must fail if an unrecognized or unsupported mode is requested. | 221 | * must fail if an unrecognized or unsupported mode is requested. |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 6e5d1978863..e6319d18a55 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -820,7 +820,7 @@ asmlinkage long sys_fanotify_mark(int fanotify_fd, unsigned int flags, | |||
820 | u64 mask, int fd, | 820 | u64 mask, int fd, |
821 | const char __user *pathname); | 821 | const char __user *pathname); |
822 | 822 | ||
823 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]); | 823 | int kernel_execve(const char *filename, const char *const argv[], const char *const envp[]); |
824 | 824 | ||
825 | 825 | ||
826 | asmlinkage long sys_perf_event_open( | 826 | asmlinkage long sys_perf_event_open( |
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 3c92121ba9a..96eb576d82f 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/list.h> | 17 | #include <linux/list.h> |
18 | #include <linux/lockdep.h> | 18 | #include <linux/lockdep.h> |
19 | #include <linux/kobject_ns.h> | ||
19 | #include <asm/atomic.h> | 20 | #include <asm/atomic.h> |
20 | 21 | ||
21 | struct kobject; | 22 | struct kobject; |
diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h index 609e8ca5f53..387fa7d05c9 100644 --- a/include/linux/sysrq.h +++ b/include/linux/sysrq.h | |||
@@ -15,9 +15,7 @@ | |||
15 | #define _LINUX_SYSRQ_H | 15 | #define _LINUX_SYSRQ_H |
16 | 16 | ||
17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
18 | 18 | #include <linux/types.h> | |
19 | struct pt_regs; | ||
20 | struct tty_struct; | ||
21 | 19 | ||
22 | /* Possible values of bitmask for enabling sysrq functions */ | 20 | /* Possible values of bitmask for enabling sysrq functions */ |
23 | /* 0x0001 is reserved for enable everything */ | 21 | /* 0x0001 is reserved for enable everything */ |
@@ -31,7 +29,7 @@ struct tty_struct; | |||
31 | #define SYSRQ_ENABLE_RTNICE 0x0100 | 29 | #define SYSRQ_ENABLE_RTNICE 0x0100 |
32 | 30 | ||
33 | struct sysrq_key_op { | 31 | struct sysrq_key_op { |
34 | void (*handler)(int, struct tty_struct *); | 32 | void (*handler)(int); |
35 | char *help_msg; | 33 | char *help_msg; |
36 | char *action_msg; | 34 | char *action_msg; |
37 | int enable_mask; | 35 | int enable_mask; |
@@ -44,8 +42,8 @@ struct sysrq_key_op { | |||
44 | * are available -- else NULL's). | 42 | * are available -- else NULL's). |
45 | */ | 43 | */ |
46 | 44 | ||
47 | void handle_sysrq(int key, struct tty_struct *tty); | 45 | void handle_sysrq(int key); |
48 | void __handle_sysrq(int key, struct tty_struct *tty, int check_mask); | 46 | void __handle_sysrq(int key, bool check_mask); |
49 | int register_sysrq_key(int key, struct sysrq_key_op *op); | 47 | int register_sysrq_key(int key, struct sysrq_key_op *op); |
50 | int unregister_sysrq_key(int key, struct sysrq_key_op *op); | 48 | int unregister_sysrq_key(int key, struct sysrq_key_op *op); |
51 | struct sysrq_key_op *__sysrq_get_key_op(int key); | 49 | struct sysrq_key_op *__sysrq_get_key_op(int key); |
@@ -54,7 +52,11 @@ int sysrq_toggle_support(int enable_mask); | |||
54 | 52 | ||
55 | #else | 53 | #else |
56 | 54 | ||
57 | static inline void handle_sysrq(int key, struct tty_struct *tty) | 55 | static inline void handle_sysrq(int key) |
56 | { | ||
57 | } | ||
58 | |||
59 | static inline void __handle_sysrq(int key, bool check_mask) | ||
58 | { | 60 | { |
59 | } | 61 | } |
60 | 62 | ||
diff --git a/include/linux/tty.h b/include/linux/tty.h index 1437da3ddc6..67d64e6efe7 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -329,6 +329,13 @@ struct tty_struct { | |||
329 | struct tty_port *port; | 329 | struct tty_port *port; |
330 | }; | 330 | }; |
331 | 331 | ||
332 | /* Each of a tty's open files has private_data pointing to tty_file_private */ | ||
333 | struct tty_file_private { | ||
334 | struct tty_struct *tty; | ||
335 | struct file *file; | ||
336 | struct list_head list; | ||
337 | }; | ||
338 | |||
332 | /* tty magic number */ | 339 | /* tty magic number */ |
333 | #define TTY_MAGIC 0x5401 | 340 | #define TTY_MAGIC 0x5401 |
334 | 341 | ||
@@ -458,6 +465,7 @@ extern void proc_clear_tty(struct task_struct *p); | |||
458 | extern struct tty_struct *get_current_tty(void); | 465 | extern struct tty_struct *get_current_tty(void); |
459 | extern void tty_default_fops(struct file_operations *fops); | 466 | extern void tty_default_fops(struct file_operations *fops); |
460 | extern struct tty_struct *alloc_tty_struct(void); | 467 | extern struct tty_struct *alloc_tty_struct(void); |
468 | extern void tty_add_file(struct tty_struct *tty, struct file *file); | ||
461 | extern void free_tty_struct(struct tty_struct *tty); | 469 | extern void free_tty_struct(struct tty_struct *tty); |
462 | extern void initialize_tty_struct(struct tty_struct *tty, | 470 | extern void initialize_tty_struct(struct tty_struct *tty, |
463 | struct tty_driver *driver, int idx); | 471 | struct tty_driver *driver, int idx); |
@@ -470,6 +478,7 @@ extern struct tty_struct *tty_pair_get_tty(struct tty_struct *tty); | |||
470 | extern struct tty_struct *tty_pair_get_pty(struct tty_struct *tty); | 478 | extern struct tty_struct *tty_pair_get_pty(struct tty_struct *tty); |
471 | 479 | ||
472 | extern struct mutex tty_mutex; | 480 | extern struct mutex tty_mutex; |
481 | extern spinlock_t tty_files_lock; | ||
473 | 482 | ||
474 | extern void tty_write_unlock(struct tty_struct *tty); | 483 | extern void tty_write_unlock(struct tty_struct *tty); |
475 | extern int tty_write_lock(struct tty_struct *tty, int ndelay); | 484 | extern int tty_write_lock(struct tty_struct *tty, int ndelay); |
diff --git a/include/linux/uinput.h b/include/linux/uinput.h index 60c81da77f0..05f7fed2b17 100644 --- a/include/linux/uinput.h +++ b/include/linux/uinput.h | |||
@@ -37,7 +37,6 @@ | |||
37 | #define UINPUT_VERSION 3 | 37 | #define UINPUT_VERSION 3 |
38 | 38 | ||
39 | #ifdef __KERNEL__ | 39 | #ifdef __KERNEL__ |
40 | #define UINPUT_MINOR 223 | ||
41 | #define UINPUT_NAME "uinput" | 40 | #define UINPUT_NAME "uinput" |
42 | #define UINPUT_BUFFER_SIZE 16 | 41 | #define UINPUT_BUFFER_SIZE 16 |
43 | #define UINPUT_NUM_REQUESTS 16 | 42 | #define UINPUT_NUM_REQUESTS 16 |
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 890bc147219..617068134ae 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h | |||
@@ -247,6 +247,7 @@ int usb_add_config(struct usb_composite_dev *, | |||
247 | * value; it should return zero on successful initialization. | 247 | * value; it should return zero on successful initialization. |
248 | * @unbind: Reverses @bind(); called as a side effect of unregistering | 248 | * @unbind: Reverses @bind(); called as a side effect of unregistering |
249 | * this driver. | 249 | * this driver. |
250 | * @disconnect: optional driver disconnect method | ||
250 | * @suspend: Notifies when the host stops sending USB traffic, | 251 | * @suspend: Notifies when the host stops sending USB traffic, |
251 | * after function notifications | 252 | * after function notifications |
252 | * @resume: Notifies configuration when the host restarts USB traffic, | 253 | * @resume: Notifies configuration when the host restarts USB traffic, |
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 84a4c44c208..55675b1efb2 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h | |||
@@ -342,8 +342,7 @@ extern int usb_serial_generic_submit_read_urb(struct usb_serial_port *port, | |||
342 | extern void usb_serial_generic_process_read_urb(struct urb *urb); | 342 | extern void usb_serial_generic_process_read_urb(struct urb *urb); |
343 | extern int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port, | 343 | extern int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port, |
344 | void *dest, size_t size); | 344 | void *dest, size_t size); |
345 | extern int usb_serial_handle_sysrq_char(struct tty_struct *tty, | 345 | extern int usb_serial_handle_sysrq_char(struct usb_serial_port *port, |
346 | struct usb_serial_port *port, | ||
347 | unsigned int ch); | 346 | unsigned int ch); |
348 | extern int usb_serial_handle_break(struct usb_serial_port *port); | 347 | extern int usb_serial_handle_break(struct usb_serial_port *port); |
349 | 348 | ||
diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h index 6228b5b77d3..e9e1524b582 100644 --- a/include/linux/vgaarb.h +++ b/include/linux/vgaarb.h | |||
@@ -93,8 +93,11 @@ extern void vga_set_legacy_decoding(struct pci_dev *pdev, | |||
93 | * Nested calls are supported (a per-resource counter is maintained) | 93 | * Nested calls are supported (a per-resource counter is maintained) |
94 | */ | 94 | */ |
95 | 95 | ||
96 | extern int vga_get(struct pci_dev *pdev, unsigned int rsrc, | 96 | #if defined(CONFIG_VGA_ARB) |
97 | int interruptible); | 97 | extern int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible); |
98 | #else | ||
99 | static inline int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible) { return 0; } | ||
100 | #endif | ||
98 | 101 | ||
99 | /** | 102 | /** |
100 | * vga_get_interruptible | 103 | * vga_get_interruptible |
@@ -131,7 +134,11 @@ static inline int vga_get_uninterruptible(struct pci_dev *pdev, | |||
131 | * are already locked by another card. It can be called in any context | 134 | * are already locked by another card. It can be called in any context |
132 | */ | 135 | */ |
133 | 136 | ||
137 | #if defined(CONFIG_VGA_ARB) | ||
134 | extern int vga_tryget(struct pci_dev *pdev, unsigned int rsrc); | 138 | extern int vga_tryget(struct pci_dev *pdev, unsigned int rsrc); |
139 | #else | ||
140 | static inline int vga_tryget(struct pci_dev *pdev, unsigned int rsrc) { return 0; } | ||
141 | #endif | ||
135 | 142 | ||
136 | /** | 143 | /** |
137 | * vga_put - release lock on legacy VGA resources | 144 | * vga_put - release lock on legacy VGA resources |
@@ -146,7 +153,11 @@ extern int vga_tryget(struct pci_dev *pdev, unsigned int rsrc); | |||
146 | * released if the counter reaches 0. | 153 | * released if the counter reaches 0. |
147 | */ | 154 | */ |
148 | 155 | ||
156 | #if defined(CONFIG_VGA_ARB) | ||
149 | extern void vga_put(struct pci_dev *pdev, unsigned int rsrc); | 157 | extern void vga_put(struct pci_dev *pdev, unsigned int rsrc); |
158 | #else | ||
159 | #define vga_put(pdev, rsrc) | ||
160 | #endif | ||
150 | 161 | ||
151 | 162 | ||
152 | /** | 163 | /** |
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 4f9d277bcd9..f11100f9648 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h | |||
@@ -25,18 +25,20 @@ typedef void (*work_func_t)(struct work_struct *work); | |||
25 | 25 | ||
26 | enum { | 26 | enum { |
27 | WORK_STRUCT_PENDING_BIT = 0, /* work item is pending execution */ | 27 | WORK_STRUCT_PENDING_BIT = 0, /* work item is pending execution */ |
28 | WORK_STRUCT_CWQ_BIT = 1, /* data points to cwq */ | 28 | WORK_STRUCT_DELAYED_BIT = 1, /* work item is delayed */ |
29 | WORK_STRUCT_LINKED_BIT = 2, /* next work is linked to this one */ | 29 | WORK_STRUCT_CWQ_BIT = 2, /* data points to cwq */ |
30 | WORK_STRUCT_LINKED_BIT = 3, /* next work is linked to this one */ | ||
30 | #ifdef CONFIG_DEBUG_OBJECTS_WORK | 31 | #ifdef CONFIG_DEBUG_OBJECTS_WORK |
31 | WORK_STRUCT_STATIC_BIT = 3, /* static initializer (debugobjects) */ | 32 | WORK_STRUCT_STATIC_BIT = 4, /* static initializer (debugobjects) */ |
32 | WORK_STRUCT_COLOR_SHIFT = 4, /* color for workqueue flushing */ | 33 | WORK_STRUCT_COLOR_SHIFT = 5, /* color for workqueue flushing */ |
33 | #else | 34 | #else |
34 | WORK_STRUCT_COLOR_SHIFT = 3, /* color for workqueue flushing */ | 35 | WORK_STRUCT_COLOR_SHIFT = 4, /* color for workqueue flushing */ |
35 | #endif | 36 | #endif |
36 | 37 | ||
37 | WORK_STRUCT_COLOR_BITS = 4, | 38 | WORK_STRUCT_COLOR_BITS = 4, |
38 | 39 | ||
39 | WORK_STRUCT_PENDING = 1 << WORK_STRUCT_PENDING_BIT, | 40 | WORK_STRUCT_PENDING = 1 << WORK_STRUCT_PENDING_BIT, |
41 | WORK_STRUCT_DELAYED = 1 << WORK_STRUCT_DELAYED_BIT, | ||
40 | WORK_STRUCT_CWQ = 1 << WORK_STRUCT_CWQ_BIT, | 42 | WORK_STRUCT_CWQ = 1 << WORK_STRUCT_CWQ_BIT, |
41 | WORK_STRUCT_LINKED = 1 << WORK_STRUCT_LINKED_BIT, | 43 | WORK_STRUCT_LINKED = 1 << WORK_STRUCT_LINKED_BIT, |
42 | #ifdef CONFIG_DEBUG_OBJECTS_WORK | 44 | #ifdef CONFIG_DEBUG_OBJECTS_WORK |
@@ -59,8 +61,8 @@ enum { | |||
59 | 61 | ||
60 | /* | 62 | /* |
61 | * Reserve 7 bits off of cwq pointer w/ debugobjects turned | 63 | * Reserve 7 bits off of cwq pointer w/ debugobjects turned |
62 | * off. This makes cwqs aligned to 128 bytes which isn't too | 64 | * off. This makes cwqs aligned to 256 bytes and allows 15 |
63 | * excessive while allowing 15 workqueue flush colors. | 65 | * workqueue flush colors. |
64 | */ | 66 | */ |
65 | WORK_STRUCT_FLAG_BITS = WORK_STRUCT_COLOR_SHIFT + | 67 | WORK_STRUCT_FLAG_BITS = WORK_STRUCT_COLOR_SHIFT + |
66 | WORK_STRUCT_COLOR_BITS, | 68 | WORK_STRUCT_COLOR_BITS, |
@@ -241,6 +243,8 @@ enum { | |||
241 | WQ_HIGHPRI = 1 << 4, /* high priority */ | 243 | WQ_HIGHPRI = 1 << 4, /* high priority */ |
242 | WQ_CPU_INTENSIVE = 1 << 5, /* cpu instensive workqueue */ | 244 | WQ_CPU_INTENSIVE = 1 << 5, /* cpu instensive workqueue */ |
243 | 245 | ||
246 | WQ_DYING = 1 << 6, /* internal: workqueue is dying */ | ||
247 | |||
244 | WQ_MAX_ACTIVE = 512, /* I like 512, better ideas? */ | 248 | WQ_MAX_ACTIVE = 512, /* I like 512, better ideas? */ |
245 | WQ_MAX_UNBOUND_PER_CPU = 4, /* 4 * #cpus for unbound wq */ | 249 | WQ_MAX_UNBOUND_PER_CPU = 4, /* 4 * #cpus for unbound wq */ |
246 | WQ_DFL_ACTIVE = WQ_MAX_ACTIVE / 2, | 250 | WQ_DFL_ACTIVE = WQ_MAX_ACTIVE / 2, |
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h index 726cc353640..ef6c24a529e 100644 --- a/include/net/cls_cgroup.h +++ b/include/net/cls_cgroup.h | |||
@@ -27,11 +27,17 @@ struct cgroup_cls_state | |||
27 | #ifdef CONFIG_NET_CLS_CGROUP | 27 | #ifdef CONFIG_NET_CLS_CGROUP |
28 | static inline u32 task_cls_classid(struct task_struct *p) | 28 | static inline u32 task_cls_classid(struct task_struct *p) |
29 | { | 29 | { |
30 | int classid; | ||
31 | |||
30 | if (in_interrupt()) | 32 | if (in_interrupt()) |
31 | return 0; | 33 | return 0; |
32 | 34 | ||
33 | return container_of(task_subsys_state(p, net_cls_subsys_id), | 35 | rcu_read_lock(); |
34 | struct cgroup_cls_state, css)->classid; | 36 | classid = container_of(task_subsys_state(p, net_cls_subsys_id), |
37 | struct cgroup_cls_state, css)->classid; | ||
38 | rcu_read_unlock(); | ||
39 | |||
40 | return classid; | ||
35 | } | 41 | } |
36 | #else | 42 | #else |
37 | extern int net_cls_subsys_id; | 43 | extern int net_cls_subsys_id; |
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index a4747a0f730..f976885f686 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h | |||
@@ -955,6 +955,9 @@ static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum) | |||
955 | return csum_partial(diff, sizeof(diff), oldsum); | 955 | return csum_partial(diff, sizeof(diff), oldsum); |
956 | } | 956 | } |
957 | 957 | ||
958 | extern void ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, | ||
959 | int outin); | ||
960 | |||
958 | #endif /* __KERNEL__ */ | 961 | #endif /* __KERNEL__ */ |
959 | 962 | ||
960 | #endif /* _NET_IP_VS_H */ | 963 | #endif /* _NET_IP_VS_H */ |
diff --git a/include/net/sock.h b/include/net/sock.h index 100e43bf95f..8ae97c4970d 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -752,6 +752,7 @@ struct proto { | |||
752 | /* Keeping track of sk's, looking them up, and port selection methods. */ | 752 | /* Keeping track of sk's, looking them up, and port selection methods. */ |
753 | void (*hash)(struct sock *sk); | 753 | void (*hash)(struct sock *sk); |
754 | void (*unhash)(struct sock *sk); | 754 | void (*unhash)(struct sock *sk); |
755 | void (*rehash)(struct sock *sk); | ||
755 | int (*get_port)(struct sock *sk, unsigned short snum); | 756 | int (*get_port)(struct sock *sk, unsigned short snum); |
756 | 757 | ||
757 | /* Keeping track of sockets in use */ | 758 | /* Keeping track of sockets in use */ |
diff --git a/include/net/tcp.h b/include/net/tcp.h index 11dbacc886c..bfc1da43295 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -268,11 +268,21 @@ static inline int between(__u32 seq1, __u32 seq2, __u32 seq3) | |||
268 | return seq3 - seq2 >= seq1 - seq2; | 268 | return seq3 - seq2 >= seq1 - seq2; |
269 | } | 269 | } |
270 | 270 | ||
271 | static inline int tcp_too_many_orphans(struct sock *sk, int num) | 271 | static inline bool tcp_too_many_orphans(struct sock *sk, int shift) |
272 | { | 272 | { |
273 | return (num > sysctl_tcp_max_orphans) || | 273 | struct percpu_counter *ocp = sk->sk_prot->orphan_count; |
274 | (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && | 274 | int orphans = percpu_counter_read_positive(ocp); |
275 | atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]); | 275 | |
276 | if (orphans << shift > sysctl_tcp_max_orphans) { | ||
277 | orphans = percpu_counter_sum_positive(ocp); | ||
278 | if (orphans << shift > sysctl_tcp_max_orphans) | ||
279 | return true; | ||
280 | } | ||
281 | |||
282 | if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && | ||
283 | atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]) | ||
284 | return true; | ||
285 | return false; | ||
276 | } | 286 | } |
277 | 287 | ||
278 | /* syncookies: remember time of last synqueue overflow */ | 288 | /* syncookies: remember time of last synqueue overflow */ |
diff --git a/include/net/udp.h b/include/net/udp.h index 7abdf305da5..a184d3496b1 100644 --- a/include/net/udp.h +++ b/include/net/udp.h | |||
@@ -151,6 +151,7 @@ static inline void udp_lib_hash(struct sock *sk) | |||
151 | } | 151 | } |
152 | 152 | ||
153 | extern void udp_lib_unhash(struct sock *sk); | 153 | extern void udp_lib_unhash(struct sock *sk); |
154 | extern void udp_lib_rehash(struct sock *sk, u16 new_hash); | ||
154 | 155 | ||
155 | static inline void udp_lib_close(struct sock *sk, long timeout) | 156 | static inline void udp_lib_close(struct sock *sk, long timeout) |
156 | { | 157 | { |
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 6a664c3f7c1..7dc97d12253 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h | |||
@@ -1707,6 +1707,7 @@ struct snd_emu10k1 { | |||
1707 | unsigned int card_type; /* EMU10K1_CARD_* */ | 1707 | unsigned int card_type; /* EMU10K1_CARD_* */ |
1708 | unsigned int ecard_ctrl; /* ecard control bits */ | 1708 | unsigned int ecard_ctrl; /* ecard control bits */ |
1709 | unsigned long dma_mask; /* PCI DMA mask */ | 1709 | unsigned long dma_mask; /* PCI DMA mask */ |
1710 | unsigned int delay_pcm_irq; /* in samples */ | ||
1710 | int max_cache_pages; /* max memory size / PAGE_SIZE */ | 1711 | int max_cache_pages; /* max memory size / PAGE_SIZE */ |
1711 | struct snd_dma_buffer silent_page; /* silent page */ | 1712 | struct snd_dma_buffer silent_page; /* silent page */ |
1712 | struct snd_dma_buffer ptb_pages; /* page table pages */ | 1713 | struct snd_dma_buffer ptb_pages; /* page table pages */ |
diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h index c624126a9c8..425bcfe56c6 100644 --- a/include/trace/events/timer.h +++ b/include/trace/events/timer.h | |||
@@ -81,14 +81,16 @@ TRACE_EVENT(timer_expire_entry, | |||
81 | TP_STRUCT__entry( | 81 | TP_STRUCT__entry( |
82 | __field( void *, timer ) | 82 | __field( void *, timer ) |
83 | __field( unsigned long, now ) | 83 | __field( unsigned long, now ) |
84 | __field( void *, function) | ||
84 | ), | 85 | ), |
85 | 86 | ||
86 | TP_fast_assign( | 87 | TP_fast_assign( |
87 | __entry->timer = timer; | 88 | __entry->timer = timer; |
88 | __entry->now = jiffies; | 89 | __entry->now = jiffies; |
90 | __entry->function = timer->function; | ||
89 | ), | 91 | ), |
90 | 92 | ||
91 | TP_printk("timer=%p now=%lu", __entry->timer, __entry->now) | 93 | TP_printk("timer=%p function=%pf now=%lu", __entry->timer, __entry->function,__entry->now) |
92 | ); | 94 | ); |
93 | 95 | ||
94 | /** | 96 | /** |
@@ -200,14 +202,16 @@ TRACE_EVENT(hrtimer_expire_entry, | |||
200 | TP_STRUCT__entry( | 202 | TP_STRUCT__entry( |
201 | __field( void *, hrtimer ) | 203 | __field( void *, hrtimer ) |
202 | __field( s64, now ) | 204 | __field( s64, now ) |
205 | __field( void *, function) | ||
203 | ), | 206 | ), |
204 | 207 | ||
205 | TP_fast_assign( | 208 | TP_fast_assign( |
206 | __entry->hrtimer = hrtimer; | 209 | __entry->hrtimer = hrtimer; |
207 | __entry->now = now->tv64; | 210 | __entry->now = now->tv64; |
211 | __entry->function = hrtimer->function; | ||
208 | ), | 212 | ), |
209 | 213 | ||
210 | TP_printk("hrtimer=%p now=%llu", __entry->hrtimer, | 214 | TP_printk("hrtimer=%p function=%pf now=%llu", __entry->hrtimer, __entry->function, |
211 | (unsigned long long)ktime_to_ns((ktime_t) { .tv64 = __entry->now })) | 215 | (unsigned long long)ktime_to_ns((ktime_t) { .tv64 = __entry->now })) |
212 | ); | 216 | ); |
213 | 217 | ||
diff --git a/include/trace/events/workqueue.h b/include/trace/events/workqueue.h new file mode 100644 index 00000000000..49682d7e9d6 --- /dev/null +++ b/include/trace/events/workqueue.h | |||
@@ -0,0 +1,62 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM workqueue | ||
3 | |||
4 | #if !defined(_TRACE_WORKQUEUE_H) || defined(TRACE_HEADER_MULTI_READ) | ||
5 | #define _TRACE_WORKQUEUE_H | ||
6 | |||
7 | #include <linux/tracepoint.h> | ||
8 | #include <linux/workqueue.h> | ||
9 | |||
10 | /** | ||
11 | * workqueue_execute_start - called immediately before the workqueue callback | ||
12 | * @work: pointer to struct work_struct | ||
13 | * | ||
14 | * Allows to track workqueue execution. | ||
15 | */ | ||
16 | TRACE_EVENT(workqueue_execute_start, | ||
17 | |||
18 | TP_PROTO(struct work_struct *work), | ||
19 | |||
20 | TP_ARGS(work), | ||
21 | |||
22 | TP_STRUCT__entry( | ||
23 | __field( void *, work ) | ||
24 | __field( void *, function) | ||
25 | ), | ||
26 | |||
27 | TP_fast_assign( | ||
28 | __entry->work = work; | ||
29 | __entry->function = work->func; | ||
30 | ), | ||
31 | |||
32 | TP_printk("work struct %p: function %pf", __entry->work, __entry->function) | ||
33 | ); | ||
34 | |||
35 | /** | ||
36 | * workqueue_execute_end - called immediately before the workqueue callback | ||
37 | * @work: pointer to struct work_struct | ||
38 | * | ||
39 | * Allows to track workqueue execution. | ||
40 | */ | ||
41 | TRACE_EVENT(workqueue_execute_end, | ||
42 | |||
43 | TP_PROTO(struct work_struct *work), | ||
44 | |||
45 | TP_ARGS(work), | ||
46 | |||
47 | TP_STRUCT__entry( | ||
48 | __field( void *, work ) | ||
49 | ), | ||
50 | |||
51 | TP_fast_assign( | ||
52 | __entry->work = work; | ||
53 | ), | ||
54 | |||
55 | TP_printk("work struct %p", __entry->work) | ||
56 | ); | ||
57 | |||
58 | |||
59 | #endif /* _TRACE_WORKQUEUE_H */ | ||
60 | |||
61 | /* This part must be outside protection */ | ||
62 | #include <trace/define_trace.h> | ||
diff --git a/include/xen/platform_pci.h b/include/xen/platform_pci.h index ce9d671c636..a785a3b0c8c 100644 --- a/include/xen/platform_pci.h +++ b/include/xen/platform_pci.h | |||
@@ -16,11 +16,15 @@ | |||
16 | #define XEN_IOPORT_PROTOVER (XEN_IOPORT_BASE + 2) /* 1 byte access (R) */ | 16 | #define XEN_IOPORT_PROTOVER (XEN_IOPORT_BASE + 2) /* 1 byte access (R) */ |
17 | #define XEN_IOPORT_PRODNUM (XEN_IOPORT_BASE + 2) /* 2 byte access (W) */ | 17 | #define XEN_IOPORT_PRODNUM (XEN_IOPORT_BASE + 2) /* 2 byte access (W) */ |
18 | 18 | ||
19 | #define XEN_UNPLUG_ALL_IDE_DISKS 1 | 19 | #define XEN_UNPLUG_ALL_IDE_DISKS (1<<0) |
20 | #define XEN_UNPLUG_ALL_NICS 2 | 20 | #define XEN_UNPLUG_ALL_NICS (1<<1) |
21 | #define XEN_UNPLUG_AUX_IDE_DISKS 4 | 21 | #define XEN_UNPLUG_AUX_IDE_DISKS (1<<2) |
22 | #define XEN_UNPLUG_ALL 7 | 22 | #define XEN_UNPLUG_ALL (XEN_UNPLUG_ALL_IDE_DISKS|\ |
23 | #define XEN_UNPLUG_IGNORE 8 | 23 | XEN_UNPLUG_ALL_NICS|\ |
24 | XEN_UNPLUG_AUX_IDE_DISKS) | ||
25 | |||
26 | #define XEN_UNPLUG_UNNECESSARY (1<<16) | ||
27 | #define XEN_UNPLUG_NEVER (1<<17) | ||
24 | 28 | ||
25 | static inline int xen_must_unplug_nics(void) { | 29 | static inline int xen_must_unplug_nics(void) { |
26 | #if (defined(CONFIG_XEN_NETDEV_FRONTEND) || \ | 30 | #if (defined(CONFIG_XEN_NETDEV_FRONTEND) || \ |
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 2b108538d0d..3098a38f3ae 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c | |||
@@ -24,10 +24,11 @@ static int __init no_initrd(char *str) | |||
24 | 24 | ||
25 | __setup("noinitrd", no_initrd); | 25 | __setup("noinitrd", no_initrd); |
26 | 26 | ||
27 | static int __init do_linuxrc(void * shell) | 27 | static int __init do_linuxrc(void *_shell) |
28 | { | 28 | { |
29 | static char *argv[] = { "linuxrc", NULL, }; | 29 | static const char *argv[] = { "linuxrc", NULL, }; |
30 | extern char * envp_init[]; | 30 | extern const char *envp_init[]; |
31 | const char *shell = _shell; | ||
31 | 32 | ||
32 | sys_close(old_fd);sys_close(root_fd); | 33 | sys_close(old_fd);sys_close(root_fd); |
33 | sys_setsid(); | 34 | sys_setsid(); |
diff --git a/init/main.c b/init/main.c index 22d61cb06f9..94ab488039a 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -197,8 +197,8 @@ static int __init set_reset_devices(char *str) | |||
197 | 197 | ||
198 | __setup("reset_devices", set_reset_devices); | 198 | __setup("reset_devices", set_reset_devices); |
199 | 199 | ||
200 | static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, }; | 200 | static const char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, }; |
201 | char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, }; | 201 | const char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, }; |
202 | static const char *panic_later, *panic_param; | 202 | static const char *panic_later, *panic_param; |
203 | 203 | ||
204 | extern const struct obs_kernel_param __setup_start[], __setup_end[]; | 204 | extern const struct obs_kernel_param __setup_start[], __setup_end[]; |
@@ -809,7 +809,7 @@ static void __init do_pre_smp_initcalls(void) | |||
809 | do_one_initcall(*fn); | 809 | do_one_initcall(*fn); |
810 | } | 810 | } |
811 | 811 | ||
812 | static void run_init_process(char *init_filename) | 812 | static void run_init_process(const char *init_filename) |
813 | { | 813 | { |
814 | argv_init[0] = init_filename; | 814 | argv_init[0] = init_filename; |
815 | kernel_execve(init_filename, argv_init, envp_init); | 815 | kernel_execve(init_filename, argv_init, envp_init); |
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 192f88c5b0f..ed19afd9e3f 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -1791,10 +1791,11 @@ out: | |||
1791 | } | 1791 | } |
1792 | 1792 | ||
1793 | /** | 1793 | /** |
1794 | * cgroup_attach_task_current_cg - attach task 'tsk' to current task's cgroup | 1794 | * cgroup_attach_task_all - attach task 'tsk' to all cgroups of task 'from' |
1795 | * @from: attach to all cgroups of a given task | ||
1795 | * @tsk: the task to be attached | 1796 | * @tsk: the task to be attached |
1796 | */ | 1797 | */ |
1797 | int cgroup_attach_task_current_cg(struct task_struct *tsk) | 1798 | int cgroup_attach_task_all(struct task_struct *from, struct task_struct *tsk) |
1798 | { | 1799 | { |
1799 | struct cgroupfs_root *root; | 1800 | struct cgroupfs_root *root; |
1800 | struct cgroup *cur_cg; | 1801 | struct cgroup *cur_cg; |
@@ -1802,7 +1803,7 @@ int cgroup_attach_task_current_cg(struct task_struct *tsk) | |||
1802 | 1803 | ||
1803 | cgroup_lock(); | 1804 | cgroup_lock(); |
1804 | for_each_active_root(root) { | 1805 | for_each_active_root(root) { |
1805 | cur_cg = task_cgroup_from_root(current, root); | 1806 | cur_cg = task_cgroup_from_root(from, root); |
1806 | retval = cgroup_attach_task(cur_cg, tsk); | 1807 | retval = cgroup_attach_task(cur_cg, tsk); |
1807 | if (retval) | 1808 | if (retval) |
1808 | break; | 1809 | break; |
@@ -1811,7 +1812,7 @@ int cgroup_attach_task_current_cg(struct task_struct *tsk) | |||
1811 | 1812 | ||
1812 | return retval; | 1813 | return retval; |
1813 | } | 1814 | } |
1814 | EXPORT_SYMBOL_GPL(cgroup_attach_task_current_cg); | 1815 | EXPORT_SYMBOL_GPL(cgroup_attach_task_all); |
1815 | 1816 | ||
1816 | /* | 1817 | /* |
1817 | * Attach task with pid 'pid' to cgroup 'cgrp'. Call with cgroup_mutex | 1818 | * Attach task with pid 'pid' to cgroup 'cgrp'. Call with cgroup_mutex |
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 3c2d4972d23..de407c78178 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c | |||
@@ -741,7 +741,7 @@ static struct console kgdbcons = { | |||
741 | }; | 741 | }; |
742 | 742 | ||
743 | #ifdef CONFIG_MAGIC_SYSRQ | 743 | #ifdef CONFIG_MAGIC_SYSRQ |
744 | static void sysrq_handle_dbg(int key, struct tty_struct *tty) | 744 | static void sysrq_handle_dbg(int key) |
745 | { | 745 | { |
746 | if (!dbg_io_ops) { | 746 | if (!dbg_io_ops) { |
747 | printk(KERN_CRIT "ERROR: No KGDB I/O module available\n"); | 747 | printk(KERN_CRIT "ERROR: No KGDB I/O module available\n"); |
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 28b844118bb..caf057a3de0 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c | |||
@@ -1929,7 +1929,7 @@ static int kdb_sr(int argc, const char **argv) | |||
1929 | if (argc != 1) | 1929 | if (argc != 1) |
1930 | return KDB_ARGCOUNT; | 1930 | return KDB_ARGCOUNT; |
1931 | kdb_trap_printk++; | 1931 | kdb_trap_printk++; |
1932 | __handle_sysrq(*argv[1], NULL, 0); | 1932 | __handle_sysrq(*argv[1], false); |
1933 | kdb_trap_printk--; | 1933 | kdb_trap_printk--; |
1934 | 1934 | ||
1935 | return 0; | 1935 | return 0; |
diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h index c438f545a32..be775f7e81e 100644 --- a/kernel/debug/kdb/kdb_private.h +++ b/kernel/debug/kdb/kdb_private.h | |||
@@ -255,7 +255,14 @@ extern void kdb_ps1(const struct task_struct *p); | |||
255 | extern void kdb_print_nameval(const char *name, unsigned long val); | 255 | extern void kdb_print_nameval(const char *name, unsigned long val); |
256 | extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info); | 256 | extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info); |
257 | extern void kdb_meminfo_proc_show(void); | 257 | extern void kdb_meminfo_proc_show(void); |
258 | #ifdef CONFIG_KALLSYMS | ||
258 | extern const char *kdb_walk_kallsyms(loff_t *pos); | 259 | extern const char *kdb_walk_kallsyms(loff_t *pos); |
260 | #else /* ! CONFIG_KALLSYMS */ | ||
261 | static inline const char *kdb_walk_kallsyms(loff_t *pos) | ||
262 | { | ||
263 | return NULL; | ||
264 | } | ||
265 | #endif /* ! CONFIG_KALLSYMS */ | ||
259 | extern char *kdb_getstr(char *, size_t, char *); | 266 | extern char *kdb_getstr(char *, size_t, char *); |
260 | 267 | ||
261 | /* Defines for kdb_symbol_print */ | 268 | /* Defines for kdb_symbol_print */ |
diff --git a/kernel/debug/kdb/kdb_support.c b/kernel/debug/kdb/kdb_support.c index 45344d5c53d..6b2485dcb05 100644 --- a/kernel/debug/kdb/kdb_support.c +++ b/kernel/debug/kdb/kdb_support.c | |||
@@ -82,8 +82,8 @@ static char *kdb_name_table[100]; /* arbitrary size */ | |||
82 | int kdbnearsym(unsigned long addr, kdb_symtab_t *symtab) | 82 | int kdbnearsym(unsigned long addr, kdb_symtab_t *symtab) |
83 | { | 83 | { |
84 | int ret = 0; | 84 | int ret = 0; |
85 | unsigned long symbolsize; | 85 | unsigned long symbolsize = 0; |
86 | unsigned long offset; | 86 | unsigned long offset = 0; |
87 | #define knt1_size 128 /* must be >= kallsyms table size */ | 87 | #define knt1_size 128 /* must be >= kallsyms table size */ |
88 | char *knt1 = NULL; | 88 | char *knt1 = NULL; |
89 | 89 | ||
diff --git a/kernel/exit.c b/kernel/exit.c index 671ed56e0a4..03120229db2 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -1386,8 +1386,7 @@ static int wait_task_stopped(struct wait_opts *wo, | |||
1386 | if (!unlikely(wo->wo_flags & WNOWAIT)) | 1386 | if (!unlikely(wo->wo_flags & WNOWAIT)) |
1387 | *p_code = 0; | 1387 | *p_code = 0; |
1388 | 1388 | ||
1389 | /* don't need the RCU readlock here as we're holding a spinlock */ | 1389 | uid = task_uid(p); |
1390 | uid = __task_cred(p)->uid; | ||
1391 | unlock_sig: | 1390 | unlock_sig: |
1392 | spin_unlock_irq(&p->sighand->siglock); | 1391 | spin_unlock_irq(&p->sighand->siglock); |
1393 | if (!exit_code) | 1392 | if (!exit_code) |
@@ -1460,7 +1459,7 @@ static int wait_task_continued(struct wait_opts *wo, struct task_struct *p) | |||
1460 | } | 1459 | } |
1461 | if (!unlikely(wo->wo_flags & WNOWAIT)) | 1460 | if (!unlikely(wo->wo_flags & WNOWAIT)) |
1462 | p->signal->flags &= ~SIGNAL_STOP_CONTINUED; | 1461 | p->signal->flags &= ~SIGNAL_STOP_CONTINUED; |
1463 | uid = __task_cred(p)->uid; | 1462 | uid = task_uid(p); |
1464 | spin_unlock_irq(&p->sighand->siglock); | 1463 | spin_unlock_irq(&p->sighand->siglock); |
1465 | 1464 | ||
1466 | pid = task_pid_vnr(p); | 1465 | pid = task_pid_vnr(p); |
diff --git a/kernel/fork.c b/kernel/fork.c index 98b450876f9..b7e9d60a675 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -300,7 +300,7 @@ out: | |||
300 | #ifdef CONFIG_MMU | 300 | #ifdef CONFIG_MMU |
301 | static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | 301 | static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) |
302 | { | 302 | { |
303 | struct vm_area_struct *mpnt, *tmp, **pprev; | 303 | struct vm_area_struct *mpnt, *tmp, *prev, **pprev; |
304 | struct rb_node **rb_link, *rb_parent; | 304 | struct rb_node **rb_link, *rb_parent; |
305 | int retval; | 305 | int retval; |
306 | unsigned long charge; | 306 | unsigned long charge; |
@@ -328,6 +328,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | |||
328 | if (retval) | 328 | if (retval) |
329 | goto out; | 329 | goto out; |
330 | 330 | ||
331 | prev = NULL; | ||
331 | for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) { | 332 | for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) { |
332 | struct file *file; | 333 | struct file *file; |
333 | 334 | ||
@@ -359,7 +360,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | |||
359 | goto fail_nomem_anon_vma_fork; | 360 | goto fail_nomem_anon_vma_fork; |
360 | tmp->vm_flags &= ~VM_LOCKED; | 361 | tmp->vm_flags &= ~VM_LOCKED; |
361 | tmp->vm_mm = mm; | 362 | tmp->vm_mm = mm; |
362 | tmp->vm_next = NULL; | 363 | tmp->vm_next = tmp->vm_prev = NULL; |
363 | file = tmp->vm_file; | 364 | file = tmp->vm_file; |
364 | if (file) { | 365 | if (file) { |
365 | struct inode *inode = file->f_path.dentry->d_inode; | 366 | struct inode *inode = file->f_path.dentry->d_inode; |
@@ -392,6 +393,8 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | |||
392 | */ | 393 | */ |
393 | *pprev = tmp; | 394 | *pprev = tmp; |
394 | pprev = &tmp->vm_next; | 395 | pprev = &tmp->vm_next; |
396 | tmp->vm_prev = prev; | ||
397 | prev = tmp; | ||
395 | 398 | ||
396 | __vma_link_rb(mm, tmp, rb_link, rb_parent); | 399 | __vma_link_rb(mm, tmp, rb_link, rb_parent); |
397 | rb_link = &tmp->vm_rb.rb_right; | 400 | rb_link = &tmp->vm_rb.rb_right; |
@@ -752,13 +755,13 @@ static int copy_fs(unsigned long clone_flags, struct task_struct *tsk) | |||
752 | struct fs_struct *fs = current->fs; | 755 | struct fs_struct *fs = current->fs; |
753 | if (clone_flags & CLONE_FS) { | 756 | if (clone_flags & CLONE_FS) { |
754 | /* tsk->fs is already what we want */ | 757 | /* tsk->fs is already what we want */ |
755 | write_lock(&fs->lock); | 758 | spin_lock(&fs->lock); |
756 | if (fs->in_exec) { | 759 | if (fs->in_exec) { |
757 | write_unlock(&fs->lock); | 760 | spin_unlock(&fs->lock); |
758 | return -EAGAIN; | 761 | return -EAGAIN; |
759 | } | 762 | } |
760 | fs->users++; | 763 | fs->users++; |
761 | write_unlock(&fs->lock); | 764 | spin_unlock(&fs->lock); |
762 | return 0; | 765 | return 0; |
763 | } | 766 | } |
764 | tsk->fs = copy_fs_struct(fs); | 767 | tsk->fs = copy_fs_struct(fs); |
@@ -1676,13 +1679,13 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags) | |||
1676 | 1679 | ||
1677 | if (new_fs) { | 1680 | if (new_fs) { |
1678 | fs = current->fs; | 1681 | fs = current->fs; |
1679 | write_lock(&fs->lock); | 1682 | spin_lock(&fs->lock); |
1680 | current->fs = new_fs; | 1683 | current->fs = new_fs; |
1681 | if (--fs->users) | 1684 | if (--fs->users) |
1682 | new_fs = NULL; | 1685 | new_fs = NULL; |
1683 | else | 1686 | else |
1684 | new_fs = fs; | 1687 | new_fs = fs; |
1685 | write_unlock(&fs->lock); | 1688 | spin_unlock(&fs->lock); |
1686 | } | 1689 | } |
1687 | 1690 | ||
1688 | if (new_mm) { | 1691 | if (new_mm) { |
diff --git a/kernel/kfifo.c b/kernel/kfifo.c index 4502604ecad..6b5580c5764 100644 --- a/kernel/kfifo.c +++ b/kernel/kfifo.c | |||
@@ -503,6 +503,15 @@ unsigned int __kfifo_out_r(struct __kfifo *fifo, void *buf, | |||
503 | } | 503 | } |
504 | EXPORT_SYMBOL(__kfifo_out_r); | 504 | EXPORT_SYMBOL(__kfifo_out_r); |
505 | 505 | ||
506 | void __kfifo_skip_r(struct __kfifo *fifo, size_t recsize) | ||
507 | { | ||
508 | unsigned int n; | ||
509 | |||
510 | n = __kfifo_peek_n(fifo, recsize); | ||
511 | fifo->out += n + recsize; | ||
512 | } | ||
513 | EXPORT_SYMBOL(__kfifo_skip_r); | ||
514 | |||
506 | int __kfifo_from_user_r(struct __kfifo *fifo, const void __user *from, | 515 | int __kfifo_from_user_r(struct __kfifo *fifo, const void __user *from, |
507 | unsigned long len, unsigned int *copied, size_t recsize) | 516 | unsigned long len, unsigned int *copied, size_t recsize) |
508 | { | 517 | { |
diff --git a/kernel/kmod.c b/kernel/kmod.c index 6e9b19667a8..9cd0591c96a 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c | |||
@@ -153,7 +153,9 @@ static int ____call_usermodehelper(void *data) | |||
153 | goto fail; | 153 | goto fail; |
154 | } | 154 | } |
155 | 155 | ||
156 | retval = kernel_execve(sub_info->path, sub_info->argv, sub_info->envp); | 156 | retval = kernel_execve(sub_info->path, |
157 | (const char *const *)sub_info->argv, | ||
158 | (const char *const *)sub_info->envp); | ||
157 | 159 | ||
158 | /* Exec failed? */ | 160 | /* Exec failed? */ |
159 | fail: | 161 | fail: |
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c index 996a4dec5f9..b7e4c362361 100644 --- a/kernel/pm_qos_params.c +++ b/kernel/pm_qos_params.c | |||
@@ -212,15 +212,17 @@ EXPORT_SYMBOL_GPL(pm_qos_request_active); | |||
212 | 212 | ||
213 | /** | 213 | /** |
214 | * pm_qos_add_request - inserts new qos request into the list | 214 | * pm_qos_add_request - inserts new qos request into the list |
215 | * @pm_qos_class: identifies which list of qos request to us | 215 | * @dep: pointer to a preallocated handle |
216 | * @pm_qos_class: identifies which list of qos request to use | ||
216 | * @value: defines the qos request | 217 | * @value: defines the qos request |
217 | * | 218 | * |
218 | * This function inserts a new entry in the pm_qos_class list of requested qos | 219 | * This function inserts a new entry in the pm_qos_class list of requested qos |
219 | * performance characteristics. It recomputes the aggregate QoS expectations | 220 | * performance characteristics. It recomputes the aggregate QoS expectations |
220 | * for the pm_qos_class of parameters, and returns the pm_qos_request list | 221 | * for the pm_qos_class of parameters and initializes the pm_qos_request_list |
221 | * element as a handle for use in updating and removal. Call needs to save | 222 | * handle. Caller needs to save this handle for later use in updates and |
222 | * this handle for later use. | 223 | * removal. |
223 | */ | 224 | */ |
225 | |||
224 | void pm_qos_add_request(struct pm_qos_request_list *dep, | 226 | void pm_qos_add_request(struct pm_qos_request_list *dep, |
225 | int pm_qos_class, s32 value) | 227 | int pm_qos_class, s32 value) |
226 | { | 228 | { |
@@ -348,7 +350,7 @@ static int pm_qos_power_open(struct inode *inode, struct file *filp) | |||
348 | 350 | ||
349 | pm_qos_class = find_pm_qos_object_by_minor(iminor(inode)); | 351 | pm_qos_class = find_pm_qos_object_by_minor(iminor(inode)); |
350 | if (pm_qos_class >= 0) { | 352 | if (pm_qos_class >= 0) { |
351 | struct pm_qos_request_list *req = kzalloc(GFP_KERNEL, sizeof(*req)); | 353 | struct pm_qos_request_list *req = kzalloc(sizeof(*req), GFP_KERNEL); |
352 | if (!req) | 354 | if (!req) |
353 | return -ENOMEM; | 355 | return -ENOMEM; |
354 | 356 | ||
diff --git a/kernel/power/poweroff.c b/kernel/power/poweroff.c index e8b33700627..d52359374e8 100644 --- a/kernel/power/poweroff.c +++ b/kernel/power/poweroff.c | |||
@@ -24,7 +24,7 @@ static void do_poweroff(struct work_struct *dummy) | |||
24 | 24 | ||
25 | static DECLARE_WORK(poweroff_work, do_poweroff); | 25 | static DECLARE_WORK(poweroff_work, do_poweroff); |
26 | 26 | ||
27 | static void handle_poweroff(int key, struct tty_struct *tty) | 27 | static void handle_poweroff(int key) |
28 | { | 28 | { |
29 | /* run sysrq poweroff on boot cpu */ | 29 | /* run sysrq poweroff on boot cpu */ |
30 | schedule_work_on(cpumask_first(cpu_online_mask), &poweroff_work); | 30 | schedule_work_on(cpumask_first(cpu_online_mask), &poweroff_work); |
diff --git a/kernel/sched.c b/kernel/sched.c index 41541d79e3c..09b574e7f4d 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -3865,8 +3865,16 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner) | |||
3865 | /* | 3865 | /* |
3866 | * Owner changed, break to re-assess state. | 3866 | * Owner changed, break to re-assess state. |
3867 | */ | 3867 | */ |
3868 | if (lock->owner != owner) | 3868 | if (lock->owner != owner) { |
3869 | /* | ||
3870 | * If the lock has switched to a different owner, | ||
3871 | * we likely have heavy contention. Return 0 to quit | ||
3872 | * optimistic spinning and not contend further: | ||
3873 | */ | ||
3874 | if (lock->owner) | ||
3875 | return 0; | ||
3869 | break; | 3876 | break; |
3877 | } | ||
3870 | 3878 | ||
3871 | /* | 3879 | /* |
3872 | * Is that owner really running on that cpu? | 3880 | * Is that owner really running on that cpu? |
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 806d1b227a2..ab661ebc489 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -3752,6 +3752,8 @@ static void task_fork_fair(struct task_struct *p) | |||
3752 | 3752 | ||
3753 | raw_spin_lock_irqsave(&rq->lock, flags); | 3753 | raw_spin_lock_irqsave(&rq->lock, flags); |
3754 | 3754 | ||
3755 | update_rq_clock(rq); | ||
3756 | |||
3755 | if (unlikely(task_cpu(p) != this_cpu)) | 3757 | if (unlikely(task_cpu(p) != this_cpu)) |
3756 | __set_task_cpu(p, this_cpu); | 3758 | __set_task_cpu(p, this_cpu); |
3757 | 3759 | ||
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 3632ce87674..19cccc3c302 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -3846,6 +3846,9 @@ int ring_buffer_read_page(struct ring_buffer *buffer, | |||
3846 | rpos = reader->read; | 3846 | rpos = reader->read; |
3847 | pos += size; | 3847 | pos += size; |
3848 | 3848 | ||
3849 | if (rpos >= commit) | ||
3850 | break; | ||
3851 | |||
3849 | event = rb_reader_event(cpu_buffer); | 3852 | event = rb_reader_event(cpu_buffer); |
3850 | size = rb_event_length(event); | 3853 | size = rb_event_length(event); |
3851 | } while (len > size); | 3854 | } while (len > size); |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index ba14a22be4c..9ec59f54115 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -3463,6 +3463,7 @@ tracing_mark_write(struct file *filp, const char __user *ubuf, | |||
3463 | size_t cnt, loff_t *fpos) | 3463 | size_t cnt, loff_t *fpos) |
3464 | { | 3464 | { |
3465 | char *buf; | 3465 | char *buf; |
3466 | size_t written; | ||
3466 | 3467 | ||
3467 | if (tracing_disabled) | 3468 | if (tracing_disabled) |
3468 | return -EINVAL; | 3469 | return -EINVAL; |
@@ -3484,11 +3485,15 @@ tracing_mark_write(struct file *filp, const char __user *ubuf, | |||
3484 | } else | 3485 | } else |
3485 | buf[cnt] = '\0'; | 3486 | buf[cnt] = '\0'; |
3486 | 3487 | ||
3487 | cnt = mark_printk("%s", buf); | 3488 | written = mark_printk("%s", buf); |
3488 | kfree(buf); | 3489 | kfree(buf); |
3489 | *fpos += cnt; | 3490 | *fpos += written; |
3490 | 3491 | ||
3491 | return cnt; | 3492 | /* don't tell userspace we wrote more - it might confuse them */ |
3493 | if (written > cnt) | ||
3494 | written = cnt; | ||
3495 | |||
3496 | return written; | ||
3492 | } | 3497 | } |
3493 | 3498 | ||
3494 | static int tracing_clock_show(struct seq_file *m, void *v) | 3499 | static int tracing_clock_show(struct seq_file *m, void *v) |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 09b4fa6e4d3..4c758f14632 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -598,88 +598,165 @@ out: | |||
598 | return ret; | 598 | return ret; |
599 | } | 599 | } |
600 | 600 | ||
601 | static void print_event_fields(struct trace_seq *s, struct list_head *head) | 601 | enum { |
602 | FORMAT_HEADER = 1, | ||
603 | FORMAT_PRINTFMT = 2, | ||
604 | }; | ||
605 | |||
606 | static void *f_next(struct seq_file *m, void *v, loff_t *pos) | ||
602 | { | 607 | { |
608 | struct ftrace_event_call *call = m->private; | ||
603 | struct ftrace_event_field *field; | 609 | struct ftrace_event_field *field; |
610 | struct list_head *head; | ||
604 | 611 | ||
605 | list_for_each_entry_reverse(field, head, link) { | 612 | (*pos)++; |
606 | /* | ||
607 | * Smartly shows the array type(except dynamic array). | ||
608 | * Normal: | ||
609 | * field:TYPE VAR | ||
610 | * If TYPE := TYPE[LEN], it is shown: | ||
611 | * field:TYPE VAR[LEN] | ||
612 | */ | ||
613 | const char *array_descriptor = strchr(field->type, '['); | ||
614 | 613 | ||
615 | if (!strncmp(field->type, "__data_loc", 10)) | 614 | switch ((unsigned long)v) { |
616 | array_descriptor = NULL; | 615 | case FORMAT_HEADER: |
616 | head = &ftrace_common_fields; | ||
617 | 617 | ||
618 | if (!array_descriptor) { | 618 | if (unlikely(list_empty(head))) |
619 | trace_seq_printf(s, "\tfield:%s %s;\toffset:%u;" | 619 | return NULL; |
620 | "\tsize:%u;\tsigned:%d;\n", | 620 | |
621 | field->type, field->name, field->offset, | 621 | field = list_entry(head->prev, struct ftrace_event_field, link); |
622 | field->size, !!field->is_signed); | 622 | return field; |
623 | } else { | 623 | |
624 | trace_seq_printf(s, "\tfield:%.*s %s%s;\toffset:%u;" | 624 | case FORMAT_PRINTFMT: |
625 | "\tsize:%u;\tsigned:%d;\n", | 625 | /* all done */ |
626 | (int)(array_descriptor - field->type), | 626 | return NULL; |
627 | field->type, field->name, | 627 | } |
628 | array_descriptor, field->offset, | 628 | |
629 | field->size, !!field->is_signed); | 629 | head = trace_get_fields(call); |
630 | } | 630 | |
631 | /* | ||
632 | * To separate common fields from event fields, the | ||
633 | * LSB is set on the first event field. Clear it in case. | ||
634 | */ | ||
635 | v = (void *)((unsigned long)v & ~1L); | ||
636 | |||
637 | field = v; | ||
638 | /* | ||
639 | * If this is a common field, and at the end of the list, then | ||
640 | * continue with main list. | ||
641 | */ | ||
642 | if (field->link.prev == &ftrace_common_fields) { | ||
643 | if (unlikely(list_empty(head))) | ||
644 | return NULL; | ||
645 | field = list_entry(head->prev, struct ftrace_event_field, link); | ||
646 | /* Set the LSB to notify f_show to print an extra newline */ | ||
647 | field = (struct ftrace_event_field *) | ||
648 | ((unsigned long)field | 1); | ||
649 | return field; | ||
631 | } | 650 | } |
651 | |||
652 | /* If we are done tell f_show to print the format */ | ||
653 | if (field->link.prev == head) | ||
654 | return (void *)FORMAT_PRINTFMT; | ||
655 | |||
656 | field = list_entry(field->link.prev, struct ftrace_event_field, link); | ||
657 | |||
658 | return field; | ||
632 | } | 659 | } |
633 | 660 | ||
634 | static ssize_t | 661 | static void *f_start(struct seq_file *m, loff_t *pos) |
635 | event_format_read(struct file *filp, char __user *ubuf, size_t cnt, | ||
636 | loff_t *ppos) | ||
637 | { | 662 | { |
638 | struct ftrace_event_call *call = filp->private_data; | 663 | loff_t l = 0; |
639 | struct list_head *head; | 664 | void *p; |
640 | struct trace_seq *s; | ||
641 | char *buf; | ||
642 | int r; | ||
643 | 665 | ||
644 | if (*ppos) | 666 | /* Start by showing the header */ |
667 | if (!*pos) | ||
668 | return (void *)FORMAT_HEADER; | ||
669 | |||
670 | p = (void *)FORMAT_HEADER; | ||
671 | do { | ||
672 | p = f_next(m, p, &l); | ||
673 | } while (p && l < *pos); | ||
674 | |||
675 | return p; | ||
676 | } | ||
677 | |||
678 | static int f_show(struct seq_file *m, void *v) | ||
679 | { | ||
680 | struct ftrace_event_call *call = m->private; | ||
681 | struct ftrace_event_field *field; | ||
682 | const char *array_descriptor; | ||
683 | |||
684 | switch ((unsigned long)v) { | ||
685 | case FORMAT_HEADER: | ||
686 | seq_printf(m, "name: %s\n", call->name); | ||
687 | seq_printf(m, "ID: %d\n", call->event.type); | ||
688 | seq_printf(m, "format:\n"); | ||
645 | return 0; | 689 | return 0; |
646 | 690 | ||
647 | s = kmalloc(sizeof(*s), GFP_KERNEL); | 691 | case FORMAT_PRINTFMT: |
648 | if (!s) | 692 | seq_printf(m, "\nprint fmt: %s\n", |
649 | return -ENOMEM; | 693 | call->print_fmt); |
694 | return 0; | ||
695 | } | ||
650 | 696 | ||
651 | trace_seq_init(s); | 697 | /* |
698 | * To separate common fields from event fields, the | ||
699 | * LSB is set on the first event field. Clear it and | ||
700 | * print a newline if it is set. | ||
701 | */ | ||
702 | if ((unsigned long)v & 1) { | ||
703 | seq_putc(m, '\n'); | ||
704 | v = (void *)((unsigned long)v & ~1L); | ||
705 | } | ||
652 | 706 | ||
653 | trace_seq_printf(s, "name: %s\n", call->name); | 707 | field = v; |
654 | trace_seq_printf(s, "ID: %d\n", call->event.type); | ||
655 | trace_seq_printf(s, "format:\n"); | ||
656 | 708 | ||
657 | /* print common fields */ | 709 | /* |
658 | print_event_fields(s, &ftrace_common_fields); | 710 | * Smartly shows the array type(except dynamic array). |
711 | * Normal: | ||
712 | * field:TYPE VAR | ||
713 | * If TYPE := TYPE[LEN], it is shown: | ||
714 | * field:TYPE VAR[LEN] | ||
715 | */ | ||
716 | array_descriptor = strchr(field->type, '['); | ||
659 | 717 | ||
660 | trace_seq_putc(s, '\n'); | 718 | if (!strncmp(field->type, "__data_loc", 10)) |
719 | array_descriptor = NULL; | ||
661 | 720 | ||
662 | /* print event specific fields */ | 721 | if (!array_descriptor) |
663 | head = trace_get_fields(call); | 722 | seq_printf(m, "\tfield:%s %s;\toffset:%u;\tsize:%u;\tsigned:%d;\n", |
664 | print_event_fields(s, head); | 723 | field->type, field->name, field->offset, |
724 | field->size, !!field->is_signed); | ||
725 | else | ||
726 | seq_printf(m, "\tfield:%.*s %s%s;\toffset:%u;\tsize:%u;\tsigned:%d;\n", | ||
727 | (int)(array_descriptor - field->type), | ||
728 | field->type, field->name, | ||
729 | array_descriptor, field->offset, | ||
730 | field->size, !!field->is_signed); | ||
665 | 731 | ||
666 | r = trace_seq_printf(s, "\nprint fmt: %s\n", call->print_fmt); | 732 | return 0; |
733 | } | ||
667 | 734 | ||
668 | if (!r) { | 735 | static void f_stop(struct seq_file *m, void *p) |
669 | /* | 736 | { |
670 | * ug! The format output is bigger than a PAGE!! | 737 | } |
671 | */ | ||
672 | buf = "FORMAT TOO BIG\n"; | ||
673 | r = simple_read_from_buffer(ubuf, cnt, ppos, | ||
674 | buf, strlen(buf)); | ||
675 | goto out; | ||
676 | } | ||
677 | 738 | ||
678 | r = simple_read_from_buffer(ubuf, cnt, ppos, | 739 | static const struct seq_operations trace_format_seq_ops = { |
679 | s->buffer, s->len); | 740 | .start = f_start, |
680 | out: | 741 | .next = f_next, |
681 | kfree(s); | 742 | .stop = f_stop, |
682 | return r; | 743 | .show = f_show, |
744 | }; | ||
745 | |||
746 | static int trace_format_open(struct inode *inode, struct file *file) | ||
747 | { | ||
748 | struct ftrace_event_call *call = inode->i_private; | ||
749 | struct seq_file *m; | ||
750 | int ret; | ||
751 | |||
752 | ret = seq_open(file, &trace_format_seq_ops); | ||
753 | if (ret < 0) | ||
754 | return ret; | ||
755 | |||
756 | m = file->private_data; | ||
757 | m->private = call; | ||
758 | |||
759 | return 0; | ||
683 | } | 760 | } |
684 | 761 | ||
685 | static ssize_t | 762 | static ssize_t |
@@ -877,8 +954,10 @@ static const struct file_operations ftrace_enable_fops = { | |||
877 | }; | 954 | }; |
878 | 955 | ||
879 | static const struct file_operations ftrace_event_format_fops = { | 956 | static const struct file_operations ftrace_event_format_fops = { |
880 | .open = tracing_open_generic, | 957 | .open = trace_format_open, |
881 | .read = event_format_read, | 958 | .read = seq_read, |
959 | .llseek = seq_lseek, | ||
960 | .release = seq_release, | ||
882 | }; | 961 | }; |
883 | 962 | ||
884 | static const struct file_operations ftrace_event_id_fops = { | 963 | static const struct file_operations ftrace_event_id_fops = { |
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 6bff2362578..6f233698518 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c | |||
@@ -507,7 +507,15 @@ get_return_for_leaf(struct trace_iterator *iter, | |||
507 | * if the output fails. | 507 | * if the output fails. |
508 | */ | 508 | */ |
509 | data->ent = *curr; | 509 | data->ent = *curr; |
510 | data->ret = *next; | 510 | /* |
511 | * If the next event is not a return type, then | ||
512 | * we only care about what type it is. Otherwise we can | ||
513 | * safely copy the entire event. | ||
514 | */ | ||
515 | if (next->ent.type == TRACE_GRAPH_RET) | ||
516 | data->ret = *next; | ||
517 | else | ||
518 | data->ret.ent.type = next->ent.type; | ||
511 | } | 519 | } |
512 | } | 520 | } |
513 | 521 | ||
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c index 056468eae7c..a6b7e0e0f3e 100644 --- a/kernel/trace/trace_stack.c +++ b/kernel/trace/trace_stack.c | |||
@@ -249,7 +249,7 @@ static int trace_lookup_stack(struct seq_file *m, long i) | |||
249 | { | 249 | { |
250 | unsigned long addr = stack_dump_trace[i]; | 250 | unsigned long addr = stack_dump_trace[i]; |
251 | 251 | ||
252 | return seq_printf(m, "%pF\n", (void *)addr); | 252 | return seq_printf(m, "%pS\n", (void *)addr); |
253 | } | 253 | } |
254 | 254 | ||
255 | static void print_disabled(struct seq_file *m) | 255 | static void print_disabled(struct seq_file *m) |
diff --git a/kernel/watchdog.c b/kernel/watchdog.c index 613bc1f0461..0d53c8e853b 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c | |||
@@ -206,6 +206,9 @@ void watchdog_overflow_callback(struct perf_event *event, int nmi, | |||
206 | struct perf_sample_data *data, | 206 | struct perf_sample_data *data, |
207 | struct pt_regs *regs) | 207 | struct pt_regs *regs) |
208 | { | 208 | { |
209 | /* Ensure the watchdog never gets throttled */ | ||
210 | event->hw.interrupts = 0; | ||
211 | |||
209 | if (__get_cpu_var(watchdog_nmi_touch) == true) { | 212 | if (__get_cpu_var(watchdog_nmi_touch) == true) { |
210 | __get_cpu_var(watchdog_nmi_touch) = false; | 213 | __get_cpu_var(watchdog_nmi_touch) = false; |
211 | return; | 214 | return; |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 2994a0e3a61..727f24e563a 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -35,6 +35,9 @@ | |||
35 | #include <linux/lockdep.h> | 35 | #include <linux/lockdep.h> |
36 | #include <linux/idr.h> | 36 | #include <linux/idr.h> |
37 | 37 | ||
38 | #define CREATE_TRACE_POINTS | ||
39 | #include <trace/events/workqueue.h> | ||
40 | |||
38 | #include "workqueue_sched.h" | 41 | #include "workqueue_sched.h" |
39 | 42 | ||
40 | enum { | 43 | enum { |
@@ -87,7 +90,8 @@ enum { | |||
87 | /* | 90 | /* |
88 | * Structure fields follow one of the following exclusion rules. | 91 | * Structure fields follow one of the following exclusion rules. |
89 | * | 92 | * |
90 | * I: Set during initialization and read-only afterwards. | 93 | * I: Modifiable by initialization/destruction paths and read-only for |
94 | * everyone else. | ||
91 | * | 95 | * |
92 | * P: Preemption protected. Disabling preemption is enough and should | 96 | * P: Preemption protected. Disabling preemption is enough and should |
93 | * only be modified and accessed from the local cpu. | 97 | * only be modified and accessed from the local cpu. |
@@ -195,7 +199,7 @@ typedef cpumask_var_t mayday_mask_t; | |||
195 | cpumask_test_and_set_cpu((cpu), (mask)) | 199 | cpumask_test_and_set_cpu((cpu), (mask)) |
196 | #define mayday_clear_cpu(cpu, mask) cpumask_clear_cpu((cpu), (mask)) | 200 | #define mayday_clear_cpu(cpu, mask) cpumask_clear_cpu((cpu), (mask)) |
197 | #define for_each_mayday_cpu(cpu, mask) for_each_cpu((cpu), (mask)) | 201 | #define for_each_mayday_cpu(cpu, mask) for_each_cpu((cpu), (mask)) |
198 | #define alloc_mayday_mask(maskp, gfp) alloc_cpumask_var((maskp), (gfp)) | 202 | #define alloc_mayday_mask(maskp, gfp) zalloc_cpumask_var((maskp), (gfp)) |
199 | #define free_mayday_mask(mask) free_cpumask_var((mask)) | 203 | #define free_mayday_mask(mask) free_cpumask_var((mask)) |
200 | #else | 204 | #else |
201 | typedef unsigned long mayday_mask_t; | 205 | typedef unsigned long mayday_mask_t; |
@@ -940,10 +944,14 @@ static void __queue_work(unsigned int cpu, struct workqueue_struct *wq, | |||
940 | struct global_cwq *gcwq; | 944 | struct global_cwq *gcwq; |
941 | struct cpu_workqueue_struct *cwq; | 945 | struct cpu_workqueue_struct *cwq; |
942 | struct list_head *worklist; | 946 | struct list_head *worklist; |
947 | unsigned int work_flags; | ||
943 | unsigned long flags; | 948 | unsigned long flags; |
944 | 949 | ||
945 | debug_work_activate(work); | 950 | debug_work_activate(work); |
946 | 951 | ||
952 | if (WARN_ON_ONCE(wq->flags & WQ_DYING)) | ||
953 | return; | ||
954 | |||
947 | /* determine gcwq to use */ | 955 | /* determine gcwq to use */ |
948 | if (!(wq->flags & WQ_UNBOUND)) { | 956 | if (!(wq->flags & WQ_UNBOUND)) { |
949 | struct global_cwq *last_gcwq; | 957 | struct global_cwq *last_gcwq; |
@@ -986,14 +994,17 @@ static void __queue_work(unsigned int cpu, struct workqueue_struct *wq, | |||
986 | BUG_ON(!list_empty(&work->entry)); | 994 | BUG_ON(!list_empty(&work->entry)); |
987 | 995 | ||
988 | cwq->nr_in_flight[cwq->work_color]++; | 996 | cwq->nr_in_flight[cwq->work_color]++; |
997 | work_flags = work_color_to_flags(cwq->work_color); | ||
989 | 998 | ||
990 | if (likely(cwq->nr_active < cwq->max_active)) { | 999 | if (likely(cwq->nr_active < cwq->max_active)) { |
991 | cwq->nr_active++; | 1000 | cwq->nr_active++; |
992 | worklist = gcwq_determine_ins_pos(gcwq, cwq); | 1001 | worklist = gcwq_determine_ins_pos(gcwq, cwq); |
993 | } else | 1002 | } else { |
1003 | work_flags |= WORK_STRUCT_DELAYED; | ||
994 | worklist = &cwq->delayed_works; | 1004 | worklist = &cwq->delayed_works; |
1005 | } | ||
995 | 1006 | ||
996 | insert_work(cwq, work, worklist, work_color_to_flags(cwq->work_color)); | 1007 | insert_work(cwq, work, worklist, work_flags); |
997 | 1008 | ||
998 | spin_unlock_irqrestore(&gcwq->lock, flags); | 1009 | spin_unlock_irqrestore(&gcwq->lock, flags); |
999 | } | 1010 | } |
@@ -1212,6 +1223,7 @@ static void worker_leave_idle(struct worker *worker) | |||
1212 | * bound), %false if offline. | 1223 | * bound), %false if offline. |
1213 | */ | 1224 | */ |
1214 | static bool worker_maybe_bind_and_lock(struct worker *worker) | 1225 | static bool worker_maybe_bind_and_lock(struct worker *worker) |
1226 | __acquires(&gcwq->lock) | ||
1215 | { | 1227 | { |
1216 | struct global_cwq *gcwq = worker->gcwq; | 1228 | struct global_cwq *gcwq = worker->gcwq; |
1217 | struct task_struct *task = worker->task; | 1229 | struct task_struct *task = worker->task; |
@@ -1485,6 +1497,8 @@ static void gcwq_mayday_timeout(unsigned long __gcwq) | |||
1485 | * otherwise. | 1497 | * otherwise. |
1486 | */ | 1498 | */ |
1487 | static bool maybe_create_worker(struct global_cwq *gcwq) | 1499 | static bool maybe_create_worker(struct global_cwq *gcwq) |
1500 | __releases(&gcwq->lock) | ||
1501 | __acquires(&gcwq->lock) | ||
1488 | { | 1502 | { |
1489 | if (!need_to_create_worker(gcwq)) | 1503 | if (!need_to_create_worker(gcwq)) |
1490 | return false; | 1504 | return false; |
@@ -1659,6 +1673,7 @@ static void cwq_activate_first_delayed(struct cpu_workqueue_struct *cwq) | |||
1659 | struct list_head *pos = gcwq_determine_ins_pos(cwq->gcwq, cwq); | 1673 | struct list_head *pos = gcwq_determine_ins_pos(cwq->gcwq, cwq); |
1660 | 1674 | ||
1661 | move_linked_works(work, pos, NULL); | 1675 | move_linked_works(work, pos, NULL); |
1676 | __clear_bit(WORK_STRUCT_DELAYED_BIT, work_data_bits(work)); | ||
1662 | cwq->nr_active++; | 1677 | cwq->nr_active++; |
1663 | } | 1678 | } |
1664 | 1679 | ||
@@ -1666,6 +1681,7 @@ static void cwq_activate_first_delayed(struct cpu_workqueue_struct *cwq) | |||
1666 | * cwq_dec_nr_in_flight - decrement cwq's nr_in_flight | 1681 | * cwq_dec_nr_in_flight - decrement cwq's nr_in_flight |
1667 | * @cwq: cwq of interest | 1682 | * @cwq: cwq of interest |
1668 | * @color: color of work which left the queue | 1683 | * @color: color of work which left the queue |
1684 | * @delayed: for a delayed work | ||
1669 | * | 1685 | * |
1670 | * A work either has completed or is removed from pending queue, | 1686 | * A work either has completed or is removed from pending queue, |
1671 | * decrement nr_in_flight of its cwq and handle workqueue flushing. | 1687 | * decrement nr_in_flight of its cwq and handle workqueue flushing. |
@@ -1673,19 +1689,22 @@ static void cwq_activate_first_delayed(struct cpu_workqueue_struct *cwq) | |||
1673 | * CONTEXT: | 1689 | * CONTEXT: |
1674 | * spin_lock_irq(gcwq->lock). | 1690 | * spin_lock_irq(gcwq->lock). |
1675 | */ | 1691 | */ |
1676 | static void cwq_dec_nr_in_flight(struct cpu_workqueue_struct *cwq, int color) | 1692 | static void cwq_dec_nr_in_flight(struct cpu_workqueue_struct *cwq, int color, |
1693 | bool delayed) | ||
1677 | { | 1694 | { |
1678 | /* ignore uncolored works */ | 1695 | /* ignore uncolored works */ |
1679 | if (color == WORK_NO_COLOR) | 1696 | if (color == WORK_NO_COLOR) |
1680 | return; | 1697 | return; |
1681 | 1698 | ||
1682 | cwq->nr_in_flight[color]--; | 1699 | cwq->nr_in_flight[color]--; |
1683 | cwq->nr_active--; | ||
1684 | 1700 | ||
1685 | if (!list_empty(&cwq->delayed_works)) { | 1701 | if (!delayed) { |
1686 | /* one down, submit a delayed one */ | 1702 | cwq->nr_active--; |
1687 | if (cwq->nr_active < cwq->max_active) | 1703 | if (!list_empty(&cwq->delayed_works)) { |
1688 | cwq_activate_first_delayed(cwq); | 1704 | /* one down, submit a delayed one */ |
1705 | if (cwq->nr_active < cwq->max_active) | ||
1706 | cwq_activate_first_delayed(cwq); | ||
1707 | } | ||
1689 | } | 1708 | } |
1690 | 1709 | ||
1691 | /* is flush in progress and are we at the flushing tip? */ | 1710 | /* is flush in progress and are we at the flushing tip? */ |
@@ -1722,6 +1741,8 @@ static void cwq_dec_nr_in_flight(struct cpu_workqueue_struct *cwq, int color) | |||
1722 | * spin_lock_irq(gcwq->lock) which is released and regrabbed. | 1741 | * spin_lock_irq(gcwq->lock) which is released and regrabbed. |
1723 | */ | 1742 | */ |
1724 | static void process_one_work(struct worker *worker, struct work_struct *work) | 1743 | static void process_one_work(struct worker *worker, struct work_struct *work) |
1744 | __releases(&gcwq->lock) | ||
1745 | __acquires(&gcwq->lock) | ||
1725 | { | 1746 | { |
1726 | struct cpu_workqueue_struct *cwq = get_work_cwq(work); | 1747 | struct cpu_workqueue_struct *cwq = get_work_cwq(work); |
1727 | struct global_cwq *gcwq = cwq->gcwq; | 1748 | struct global_cwq *gcwq = cwq->gcwq; |
@@ -1790,7 +1811,13 @@ static void process_one_work(struct worker *worker, struct work_struct *work) | |||
1790 | work_clear_pending(work); | 1811 | work_clear_pending(work); |
1791 | lock_map_acquire(&cwq->wq->lockdep_map); | 1812 | lock_map_acquire(&cwq->wq->lockdep_map); |
1792 | lock_map_acquire(&lockdep_map); | 1813 | lock_map_acquire(&lockdep_map); |
1814 | trace_workqueue_execute_start(work); | ||
1793 | f(work); | 1815 | f(work); |
1816 | /* | ||
1817 | * While we must be careful to not use "work" after this, the trace | ||
1818 | * point will only record its address. | ||
1819 | */ | ||
1820 | trace_workqueue_execute_end(work); | ||
1794 | lock_map_release(&lockdep_map); | 1821 | lock_map_release(&lockdep_map); |
1795 | lock_map_release(&cwq->wq->lockdep_map); | 1822 | lock_map_release(&cwq->wq->lockdep_map); |
1796 | 1823 | ||
@@ -1814,7 +1841,7 @@ static void process_one_work(struct worker *worker, struct work_struct *work) | |||
1814 | hlist_del_init(&worker->hentry); | 1841 | hlist_del_init(&worker->hentry); |
1815 | worker->current_work = NULL; | 1842 | worker->current_work = NULL; |
1816 | worker->current_cwq = NULL; | 1843 | worker->current_cwq = NULL; |
1817 | cwq_dec_nr_in_flight(cwq, work_color); | 1844 | cwq_dec_nr_in_flight(cwq, work_color, false); |
1818 | } | 1845 | } |
1819 | 1846 | ||
1820 | /** | 1847 | /** |
@@ -2379,7 +2406,8 @@ static int try_to_grab_pending(struct work_struct *work) | |||
2379 | debug_work_deactivate(work); | 2406 | debug_work_deactivate(work); |
2380 | list_del_init(&work->entry); | 2407 | list_del_init(&work->entry); |
2381 | cwq_dec_nr_in_flight(get_work_cwq(work), | 2408 | cwq_dec_nr_in_flight(get_work_cwq(work), |
2382 | get_work_color(work)); | 2409 | get_work_color(work), |
2410 | *work_data_bits(work) & WORK_STRUCT_DELAYED); | ||
2383 | ret = 1; | 2411 | ret = 1; |
2384 | } | 2412 | } |
2385 | } | 2413 | } |
@@ -2782,7 +2810,6 @@ struct workqueue_struct *__alloc_workqueue_key(const char *name, | |||
2782 | if (IS_ERR(rescuer->task)) | 2810 | if (IS_ERR(rescuer->task)) |
2783 | goto err; | 2811 | goto err; |
2784 | 2812 | ||
2785 | wq->rescuer = rescuer; | ||
2786 | rescuer->task->flags |= PF_THREAD_BOUND; | 2813 | rescuer->task->flags |= PF_THREAD_BOUND; |
2787 | wake_up_process(rescuer->task); | 2814 | wake_up_process(rescuer->task); |
2788 | } | 2815 | } |
@@ -2824,6 +2851,7 @@ void destroy_workqueue(struct workqueue_struct *wq) | |||
2824 | { | 2851 | { |
2825 | unsigned int cpu; | 2852 | unsigned int cpu; |
2826 | 2853 | ||
2854 | wq->flags |= WQ_DYING; | ||
2827 | flush_workqueue(wq); | 2855 | flush_workqueue(wq); |
2828 | 2856 | ||
2829 | /* | 2857 | /* |
@@ -2848,6 +2876,7 @@ void destroy_workqueue(struct workqueue_struct *wq) | |||
2848 | if (wq->flags & WQ_RESCUER) { | 2876 | if (wq->flags & WQ_RESCUER) { |
2849 | kthread_stop(wq->rescuer->task); | 2877 | kthread_stop(wq->rescuer->task); |
2850 | free_mayday_mask(wq->mayday_mask); | 2878 | free_mayday_mask(wq->mayday_mask); |
2879 | kfree(wq->rescuer); | ||
2851 | } | 2880 | } |
2852 | 2881 | ||
2853 | free_cwqs(wq); | 2882 | free_cwqs(wq); |
@@ -3230,6 +3259,8 @@ static int __cpuinit trustee_thread(void *__gcwq) | |||
3230 | * multiple times. To be used by cpu_callback. | 3259 | * multiple times. To be used by cpu_callback. |
3231 | */ | 3260 | */ |
3232 | static void __cpuinit wait_trustee_state(struct global_cwq *gcwq, int state) | 3261 | static void __cpuinit wait_trustee_state(struct global_cwq *gcwq, int state) |
3262 | __releases(&gcwq->lock) | ||
3263 | __acquires(&gcwq->lock) | ||
3233 | { | 3264 | { |
3234 | if (!(gcwq->trustee_state == state || | 3265 | if (!(gcwq->trustee_state == state || |
3235 | gcwq->trustee_state == TRUSTEE_DONE)) { | 3266 | gcwq->trustee_state == TRUSTEE_DONE)) { |
@@ -3536,8 +3567,7 @@ static int __init init_workqueues(void) | |||
3536 | spin_lock_init(&gcwq->lock); | 3567 | spin_lock_init(&gcwq->lock); |
3537 | INIT_LIST_HEAD(&gcwq->worklist); | 3568 | INIT_LIST_HEAD(&gcwq->worklist); |
3538 | gcwq->cpu = cpu; | 3569 | gcwq->cpu = cpu; |
3539 | if (cpu == WORK_CPU_UNBOUND) | 3570 | gcwq->flags |= GCWQ_DISASSOCIATED; |
3540 | gcwq->flags |= GCWQ_DISASSOCIATED; | ||
3541 | 3571 | ||
3542 | INIT_LIST_HEAD(&gcwq->idle_list); | 3572 | INIT_LIST_HEAD(&gcwq->idle_list); |
3543 | for (i = 0; i < BUSY_WORKER_HASH_SIZE; i++) | 3573 | for (i = 0; i < BUSY_WORKER_HASH_SIZE; i++) |
@@ -3561,6 +3591,8 @@ static int __init init_workqueues(void) | |||
3561 | struct global_cwq *gcwq = get_gcwq(cpu); | 3591 | struct global_cwq *gcwq = get_gcwq(cpu); |
3562 | struct worker *worker; | 3592 | struct worker *worker; |
3563 | 3593 | ||
3594 | if (cpu != WORK_CPU_UNBOUND) | ||
3595 | gcwq->flags &= ~GCWQ_DISASSOCIATED; | ||
3564 | worker = create_worker(gcwq, true); | 3596 | worker = create_worker(gcwq, true); |
3565 | BUG_ON(!worker); | 3597 | BUG_ON(!worker); |
3566 | spin_lock_irq(&gcwq->lock); | 3598 | spin_lock_irq(&gcwq->lock); |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 9e06b7f5ecf..1b4afd2e6ca 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -994,13 +994,16 @@ config FAULT_INJECTION_STACKTRACE_FILTER | |||
994 | 994 | ||
995 | config LATENCYTOP | 995 | config LATENCYTOP |
996 | bool "Latency measuring infrastructure" | 996 | bool "Latency measuring infrastructure" |
997 | depends on HAVE_LATENCYTOP_SUPPORT | ||
998 | depends on DEBUG_KERNEL | ||
999 | depends on STACKTRACE_SUPPORT | ||
1000 | depends on PROC_FS | ||
997 | select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE | 1001 | select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE |
998 | select KALLSYMS | 1002 | select KALLSYMS |
999 | select KALLSYMS_ALL | 1003 | select KALLSYMS_ALL |
1000 | select STACKTRACE | 1004 | select STACKTRACE |
1001 | select SCHEDSTATS | 1005 | select SCHEDSTATS |
1002 | select SCHED_DEBUG | 1006 | select SCHED_DEBUG |
1003 | depends on HAVE_LATENCYTOP_SUPPORT | ||
1004 | help | 1007 | help |
1005 | Enable this option if you want to use the LatencyTOP tool | 1008 | Enable this option if you want to use the LatencyTOP tool |
1006 | to find out which userspace is blocking on what kernel operations. | 1009 | to find out which userspace is blocking on what kernel operations. |
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index b93579504df..70af0a7f97c 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c | |||
@@ -123,7 +123,7 @@ static int kobj_usermode_filter(struct kobject *kobj) | |||
123 | * @kobj: struct kobject that the action is happening to | 123 | * @kobj: struct kobject that the action is happening to |
124 | * @envp_ext: pointer to environmental data | 124 | * @envp_ext: pointer to environmental data |
125 | * | 125 | * |
126 | * Returns 0 if kobject_uevent() is completed with success or the | 126 | * Returns 0 if kobject_uevent_env() is completed with success or the |
127 | * corresponding error when it fails. | 127 | * corresponding error when it fails. |
128 | */ | 128 | */ |
129 | int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, | 129 | int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, |
@@ -317,7 +317,7 @@ exit: | |||
317 | EXPORT_SYMBOL_GPL(kobject_uevent_env); | 317 | EXPORT_SYMBOL_GPL(kobject_uevent_env); |
318 | 318 | ||
319 | /** | 319 | /** |
320 | * kobject_uevent - notify userspace by ending an uevent | 320 | * kobject_uevent - notify userspace by sending an uevent |
321 | * | 321 | * |
322 | * @action: action that is happening | 322 | * @action: action that is happening |
323 | * @kobj: struct kobject that the action is happening to | 323 | * @kobj: struct kobject that the action is happening to |
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index e907858498a..efd16fa80b1 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
@@ -174,14 +174,16 @@ static void radix_tree_node_rcu_free(struct rcu_head *head) | |||
174 | { | 174 | { |
175 | struct radix_tree_node *node = | 175 | struct radix_tree_node *node = |
176 | container_of(head, struct radix_tree_node, rcu_head); | 176 | container_of(head, struct radix_tree_node, rcu_head); |
177 | int i; | ||
177 | 178 | ||
178 | /* | 179 | /* |
179 | * must only free zeroed nodes into the slab. radix_tree_shrink | 180 | * must only free zeroed nodes into the slab. radix_tree_shrink |
180 | * can leave us with a non-NULL entry in the first slot, so clear | 181 | * can leave us with a non-NULL entry in the first slot, so clear |
181 | * that here to make sure. | 182 | * that here to make sure. |
182 | */ | 183 | */ |
183 | tag_clear(node, 0, 0); | 184 | for (i = 0; i < RADIX_TREE_MAX_TAGS; i++) |
184 | tag_clear(node, 1, 0); | 185 | tag_clear(node, i, 0); |
186 | |||
185 | node->slots[0] = NULL; | 187 | node->slots[0] = NULL; |
186 | node->count = 0; | 188 | node->count = 0; |
187 | 189 | ||
@@ -623,17 +625,30 @@ EXPORT_SYMBOL(radix_tree_tag_get); | |||
623 | * also settag. The function stops either after tagging nr_to_tag items or | 625 | * also settag. The function stops either after tagging nr_to_tag items or |
624 | * after reaching last_index. | 626 | * after reaching last_index. |
625 | * | 627 | * |
628 | * The tags must be set from the leaf level only and propagated back up the | ||
629 | * path to the root. We must do this so that we resolve the full path before | ||
630 | * setting any tags on intermediate nodes. If we set tags as we descend, then | ||
631 | * we can get to the leaf node and find that the index that has the iftag | ||
632 | * set is outside the range we are scanning. This reults in dangling tags and | ||
633 | * can lead to problems with later tag operations (e.g. livelocks on lookups). | ||
634 | * | ||
626 | * The function returns number of leaves where the tag was set and sets | 635 | * The function returns number of leaves where the tag was set and sets |
627 | * *first_indexp to the first unscanned index. | 636 | * *first_indexp to the first unscanned index. |
637 | * WARNING! *first_indexp can wrap if last_index is ULONG_MAX. Caller must | ||
638 | * be prepared to handle that. | ||
628 | */ | 639 | */ |
629 | unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root, | 640 | unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root, |
630 | unsigned long *first_indexp, unsigned long last_index, | 641 | unsigned long *first_indexp, unsigned long last_index, |
631 | unsigned long nr_to_tag, | 642 | unsigned long nr_to_tag, |
632 | unsigned int iftag, unsigned int settag) | 643 | unsigned int iftag, unsigned int settag) |
633 | { | 644 | { |
634 | unsigned int height = root->height, shift; | 645 | unsigned int height = root->height; |
635 | unsigned long tagged = 0, index = *first_indexp; | 646 | struct radix_tree_path path[height]; |
636 | struct radix_tree_node *open_slots[height], *slot; | 647 | struct radix_tree_path *pathp = path; |
648 | struct radix_tree_node *slot; | ||
649 | unsigned int shift; | ||
650 | unsigned long tagged = 0; | ||
651 | unsigned long index = *first_indexp; | ||
637 | 652 | ||
638 | last_index = min(last_index, radix_tree_maxindex(height)); | 653 | last_index = min(last_index, radix_tree_maxindex(height)); |
639 | if (index > last_index) | 654 | if (index > last_index) |
@@ -653,6 +668,13 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root, | |||
653 | shift = (height - 1) * RADIX_TREE_MAP_SHIFT; | 668 | shift = (height - 1) * RADIX_TREE_MAP_SHIFT; |
654 | slot = radix_tree_indirect_to_ptr(root->rnode); | 669 | slot = radix_tree_indirect_to_ptr(root->rnode); |
655 | 670 | ||
671 | /* | ||
672 | * we fill the path from (root->height - 2) to 0, leaving the index at | ||
673 | * (root->height - 1) as a terminator. Zero the node in the terminator | ||
674 | * so that we can use this to end walk loops back up the path. | ||
675 | */ | ||
676 | path[height - 1].node = NULL; | ||
677 | |||
656 | for (;;) { | 678 | for (;;) { |
657 | int offset; | 679 | int offset; |
658 | 680 | ||
@@ -661,21 +683,35 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root, | |||
661 | goto next; | 683 | goto next; |
662 | if (!tag_get(slot, iftag, offset)) | 684 | if (!tag_get(slot, iftag, offset)) |
663 | goto next; | 685 | goto next; |
686 | if (height > 1) { | ||
687 | /* Go down one level */ | ||
688 | height--; | ||
689 | shift -= RADIX_TREE_MAP_SHIFT; | ||
690 | path[height - 1].node = slot; | ||
691 | path[height - 1].offset = offset; | ||
692 | slot = slot->slots[offset]; | ||
693 | continue; | ||
694 | } | ||
695 | |||
696 | /* tag the leaf */ | ||
697 | tagged++; | ||
664 | tag_set(slot, settag, offset); | 698 | tag_set(slot, settag, offset); |
665 | if (height == 1) { | 699 | |
666 | tagged++; | 700 | /* walk back up the path tagging interior nodes */ |
667 | goto next; | 701 | pathp = &path[0]; |
702 | while (pathp->node) { | ||
703 | /* stop if we find a node with the tag already set */ | ||
704 | if (tag_get(pathp->node, settag, pathp->offset)) | ||
705 | break; | ||
706 | tag_set(pathp->node, settag, pathp->offset); | ||
707 | pathp++; | ||
668 | } | 708 | } |
669 | /* Go down one level */ | 709 | |
670 | height--; | ||
671 | shift -= RADIX_TREE_MAP_SHIFT; | ||
672 | open_slots[height] = slot; | ||
673 | slot = slot->slots[offset]; | ||
674 | continue; | ||
675 | next: | 710 | next: |
676 | /* Go to next item at level determined by 'shift' */ | 711 | /* Go to next item at level determined by 'shift' */ |
677 | index = ((index >> shift) + 1) << shift; | 712 | index = ((index >> shift) + 1) << shift; |
678 | if (index > last_index) | 713 | /* Overflow can happen when last_index is ~0UL... */ |
714 | if (index > last_index || !index) | ||
679 | break; | 715 | break; |
680 | if (tagged >= nr_to_tag) | 716 | if (tagged >= nr_to_tag) |
681 | break; | 717 | break; |
@@ -685,7 +721,7 @@ next: | |||
685 | * last_index is guaranteed to be in the tree, what | 721 | * last_index is guaranteed to be in the tree, what |
686 | * we do below cannot wander astray. | 722 | * we do below cannot wander astray. |
687 | */ | 723 | */ |
688 | slot = open_slots[height]; | 724 | slot = path[height - 1].node; |
689 | height++; | 725 | height++; |
690 | shift += RADIX_TREE_MAP_SHIFT; | 726 | shift += RADIX_TREE_MAP_SHIFT; |
691 | } | 727 | } |
diff --git a/lib/raid6/.gitignore b/lib/raid6/.gitignore new file mode 100644 index 00000000000..162becacf97 --- /dev/null +++ b/lib/raid6/.gitignore | |||
@@ -0,0 +1,4 @@ | |||
1 | mktables | ||
2 | altivec*.c | ||
3 | int*.c | ||
4 | tables.c | ||
diff --git a/mm/memory.c b/mm/memory.c index b6e5fd23cc5..6b2ab105185 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -2760,21 +2760,35 @@ out_release: | |||
2760 | } | 2760 | } |
2761 | 2761 | ||
2762 | /* | 2762 | /* |
2763 | * This is like a special single-page "expand_downwards()", | 2763 | * This is like a special single-page "expand_{down|up}wards()", |
2764 | * except we must first make sure that 'address-PAGE_SIZE' | 2764 | * except we must first make sure that 'address{-|+}PAGE_SIZE' |
2765 | * doesn't hit another vma. | 2765 | * doesn't hit another vma. |
2766 | * | ||
2767 | * The "find_vma()" will do the right thing even if we wrap | ||
2768 | */ | 2766 | */ |
2769 | static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address) | 2767 | static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address) |
2770 | { | 2768 | { |
2771 | address &= PAGE_MASK; | 2769 | address &= PAGE_MASK; |
2772 | if ((vma->vm_flags & VM_GROWSDOWN) && address == vma->vm_start) { | 2770 | if ((vma->vm_flags & VM_GROWSDOWN) && address == vma->vm_start) { |
2773 | address -= PAGE_SIZE; | 2771 | struct vm_area_struct *prev = vma->vm_prev; |
2774 | if (find_vma(vma->vm_mm, address) != vma) | 2772 | |
2775 | return -ENOMEM; | 2773 | /* |
2774 | * Is there a mapping abutting this one below? | ||
2775 | * | ||
2776 | * That's only ok if it's the same stack mapping | ||
2777 | * that has gotten split.. | ||
2778 | */ | ||
2779 | if (prev && prev->vm_end == address) | ||
2780 | return prev->vm_flags & VM_GROWSDOWN ? 0 : -ENOMEM; | ||
2781 | |||
2782 | expand_stack(vma, address - PAGE_SIZE); | ||
2783 | } | ||
2784 | if ((vma->vm_flags & VM_GROWSUP) && address + PAGE_SIZE == vma->vm_end) { | ||
2785 | struct vm_area_struct *next = vma->vm_next; | ||
2786 | |||
2787 | /* As VM_GROWSDOWN but s/below/above/ */ | ||
2788 | if (next && next->vm_start == address + PAGE_SIZE) | ||
2789 | return next->vm_flags & VM_GROWSUP ? 0 : -ENOMEM; | ||
2776 | 2790 | ||
2777 | expand_stack(vma, address); | 2791 | expand_upwards(vma, address + PAGE_SIZE); |
2778 | } | 2792 | } |
2779 | return 0; | 2793 | return 0; |
2780 | } | 2794 | } |
diff --git a/mm/mlock.c b/mm/mlock.c index 49e5e4cb823..cbae7c5b956 100644 --- a/mm/mlock.c +++ b/mm/mlock.c | |||
@@ -135,6 +135,19 @@ void munlock_vma_page(struct page *page) | |||
135 | } | 135 | } |
136 | } | 136 | } |
137 | 137 | ||
138 | /* Is the vma a continuation of the stack vma above it? */ | ||
139 | static inline int vma_stack_continue(struct vm_area_struct *vma, unsigned long addr) | ||
140 | { | ||
141 | return vma && (vma->vm_end == addr) && (vma->vm_flags & VM_GROWSDOWN); | ||
142 | } | ||
143 | |||
144 | static inline int stack_guard_page(struct vm_area_struct *vma, unsigned long addr) | ||
145 | { | ||
146 | return (vma->vm_flags & VM_GROWSDOWN) && | ||
147 | (vma->vm_start == addr) && | ||
148 | !vma_stack_continue(vma->vm_prev, addr); | ||
149 | } | ||
150 | |||
138 | /** | 151 | /** |
139 | * __mlock_vma_pages_range() - mlock a range of pages in the vma. | 152 | * __mlock_vma_pages_range() - mlock a range of pages in the vma. |
140 | * @vma: target vma | 153 | * @vma: target vma |
@@ -168,11 +181,9 @@ static long __mlock_vma_pages_range(struct vm_area_struct *vma, | |||
168 | gup_flags |= FOLL_WRITE; | 181 | gup_flags |= FOLL_WRITE; |
169 | 182 | ||
170 | /* We don't try to access the guard page of a stack vma */ | 183 | /* We don't try to access the guard page of a stack vma */ |
171 | if (vma->vm_flags & VM_GROWSDOWN) { | 184 | if (stack_guard_page(vma, start)) { |
172 | if (start == vma->vm_start) { | 185 | addr += PAGE_SIZE; |
173 | start += PAGE_SIZE; | 186 | nr_pages--; |
174 | nr_pages--; | ||
175 | } | ||
176 | } | 187 | } |
177 | 188 | ||
178 | while (nr_pages > 0) { | 189 | while (nr_pages > 0) { |
@@ -388,17 +388,23 @@ static inline void | |||
388 | __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma, | 388 | __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma, |
389 | struct vm_area_struct *prev, struct rb_node *rb_parent) | 389 | struct vm_area_struct *prev, struct rb_node *rb_parent) |
390 | { | 390 | { |
391 | struct vm_area_struct *next; | ||
392 | |||
393 | vma->vm_prev = prev; | ||
391 | if (prev) { | 394 | if (prev) { |
392 | vma->vm_next = prev->vm_next; | 395 | next = prev->vm_next; |
393 | prev->vm_next = vma; | 396 | prev->vm_next = vma; |
394 | } else { | 397 | } else { |
395 | mm->mmap = vma; | 398 | mm->mmap = vma; |
396 | if (rb_parent) | 399 | if (rb_parent) |
397 | vma->vm_next = rb_entry(rb_parent, | 400 | next = rb_entry(rb_parent, |
398 | struct vm_area_struct, vm_rb); | 401 | struct vm_area_struct, vm_rb); |
399 | else | 402 | else |
400 | vma->vm_next = NULL; | 403 | next = NULL; |
401 | } | 404 | } |
405 | vma->vm_next = next; | ||
406 | if (next) | ||
407 | next->vm_prev = vma; | ||
402 | } | 408 | } |
403 | 409 | ||
404 | void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma, | 410 | void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma, |
@@ -483,7 +489,11 @@ static inline void | |||
483 | __vma_unlink(struct mm_struct *mm, struct vm_area_struct *vma, | 489 | __vma_unlink(struct mm_struct *mm, struct vm_area_struct *vma, |
484 | struct vm_area_struct *prev) | 490 | struct vm_area_struct *prev) |
485 | { | 491 | { |
486 | prev->vm_next = vma->vm_next; | 492 | struct vm_area_struct *next = vma->vm_next; |
493 | |||
494 | prev->vm_next = next; | ||
495 | if (next) | ||
496 | next->vm_prev = prev; | ||
487 | rb_erase(&vma->vm_rb, &mm->mm_rb); | 497 | rb_erase(&vma->vm_rb, &mm->mm_rb); |
488 | if (mm->mmap_cache == vma) | 498 | if (mm->mmap_cache == vma) |
489 | mm->mmap_cache = prev; | 499 | mm->mmap_cache = prev; |
@@ -1706,9 +1716,6 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns | |||
1706 | * PA-RISC uses this for its stack; IA64 for its Register Backing Store. | 1716 | * PA-RISC uses this for its stack; IA64 for its Register Backing Store. |
1707 | * vma is the last one with address > vma->vm_end. Have to extend vma. | 1717 | * vma is the last one with address > vma->vm_end. Have to extend vma. |
1708 | */ | 1718 | */ |
1709 | #ifndef CONFIG_IA64 | ||
1710 | static | ||
1711 | #endif | ||
1712 | int expand_upwards(struct vm_area_struct *vma, unsigned long address) | 1719 | int expand_upwards(struct vm_area_struct *vma, unsigned long address) |
1713 | { | 1720 | { |
1714 | int error; | 1721 | int error; |
@@ -1915,6 +1922,7 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, | |||
1915 | unsigned long addr; | 1922 | unsigned long addr; |
1916 | 1923 | ||
1917 | insertion_point = (prev ? &prev->vm_next : &mm->mmap); | 1924 | insertion_point = (prev ? &prev->vm_next : &mm->mmap); |
1925 | vma->vm_prev = NULL; | ||
1918 | do { | 1926 | do { |
1919 | rb_erase(&vma->vm_rb, &mm->mm_rb); | 1927 | rb_erase(&vma->vm_rb, &mm->mm_rb); |
1920 | mm->map_count--; | 1928 | mm->map_count--; |
@@ -1922,6 +1930,8 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, | |||
1922 | vma = vma->vm_next; | 1930 | vma = vma->vm_next; |
1923 | } while (vma && vma->vm_start < end); | 1931 | } while (vma && vma->vm_start < end); |
1924 | *insertion_point = vma; | 1932 | *insertion_point = vma; |
1933 | if (vma) | ||
1934 | vma->vm_prev = prev; | ||
1925 | tail_vma->vm_next = NULL; | 1935 | tail_vma->vm_next = NULL; |
1926 | if (mm->unmap_area == arch_unmap_area) | 1936 | if (mm->unmap_area == arch_unmap_area) |
1927 | addr = prev ? prev->vm_end : mm->mmap_base; | 1937 | addr = prev ? prev->vm_end : mm->mmap_base; |
diff --git a/mm/nommu.c b/mm/nommu.c index efa9a380335..88ff091eb07 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
@@ -604,7 +604,7 @@ static void protect_vma(struct vm_area_struct *vma, unsigned long flags) | |||
604 | */ | 604 | */ |
605 | static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma) | 605 | static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma) |
606 | { | 606 | { |
607 | struct vm_area_struct *pvma, **pp; | 607 | struct vm_area_struct *pvma, **pp, *next; |
608 | struct address_space *mapping; | 608 | struct address_space *mapping; |
609 | struct rb_node **p, *parent; | 609 | struct rb_node **p, *parent; |
610 | 610 | ||
@@ -664,8 +664,11 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma) | |||
664 | break; | 664 | break; |
665 | } | 665 | } |
666 | 666 | ||
667 | vma->vm_next = *pp; | 667 | next = *pp; |
668 | *pp = vma; | 668 | *pp = vma; |
669 | vma->vm_next = next; | ||
670 | if (next) | ||
671 | next->vm_prev = vma; | ||
669 | } | 672 | } |
670 | 673 | ||
671 | /* | 674 | /* |
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 5014e50644d..fc81cb22869 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
@@ -372,7 +372,7 @@ static void dump_tasks(const struct mem_cgroup *mem) | |||
372 | } | 372 | } |
373 | 373 | ||
374 | pr_info("[%5d] %5d %5d %8lu %8lu %3u %3d %5d %s\n", | 374 | pr_info("[%5d] %5d %5d %8lu %8lu %3u %3d %5d %s\n", |
375 | task->pid, __task_cred(task)->uid, task->tgid, | 375 | task->pid, task_uid(task), task->tgid, |
376 | task->mm->total_vm, get_mm_rss(task->mm), | 376 | task->mm->total_vm, get_mm_rss(task->mm), |
377 | task_cpu(task), task->signal->oom_adj, | 377 | task_cpu(task), task->signal->oom_adj, |
378 | task->signal->oom_score_adj, task->comm); | 378 | task->signal->oom_score_adj, task->comm); |
@@ -401,10 +401,9 @@ static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order, | |||
401 | static int oom_kill_task(struct task_struct *p, struct mem_cgroup *mem) | 401 | static int oom_kill_task(struct task_struct *p, struct mem_cgroup *mem) |
402 | { | 402 | { |
403 | p = find_lock_task_mm(p); | 403 | p = find_lock_task_mm(p); |
404 | if (!p) { | 404 | if (!p) |
405 | task_unlock(p); | ||
406 | return 1; | 405 | return 1; |
407 | } | 406 | |
408 | pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n", | 407 | pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n", |
409 | task_pid_nr(p), p->comm, K(p->mm->total_vm), | 408 | task_pid_nr(p), p->comm, K(p->mm->total_vm), |
410 | K(get_mm_counter(p->mm, MM_ANONPAGES)), | 409 | K(get_mm_counter(p->mm, MM_ANONPAGES)), |
@@ -647,6 +646,7 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, | |||
647 | unsigned long freed = 0; | 646 | unsigned long freed = 0; |
648 | unsigned int points; | 647 | unsigned int points; |
649 | enum oom_constraint constraint = CONSTRAINT_NONE; | 648 | enum oom_constraint constraint = CONSTRAINT_NONE; |
649 | int killed = 0; | ||
650 | 650 | ||
651 | blocking_notifier_call_chain(&oom_notify_list, 0, &freed); | 651 | blocking_notifier_call_chain(&oom_notify_list, 0, &freed); |
652 | if (freed > 0) | 652 | if (freed > 0) |
@@ -684,7 +684,7 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, | |||
684 | if (!oom_kill_process(current, gfp_mask, order, 0, totalpages, | 684 | if (!oom_kill_process(current, gfp_mask, order, 0, totalpages, |
685 | NULL, nodemask, | 685 | NULL, nodemask, |
686 | "Out of memory (oom_kill_allocating_task)")) | 686 | "Out of memory (oom_kill_allocating_task)")) |
687 | return; | 687 | goto out; |
688 | } | 688 | } |
689 | 689 | ||
690 | retry: | 690 | retry: |
@@ -692,7 +692,7 @@ retry: | |||
692 | constraint == CONSTRAINT_MEMORY_POLICY ? nodemask : | 692 | constraint == CONSTRAINT_MEMORY_POLICY ? nodemask : |
693 | NULL); | 693 | NULL); |
694 | if (PTR_ERR(p) == -1UL) | 694 | if (PTR_ERR(p) == -1UL) |
695 | return; | 695 | goto out; |
696 | 696 | ||
697 | /* Found nothing?!?! Either we hang forever, or we panic. */ | 697 | /* Found nothing?!?! Either we hang forever, or we panic. */ |
698 | if (!p) { | 698 | if (!p) { |
@@ -704,13 +704,15 @@ retry: | |||
704 | if (oom_kill_process(p, gfp_mask, order, points, totalpages, NULL, | 704 | if (oom_kill_process(p, gfp_mask, order, points, totalpages, NULL, |
705 | nodemask, "Out of memory")) | 705 | nodemask, "Out of memory")) |
706 | goto retry; | 706 | goto retry; |
707 | killed = 1; | ||
708 | out: | ||
707 | read_unlock(&tasklist_lock); | 709 | read_unlock(&tasklist_lock); |
708 | 710 | ||
709 | /* | 711 | /* |
710 | * Give "p" a good chance of killing itself before we | 712 | * Give "p" a good chance of killing itself before we |
711 | * retry to allocate memory unless "p" is current | 713 | * retry to allocate memory unless "p" is current |
712 | */ | 714 | */ |
713 | if (!test_thread_flag(TIF_MEMDIE)) | 715 | if (killed && !test_thread_flag(TIF_MEMDIE)) |
714 | schedule_timeout_uninterruptible(1); | 716 | schedule_timeout_uninterruptible(1); |
715 | } | 717 | } |
716 | 718 | ||
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 7262aacea8a..e3bccac1f02 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -836,7 +836,8 @@ void tag_pages_for_writeback(struct address_space *mapping, | |||
836 | spin_unlock_irq(&mapping->tree_lock); | 836 | spin_unlock_irq(&mapping->tree_lock); |
837 | WARN_ON_ONCE(tagged > WRITEBACK_TAG_BATCH); | 837 | WARN_ON_ONCE(tagged > WRITEBACK_TAG_BATCH); |
838 | cond_resched(); | 838 | cond_resched(); |
839 | } while (tagged >= WRITEBACK_TAG_BATCH); | 839 | /* We check 'start' to handle wrapping when end == ~0UL */ |
840 | } while (tagged >= WRITEBACK_TAG_BATCH && start); | ||
840 | } | 841 | } |
841 | EXPORT_SYMBOL(tag_pages_for_writeback); | 842 | EXPORT_SYMBOL(tag_pages_for_writeback); |
842 | 843 | ||
@@ -984,22 +985,16 @@ continue_unlock: | |||
984 | } | 985 | } |
985 | } | 986 | } |
986 | 987 | ||
987 | if (wbc->nr_to_write > 0) { | 988 | /* |
988 | if (--wbc->nr_to_write == 0 && | 989 | * We stop writing back only if we are not doing |
989 | wbc->sync_mode == WB_SYNC_NONE) { | 990 | * integrity sync. In case of integrity sync we have to |
990 | /* | 991 | * keep going until we have written all the pages |
991 | * We stop writing back only if we are | 992 | * we tagged for writeback prior to entering this loop. |
992 | * not doing integrity sync. In case of | 993 | */ |
993 | * integrity sync we have to keep going | 994 | if (--wbc->nr_to_write <= 0 && |
994 | * because someone may be concurrently | 995 | wbc->sync_mode == WB_SYNC_NONE) { |
995 | * dirtying pages, and we might have | 996 | done = 1; |
996 | * synced a lot of newly appeared dirty | 997 | break; |
997 | * pages, but have not synced all of the | ||
998 | * old dirty pages. | ||
999 | */ | ||
1000 | done = 1; | ||
1001 | break; | ||
1002 | } | ||
1003 | } | 998 | } |
1004 | } | 999 | } |
1005 | pagevec_release(&pvec); | 1000 | pagevec_release(&pvec); |
@@ -1131,6 +1126,7 @@ void account_page_dirtied(struct page *page, struct address_space *mapping) | |||
1131 | task_io_account_write(PAGE_CACHE_SIZE); | 1126 | task_io_account_write(PAGE_CACHE_SIZE); |
1132 | } | 1127 | } |
1133 | } | 1128 | } |
1129 | EXPORT_SYMBOL(account_page_dirtied); | ||
1134 | 1130 | ||
1135 | /* | 1131 | /* |
1136 | * For address_spaces which do not use buffers. Just tag the page as dirty in | 1132 | * For address_spaces which do not use buffers. Just tag the page as dirty in |
diff --git a/mm/percpu.c b/mm/percpu.c index e61dc2cc587..58c572b18b0 100644 --- a/mm/percpu.c +++ b/mm/percpu.c | |||
@@ -393,7 +393,9 @@ static int pcpu_extend_area_map(struct pcpu_chunk *chunk, int new_alloc) | |||
393 | goto out_unlock; | 393 | goto out_unlock; |
394 | 394 | ||
395 | old_size = chunk->map_alloc * sizeof(chunk->map[0]); | 395 | old_size = chunk->map_alloc * sizeof(chunk->map[0]); |
396 | memcpy(new, chunk->map, old_size); | 396 | old = chunk->map; |
397 | |||
398 | memcpy(new, old, old_size); | ||
397 | 399 | ||
398 | chunk->map_alloc = new_alloc; | 400 | chunk->map_alloc = new_alloc; |
399 | chunk->map = new; | 401 | chunk->map = new; |
@@ -1162,7 +1164,7 @@ static struct pcpu_alloc_info * __init pcpu_build_alloc_info( | |||
1162 | } | 1164 | } |
1163 | 1165 | ||
1164 | /* | 1166 | /* |
1165 | * Don't accept if wastage is over 25%. The | 1167 | * Don't accept if wastage is over 1/3. The |
1166 | * greater-than comparison ensures upa==1 always | 1168 | * greater-than comparison ensures upa==1 always |
1167 | * passes the following check. | 1169 | * passes the following check. |
1168 | */ | 1170 | */ |
diff --git a/mm/percpu_up.c b/mm/percpu_up.c index c4351c7f57d..db884fae572 100644 --- a/mm/percpu_up.c +++ b/mm/percpu_up.c | |||
@@ -14,13 +14,13 @@ void __percpu *__alloc_percpu(size_t size, size_t align) | |||
14 | * percpu sections on SMP for which this path isn't used. | 14 | * percpu sections on SMP for which this path isn't used. |
15 | */ | 15 | */ |
16 | WARN_ON_ONCE(align > SMP_CACHE_BYTES); | 16 | WARN_ON_ONCE(align > SMP_CACHE_BYTES); |
17 | return kzalloc(size, GFP_KERNEL); | 17 | return (void __percpu __force *)kzalloc(size, GFP_KERNEL); |
18 | } | 18 | } |
19 | EXPORT_SYMBOL_GPL(__alloc_percpu); | 19 | EXPORT_SYMBOL_GPL(__alloc_percpu); |
20 | 20 | ||
21 | void free_percpu(void __percpu *p) | 21 | void free_percpu(void __percpu *p) |
22 | { | 22 | { |
23 | kfree(p); | 23 | kfree(this_cpu_ptr(p)); |
24 | } | 24 | } |
25 | EXPORT_SYMBOL_GPL(free_percpu); | 25 | EXPORT_SYMBOL_GPL(free_percpu); |
26 | 26 | ||
@@ -316,7 +316,7 @@ void __init anon_vma_init(void) | |||
316 | */ | 316 | */ |
317 | struct anon_vma *page_lock_anon_vma(struct page *page) | 317 | struct anon_vma *page_lock_anon_vma(struct page *page) |
318 | { | 318 | { |
319 | struct anon_vma *anon_vma; | 319 | struct anon_vma *anon_vma, *root_anon_vma; |
320 | unsigned long anon_mapping; | 320 | unsigned long anon_mapping; |
321 | 321 | ||
322 | rcu_read_lock(); | 322 | rcu_read_lock(); |
@@ -327,8 +327,21 @@ struct anon_vma *page_lock_anon_vma(struct page *page) | |||
327 | goto out; | 327 | goto out; |
328 | 328 | ||
329 | anon_vma = (struct anon_vma *) (anon_mapping - PAGE_MAPPING_ANON); | 329 | anon_vma = (struct anon_vma *) (anon_mapping - PAGE_MAPPING_ANON); |
330 | anon_vma_lock(anon_vma); | 330 | root_anon_vma = ACCESS_ONCE(anon_vma->root); |
331 | return anon_vma; | 331 | spin_lock(&root_anon_vma->lock); |
332 | |||
333 | /* | ||
334 | * If this page is still mapped, then its anon_vma cannot have been | ||
335 | * freed. But if it has been unmapped, we have no security against | ||
336 | * the anon_vma structure being freed and reused (for another anon_vma: | ||
337 | * SLAB_DESTROY_BY_RCU guarantees that - so the spin_lock above cannot | ||
338 | * corrupt): with anon_vma_prepare() or anon_vma_fork() redirecting | ||
339 | * anon_vma->root before page_unlock_anon_vma() is called to unlock. | ||
340 | */ | ||
341 | if (page_mapped(page)) | ||
342 | return anon_vma; | ||
343 | |||
344 | spin_unlock(&root_anon_vma->lock); | ||
332 | out: | 345 | out: |
333 | rcu_read_unlock(); | 346 | rcu_read_unlock(); |
334 | return NULL; | 347 | return NULL; |
diff --git a/mm/shmem.c b/mm/shmem.c index dfaa0f4e978..080b09a57a8 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -2325,7 +2325,10 @@ static int shmem_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
2325 | 2325 | ||
2326 | static void shmem_put_super(struct super_block *sb) | 2326 | static void shmem_put_super(struct super_block *sb) |
2327 | { | 2327 | { |
2328 | kfree(sb->s_fs_info); | 2328 | struct shmem_sb_info *sbinfo = SHMEM_SB(sb); |
2329 | |||
2330 | percpu_counter_destroy(&sbinfo->used_blocks); | ||
2331 | kfree(sbinfo); | ||
2329 | sb->s_fs_info = NULL; | 2332 | sb->s_fs_info = NULL; |
2330 | } | 2333 | } |
2331 | 2334 | ||
@@ -2367,7 +2370,8 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) | |||
2367 | #endif | 2370 | #endif |
2368 | 2371 | ||
2369 | spin_lock_init(&sbinfo->stat_lock); | 2372 | spin_lock_init(&sbinfo->stat_lock); |
2370 | percpu_counter_init(&sbinfo->used_blocks, 0); | 2373 | if (percpu_counter_init(&sbinfo->used_blocks, 0)) |
2374 | goto failed; | ||
2371 | sbinfo->free_inodes = sbinfo->max_inodes; | 2375 | sbinfo->free_inodes = sbinfo->max_inodes; |
2372 | 2376 | ||
2373 | sb->s_maxbytes = SHMEM_MAX_BYTES; | 2377 | sb->s_maxbytes = SHMEM_MAX_BYTES; |
@@ -2330,8 +2330,8 @@ kmem_cache_create (const char *name, size_t size, size_t align, | |||
2330 | } | 2330 | } |
2331 | #if FORCED_DEBUG && defined(CONFIG_DEBUG_PAGEALLOC) | 2331 | #if FORCED_DEBUG && defined(CONFIG_DEBUG_PAGEALLOC) |
2332 | if (size >= malloc_sizes[INDEX_L3 + 1].cs_size | 2332 | if (size >= malloc_sizes[INDEX_L3 + 1].cs_size |
2333 | && cachep->obj_size > cache_line_size() && size < PAGE_SIZE) { | 2333 | && cachep->obj_size > cache_line_size() && ALIGN(size, align) < PAGE_SIZE) { |
2334 | cachep->obj_offset += PAGE_SIZE - size; | 2334 | cachep->obj_offset += PAGE_SIZE - ALIGN(size, align); |
2335 | size = PAGE_SIZE; | 2335 | size = PAGE_SIZE; |
2336 | } | 2336 | } |
2337 | #endif | 2337 | #endif |
diff --git a/net/ax25/ax25_ds_timer.c b/net/ax25/ax25_ds_timer.c index 2ce79df0068..c7d81436213 100644 --- a/net/ax25/ax25_ds_timer.c +++ b/net/ax25/ax25_ds_timer.c | |||
@@ -112,8 +112,8 @@ void ax25_ds_heartbeat_expiry(ax25_cb *ax25) | |||
112 | if (sk) { | 112 | if (sk) { |
113 | sock_hold(sk); | 113 | sock_hold(sk); |
114 | ax25_destroy_socket(ax25); | 114 | ax25_destroy_socket(ax25); |
115 | sock_put(sk); | ||
116 | bh_unlock_sock(sk); | 115 | bh_unlock_sock(sk); |
116 | sock_put(sk); | ||
117 | } else | 117 | } else |
118 | ax25_destroy_socket(ax25); | 118 | ax25_destroy_socket(ax25); |
119 | return; | 119 | return; |
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 2c911c0759c..137f23259a9 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
@@ -162,8 +162,8 @@ static inline struct nf_bridge_info *nf_bridge_unshare(struct sk_buff *skb) | |||
162 | if (tmp) { | 162 | if (tmp) { |
163 | memcpy(tmp, nf_bridge, sizeof(struct nf_bridge_info)); | 163 | memcpy(tmp, nf_bridge, sizeof(struct nf_bridge_info)); |
164 | atomic_set(&tmp->use, 1); | 164 | atomic_set(&tmp->use, 1); |
165 | nf_bridge_put(nf_bridge); | ||
166 | } | 165 | } |
166 | nf_bridge_put(nf_bridge); | ||
167 | nf_bridge = tmp; | 167 | nf_bridge = tmp; |
168 | } | 168 | } |
169 | return nf_bridge; | 169 | return nf_bridge; |
@@ -761,9 +761,11 @@ static int br_nf_dev_queue_xmit(struct sk_buff *skb) | |||
761 | { | 761 | { |
762 | if (skb->nfct != NULL && skb->protocol == htons(ETH_P_IP) && | 762 | if (skb->nfct != NULL && skb->protocol == htons(ETH_P_IP) && |
763 | skb->len + nf_bridge_mtu_reduction(skb) > skb->dev->mtu && | 763 | skb->len + nf_bridge_mtu_reduction(skb) > skb->dev->mtu && |
764 | !skb_is_gso(skb)) | 764 | !skb_is_gso(skb)) { |
765 | /* BUG: Should really parse the IP options here. */ | ||
766 | memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); | ||
765 | return ip_fragment(skb, br_dev_queue_push_xmit); | 767 | return ip_fragment(skb, br_dev_queue_push_xmit); |
766 | else | 768 | } else |
767 | return br_dev_queue_push_xmit(skb); | 769 | return br_dev_queue_push_xmit(skb); |
768 | } | 770 | } |
769 | #else | 771 | #else |
diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c index 6acaeba2060..bde8481e8d2 100644 --- a/net/caif/cfrfml.c +++ b/net/caif/cfrfml.c | |||
@@ -9,7 +9,7 @@ | |||
9 | #include <linux/stddef.h> | 9 | #include <linux/stddef.h> |
10 | #include <linux/spinlock.h> | 10 | #include <linux/spinlock.h> |
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/unaligned/le_byteshift.h> | 12 | #include <asm/unaligned.h> |
13 | #include <net/caif/caif_layer.h> | 13 | #include <net/caif/caif_layer.h> |
14 | #include <net/caif/cfsrvl.h> | 14 | #include <net/caif/cfsrvl.h> |
15 | #include <net/caif/cfpkt.h> | 15 | #include <net/caif/cfpkt.h> |
diff --git a/net/core/dev.c b/net/core/dev.c index cdbbea39c54..fc2dc933bee 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2056,16 +2056,16 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev, | |||
2056 | struct sk_buff *skb) | 2056 | struct sk_buff *skb) |
2057 | { | 2057 | { |
2058 | int queue_index; | 2058 | int queue_index; |
2059 | struct sock *sk = skb->sk; | 2059 | const struct net_device_ops *ops = dev->netdev_ops; |
2060 | 2060 | ||
2061 | queue_index = sk_tx_queue_get(sk); | 2061 | if (ops->ndo_select_queue) { |
2062 | if (queue_index < 0) { | 2062 | queue_index = ops->ndo_select_queue(dev, skb); |
2063 | const struct net_device_ops *ops = dev->netdev_ops; | 2063 | queue_index = dev_cap_txqueue(dev, queue_index); |
2064 | } else { | ||
2065 | struct sock *sk = skb->sk; | ||
2066 | queue_index = sk_tx_queue_get(sk); | ||
2067 | if (queue_index < 0) { | ||
2064 | 2068 | ||
2065 | if (ops->ndo_select_queue) { | ||
2066 | queue_index = ops->ndo_select_queue(dev, skb); | ||
2067 | queue_index = dev_cap_txqueue(dev, queue_index); | ||
2068 | } else { | ||
2069 | queue_index = 0; | 2069 | queue_index = 0; |
2070 | if (dev->real_num_tx_queues > 1) | 2070 | if (dev->real_num_tx_queues > 1) |
2071 | queue_index = skb_tx_hash(dev, skb); | 2071 | queue_index = skb_tx_hash(dev, skb); |
diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c index 9fbe7f7429b..6743146e4d6 100644 --- a/net/core/gen_estimator.c +++ b/net/core/gen_estimator.c | |||
@@ -232,7 +232,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats, | |||
232 | est->last_packets = bstats->packets; | 232 | est->last_packets = bstats->packets; |
233 | est->avpps = rate_est->pps<<10; | 233 | est->avpps = rate_est->pps<<10; |
234 | 234 | ||
235 | spin_lock(&est_tree_lock); | 235 | spin_lock_bh(&est_tree_lock); |
236 | if (!elist[idx].timer.function) { | 236 | if (!elist[idx].timer.function) { |
237 | INIT_LIST_HEAD(&elist[idx].list); | 237 | INIT_LIST_HEAD(&elist[idx].list); |
238 | setup_timer(&elist[idx].timer, est_timer, idx); | 238 | setup_timer(&elist[idx].timer, est_timer, idx); |
@@ -243,7 +243,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats, | |||
243 | 243 | ||
244 | list_add_rcu(&est->list, &elist[idx].list); | 244 | list_add_rcu(&est->list, &elist[idx].list); |
245 | gen_add_node(est); | 245 | gen_add_node(est); |
246 | spin_unlock(&est_tree_lock); | 246 | spin_unlock_bh(&est_tree_lock); |
247 | 247 | ||
248 | return 0; | 248 | return 0; |
249 | } | 249 | } |
@@ -270,7 +270,7 @@ void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, | |||
270 | { | 270 | { |
271 | struct gen_estimator *e; | 271 | struct gen_estimator *e; |
272 | 272 | ||
273 | spin_lock(&est_tree_lock); | 273 | spin_lock_bh(&est_tree_lock); |
274 | while ((e = gen_find_node(bstats, rate_est))) { | 274 | while ((e = gen_find_node(bstats, rate_est))) { |
275 | rb_erase(&e->node, &est_root); | 275 | rb_erase(&e->node, &est_root); |
276 | 276 | ||
@@ -281,7 +281,7 @@ void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, | |||
281 | list_del_rcu(&e->list); | 281 | list_del_rcu(&e->list); |
282 | call_rcu(&e->e_rcu, __gen_kill_estimator); | 282 | call_rcu(&e->e_rcu, __gen_kill_estimator); |
283 | } | 283 | } |
284 | spin_unlock(&est_tree_lock); | 284 | spin_unlock_bh(&est_tree_lock); |
285 | } | 285 | } |
286 | EXPORT_SYMBOL(gen_kill_estimator); | 286 | EXPORT_SYMBOL(gen_kill_estimator); |
287 | 287 | ||
@@ -320,9 +320,9 @@ bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats, | |||
320 | 320 | ||
321 | ASSERT_RTNL(); | 321 | ASSERT_RTNL(); |
322 | 322 | ||
323 | spin_lock(&est_tree_lock); | 323 | spin_lock_bh(&est_tree_lock); |
324 | res = gen_find_node(bstats, rate_est) != NULL; | 324 | res = gen_find_node(bstats, rate_est) != NULL; |
325 | spin_unlock(&est_tree_lock); | 325 | spin_unlock_bh(&est_tree_lock); |
326 | 326 | ||
327 | return res; | 327 | return res; |
328 | } | 328 | } |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 2d1bc761fe4..752c1972b3a 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -2569,6 +2569,10 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features) | |||
2569 | __copy_skb_header(nskb, skb); | 2569 | __copy_skb_header(nskb, skb); |
2570 | nskb->mac_len = skb->mac_len; | 2570 | nskb->mac_len = skb->mac_len; |
2571 | 2571 | ||
2572 | /* nskb and skb might have different headroom */ | ||
2573 | if (nskb->ip_summed == CHECKSUM_PARTIAL) | ||
2574 | nskb->csum_start += skb_headroom(nskb) - headroom; | ||
2575 | |||
2572 | skb_reset_mac_header(nskb); | 2576 | skb_reset_mac_header(nskb); |
2573 | skb_set_network_header(nskb, skb->mac_len); | 2577 | skb_set_network_header(nskb, skb->mac_len); |
2574 | nskb->transport_header = (nskb->network_header + | 2578 | nskb->transport_header = (nskb->network_header + |
@@ -2699,7 +2703,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
2699 | return -E2BIG; | 2703 | return -E2BIG; |
2700 | 2704 | ||
2701 | headroom = skb_headroom(p); | 2705 | headroom = skb_headroom(p); |
2702 | nskb = netdev_alloc_skb(p->dev, headroom + skb_gro_offset(p)); | 2706 | nskb = alloc_skb(headroom + skb_gro_offset(p), GFP_ATOMIC); |
2703 | if (unlikely(!nskb)) | 2707 | if (unlikely(!nskb)) |
2704 | return -ENOMEM; | 2708 | return -ENOMEM; |
2705 | 2709 | ||
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 7458bdae7e9..5462e2d147a 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig | |||
@@ -46,7 +46,7 @@ config IP_ADVANCED_ROUTER | |||
46 | rp_filter on use: | 46 | rp_filter on use: |
47 | 47 | ||
48 | echo 1 > /proc/sys/net/ipv4/conf/<device>/rp_filter | 48 | echo 1 > /proc/sys/net/ipv4/conf/<device>/rp_filter |
49 | and | 49 | or |
50 | echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter | 50 | echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter |
51 | 51 | ||
52 | Note that some distributions enable it in startup scripts. | 52 | Note that some distributions enable it in startup scripts. |
diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c index f0550941df7..721a8a37b45 100644 --- a/net/ipv4/datagram.c +++ b/net/ipv4/datagram.c | |||
@@ -62,8 +62,11 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
62 | } | 62 | } |
63 | if (!inet->inet_saddr) | 63 | if (!inet->inet_saddr) |
64 | inet->inet_saddr = rt->rt_src; /* Update source address */ | 64 | inet->inet_saddr = rt->rt_src; /* Update source address */ |
65 | if (!inet->inet_rcv_saddr) | 65 | if (!inet->inet_rcv_saddr) { |
66 | inet->inet_rcv_saddr = rt->rt_src; | 66 | inet->inet_rcv_saddr = rt->rt_src; |
67 | if (sk->sk_prot->rehash) | ||
68 | sk->sk_prot->rehash(sk); | ||
69 | } | ||
67 | inet->inet_daddr = rt->rt_dst; | 70 | inet->inet_daddr = rt->rt_dst; |
68 | inet->inet_dport = usin->sin_port; | 71 | inet->inet_dport = usin->sin_port; |
69 | sk->sk_state = TCP_ESTABLISHED; | 72 | sk->sk_state = TCP_ESTABLISHED; |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index a4396891835..7d02a9f999f 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -246,6 +246,7 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, | |||
246 | 246 | ||
247 | struct fib_result res; | 247 | struct fib_result res; |
248 | int no_addr, rpf, accept_local; | 248 | int no_addr, rpf, accept_local; |
249 | bool dev_match; | ||
249 | int ret; | 250 | int ret; |
250 | struct net *net; | 251 | struct net *net; |
251 | 252 | ||
@@ -273,12 +274,22 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, | |||
273 | } | 274 | } |
274 | *spec_dst = FIB_RES_PREFSRC(res); | 275 | *spec_dst = FIB_RES_PREFSRC(res); |
275 | fib_combine_itag(itag, &res); | 276 | fib_combine_itag(itag, &res); |
277 | dev_match = false; | ||
278 | |||
276 | #ifdef CONFIG_IP_ROUTE_MULTIPATH | 279 | #ifdef CONFIG_IP_ROUTE_MULTIPATH |
277 | if (FIB_RES_DEV(res) == dev || res.fi->fib_nhs > 1) | 280 | for (ret = 0; ret < res.fi->fib_nhs; ret++) { |
281 | struct fib_nh *nh = &res.fi->fib_nh[ret]; | ||
282 | |||
283 | if (nh->nh_dev == dev) { | ||
284 | dev_match = true; | ||
285 | break; | ||
286 | } | ||
287 | } | ||
278 | #else | 288 | #else |
279 | if (FIB_RES_DEV(res) == dev) | 289 | if (FIB_RES_DEV(res) == dev) |
290 | dev_match = true; | ||
280 | #endif | 291 | #endif |
281 | { | 292 | if (dev_match) { |
282 | ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST; | 293 | ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST; |
283 | fib_res_put(&res); | 294 | fib_res_put(&res); |
284 | return ret; | 295 | return ret; |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 79d057a939b..4a8e370862b 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -186,7 +186,9 @@ static inline struct tnode *node_parent_rcu(struct node *node) | |||
186 | { | 186 | { |
187 | struct tnode *ret = node_parent(node); | 187 | struct tnode *ret = node_parent(node); |
188 | 188 | ||
189 | return rcu_dereference(ret); | 189 | return rcu_dereference_check(ret, |
190 | rcu_read_lock_held() || | ||
191 | lockdep_rtnl_is_held()); | ||
190 | } | 192 | } |
191 | 193 | ||
192 | /* Same as rcu_assign_pointer | 194 | /* Same as rcu_assign_pointer |
@@ -1753,7 +1755,9 @@ static struct leaf *leaf_walk_rcu(struct tnode *p, struct node *c) | |||
1753 | 1755 | ||
1754 | static struct leaf *trie_firstleaf(struct trie *t) | 1756 | static struct leaf *trie_firstleaf(struct trie *t) |
1755 | { | 1757 | { |
1756 | struct tnode *n = (struct tnode *) rcu_dereference(t->trie); | 1758 | struct tnode *n = (struct tnode *) rcu_dereference_check(t->trie, |
1759 | rcu_read_lock_held() || | ||
1760 | lockdep_rtnl_is_held()); | ||
1757 | 1761 | ||
1758 | if (!n) | 1762 | if (!n) |
1759 | return NULL; | 1763 | return NULL; |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 51d6c316797..e8f4f9a57f1 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -1420,6 +1420,9 @@ static int translate_compat_table(const char *name, | |||
1420 | if (ret != 0) | 1420 | if (ret != 0) |
1421 | break; | 1421 | break; |
1422 | ++i; | 1422 | ++i; |
1423 | if (strcmp(arpt_get_target(iter1)->u.user.name, | ||
1424 | XT_ERROR_TARGET) == 0) | ||
1425 | ++newinfo->stacksize; | ||
1423 | } | 1426 | } |
1424 | if (ret) { | 1427 | if (ret) { |
1425 | /* | 1428 | /* |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 97b64b22c41..d163f2e3b2e 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -1751,6 +1751,9 @@ translate_compat_table(struct net *net, | |||
1751 | if (ret != 0) | 1751 | if (ret != 0) |
1752 | break; | 1752 | break; |
1753 | ++i; | 1753 | ++i; |
1754 | if (strcmp(ipt_get_target(iter1)->u.user.name, | ||
1755 | XT_ERROR_TARGET) == 0) | ||
1756 | ++newinfo->stacksize; | ||
1754 | } | 1757 | } |
1755 | if (ret) { | 1758 | if (ret) { |
1756 | /* | 1759 | /* |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 85a67c9d598..e24d48dd99d 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -2731,6 +2731,11 @@ slow_output: | |||
2731 | } | 2731 | } |
2732 | EXPORT_SYMBOL_GPL(__ip_route_output_key); | 2732 | EXPORT_SYMBOL_GPL(__ip_route_output_key); |
2733 | 2733 | ||
2734 | static struct dst_entry *ipv4_blackhole_dst_check(struct dst_entry *dst, u32 cookie) | ||
2735 | { | ||
2736 | return NULL; | ||
2737 | } | ||
2738 | |||
2734 | static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) | 2739 | static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) |
2735 | { | 2740 | { |
2736 | } | 2741 | } |
@@ -2739,7 +2744,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = { | |||
2739 | .family = AF_INET, | 2744 | .family = AF_INET, |
2740 | .protocol = cpu_to_be16(ETH_P_IP), | 2745 | .protocol = cpu_to_be16(ETH_P_IP), |
2741 | .destroy = ipv4_dst_destroy, | 2746 | .destroy = ipv4_dst_destroy, |
2742 | .check = ipv4_dst_check, | 2747 | .check = ipv4_blackhole_dst_check, |
2743 | .update_pmtu = ipv4_rt_blackhole_update_pmtu, | 2748 | .update_pmtu = ipv4_rt_blackhole_update_pmtu, |
2744 | .entries = ATOMIC_INIT(0), | 2749 | .entries = ATOMIC_INIT(0), |
2745 | }; | 2750 | }; |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index cf325452875..3e8a4dbc721 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -451,7 +451,8 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
451 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) | 451 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) |
452 | mask |= POLLOUT | POLLWRNORM; | 452 | mask |= POLLOUT | POLLWRNORM; |
453 | } | 453 | } |
454 | } | 454 | } else |
455 | mask |= POLLOUT | POLLWRNORM; | ||
455 | 456 | ||
456 | if (tp->urg_data & TCP_URG_VALID) | 457 | if (tp->urg_data & TCP_URG_VALID) |
457 | mask |= POLLPRI; | 458 | mask |= POLLPRI; |
@@ -2011,11 +2012,8 @@ adjudge_to_death: | |||
2011 | } | 2012 | } |
2012 | } | 2013 | } |
2013 | if (sk->sk_state != TCP_CLOSE) { | 2014 | if (sk->sk_state != TCP_CLOSE) { |
2014 | int orphan_count = percpu_counter_read_positive( | ||
2015 | sk->sk_prot->orphan_count); | ||
2016 | |||
2017 | sk_mem_reclaim(sk); | 2015 | sk_mem_reclaim(sk); |
2018 | if (tcp_too_many_orphans(sk, orphan_count)) { | 2016 | if (tcp_too_many_orphans(sk, 0)) { |
2019 | if (net_ratelimit()) | 2017 | if (net_ratelimit()) |
2020 | printk(KERN_INFO "TCP: too many of orphaned " | 2018 | printk(KERN_INFO "TCP: too many of orphaned " |
2021 | "sockets\n"); | 2019 | "sockets\n"); |
@@ -3221,7 +3219,7 @@ void __init tcp_init(void) | |||
3221 | { | 3219 | { |
3222 | struct sk_buff *skb = NULL; | 3220 | struct sk_buff *skb = NULL; |
3223 | unsigned long nr_pages, limit; | 3221 | unsigned long nr_pages, limit; |
3224 | int order, i, max_share; | 3222 | int i, max_share, cnt; |
3225 | unsigned long jiffy = jiffies; | 3223 | unsigned long jiffy = jiffies; |
3226 | 3224 | ||
3227 | BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb)); | 3225 | BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb)); |
@@ -3270,22 +3268,12 @@ void __init tcp_init(void) | |||
3270 | INIT_HLIST_HEAD(&tcp_hashinfo.bhash[i].chain); | 3268 | INIT_HLIST_HEAD(&tcp_hashinfo.bhash[i].chain); |
3271 | } | 3269 | } |
3272 | 3270 | ||
3273 | /* Try to be a bit smarter and adjust defaults depending | 3271 | |
3274 | * on available memory. | 3272 | cnt = tcp_hashinfo.ehash_mask + 1; |
3275 | */ | 3273 | |
3276 | for (order = 0; ((1 << order) << PAGE_SHIFT) < | 3274 | tcp_death_row.sysctl_max_tw_buckets = cnt / 2; |
3277 | (tcp_hashinfo.bhash_size * sizeof(struct inet_bind_hashbucket)); | 3275 | sysctl_tcp_max_orphans = cnt / 2; |
3278 | order++) | 3276 | sysctl_max_syn_backlog = max(128, cnt / 256); |
3279 | ; | ||
3280 | if (order >= 4) { | ||
3281 | tcp_death_row.sysctl_max_tw_buckets = 180000; | ||
3282 | sysctl_tcp_max_orphans = 4096 << (order - 4); | ||
3283 | sysctl_max_syn_backlog = 1024; | ||
3284 | } else if (order < 3) { | ||
3285 | tcp_death_row.sysctl_max_tw_buckets >>= (3 - order); | ||
3286 | sysctl_tcp_max_orphans >>= (3 - order); | ||
3287 | sysctl_max_syn_backlog = 128; | ||
3288 | } | ||
3289 | 3277 | ||
3290 | /* Set the pressure threshold to be a fraction of global memory that | 3278 | /* Set the pressure threshold to be a fraction of global memory that |
3291 | * is up to 1/2 at 256 MB, decreasing toward zero with the amount of | 3279 | * is up to 1/2 at 256 MB, decreasing toward zero with the amount of |
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index 0ec9bd0ae94..850c737e08e 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
@@ -196,10 +196,10 @@ void tcp_get_allowed_congestion_control(char *buf, size_t maxlen) | |||
196 | int tcp_set_allowed_congestion_control(char *val) | 196 | int tcp_set_allowed_congestion_control(char *val) |
197 | { | 197 | { |
198 | struct tcp_congestion_ops *ca; | 198 | struct tcp_congestion_ops *ca; |
199 | char *clone, *name; | 199 | char *saved_clone, *clone, *name; |
200 | int ret = 0; | 200 | int ret = 0; |
201 | 201 | ||
202 | clone = kstrdup(val, GFP_USER); | 202 | saved_clone = clone = kstrdup(val, GFP_USER); |
203 | if (!clone) | 203 | if (!clone) |
204 | return -ENOMEM; | 204 | return -ENOMEM; |
205 | 205 | ||
@@ -226,6 +226,7 @@ int tcp_set_allowed_congestion_control(char *val) | |||
226 | } | 226 | } |
227 | out: | 227 | out: |
228 | spin_unlock(&tcp_cong_list_lock); | 228 | spin_unlock(&tcp_cong_list_lock); |
229 | kfree(saved_clone); | ||
229 | 230 | ||
230 | return ret; | 231 | return ret; |
231 | } | 232 | } |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 11569deccbe..baea4a12902 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -66,18 +66,18 @@ static void tcp_write_err(struct sock *sk) | |||
66 | static int tcp_out_of_resources(struct sock *sk, int do_reset) | 66 | static int tcp_out_of_resources(struct sock *sk, int do_reset) |
67 | { | 67 | { |
68 | struct tcp_sock *tp = tcp_sk(sk); | 68 | struct tcp_sock *tp = tcp_sk(sk); |
69 | int orphans = percpu_counter_read_positive(&tcp_orphan_count); | 69 | int shift = 0; |
70 | 70 | ||
71 | /* If peer does not open window for long time, or did not transmit | 71 | /* If peer does not open window for long time, or did not transmit |
72 | * anything for long time, penalize it. */ | 72 | * anything for long time, penalize it. */ |
73 | if ((s32)(tcp_time_stamp - tp->lsndtime) > 2*TCP_RTO_MAX || !do_reset) | 73 | if ((s32)(tcp_time_stamp - tp->lsndtime) > 2*TCP_RTO_MAX || !do_reset) |
74 | orphans <<= 1; | 74 | shift++; |
75 | 75 | ||
76 | /* If some dubious ICMP arrived, penalize even more. */ | 76 | /* If some dubious ICMP arrived, penalize even more. */ |
77 | if (sk->sk_err_soft) | 77 | if (sk->sk_err_soft) |
78 | orphans <<= 1; | 78 | shift++; |
79 | 79 | ||
80 | if (tcp_too_many_orphans(sk, orphans)) { | 80 | if (tcp_too_many_orphans(sk, shift)) { |
81 | if (net_ratelimit()) | 81 | if (net_ratelimit()) |
82 | printk(KERN_INFO "Out of socket memory\n"); | 82 | printk(KERN_INFO "Out of socket memory\n"); |
83 | 83 | ||
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 86e757e162e..b3f7e8cf18a 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -1260,6 +1260,49 @@ void udp_lib_unhash(struct sock *sk) | |||
1260 | } | 1260 | } |
1261 | EXPORT_SYMBOL(udp_lib_unhash); | 1261 | EXPORT_SYMBOL(udp_lib_unhash); |
1262 | 1262 | ||
1263 | /* | ||
1264 | * inet_rcv_saddr was changed, we must rehash secondary hash | ||
1265 | */ | ||
1266 | void udp_lib_rehash(struct sock *sk, u16 newhash) | ||
1267 | { | ||
1268 | if (sk_hashed(sk)) { | ||
1269 | struct udp_table *udptable = sk->sk_prot->h.udp_table; | ||
1270 | struct udp_hslot *hslot, *hslot2, *nhslot2; | ||
1271 | |||
1272 | hslot2 = udp_hashslot2(udptable, udp_sk(sk)->udp_portaddr_hash); | ||
1273 | nhslot2 = udp_hashslot2(udptable, newhash); | ||
1274 | udp_sk(sk)->udp_portaddr_hash = newhash; | ||
1275 | if (hslot2 != nhslot2) { | ||
1276 | hslot = udp_hashslot(udptable, sock_net(sk), | ||
1277 | udp_sk(sk)->udp_port_hash); | ||
1278 | /* we must lock primary chain too */ | ||
1279 | spin_lock_bh(&hslot->lock); | ||
1280 | |||
1281 | spin_lock(&hslot2->lock); | ||
1282 | hlist_nulls_del_init_rcu(&udp_sk(sk)->udp_portaddr_node); | ||
1283 | hslot2->count--; | ||
1284 | spin_unlock(&hslot2->lock); | ||
1285 | |||
1286 | spin_lock(&nhslot2->lock); | ||
1287 | hlist_nulls_add_head_rcu(&udp_sk(sk)->udp_portaddr_node, | ||
1288 | &nhslot2->head); | ||
1289 | nhslot2->count++; | ||
1290 | spin_unlock(&nhslot2->lock); | ||
1291 | |||
1292 | spin_unlock_bh(&hslot->lock); | ||
1293 | } | ||
1294 | } | ||
1295 | } | ||
1296 | EXPORT_SYMBOL(udp_lib_rehash); | ||
1297 | |||
1298 | static void udp_v4_rehash(struct sock *sk) | ||
1299 | { | ||
1300 | u16 new_hash = udp4_portaddr_hash(sock_net(sk), | ||
1301 | inet_sk(sk)->inet_rcv_saddr, | ||
1302 | inet_sk(sk)->inet_num); | ||
1303 | udp_lib_rehash(sk, new_hash); | ||
1304 | } | ||
1305 | |||
1263 | static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | 1306 | static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) |
1264 | { | 1307 | { |
1265 | int rc; | 1308 | int rc; |
@@ -1843,6 +1886,7 @@ struct proto udp_prot = { | |||
1843 | .backlog_rcv = __udp_queue_rcv_skb, | 1886 | .backlog_rcv = __udp_queue_rcv_skb, |
1844 | .hash = udp_lib_hash, | 1887 | .hash = udp_lib_hash, |
1845 | .unhash = udp_lib_unhash, | 1888 | .unhash = udp_lib_unhash, |
1889 | .rehash = udp_v4_rehash, | ||
1846 | .get_port = udp_v4_get_port, | 1890 | .get_port = udp_v4_get_port, |
1847 | .memory_allocated = &udp_memory_allocated, | 1891 | .memory_allocated = &udp_memory_allocated, |
1848 | .sysctl_mem = sysctl_udp_mem, | 1892 | .sysctl_mem = sysctl_udp_mem, |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 7d929a22cbc..ef371aa01ac 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -105,9 +105,12 @@ ipv4_connected: | |||
105 | if (ipv6_addr_any(&np->saddr)) | 105 | if (ipv6_addr_any(&np->saddr)) |
106 | ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr); | 106 | ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr); |
107 | 107 | ||
108 | if (ipv6_addr_any(&np->rcv_saddr)) | 108 | if (ipv6_addr_any(&np->rcv_saddr)) { |
109 | ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, | 109 | ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, |
110 | &np->rcv_saddr); | 110 | &np->rcv_saddr); |
111 | if (sk->sk_prot->rehash) | ||
112 | sk->sk_prot->rehash(sk); | ||
113 | } | ||
111 | 114 | ||
112 | goto out; | 115 | goto out; |
113 | } | 116 | } |
@@ -181,6 +184,8 @@ ipv4_connected: | |||
181 | if (ipv6_addr_any(&np->rcv_saddr)) { | 184 | if (ipv6_addr_any(&np->rcv_saddr)) { |
182 | ipv6_addr_copy(&np->rcv_saddr, &fl.fl6_src); | 185 | ipv6_addr_copy(&np->rcv_saddr, &fl.fl6_src); |
183 | inet->inet_rcv_saddr = LOOPBACK4_IPV6; | 186 | inet->inet_rcv_saddr = LOOPBACK4_IPV6; |
187 | if (sk->sk_prot->rehash) | ||
188 | sk->sk_prot->rehash(sk); | ||
184 | } | 189 | } |
185 | 190 | ||
186 | ip6_dst_store(sk, dst, | 191 | ip6_dst_store(sk, dst, |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 29a7bca29e3..8e754be92c2 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -1766,6 +1766,9 @@ translate_compat_table(struct net *net, | |||
1766 | if (ret != 0) | 1766 | if (ret != 0) |
1767 | break; | 1767 | break; |
1768 | ++i; | 1768 | ++i; |
1769 | if (strcmp(ip6t_get_target(iter1)->u.user.name, | ||
1770 | XT_ERROR_TARGET) == 0) | ||
1771 | ++newinfo->stacksize; | ||
1769 | } | 1772 | } |
1770 | if (ret) { | 1773 | if (ret) { |
1771 | /* | 1774 | /* |
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 089c598773c..138a8b36270 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
@@ -113,14 +113,6 @@ static void nf_skb_free(struct sk_buff *skb) | |||
113 | kfree_skb(NFCT_FRAG6_CB(skb)->orig); | 113 | kfree_skb(NFCT_FRAG6_CB(skb)->orig); |
114 | } | 114 | } |
115 | 115 | ||
116 | /* Memory Tracking Functions. */ | ||
117 | static void frag_kfree_skb(struct sk_buff *skb) | ||
118 | { | ||
119 | atomic_sub(skb->truesize, &nf_init_frags.mem); | ||
120 | nf_skb_free(skb); | ||
121 | kfree_skb(skb); | ||
122 | } | ||
123 | |||
124 | /* Destruction primitives. */ | 116 | /* Destruction primitives. */ |
125 | 117 | ||
126 | static __inline__ void fq_put(struct nf_ct_frag6_queue *fq) | 118 | static __inline__ void fq_put(struct nf_ct_frag6_queue *fq) |
@@ -282,66 +274,22 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, | |||
282 | } | 274 | } |
283 | 275 | ||
284 | found: | 276 | found: |
285 | /* We found where to put this one. Check for overlap with | 277 | /* RFC5722, Section 4: |
286 | * preceding fragment, and, if needed, align things so that | 278 | * When reassembling an IPv6 datagram, if |
287 | * any overlaps are eliminated. | 279 | * one or more its constituent fragments is determined to be an |
288 | */ | 280 | * overlapping fragment, the entire datagram (and any constituent |
289 | if (prev) { | 281 | * fragments, including those not yet received) MUST be silently |
290 | int i = (NFCT_FRAG6_CB(prev)->offset + prev->len) - offset; | 282 | * discarded. |
291 | |||
292 | if (i > 0) { | ||
293 | offset += i; | ||
294 | if (end <= offset) { | ||
295 | pr_debug("overlap\n"); | ||
296 | goto err; | ||
297 | } | ||
298 | if (!pskb_pull(skb, i)) { | ||
299 | pr_debug("Can't pull\n"); | ||
300 | goto err; | ||
301 | } | ||
302 | if (skb->ip_summed != CHECKSUM_UNNECESSARY) | ||
303 | skb->ip_summed = CHECKSUM_NONE; | ||
304 | } | ||
305 | } | ||
306 | |||
307 | /* Look for overlap with succeeding segments. | ||
308 | * If we can merge fragments, do it. | ||
309 | */ | 283 | */ |
310 | while (next && NFCT_FRAG6_CB(next)->offset < end) { | ||
311 | /* overlap is 'i' bytes */ | ||
312 | int i = end - NFCT_FRAG6_CB(next)->offset; | ||
313 | |||
314 | if (i < next->len) { | ||
315 | /* Eat head of the next overlapped fragment | ||
316 | * and leave the loop. The next ones cannot overlap. | ||
317 | */ | ||
318 | pr_debug("Eat head of the overlapped parts.: %d", i); | ||
319 | if (!pskb_pull(next, i)) | ||
320 | goto err; | ||
321 | 284 | ||
322 | /* next fragment */ | 285 | /* Check for overlap with preceding fragment. */ |
323 | NFCT_FRAG6_CB(next)->offset += i; | 286 | if (prev && |
324 | fq->q.meat -= i; | 287 | (NFCT_FRAG6_CB(prev)->offset + prev->len) - offset > 0) |
325 | if (next->ip_summed != CHECKSUM_UNNECESSARY) | 288 | goto discard_fq; |
326 | next->ip_summed = CHECKSUM_NONE; | ||
327 | break; | ||
328 | } else { | ||
329 | struct sk_buff *free_it = next; | ||
330 | |||
331 | /* Old fragmnet is completely overridden with | ||
332 | * new one drop it. | ||
333 | */ | ||
334 | next = next->next; | ||
335 | 289 | ||
336 | if (prev) | 290 | /* Look for overlap with succeeding segment. */ |
337 | prev->next = next; | 291 | if (next && NFCT_FRAG6_CB(next)->offset < end) |
338 | else | 292 | goto discard_fq; |
339 | fq->q.fragments = next; | ||
340 | |||
341 | fq->q.meat -= free_it->len; | ||
342 | frag_kfree_skb(free_it); | ||
343 | } | ||
344 | } | ||
345 | 293 | ||
346 | NFCT_FRAG6_CB(skb)->offset = offset; | 294 | NFCT_FRAG6_CB(skb)->offset = offset; |
347 | 295 | ||
@@ -371,6 +319,8 @@ found: | |||
371 | write_unlock(&nf_frags.lock); | 319 | write_unlock(&nf_frags.lock); |
372 | return 0; | 320 | return 0; |
373 | 321 | ||
322 | discard_fq: | ||
323 | fq_kill(fq); | ||
374 | err: | 324 | err: |
375 | return -1; | 325 | return -1; |
376 | } | 326 | } |
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 8aea3f3f18d..c7ba3149633 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
@@ -149,13 +149,6 @@ int ip6_frag_match(struct inet_frag_queue *q, void *a) | |||
149 | } | 149 | } |
150 | EXPORT_SYMBOL(ip6_frag_match); | 150 | EXPORT_SYMBOL(ip6_frag_match); |
151 | 151 | ||
152 | /* Memory Tracking Functions. */ | ||
153 | static void frag_kfree_skb(struct netns_frags *nf, struct sk_buff *skb) | ||
154 | { | ||
155 | atomic_sub(skb->truesize, &nf->mem); | ||
156 | kfree_skb(skb); | ||
157 | } | ||
158 | |||
159 | void ip6_frag_init(struct inet_frag_queue *q, void *a) | 152 | void ip6_frag_init(struct inet_frag_queue *q, void *a) |
160 | { | 153 | { |
161 | struct frag_queue *fq = container_of(q, struct frag_queue, q); | 154 | struct frag_queue *fq = container_of(q, struct frag_queue, q); |
@@ -346,58 +339,22 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, | |||
346 | } | 339 | } |
347 | 340 | ||
348 | found: | 341 | found: |
349 | /* We found where to put this one. Check for overlap with | 342 | /* RFC5722, Section 4: |
350 | * preceding fragment, and, if needed, align things so that | 343 | * When reassembling an IPv6 datagram, if |
351 | * any overlaps are eliminated. | 344 | * one or more its constituent fragments is determined to be an |
345 | * overlapping fragment, the entire datagram (and any constituent | ||
346 | * fragments, including those not yet received) MUST be silently | ||
347 | * discarded. | ||
352 | */ | 348 | */ |
353 | if (prev) { | ||
354 | int i = (FRAG6_CB(prev)->offset + prev->len) - offset; | ||
355 | 349 | ||
356 | if (i > 0) { | 350 | /* Check for overlap with preceding fragment. */ |
357 | offset += i; | 351 | if (prev && |
358 | if (end <= offset) | 352 | (FRAG6_CB(prev)->offset + prev->len) - offset > 0) |
359 | goto err; | 353 | goto discard_fq; |
360 | if (!pskb_pull(skb, i)) | ||
361 | goto err; | ||
362 | if (skb->ip_summed != CHECKSUM_UNNECESSARY) | ||
363 | skb->ip_summed = CHECKSUM_NONE; | ||
364 | } | ||
365 | } | ||
366 | 354 | ||
367 | /* Look for overlap with succeeding segments. | 355 | /* Look for overlap with succeeding segment. */ |
368 | * If we can merge fragments, do it. | 356 | if (next && FRAG6_CB(next)->offset < end) |
369 | */ | 357 | goto discard_fq; |
370 | while (next && FRAG6_CB(next)->offset < end) { | ||
371 | int i = end - FRAG6_CB(next)->offset; /* overlap is 'i' bytes */ | ||
372 | |||
373 | if (i < next->len) { | ||
374 | /* Eat head of the next overlapped fragment | ||
375 | * and leave the loop. The next ones cannot overlap. | ||
376 | */ | ||
377 | if (!pskb_pull(next, i)) | ||
378 | goto err; | ||
379 | FRAG6_CB(next)->offset += i; /* next fragment */ | ||
380 | fq->q.meat -= i; | ||
381 | if (next->ip_summed != CHECKSUM_UNNECESSARY) | ||
382 | next->ip_summed = CHECKSUM_NONE; | ||
383 | break; | ||
384 | } else { | ||
385 | struct sk_buff *free_it = next; | ||
386 | |||
387 | /* Old fragment is completely overridden with | ||
388 | * new one drop it. | ||
389 | */ | ||
390 | next = next->next; | ||
391 | |||
392 | if (prev) | ||
393 | prev->next = next; | ||
394 | else | ||
395 | fq->q.fragments = next; | ||
396 | |||
397 | fq->q.meat -= free_it->len; | ||
398 | frag_kfree_skb(fq->q.net, free_it); | ||
399 | } | ||
400 | } | ||
401 | 358 | ||
402 | FRAG6_CB(skb)->offset = offset; | 359 | FRAG6_CB(skb)->offset = offset; |
403 | 360 | ||
@@ -436,6 +393,8 @@ found: | |||
436 | write_unlock(&ip6_frags.lock); | 393 | write_unlock(&ip6_frags.lock); |
437 | return -1; | 394 | return -1; |
438 | 395 | ||
396 | discard_fq: | ||
397 | fq_kill(fq); | ||
439 | err: | 398 | err: |
440 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), | 399 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), |
441 | IPSTATS_MIB_REASMFAILS); | 400 | IPSTATS_MIB_REASMFAILS); |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 1dd1affdead..5acb3560ff1 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -111,6 +111,15 @@ int udp_v6_get_port(struct sock *sk, unsigned short snum) | |||
111 | return udp_lib_get_port(sk, snum, ipv6_rcv_saddr_equal, hash2_nulladdr); | 111 | return udp_lib_get_port(sk, snum, ipv6_rcv_saddr_equal, hash2_nulladdr); |
112 | } | 112 | } |
113 | 113 | ||
114 | static void udp_v6_rehash(struct sock *sk) | ||
115 | { | ||
116 | u16 new_hash = udp6_portaddr_hash(sock_net(sk), | ||
117 | &inet6_sk(sk)->rcv_saddr, | ||
118 | inet_sk(sk)->inet_num); | ||
119 | |||
120 | udp_lib_rehash(sk, new_hash); | ||
121 | } | ||
122 | |||
114 | static inline int compute_score(struct sock *sk, struct net *net, | 123 | static inline int compute_score(struct sock *sk, struct net *net, |
115 | unsigned short hnum, | 124 | unsigned short hnum, |
116 | struct in6_addr *saddr, __be16 sport, | 125 | struct in6_addr *saddr, __be16 sport, |
@@ -1447,6 +1456,7 @@ struct proto udpv6_prot = { | |||
1447 | .backlog_rcv = udpv6_queue_rcv_skb, | 1456 | .backlog_rcv = udpv6_queue_rcv_skb, |
1448 | .hash = udp_lib_hash, | 1457 | .hash = udp_lib_hash, |
1449 | .unhash = udp_lib_unhash, | 1458 | .unhash = udp_lib_unhash, |
1459 | .rehash = udp_v6_rehash, | ||
1450 | .get_port = udp_v6_get_port, | 1460 | .get_port = udp_v6_get_port, |
1451 | .memory_allocated = &udp_memory_allocated, | 1461 | .memory_allocated = &udp_memory_allocated, |
1452 | .sysctl_mem = sysctl_udp_mem, | 1462 | .sysctl_mem = sysctl_udp_mem, |
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 79986a674f6..fd55b5135de 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
@@ -824,8 +824,8 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
824 | 824 | ||
825 | err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name); | 825 | err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name); |
826 | if (err < 0) { | 826 | if (err < 0) { |
827 | kfree(self->ias_obj->name); | 827 | irias_delete_object(self->ias_obj); |
828 | kfree(self->ias_obj); | 828 | self->ias_obj = NULL; |
829 | goto out; | 829 | goto out; |
830 | } | 830 | } |
831 | 831 | ||
diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c index a788f9e9427..6130f9d9dbe 100644 --- a/net/irda/irlan/irlan_common.c +++ b/net/irda/irlan/irlan_common.c | |||
@@ -1102,7 +1102,7 @@ int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len) | |||
1102 | memcpy(&val_len, buf+n, 2); /* To avoid alignment problems */ | 1102 | memcpy(&val_len, buf+n, 2); /* To avoid alignment problems */ |
1103 | le16_to_cpus(&val_len); n+=2; | 1103 | le16_to_cpus(&val_len); n+=2; |
1104 | 1104 | ||
1105 | if (val_len > 1016) { | 1105 | if (val_len >= 1016) { |
1106 | IRDA_DEBUG(2, "%s(), parameter length to long\n", __func__ ); | 1106 | IRDA_DEBUG(2, "%s(), parameter length to long\n", __func__ ); |
1107 | return -RSP_INVALID_COMMAND_FORMAT; | 1107 | return -RSP_INVALID_COMMAND_FORMAT; |
1108 | } | 1108 | } |
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index f3468ba3f5c..8d9ce0accc9 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c | |||
@@ -132,7 +132,7 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, | |||
132 | printk("\n"); | 132 | printk("\n"); |
133 | } | 133 | } |
134 | 134 | ||
135 | if (data_len < ETH_HLEN) | 135 | if (!pskb_may_pull(skb, sizeof(ETH_HLEN))) |
136 | goto error; | 136 | goto error; |
137 | 137 | ||
138 | secpath_reset(skb); | 138 | secpath_reset(skb); |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index a06b6ee63c0..4935b843bcc 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -850,6 +850,12 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
850 | 850 | ||
851 | rtnl_unlock(); | 851 | rtnl_unlock(); |
852 | 852 | ||
853 | /* | ||
854 | * Now all work items will be gone, but the | ||
855 | * timer might still be armed, so delete it | ||
856 | */ | ||
857 | del_timer_sync(&local->work_timer); | ||
858 | |||
853 | cancel_work_sync(&local->restart_work); | 859 | cancel_work_sync(&local->restart_work); |
854 | cancel_work_sync(&local->reconfig_filter); | 860 | cancel_work_sync(&local->reconfig_filter); |
855 | 861 | ||
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index b7ce5b441b3..0c043b6ce65 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
@@ -927,6 +927,7 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, | |||
927 | 927 | ||
928 | ip_vs_out_stats(cp, skb); | 928 | ip_vs_out_stats(cp, skb); |
929 | ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp); | 929 | ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp); |
930 | ip_vs_update_conntrack(skb, cp, 0); | ||
930 | ip_vs_conn_put(cp); | 931 | ip_vs_conn_put(cp); |
931 | 932 | ||
932 | skb->ipvs_property = 1; | 933 | skb->ipvs_property = 1; |
diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c index f228a17ec64..7e9af5b76d9 100644 --- a/net/netfilter/ipvs/ip_vs_ftp.c +++ b/net/netfilter/ipvs/ip_vs_ftp.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/netfilter.h> | 45 | #include <linux/netfilter.h> |
46 | #include <net/netfilter/nf_conntrack.h> | 46 | #include <net/netfilter/nf_conntrack.h> |
47 | #include <net/netfilter/nf_conntrack_expect.h> | 47 | #include <net/netfilter/nf_conntrack_expect.h> |
48 | #include <net/netfilter/nf_nat.h> | ||
48 | #include <net/netfilter/nf_nat_helper.h> | 49 | #include <net/netfilter/nf_nat_helper.h> |
49 | #include <linux/gfp.h> | 50 | #include <linux/gfp.h> |
50 | #include <net/protocol.h> | 51 | #include <net/protocol.h> |
@@ -359,7 +360,7 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, | |||
359 | buf_len = strlen(buf); | 360 | buf_len = strlen(buf); |
360 | 361 | ||
361 | ct = nf_ct_get(skb, &ctinfo); | 362 | ct = nf_ct_get(skb, &ctinfo); |
362 | if (ct && !nf_ct_is_untracked(ct)) { | 363 | if (ct && !nf_ct_is_untracked(ct) && nfct_nat(ct)) { |
363 | /* If mangling fails this function will return 0 | 364 | /* If mangling fails this function will return 0 |
364 | * which will cause the packet to be dropped. | 365 | * which will cause the packet to be dropped. |
365 | * Mangling can only fail under memory pressure, | 366 | * Mangling can only fail under memory pressure, |
@@ -409,7 +410,6 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, | |||
409 | union nf_inet_addr to; | 410 | union nf_inet_addr to; |
410 | __be16 port; | 411 | __be16 port; |
411 | struct ip_vs_conn *n_cp; | 412 | struct ip_vs_conn *n_cp; |
412 | struct nf_conn *ct; | ||
413 | 413 | ||
414 | #ifdef CONFIG_IP_VS_IPV6 | 414 | #ifdef CONFIG_IP_VS_IPV6 |
415 | /* This application helper doesn't work with IPv6 yet, | 415 | /* This application helper doesn't work with IPv6 yet, |
@@ -496,11 +496,6 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, | |||
496 | ip_vs_control_add(n_cp, cp); | 496 | ip_vs_control_add(n_cp, cp); |
497 | } | 497 | } |
498 | 498 | ||
499 | ct = (struct nf_conn *)skb->nfct; | ||
500 | if (ct && ct != &nf_conntrack_untracked) | ||
501 | ip_vs_expect_related(skb, ct, n_cp, | ||
502 | IPPROTO_TCP, &n_cp->dport, 1); | ||
503 | |||
504 | /* | 499 | /* |
505 | * Move tunnel to listen state | 500 | * Move tunnel to listen state |
506 | */ | 501 | */ |
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 21e1a5e9b9d..49df6bea6a2 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c | |||
@@ -349,8 +349,8 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
349 | } | 349 | } |
350 | #endif | 350 | #endif |
351 | 351 | ||
352 | static void | 352 | void |
353 | ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp) | 353 | ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, int outin) |
354 | { | 354 | { |
355 | struct nf_conn *ct = (struct nf_conn *)skb->nfct; | 355 | struct nf_conn *ct = (struct nf_conn *)skb->nfct; |
356 | struct nf_conntrack_tuple new_tuple; | 356 | struct nf_conntrack_tuple new_tuple; |
@@ -365,11 +365,17 @@ ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp) | |||
365 | * real-server we will see RIP->DIP. | 365 | * real-server we will see RIP->DIP. |
366 | */ | 366 | */ |
367 | new_tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; | 367 | new_tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; |
368 | new_tuple.src.u3 = cp->daddr; | 368 | if (outin) |
369 | new_tuple.src.u3 = cp->daddr; | ||
370 | else | ||
371 | new_tuple.dst.u3 = cp->vaddr; | ||
369 | /* | 372 | /* |
370 | * This will also take care of UDP and other protocols. | 373 | * This will also take care of UDP and other protocols. |
371 | */ | 374 | */ |
372 | new_tuple.src.u.tcp.port = cp->dport; | 375 | if (outin) |
376 | new_tuple.src.u.tcp.port = cp->dport; | ||
377 | else | ||
378 | new_tuple.dst.u.tcp.port = cp->vport; | ||
373 | nf_conntrack_alter_reply(ct, &new_tuple); | 379 | nf_conntrack_alter_reply(ct, &new_tuple); |
374 | } | 380 | } |
375 | 381 | ||
@@ -428,7 +434,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
428 | 434 | ||
429 | IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); | 435 | IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); |
430 | 436 | ||
431 | ip_vs_update_conntrack(skb, cp); | 437 | ip_vs_update_conntrack(skb, cp, 1); |
432 | 438 | ||
433 | /* FIXME: when application helper enlarges the packet and the length | 439 | /* FIXME: when application helper enlarges the packet and the length |
434 | is larger than the MTU of outgoing device, there will be still | 440 | is larger than the MTU of outgoing device, there will be still |
@@ -506,7 +512,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
506 | 512 | ||
507 | IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); | 513 | IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); |
508 | 514 | ||
509 | ip_vs_update_conntrack(skb, cp); | 515 | ip_vs_update_conntrack(skb, cp, 1); |
510 | 516 | ||
511 | /* FIXME: when application helper enlarges the packet and the length | 517 | /* FIXME: when application helper enlarges the packet and the length |
512 | is larger than the MTU of outgoing device, there will be still | 518 | is larger than the MTU of outgoing device, there will be still |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 980fe4ad001..cd96ed3ccee 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -2102,6 +2102,26 @@ static void __net_exit netlink_net_exit(struct net *net) | |||
2102 | #endif | 2102 | #endif |
2103 | } | 2103 | } |
2104 | 2104 | ||
2105 | static void __init netlink_add_usersock_entry(void) | ||
2106 | { | ||
2107 | unsigned long *listeners; | ||
2108 | int groups = 32; | ||
2109 | |||
2110 | listeners = kzalloc(NLGRPSZ(groups) + sizeof(struct listeners_rcu_head), | ||
2111 | GFP_KERNEL); | ||
2112 | if (!listeners) | ||
2113 | panic("netlink_add_usersock_entry: Cannot allocate listneres\n"); | ||
2114 | |||
2115 | netlink_table_grab(); | ||
2116 | |||
2117 | nl_table[NETLINK_USERSOCK].groups = groups; | ||
2118 | nl_table[NETLINK_USERSOCK].listeners = listeners; | ||
2119 | nl_table[NETLINK_USERSOCK].module = THIS_MODULE; | ||
2120 | nl_table[NETLINK_USERSOCK].registered = 1; | ||
2121 | |||
2122 | netlink_table_ungrab(); | ||
2123 | } | ||
2124 | |||
2105 | static struct pernet_operations __net_initdata netlink_net_ops = { | 2125 | static struct pernet_operations __net_initdata netlink_net_ops = { |
2106 | .init = netlink_net_init, | 2126 | .init = netlink_net_init, |
2107 | .exit = netlink_net_exit, | 2127 | .exit = netlink_net_exit, |
@@ -2150,6 +2170,8 @@ static int __init netlink_proto_init(void) | |||
2150 | hash->rehash_time = jiffies; | 2170 | hash->rehash_time = jiffies; |
2151 | } | 2171 | } |
2152 | 2172 | ||
2173 | netlink_add_usersock_entry(); | ||
2174 | |||
2153 | sock_register(&netlink_family_ops); | 2175 | sock_register(&netlink_family_ops); |
2154 | register_pernet_subsys(&netlink_net_ops); | 2176 | register_pernet_subsys(&netlink_net_ops); |
2155 | /* The netlink device handler may be needed early. */ | 2177 | /* The netlink device handler may be needed early. */ |
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 537a48732e9..7ebf7439b47 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
@@ -350,22 +350,19 @@ tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) | |||
350 | { | 350 | { |
351 | unsigned char *b = skb_tail_pointer(skb); | 351 | unsigned char *b = skb_tail_pointer(skb); |
352 | struct tcf_police *police = a->priv; | 352 | struct tcf_police *police = a->priv; |
353 | struct tc_police opt; | 353 | struct tc_police opt = { |
354 | 354 | .index = police->tcf_index, | |
355 | opt.index = police->tcf_index; | 355 | .action = police->tcf_action, |
356 | opt.action = police->tcf_action; | 356 | .mtu = police->tcfp_mtu, |
357 | opt.mtu = police->tcfp_mtu; | 357 | .burst = police->tcfp_burst, |
358 | opt.burst = police->tcfp_burst; | 358 | .refcnt = police->tcf_refcnt - ref, |
359 | opt.refcnt = police->tcf_refcnt - ref; | 359 | .bindcnt = police->tcf_bindcnt - bind, |
360 | opt.bindcnt = police->tcf_bindcnt - bind; | 360 | }; |
361 | |||
361 | if (police->tcfp_R_tab) | 362 | if (police->tcfp_R_tab) |
362 | opt.rate = police->tcfp_R_tab->rate; | 363 | opt.rate = police->tcfp_R_tab->rate; |
363 | else | ||
364 | memset(&opt.rate, 0, sizeof(opt.rate)); | ||
365 | if (police->tcfp_P_tab) | 364 | if (police->tcfp_P_tab) |
366 | opt.peakrate = police->tcfp_P_tab->rate; | 365 | opt.peakrate = police->tcfp_P_tab->rate; |
367 | else | ||
368 | memset(&opt.peakrate, 0, sizeof(opt.peakrate)); | ||
369 | NLA_PUT(skb, TCA_POLICE_TBF, sizeof(opt), &opt); | 366 | NLA_PUT(skb, TCA_POLICE_TBF, sizeof(opt), &opt); |
370 | if (police->tcfp_result) | 367 | if (police->tcfp_result) |
371 | NLA_PUT_U32(skb, TCA_POLICE_RESULT, police->tcfp_result); | 368 | NLA_PUT_U32(skb, TCA_POLICE_RESULT, police->tcfp_result); |
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index abd904be428..47496098d35 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c | |||
@@ -761,8 +761,8 @@ init_vf(struct hfsc_class *cl, unsigned int len) | |||
761 | if (f != cl->cl_f) { | 761 | if (f != cl->cl_f) { |
762 | cl->cl_f = f; | 762 | cl->cl_f = f; |
763 | cftree_update(cl); | 763 | cftree_update(cl); |
764 | update_cfmin(cl->cl_parent); | ||
765 | } | 764 | } |
765 | update_cfmin(cl->cl_parent); | ||
766 | } | 766 | } |
767 | } | 767 | } |
768 | 768 | ||
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 8b284436be6..4b4eb7c96bb 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -1232,6 +1232,18 @@ out: | |||
1232 | return 0; | 1232 | return 0; |
1233 | } | 1233 | } |
1234 | 1234 | ||
1235 | static bool list_has_sctp_addr(const struct list_head *list, | ||
1236 | union sctp_addr *ipaddr) | ||
1237 | { | ||
1238 | struct sctp_transport *addr; | ||
1239 | |||
1240 | list_for_each_entry(addr, list, transports) { | ||
1241 | if (sctp_cmp_addr_exact(ipaddr, &addr->ipaddr)) | ||
1242 | return true; | ||
1243 | } | ||
1244 | |||
1245 | return false; | ||
1246 | } | ||
1235 | /* A restart is occurring, check to make sure no new addresses | 1247 | /* A restart is occurring, check to make sure no new addresses |
1236 | * are being added as we may be under a takeover attack. | 1248 | * are being added as we may be under a takeover attack. |
1237 | */ | 1249 | */ |
@@ -1240,10 +1252,10 @@ static int sctp_sf_check_restart_addrs(const struct sctp_association *new_asoc, | |||
1240 | struct sctp_chunk *init, | 1252 | struct sctp_chunk *init, |
1241 | sctp_cmd_seq_t *commands) | 1253 | sctp_cmd_seq_t *commands) |
1242 | { | 1254 | { |
1243 | struct sctp_transport *new_addr, *addr; | 1255 | struct sctp_transport *new_addr; |
1244 | int found; | 1256 | int ret = 1; |
1245 | 1257 | ||
1246 | /* Implementor's Guide - Sectin 5.2.2 | 1258 | /* Implementor's Guide - Section 5.2.2 |
1247 | * ... | 1259 | * ... |
1248 | * Before responding the endpoint MUST check to see if the | 1260 | * Before responding the endpoint MUST check to see if the |
1249 | * unexpected INIT adds new addresses to the association. If new | 1261 | * unexpected INIT adds new addresses to the association. If new |
@@ -1254,31 +1266,19 @@ static int sctp_sf_check_restart_addrs(const struct sctp_association *new_asoc, | |||
1254 | /* Search through all current addresses and make sure | 1266 | /* Search through all current addresses and make sure |
1255 | * we aren't adding any new ones. | 1267 | * we aren't adding any new ones. |
1256 | */ | 1268 | */ |
1257 | new_addr = NULL; | ||
1258 | found = 0; | ||
1259 | |||
1260 | list_for_each_entry(new_addr, &new_asoc->peer.transport_addr_list, | 1269 | list_for_each_entry(new_addr, &new_asoc->peer.transport_addr_list, |
1261 | transports) { | 1270 | transports) { |
1262 | found = 0; | 1271 | if (!list_has_sctp_addr(&asoc->peer.transport_addr_list, |
1263 | list_for_each_entry(addr, &asoc->peer.transport_addr_list, | 1272 | &new_addr->ipaddr)) { |
1264 | transports) { | 1273 | sctp_sf_send_restart_abort(&new_addr->ipaddr, init, |
1265 | if (sctp_cmp_addr_exact(&new_addr->ipaddr, | 1274 | commands); |
1266 | &addr->ipaddr)) { | 1275 | ret = 0; |
1267 | found = 1; | ||
1268 | break; | ||
1269 | } | ||
1270 | } | ||
1271 | if (!found) | ||
1272 | break; | 1276 | break; |
1273 | } | 1277 | } |
1274 | |||
1275 | /* If a new address was added, ABORT the sender. */ | ||
1276 | if (!found && new_addr) { | ||
1277 | sctp_sf_send_restart_abort(&new_addr->ipaddr, init, commands); | ||
1278 | } | 1278 | } |
1279 | 1279 | ||
1280 | /* Return success if all addresses were found. */ | 1280 | /* Return success if all addresses were found. */ |
1281 | return found; | 1281 | return ret; |
1282 | } | 1282 | } |
1283 | 1283 | ||
1284 | /* Populate the verification/tie tags based on overlapping INIT | 1284 | /* Populate the verification/tie tags based on overlapping INIT |
diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig index 443c161eb8b..3376d765718 100644 --- a/net/sunrpc/Kconfig +++ b/net/sunrpc/Kconfig | |||
@@ -18,10 +18,11 @@ config SUNRPC_XPRT_RDMA | |||
18 | If unsure, say N. | 18 | If unsure, say N. |
19 | 19 | ||
20 | config RPCSEC_GSS_KRB5 | 20 | config RPCSEC_GSS_KRB5 |
21 | tristate "Secure RPC: Kerberos V mechanism (EXPERIMENTAL)" | 21 | tristate |
22 | depends on SUNRPC && EXPERIMENTAL | 22 | depends on SUNRPC && CRYPTO |
23 | prompt "Secure RPC: Kerberos V mechanism" if !(NFS_V4 || NFSD_V4) | ||
24 | default y | ||
23 | select SUNRPC_GSS | 25 | select SUNRPC_GSS |
24 | select CRYPTO | ||
25 | select CRYPTO_MD5 | 26 | select CRYPTO_MD5 |
26 | select CRYPTO_DES | 27 | select CRYPTO_DES |
27 | select CRYPTO_CBC | 28 | select CRYPTO_CBC |
@@ -34,7 +35,7 @@ config RPCSEC_GSS_KRB5 | |||
34 | available from http://linux-nfs.org/. In addition, user-space | 35 | available from http://linux-nfs.org/. In addition, user-space |
35 | Kerberos support should be installed. | 36 | Kerberos support should be installed. |
36 | 37 | ||
37 | If unsure, say N. | 38 | If unsure, say Y. |
38 | 39 | ||
39 | config RPCSEC_GSS_SPKM3 | 40 | config RPCSEC_GSS_SPKM3 |
40 | tristate "Secure RPC: SPKM3 mechanism (EXPERIMENTAL)" | 41 | tristate "Secure RPC: SPKM3 mechanism (EXPERIMENTAL)" |
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index e5e28d1946a..2ac3f6e8adf 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c | |||
@@ -249,6 +249,8 @@ rpcrdma_create_chunks(struct rpc_rqst *rqst, struct xdr_buf *target, | |||
249 | req->rl_nchunks = nchunks; | 249 | req->rl_nchunks = nchunks; |
250 | 250 | ||
251 | BUG_ON(nchunks == 0); | 251 | BUG_ON(nchunks == 0); |
252 | BUG_ON((r_xprt->rx_ia.ri_memreg_strategy == RPCRDMA_FRMR) | ||
253 | && (nchunks > 3)); | ||
252 | 254 | ||
253 | /* | 255 | /* |
254 | * finish off header. If write, marshal discrim and nchunks. | 256 | * finish off header. If write, marshal discrim and nchunks. |
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 27015c6d8eb..5f4c7b3bc71 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c | |||
@@ -650,10 +650,22 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia, | |||
650 | ep->rep_attr.cap.max_send_wr = cdata->max_requests; | 650 | ep->rep_attr.cap.max_send_wr = cdata->max_requests; |
651 | switch (ia->ri_memreg_strategy) { | 651 | switch (ia->ri_memreg_strategy) { |
652 | case RPCRDMA_FRMR: | 652 | case RPCRDMA_FRMR: |
653 | /* Add room for frmr register and invalidate WRs */ | 653 | /* Add room for frmr register and invalidate WRs. |
654 | ep->rep_attr.cap.max_send_wr *= 3; | 654 | * 1. FRMR reg WR for head |
655 | if (ep->rep_attr.cap.max_send_wr > devattr.max_qp_wr) | 655 | * 2. FRMR invalidate WR for head |
656 | return -EINVAL; | 656 | * 3. FRMR reg WR for pagelist |
657 | * 4. FRMR invalidate WR for pagelist | ||
658 | * 5. FRMR reg WR for tail | ||
659 | * 6. FRMR invalidate WR for tail | ||
660 | * 7. The RDMA_SEND WR | ||
661 | */ | ||
662 | ep->rep_attr.cap.max_send_wr *= 7; | ||
663 | if (ep->rep_attr.cap.max_send_wr > devattr.max_qp_wr) { | ||
664 | cdata->max_requests = devattr.max_qp_wr / 7; | ||
665 | if (!cdata->max_requests) | ||
666 | return -EINVAL; | ||
667 | ep->rep_attr.cap.max_send_wr = cdata->max_requests * 7; | ||
668 | } | ||
657 | break; | 669 | break; |
658 | case RPCRDMA_MEMWINDOWS_ASYNC: | 670 | case RPCRDMA_MEMWINDOWS_ASYNC: |
659 | case RPCRDMA_MEMWINDOWS: | 671 | case RPCRDMA_MEMWINDOWS: |
@@ -1490,7 +1502,7 @@ rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg, | |||
1490 | memset(&frmr_wr, 0, sizeof frmr_wr); | 1502 | memset(&frmr_wr, 0, sizeof frmr_wr); |
1491 | frmr_wr.opcode = IB_WR_FAST_REG_MR; | 1503 | frmr_wr.opcode = IB_WR_FAST_REG_MR; |
1492 | frmr_wr.send_flags = 0; /* unsignaled */ | 1504 | frmr_wr.send_flags = 0; /* unsignaled */ |
1493 | frmr_wr.wr.fast_reg.iova_start = (unsigned long)seg1->mr_dma; | 1505 | frmr_wr.wr.fast_reg.iova_start = seg1->mr_dma; |
1494 | frmr_wr.wr.fast_reg.page_list = seg1->mr_chunk.rl_mw->r.frmr.fr_pgl; | 1506 | frmr_wr.wr.fast_reg.page_list = seg1->mr_chunk.rl_mw->r.frmr.fr_pgl; |
1495 | frmr_wr.wr.fast_reg.page_list_len = i; | 1507 | frmr_wr.wr.fast_reg.page_list_len = i; |
1496 | frmr_wr.wr.fast_reg.page_shift = PAGE_SHIFT; | 1508 | frmr_wr.wr.fast_reg.page_shift = PAGE_SHIFT; |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 49a62f0c4b8..b6309db5622 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -1305,10 +1305,11 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1305 | if (!(xprt = xprt_from_sock(sk))) | 1305 | if (!(xprt = xprt_from_sock(sk))) |
1306 | goto out; | 1306 | goto out; |
1307 | dprintk("RPC: xs_tcp_state_change client %p...\n", xprt); | 1307 | dprintk("RPC: xs_tcp_state_change client %p...\n", xprt); |
1308 | dprintk("RPC: state %x conn %d dead %d zapped %d\n", | 1308 | dprintk("RPC: state %x conn %d dead %d zapped %d sk_shutdown %d\n", |
1309 | sk->sk_state, xprt_connected(xprt), | 1309 | sk->sk_state, xprt_connected(xprt), |
1310 | sock_flag(sk, SOCK_DEAD), | 1310 | sock_flag(sk, SOCK_DEAD), |
1311 | sock_flag(sk, SOCK_ZAPPED)); | 1311 | sock_flag(sk, SOCK_ZAPPED), |
1312 | sk->sk_shutdown); | ||
1312 | 1313 | ||
1313 | switch (sk->sk_state) { | 1314 | switch (sk->sk_state) { |
1314 | case TCP_ESTABLISHED: | 1315 | case TCP_ESTABLISHED: |
@@ -1779,10 +1780,25 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt, struct sock_xprt *tra | |||
1779 | { | 1780 | { |
1780 | unsigned int state = transport->inet->sk_state; | 1781 | unsigned int state = transport->inet->sk_state; |
1781 | 1782 | ||
1782 | if (state == TCP_CLOSE && transport->sock->state == SS_UNCONNECTED) | 1783 | if (state == TCP_CLOSE && transport->sock->state == SS_UNCONNECTED) { |
1783 | return; | 1784 | /* we don't need to abort the connection if the socket |
1784 | if ((1 << state) & (TCPF_ESTABLISHED|TCPF_SYN_SENT)) | 1785 | * hasn't undergone a shutdown |
1785 | return; | 1786 | */ |
1787 | if (transport->inet->sk_shutdown == 0) | ||
1788 | return; | ||
1789 | dprintk("RPC: %s: TCP_CLOSEd and sk_shutdown set to %d\n", | ||
1790 | __func__, transport->inet->sk_shutdown); | ||
1791 | } | ||
1792 | if ((1 << state) & (TCPF_ESTABLISHED|TCPF_SYN_SENT)) { | ||
1793 | /* we don't need to abort the connection if the socket | ||
1794 | * hasn't undergone a shutdown | ||
1795 | */ | ||
1796 | if (transport->inet->sk_shutdown == 0) | ||
1797 | return; | ||
1798 | dprintk("RPC: %s: ESTABLISHED/SYN_SENT " | ||
1799 | "sk_shutdown set to %d\n", | ||
1800 | __func__, transport->inet->sk_shutdown); | ||
1801 | } | ||
1786 | xs_abort_connection(xprt, transport); | 1802 | xs_abort_connection(xprt, transport); |
1787 | } | 1803 | } |
1788 | 1804 | ||
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 9077b4ea00c..c586da3f4f1 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -692,6 +692,7 @@ static int unix_autobind(struct socket *sock) | |||
692 | static u32 ordernum = 1; | 692 | static u32 ordernum = 1; |
693 | struct unix_address *addr; | 693 | struct unix_address *addr; |
694 | int err; | 694 | int err; |
695 | unsigned int retries = 0; | ||
695 | 696 | ||
696 | mutex_lock(&u->readlock); | 697 | mutex_lock(&u->readlock); |
697 | 698 | ||
@@ -717,9 +718,17 @@ retry: | |||
717 | if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type, | 718 | if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type, |
718 | addr->hash)) { | 719 | addr->hash)) { |
719 | spin_unlock(&unix_table_lock); | 720 | spin_unlock(&unix_table_lock); |
720 | /* Sanity yield. It is unusual case, but yet... */ | 721 | /* |
721 | if (!(ordernum&0xFF)) | 722 | * __unix_find_socket_byname() may take long time if many names |
722 | yield(); | 723 | * are already in use. |
724 | */ | ||
725 | cond_resched(); | ||
726 | /* Give up if all names seems to be in use. */ | ||
727 | if (retries++ == 0xFFFFF) { | ||
728 | err = -ENOSPC; | ||
729 | kfree(addr); | ||
730 | goto out; | ||
731 | } | ||
723 | goto retry; | 732 | goto retry; |
724 | } | 733 | } |
725 | addr->hash ^= sk->sk_type; | 734 | addr->hash ^= sk->sk_type; |
diff --git a/net/wireless/core.c b/net/wireless/core.c index d52630bbab0..d587ad284b3 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -480,12 +480,10 @@ int wiphy_register(struct wiphy *wiphy) | |||
480 | mutex_lock(&cfg80211_mutex); | 480 | mutex_lock(&cfg80211_mutex); |
481 | 481 | ||
482 | res = device_add(&rdev->wiphy.dev); | 482 | res = device_add(&rdev->wiphy.dev); |
483 | if (res) | 483 | if (res) { |
484 | goto out_unlock; | 484 | mutex_unlock(&cfg80211_mutex); |
485 | 485 | return res; | |
486 | res = rfkill_register(rdev->rfkill); | 486 | } |
487 | if (res) | ||
488 | goto out_rm_dev; | ||
489 | 487 | ||
490 | /* set up regulatory info */ | 488 | /* set up regulatory info */ |
491 | wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); | 489 | wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); |
@@ -514,13 +512,18 @@ int wiphy_register(struct wiphy *wiphy) | |||
514 | cfg80211_debugfs_rdev_add(rdev); | 512 | cfg80211_debugfs_rdev_add(rdev); |
515 | mutex_unlock(&cfg80211_mutex); | 513 | mutex_unlock(&cfg80211_mutex); |
516 | 514 | ||
515 | /* | ||
516 | * due to a locking dependency this has to be outside of the | ||
517 | * cfg80211_mutex lock | ||
518 | */ | ||
519 | res = rfkill_register(rdev->rfkill); | ||
520 | if (res) | ||
521 | goto out_rm_dev; | ||
522 | |||
517 | return 0; | 523 | return 0; |
518 | 524 | ||
519 | out_rm_dev: | 525 | out_rm_dev: |
520 | device_del(&rdev->wiphy.dev); | 526 | device_del(&rdev->wiphy.dev); |
521 | |||
522 | out_unlock: | ||
523 | mutex_unlock(&cfg80211_mutex); | ||
524 | return res; | 527 | return res; |
525 | } | 528 | } |
526 | EXPORT_SYMBOL(wiphy_register); | 529 | EXPORT_SYMBOL(wiphy_register); |
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index bb5e0a5ecfa..7e5c3a45f81 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -1420,6 +1420,9 @@ int cfg80211_wext_giwessid(struct net_device *dev, | |||
1420 | { | 1420 | { |
1421 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 1421 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
1422 | 1422 | ||
1423 | data->flags = 0; | ||
1424 | data->length = 0; | ||
1425 | |||
1423 | switch (wdev->iftype) { | 1426 | switch (wdev->iftype) { |
1424 | case NL80211_IFTYPE_ADHOC: | 1427 | case NL80211_IFTYPE_ADHOC: |
1425 | return cfg80211_ibss_wext_giwessid(dev, info, data, ssid); | 1428 | return cfg80211_ibss_wext_giwessid(dev, info, data, ssid); |
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index 40385936e28..dc675a3daa3 100644 --- a/net/wireless/wext-core.c +++ b/net/wireless/wext-core.c | |||
@@ -782,6 +782,22 @@ static int ioctl_standard_iw_point(struct iw_point *iwp, unsigned int cmd, | |||
782 | } | 782 | } |
783 | } | 783 | } |
784 | 784 | ||
785 | if (IW_IS_GET(cmd) && !(descr->flags & IW_DESCR_FLAG_NOMAX)) { | ||
786 | /* | ||
787 | * If this is a GET, but not NOMAX, it means that the extra | ||
788 | * data is not bounded by userspace, but by max_tokens. Thus | ||
789 | * set the length to max_tokens. This matches the extra data | ||
790 | * allocation. | ||
791 | * The driver should fill it with the number of tokens it | ||
792 | * provided, and it may check iwp->length rather than having | ||
793 | * knowledge of max_tokens. If the driver doesn't change the | ||
794 | * iwp->length, this ioctl just copies back max_token tokens | ||
795 | * filled with zeroes. Hopefully the driver isn't claiming | ||
796 | * them to be valid data. | ||
797 | */ | ||
798 | iwp->length = descr->max_tokens; | ||
799 | } | ||
800 | |||
785 | err = handler(dev, info, (union iwreq_data *) iwp, extra); | 801 | err = handler(dev, info, (union iwreq_data *) iwp, extra); |
786 | 802 | ||
787 | iwp->length += essid_compat; | 803 | iwp->length += essid_compat; |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index b14ed4b1f27..8bae6b22c84 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -1801,7 +1801,7 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1801 | struct xfrm_user_expire *ue = nlmsg_data(nlh); | 1801 | struct xfrm_user_expire *ue = nlmsg_data(nlh); |
1802 | struct xfrm_usersa_info *p = &ue->state; | 1802 | struct xfrm_usersa_info *p = &ue->state; |
1803 | struct xfrm_mark m; | 1803 | struct xfrm_mark m; |
1804 | u32 mark = xfrm_mark_get(attrs, &m);; | 1804 | u32 mark = xfrm_mark_get(attrs, &m); |
1805 | 1805 | ||
1806 | x = xfrm_state_lookup(net, mark, &p->id.daddr, p->id.spi, p->id.proto, p->family); | 1806 | x = xfrm_state_lookup(net, mark, &p->id.daddr, p->id.spi, p->id.proto, p->family); |
1807 | 1807 | ||
diff --git a/samples/kfifo/bytestream-example.c b/samples/kfifo/bytestream-example.c index 642eef3f633..178061e87ff 100644 --- a/samples/kfifo/bytestream-example.c +++ b/samples/kfifo/bytestream-example.c | |||
@@ -44,10 +44,17 @@ static struct kfifo test; | |||
44 | static DECLARE_KFIFO(test, unsigned char, FIFO_SIZE); | 44 | static DECLARE_KFIFO(test, unsigned char, FIFO_SIZE); |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | static const unsigned char expected_result[FIFO_SIZE] = { | ||
48 | 3, 4, 5, 6, 7, 8, 9, 0, | ||
49 | 1, 20, 21, 22, 23, 24, 25, 26, | ||
50 | 27, 28, 29, 30, 31, 32, 33, 34, | ||
51 | 35, 36, 37, 38, 39, 40, 41, 42, | ||
52 | }; | ||
53 | |||
47 | static int __init testfunc(void) | 54 | static int __init testfunc(void) |
48 | { | 55 | { |
49 | unsigned char buf[6]; | 56 | unsigned char buf[6]; |
50 | unsigned char i; | 57 | unsigned char i, j; |
51 | unsigned int ret; | 58 | unsigned int ret; |
52 | 59 | ||
53 | printk(KERN_INFO "byte stream fifo test start\n"); | 60 | printk(KERN_INFO "byte stream fifo test start\n"); |
@@ -73,16 +80,34 @@ static int __init testfunc(void) | |||
73 | ret = kfifo_in(&test, buf, ret); | 80 | ret = kfifo_in(&test, buf, ret); |
74 | printk(KERN_INFO "ret: %d\n", ret); | 81 | printk(KERN_INFO "ret: %d\n", ret); |
75 | 82 | ||
83 | /* skip first element of the fifo */ | ||
84 | printk(KERN_INFO "skip 1st element\n"); | ||
85 | kfifo_skip(&test); | ||
86 | |||
76 | /* put values into the fifo until is full */ | 87 | /* put values into the fifo until is full */ |
77 | for (i = 20; kfifo_put(&test, &i); i++) | 88 | for (i = 20; kfifo_put(&test, &i); i++) |
78 | ; | 89 | ; |
79 | 90 | ||
80 | printk(KERN_INFO "queue len: %u\n", kfifo_len(&test)); | 91 | printk(KERN_INFO "queue len: %u\n", kfifo_len(&test)); |
81 | 92 | ||
82 | /* print out all values in the fifo */ | 93 | /* show the first value without removing from the fifo */ |
83 | while (kfifo_get(&test, &i)) | 94 | if (kfifo_peek(&test, &i)) |
84 | printk("%d ", i); | 95 | printk(KERN_INFO "%d\n", i); |
85 | printk("\n"); | 96 | |
97 | /* check the correctness of all values in the fifo */ | ||
98 | j = 0; | ||
99 | while (kfifo_get(&test, &i)) { | ||
100 | printk(KERN_INFO "item = %d\n", i); | ||
101 | if (i != expected_result[j++]) { | ||
102 | printk(KERN_WARNING "value mismatch: test failed\n"); | ||
103 | return -EIO; | ||
104 | } | ||
105 | } | ||
106 | if (j != ARRAY_SIZE(expected_result)) { | ||
107 | printk(KERN_WARNING "size mismatch: test failed\n"); | ||
108 | return -EIO; | ||
109 | } | ||
110 | printk(KERN_INFO "test passed\n"); | ||
86 | 111 | ||
87 | return 0; | 112 | return 0; |
88 | } | 113 | } |
@@ -138,7 +163,12 @@ static int __init example_init(void) | |||
138 | #else | 163 | #else |
139 | INIT_KFIFO(test); | 164 | INIT_KFIFO(test); |
140 | #endif | 165 | #endif |
141 | testfunc(); | 166 | if (testfunc() < 0) { |
167 | #ifdef DYNAMIC | ||
168 | kfifo_free(&test); | ||
169 | #endif | ||
170 | return -EIO; | ||
171 | } | ||
142 | 172 | ||
143 | if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) { | 173 | if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) { |
144 | #ifdef DYNAMIC | 174 | #ifdef DYNAMIC |
diff --git a/samples/kfifo/dma-example.c b/samples/kfifo/dma-example.c index b9482c28b41..ee03a4f0b64 100644 --- a/samples/kfifo/dma-example.c +++ b/samples/kfifo/dma-example.c | |||
@@ -29,8 +29,8 @@ static int __init example_init(void) | |||
29 | printk(KERN_INFO "DMA fifo test start\n"); | 29 | printk(KERN_INFO "DMA fifo test start\n"); |
30 | 30 | ||
31 | if (kfifo_alloc(&fifo, FIFO_SIZE, GFP_KERNEL)) { | 31 | if (kfifo_alloc(&fifo, FIFO_SIZE, GFP_KERNEL)) { |
32 | printk(KERN_ERR "error kfifo_alloc\n"); | 32 | printk(KERN_WARNING "error kfifo_alloc\n"); |
33 | return 1; | 33 | return -ENOMEM; |
34 | } | 34 | } |
35 | 35 | ||
36 | printk(KERN_INFO "queue size: %u\n", kfifo_size(&fifo)); | 36 | printk(KERN_INFO "queue size: %u\n", kfifo_size(&fifo)); |
@@ -41,72 +41,99 @@ static int __init example_init(void) | |||
41 | kfifo_put(&fifo, &i); | 41 | kfifo_put(&fifo, &i); |
42 | 42 | ||
43 | /* kick away first byte */ | 43 | /* kick away first byte */ |
44 | ret = kfifo_get(&fifo, &i); | 44 | kfifo_skip(&fifo); |
45 | 45 | ||
46 | printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo)); | 46 | printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo)); |
47 | 47 | ||
48 | /* | ||
49 | * Configure the kfifo buffer to receive data from DMA input. | ||
50 | * | ||
51 | * .--------------------------------------. | ||
52 | * | 0 | 1 | 2 | ... | 12 | 13 | ... | 31 | | ||
53 | * |---|------------------|---------------| | ||
54 | * \_/ \________________/ \_____________/ | ||
55 | * \ \ \ | ||
56 | * \ \_allocated data \ | ||
57 | * \_*free space* \_*free space* | ||
58 | * | ||
59 | * We need two different SG entries: one for the free space area at the | ||
60 | * end of the kfifo buffer (19 bytes) and another for the first free | ||
61 | * byte at the beginning, after the kfifo_skip(). | ||
62 | */ | ||
63 | sg_init_table(sg, ARRAY_SIZE(sg)); | ||
48 | ret = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE); | 64 | ret = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE); |
49 | printk(KERN_INFO "DMA sgl entries: %d\n", ret); | 65 | printk(KERN_INFO "DMA sgl entries: %d\n", ret); |
66 | if (!ret) { | ||
67 | /* fifo is full and no sgl was created */ | ||
68 | printk(KERN_WARNING "error kfifo_dma_in_prepare\n"); | ||
69 | return -EIO; | ||
70 | } | ||
50 | 71 | ||
51 | /* if 0 was returned, fifo is full and no sgl was created */ | 72 | /* receive data */ |
52 | if (ret) { | 73 | printk(KERN_INFO "scatterlist for receive:\n"); |
53 | printk(KERN_INFO "scatterlist for receive:\n"); | 74 | for (i = 0; i < ARRAY_SIZE(sg); i++) { |
54 | for (i = 0; i < ARRAY_SIZE(sg); i++) { | 75 | printk(KERN_INFO |
55 | printk(KERN_INFO | 76 | "sg[%d] -> " |
56 | "sg[%d] -> " | 77 | "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", |
57 | "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", | 78 | i, sg[i].page_link, sg[i].offset, sg[i].length); |
58 | i, sg[i].page_link, sg[i].offset, sg[i].length); | ||
59 | 79 | ||
60 | if (sg_is_last(&sg[i])) | 80 | if (sg_is_last(&sg[i])) |
61 | break; | 81 | break; |
62 | } | 82 | } |
63 | 83 | ||
64 | /* but here your code to setup and exectute the dma operation */ | 84 | /* put here your code to setup and exectute the dma operation */ |
65 | /* ... */ | 85 | /* ... */ |
66 | 86 | ||
67 | /* example: zero bytes received */ | 87 | /* example: zero bytes received */ |
68 | ret = 0; | 88 | ret = 0; |
69 | 89 | ||
70 | /* finish the dma operation and update the received data */ | 90 | /* finish the dma operation and update the received data */ |
71 | kfifo_dma_in_finish(&fifo, ret); | 91 | kfifo_dma_in_finish(&fifo, ret); |
72 | } | ||
73 | 92 | ||
93 | /* Prepare to transmit data, example: 8 bytes */ | ||
74 | ret = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8); | 94 | ret = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8); |
75 | printk(KERN_INFO "DMA sgl entries: %d\n", ret); | 95 | printk(KERN_INFO "DMA sgl entries: %d\n", ret); |
96 | if (!ret) { | ||
97 | /* no data was available and no sgl was created */ | ||
98 | printk(KERN_WARNING "error kfifo_dma_out_prepare\n"); | ||
99 | return -EIO; | ||
100 | } | ||
76 | 101 | ||
77 | /* if 0 was returned, no data was available and no sgl was created */ | 102 | printk(KERN_INFO "scatterlist for transmit:\n"); |
78 | if (ret) { | 103 | for (i = 0; i < ARRAY_SIZE(sg); i++) { |
79 | printk(KERN_INFO "scatterlist for transmit:\n"); | 104 | printk(KERN_INFO |
80 | for (i = 0; i < ARRAY_SIZE(sg); i++) { | 105 | "sg[%d] -> " |
81 | printk(KERN_INFO | 106 | "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", |
82 | "sg[%d] -> " | 107 | i, sg[i].page_link, sg[i].offset, sg[i].length); |
83 | "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", | ||
84 | i, sg[i].page_link, sg[i].offset, sg[i].length); | ||
85 | 108 | ||
86 | if (sg_is_last(&sg[i])) | 109 | if (sg_is_last(&sg[i])) |
87 | break; | 110 | break; |
88 | } | 111 | } |
89 | 112 | ||
90 | /* but here your code to setup and exectute the dma operation */ | 113 | /* put here your code to setup and exectute the dma operation */ |
91 | /* ... */ | 114 | /* ... */ |
92 | 115 | ||
93 | /* example: 5 bytes transmitted */ | 116 | /* example: 5 bytes transmitted */ |
94 | ret = 5; | 117 | ret = 5; |
95 | 118 | ||
96 | /* finish the dma operation and update the transmitted data */ | 119 | /* finish the dma operation and update the transmitted data */ |
97 | kfifo_dma_out_finish(&fifo, ret); | 120 | kfifo_dma_out_finish(&fifo, ret); |
98 | } | ||
99 | 121 | ||
122 | ret = kfifo_len(&fifo); | ||
100 | printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo)); | 123 | printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo)); |
101 | 124 | ||
125 | if (ret != 7) { | ||
126 | printk(KERN_WARNING "size mismatch: test failed"); | ||
127 | return -EIO; | ||
128 | } | ||
129 | printk(KERN_INFO "test passed\n"); | ||
130 | |||
102 | return 0; | 131 | return 0; |
103 | } | 132 | } |
104 | 133 | ||
105 | static void __exit example_exit(void) | 134 | static void __exit example_exit(void) |
106 | { | 135 | { |
107 | #ifdef DYNAMIC | 136 | kfifo_free(&fifo); |
108 | kfifo_free(&test); | ||
109 | #endif | ||
110 | } | 137 | } |
111 | 138 | ||
112 | module_init(example_init); | 139 | module_init(example_init); |
diff --git a/samples/kfifo/inttype-example.c b/samples/kfifo/inttype-example.c index d6c5b7d9df6..71b2aabca96 100644 --- a/samples/kfifo/inttype-example.c +++ b/samples/kfifo/inttype-example.c | |||
@@ -44,10 +44,17 @@ static DECLARE_KFIFO_PTR(test, int); | |||
44 | static DEFINE_KFIFO(test, int, FIFO_SIZE); | 44 | static DEFINE_KFIFO(test, int, FIFO_SIZE); |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | static const int expected_result[FIFO_SIZE] = { | ||
48 | 3, 4, 5, 6, 7, 8, 9, 0, | ||
49 | 1, 20, 21, 22, 23, 24, 25, 26, | ||
50 | 27, 28, 29, 30, 31, 32, 33, 34, | ||
51 | 35, 36, 37, 38, 39, 40, 41, 42, | ||
52 | }; | ||
53 | |||
47 | static int __init testfunc(void) | 54 | static int __init testfunc(void) |
48 | { | 55 | { |
49 | int buf[6]; | 56 | int buf[6]; |
50 | int i; | 57 | int i, j; |
51 | unsigned int ret; | 58 | unsigned int ret; |
52 | 59 | ||
53 | printk(KERN_INFO "int fifo test start\n"); | 60 | printk(KERN_INFO "int fifo test start\n"); |
@@ -66,8 +73,13 @@ static int __init testfunc(void) | |||
66 | ret = kfifo_in(&test, buf, ret); | 73 | ret = kfifo_in(&test, buf, ret); |
67 | printk(KERN_INFO "ret: %d\n", ret); | 74 | printk(KERN_INFO "ret: %d\n", ret); |
68 | 75 | ||
69 | for (i = 20; i != 30; i++) | 76 | /* skip first element of the fifo */ |
70 | kfifo_put(&test, &i); | 77 | printk(KERN_INFO "skip 1st element\n"); |
78 | kfifo_skip(&test); | ||
79 | |||
80 | /* put values into the fifo until is full */ | ||
81 | for (i = 20; kfifo_put(&test, &i); i++) | ||
82 | ; | ||
71 | 83 | ||
72 | printk(KERN_INFO "queue len: %u\n", kfifo_len(&test)); | 84 | printk(KERN_INFO "queue len: %u\n", kfifo_len(&test)); |
73 | 85 | ||
@@ -75,10 +87,20 @@ static int __init testfunc(void) | |||
75 | if (kfifo_peek(&test, &i)) | 87 | if (kfifo_peek(&test, &i)) |
76 | printk(KERN_INFO "%d\n", i); | 88 | printk(KERN_INFO "%d\n", i); |
77 | 89 | ||
78 | /* print out all values in the fifo */ | 90 | /* check the correctness of all values in the fifo */ |
79 | while (kfifo_get(&test, &i)) | 91 | j = 0; |
80 | printk("%d ", i); | 92 | while (kfifo_get(&test, &i)) { |
81 | printk("\n"); | 93 | printk(KERN_INFO "item = %d\n", i); |
94 | if (i != expected_result[j++]) { | ||
95 | printk(KERN_WARNING "value mismatch: test failed\n"); | ||
96 | return -EIO; | ||
97 | } | ||
98 | } | ||
99 | if (j != ARRAY_SIZE(expected_result)) { | ||
100 | printk(KERN_WARNING "size mismatch: test failed\n"); | ||
101 | return -EIO; | ||
102 | } | ||
103 | printk(KERN_INFO "test passed\n"); | ||
82 | 104 | ||
83 | return 0; | 105 | return 0; |
84 | } | 106 | } |
@@ -132,7 +154,12 @@ static int __init example_init(void) | |||
132 | return ret; | 154 | return ret; |
133 | } | 155 | } |
134 | #endif | 156 | #endif |
135 | testfunc(); | 157 | if (testfunc() < 0) { |
158 | #ifdef DYNAMIC | ||
159 | kfifo_free(&test); | ||
160 | #endif | ||
161 | return -EIO; | ||
162 | } | ||
136 | 163 | ||
137 | if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) { | 164 | if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) { |
138 | #ifdef DYNAMIC | 165 | #ifdef DYNAMIC |
diff --git a/samples/kfifo/record-example.c b/samples/kfifo/record-example.c index 32c6e0bda74..e68bd16a5da 100644 --- a/samples/kfifo/record-example.c +++ b/samples/kfifo/record-example.c | |||
@@ -55,6 +55,19 @@ typedef STRUCT_KFIFO_REC_1(FIFO_SIZE) mytest; | |||
55 | static mytest test; | 55 | static mytest test; |
56 | #endif | 56 | #endif |
57 | 57 | ||
58 | static const char *expected_result[] = { | ||
59 | "a", | ||
60 | "bb", | ||
61 | "ccc", | ||
62 | "dddd", | ||
63 | "eeeee", | ||
64 | "ffffff", | ||
65 | "ggggggg", | ||
66 | "hhhhhhhh", | ||
67 | "iiiiiiiii", | ||
68 | "jjjjjjjjjj", | ||
69 | }; | ||
70 | |||
58 | static int __init testfunc(void) | 71 | static int __init testfunc(void) |
59 | { | 72 | { |
60 | char buf[100]; | 73 | char buf[100]; |
@@ -75,6 +88,10 @@ static int __init testfunc(void) | |||
75 | kfifo_in(&test, buf, i + 1); | 88 | kfifo_in(&test, buf, i + 1); |
76 | } | 89 | } |
77 | 90 | ||
91 | /* skip first element of the fifo */ | ||
92 | printk(KERN_INFO "skip 1st element\n"); | ||
93 | kfifo_skip(&test); | ||
94 | |||
78 | printk(KERN_INFO "fifo len: %u\n", kfifo_len(&test)); | 95 | printk(KERN_INFO "fifo len: %u\n", kfifo_len(&test)); |
79 | 96 | ||
80 | /* show the first record without removing from the fifo */ | 97 | /* show the first record without removing from the fifo */ |
@@ -82,11 +99,22 @@ static int __init testfunc(void) | |||
82 | if (ret) | 99 | if (ret) |
83 | printk(KERN_INFO "%.*s\n", ret, buf); | 100 | printk(KERN_INFO "%.*s\n", ret, buf); |
84 | 101 | ||
85 | /* print out all records in the fifo */ | 102 | /* check the correctness of all values in the fifo */ |
103 | i = 0; | ||
86 | while (!kfifo_is_empty(&test)) { | 104 | while (!kfifo_is_empty(&test)) { |
87 | ret = kfifo_out(&test, buf, sizeof(buf)); | 105 | ret = kfifo_out(&test, buf, sizeof(buf)); |
88 | printk(KERN_INFO "%.*s\n", ret, buf); | 106 | buf[ret] = '\0'; |
107 | printk(KERN_INFO "item = %.*s\n", ret, buf); | ||
108 | if (strcmp(buf, expected_result[i++])) { | ||
109 | printk(KERN_WARNING "value mismatch: test failed\n"); | ||
110 | return -EIO; | ||
111 | } | ||
112 | } | ||
113 | if (i != ARRAY_SIZE(expected_result)) { | ||
114 | printk(KERN_WARNING "size mismatch: test failed\n"); | ||
115 | return -EIO; | ||
89 | } | 116 | } |
117 | printk(KERN_INFO "test passed\n"); | ||
90 | 118 | ||
91 | return 0; | 119 | return 0; |
92 | } | 120 | } |
@@ -142,7 +170,12 @@ static int __init example_init(void) | |||
142 | #else | 170 | #else |
143 | INIT_KFIFO(test); | 171 | INIT_KFIFO(test); |
144 | #endif | 172 | #endif |
145 | testfunc(); | 173 | if (testfunc() < 0) { |
174 | #ifdef DYNAMIC | ||
175 | kfifo_free(&test); | ||
176 | #endif | ||
177 | return -EIO; | ||
178 | } | ||
146 | 179 | ||
147 | if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) { | 180 | if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) { |
148 | #ifdef DYNAMIC | 181 | #ifdef DYNAMIC |
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index c39327e60ea..515253fe46c 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c | |||
@@ -497,7 +497,9 @@ int conf_write_defconfig(const char *filename) | |||
497 | /* | 497 | /* |
498 | * If symbol is a choice value and equals to the | 498 | * If symbol is a choice value and equals to the |
499 | * default for a choice - skip. | 499 | * default for a choice - skip. |
500 | * But only if value is bool and equal to "y" . | 500 | * But only if value is bool and equal to "y" and |
501 | * choice is not "optional". | ||
502 | * (If choice is "optional" then all values can be "n") | ||
501 | */ | 503 | */ |
502 | if (sym_is_choice_value(sym)) { | 504 | if (sym_is_choice_value(sym)) { |
503 | struct symbol *cs; | 505 | struct symbol *cs; |
@@ -505,7 +507,7 @@ int conf_write_defconfig(const char *filename) | |||
505 | 507 | ||
506 | cs = prop_get_symbol(sym_get_choice_prop(sym)); | 508 | cs = prop_get_symbol(sym_get_choice_prop(sym)); |
507 | ds = sym_choice_default(cs); | 509 | ds = sym_choice_default(cs); |
508 | if (sym == ds) { | 510 | if (!sym_is_optional(cs) && sym == ds) { |
509 | if ((sym->type == S_BOOLEAN) && | 511 | if ((sym->type == S_BOOLEAN) && |
510 | sym_get_tristate_value(sym) == yes) | 512 | sym_get_tristate_value(sym) == yes) |
511 | goto next_menu; | 513 | goto next_menu; |
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index e95718fea35..943712ca6c0 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c | |||
@@ -937,6 +937,8 @@ static void sym_check_print_recursive(struct symbol *last_sym) | |||
937 | sym = stack->sym; | 937 | sym = stack->sym; |
938 | next_sym = stack->next ? stack->next->sym : last_sym; | 938 | next_sym = stack->next ? stack->next->sym : last_sym; |
939 | prop = stack->prop; | 939 | prop = stack->prop; |
940 | if (prop == NULL) | ||
941 | prop = stack->sym->prop; | ||
940 | 942 | ||
941 | /* for choice values find the menu entry (used below) */ | 943 | /* for choice values find the menu entry (used below) */ |
942 | if (sym_is_choice(sym) || sym_is_choice_value(sym)) { | 944 | if (sym_is_choice(sym) || sym_is_choice_value(sym)) { |
diff --git a/scripts/mkmakefile b/scripts/mkmakefile index 67d59c7a18d..5325423ceab 100644 --- a/scripts/mkmakefile +++ b/scripts/mkmakefile | |||
@@ -44,7 +44,9 @@ all: | |||
44 | 44 | ||
45 | Makefile:; | 45 | Makefile:; |
46 | 46 | ||
47 | \$(all) %/: all | 47 | \$(all): all |
48 | @: | 48 | @: |
49 | 49 | ||
50 | %/: all | ||
51 | @: | ||
50 | EOF | 52 | EOF |
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 0171060b5fd..e67f0548608 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl | |||
@@ -159,6 +159,7 @@ my $section_regex; # Find the start of a section | |||
159 | my $function_regex; # Find the name of a function | 159 | my $function_regex; # Find the name of a function |
160 | # (return offset and func name) | 160 | # (return offset and func name) |
161 | my $mcount_regex; # Find the call site to mcount (return offset) | 161 | my $mcount_regex; # Find the call site to mcount (return offset) |
162 | my $mcount_adjust; # Address adjustment to mcount offset | ||
162 | my $alignment; # The .align value to use for $mcount_section | 163 | my $alignment; # The .align value to use for $mcount_section |
163 | my $section_type; # Section header plus possible alignment command | 164 | my $section_type; # Section header plus possible alignment command |
164 | my $can_use_local = 0; # If we can use local function references | 165 | my $can_use_local = 0; # If we can use local function references |
@@ -213,6 +214,7 @@ $section_regex = "Disassembly of section\\s+(\\S+):"; | |||
213 | $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:"; | 214 | $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:"; |
214 | $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$"; | 215 | $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$"; |
215 | $section_type = '@progbits'; | 216 | $section_type = '@progbits'; |
217 | $mcount_adjust = 0; | ||
216 | $type = ".long"; | 218 | $type = ".long"; |
217 | 219 | ||
218 | if ($arch eq "x86_64") { | 220 | if ($arch eq "x86_64") { |
@@ -351,6 +353,9 @@ if ($arch eq "x86_64") { | |||
351 | } elsif ($arch eq "microblaze") { | 353 | } elsif ($arch eq "microblaze") { |
352 | # Microblaze calls '_mcount' instead of plain 'mcount'. | 354 | # Microblaze calls '_mcount' instead of plain 'mcount'. |
353 | $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; | 355 | $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; |
356 | } elsif ($arch eq "blackfin") { | ||
357 | $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s__mcount\$"; | ||
358 | $mcount_adjust = -4; | ||
354 | } else { | 359 | } else { |
355 | die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; | 360 | die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; |
356 | } | 361 | } |
@@ -511,7 +516,7 @@ while (<IN>) { | |||
511 | } | 516 | } |
512 | # is this a call site to mcount? If so, record it to print later | 517 | # is this a call site to mcount? If so, record it to print later |
513 | if ($text_found && /$mcount_regex/) { | 518 | if ($text_found && /$mcount_regex/) { |
514 | push(@offsets, hex $1); | 519 | push(@offsets, (hex $1) + $mcount_adjust); |
515 | } | 520 | } |
516 | } | 521 | } |
517 | 522 | ||
diff --git a/scripts/setlocalversion b/scripts/setlocalversion index e90a91cc518..057b6b3c5df 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion | |||
@@ -43,7 +43,7 @@ scm_version() | |||
43 | fi | 43 | fi |
44 | 44 | ||
45 | # Check for git and a git repo. | 45 | # Check for git and a git repo. |
46 | if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then | 46 | if test -d .git && head=`git rev-parse --verify --short HEAD 2>/dev/null`; then |
47 | 47 | ||
48 | # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore | 48 | # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore |
49 | # it, because this version is defined in the top level Makefile. | 49 | # it, because this version is defined in the top level Makefile. |
@@ -85,7 +85,7 @@ scm_version() | |||
85 | fi | 85 | fi |
86 | 86 | ||
87 | # Check for mercurial and a mercurial repo. | 87 | # Check for mercurial and a mercurial repo. |
88 | if hgid=`hg id 2>/dev/null`; then | 88 | if test -d .hg && hgid=`hg id 2>/dev/null`; then |
89 | tag=`printf '%s' "$hgid" | cut -s -d' ' -f2` | 89 | tag=`printf '%s' "$hgid" | cut -s -d' ' -f2` |
90 | 90 | ||
91 | # Do we have an untagged version? | 91 | # Do we have an untagged version? |
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index d5666d3cc21..f73e2c20421 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
@@ -607,8 +607,8 @@ static int apparmor_setprocattr(struct task_struct *task, char *name, | |||
607 | return error; | 607 | return error; |
608 | } | 608 | } |
609 | 609 | ||
610 | static int apparmor_task_setrlimit(unsigned int resource, | 610 | static int apparmor_task_setrlimit(struct task_struct *task, |
611 | struct rlimit *new_rlim) | 611 | unsigned int resource, struct rlimit *new_rlim) |
612 | { | 612 | { |
613 | struct aa_profile *profile = aa_current_profile(); | 613 | struct aa_profile *profile = aa_current_profile(); |
614 | int error = 0; | 614 | int error = 0; |
diff --git a/security/apparmor/path.c b/security/apparmor/path.c index 96bab9469d4..19358dc1460 100644 --- a/security/apparmor/path.c +++ b/security/apparmor/path.c | |||
@@ -62,19 +62,14 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, | |||
62 | int deleted, connected; | 62 | int deleted, connected; |
63 | int error = 0; | 63 | int error = 0; |
64 | 64 | ||
65 | /* Get the root we want to resolve too */ | 65 | /* Get the root we want to resolve too, released below */ |
66 | if (flags & PATH_CHROOT_REL) { | 66 | if (flags & PATH_CHROOT_REL) { |
67 | /* resolve paths relative to chroot */ | 67 | /* resolve paths relative to chroot */ |
68 | read_lock(¤t->fs->lock); | 68 | get_fs_root(current->fs, &root); |
69 | root = current->fs->root; | ||
70 | /* released below */ | ||
71 | path_get(&root); | ||
72 | read_unlock(¤t->fs->lock); | ||
73 | } else { | 69 | } else { |
74 | /* resolve paths relative to namespace */ | 70 | /* resolve paths relative to namespace */ |
75 | root.mnt = current->nsproxy->mnt_ns->root; | 71 | root.mnt = current->nsproxy->mnt_ns->root; |
76 | root.dentry = root.mnt->mnt_root; | 72 | root.dentry = root.mnt->mnt_root; |
77 | /* released below */ | ||
78 | path_get(&root); | 73 | path_get(&root); |
79 | } | 74 | } |
80 | 75 | ||
diff --git a/security/commoncap.c b/security/commoncap.c index 4e015996dd4..9d172e6e330 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
@@ -40,7 +40,7 @@ | |||
40 | * | 40 | * |
41 | * Warn if that happens, once per boot. | 41 | * Warn if that happens, once per boot. |
42 | */ | 42 | */ |
43 | static void warn_setuid_and_fcaps_mixed(char *fname) | 43 | static void warn_setuid_and_fcaps_mixed(const char *fname) |
44 | { | 44 | { |
45 | static int warned; | 45 | static int warned; |
46 | if (!warned) { | 46 | if (!warned) { |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 42043f96e54..4796ddd4e72 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -2170,8 +2170,9 @@ static inline void flush_unauthorized_files(const struct cred *cred, | |||
2170 | 2170 | ||
2171 | tty = get_current_tty(); | 2171 | tty = get_current_tty(); |
2172 | if (tty) { | 2172 | if (tty) { |
2173 | file_list_lock(); | 2173 | spin_lock(&tty_files_lock); |
2174 | if (!list_empty(&tty->tty_files)) { | 2174 | if (!list_empty(&tty->tty_files)) { |
2175 | struct tty_file_private *file_priv; | ||
2175 | struct inode *inode; | 2176 | struct inode *inode; |
2176 | 2177 | ||
2177 | /* Revalidate access to controlling tty. | 2178 | /* Revalidate access to controlling tty. |
@@ -2179,14 +2180,16 @@ static inline void flush_unauthorized_files(const struct cred *cred, | |||
2179 | than using file_has_perm, as this particular open | 2180 | than using file_has_perm, as this particular open |
2180 | file may belong to another process and we are only | 2181 | file may belong to another process and we are only |
2181 | interested in the inode-based check here. */ | 2182 | interested in the inode-based check here. */ |
2182 | file = list_first_entry(&tty->tty_files, struct file, f_u.fu_list); | 2183 | file_priv = list_first_entry(&tty->tty_files, |
2184 | struct tty_file_private, list); | ||
2185 | file = file_priv->file; | ||
2183 | inode = file->f_path.dentry->d_inode; | 2186 | inode = file->f_path.dentry->d_inode; |
2184 | if (inode_has_perm(cred, inode, | 2187 | if (inode_has_perm(cred, inode, |
2185 | FILE__READ | FILE__WRITE, NULL)) { | 2188 | FILE__READ | FILE__WRITE, NULL)) { |
2186 | drop_tty = 1; | 2189 | drop_tty = 1; |
2187 | } | 2190 | } |
2188 | } | 2191 | } |
2189 | file_list_unlock(); | 2192 | spin_unlock(&tty_files_lock); |
2190 | tty_kref_put(tty); | 2193 | tty_kref_put(tty); |
2191 | } | 2194 | } |
2192 | /* Reset controlling tty. */ | 2195 | /* Reset controlling tty. */ |
diff --git a/sound/core/pcm.c b/sound/core/pcm.c index cbe815dfbdc..204af48c5cc 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c | |||
@@ -203,10 +203,16 @@ static char *snd_pcm_format_names[] = { | |||
203 | FORMAT(S18_3BE), | 203 | FORMAT(S18_3BE), |
204 | FORMAT(U18_3LE), | 204 | FORMAT(U18_3LE), |
205 | FORMAT(U18_3BE), | 205 | FORMAT(U18_3BE), |
206 | FORMAT(G723_24), | ||
207 | FORMAT(G723_24_1B), | ||
208 | FORMAT(G723_40), | ||
209 | FORMAT(G723_40_1B), | ||
206 | }; | 210 | }; |
207 | 211 | ||
208 | const char *snd_pcm_format_name(snd_pcm_format_t format) | 212 | const char *snd_pcm_format_name(snd_pcm_format_t format) |
209 | { | 213 | { |
214 | if (format >= ARRAY_SIZE(snd_pcm_format_names)) | ||
215 | return "Unknown"; | ||
210 | return snd_pcm_format_names[format]; | 216 | return snd_pcm_format_names[format]; |
211 | } | 217 | } |
212 | EXPORT_SYMBOL_GPL(snd_pcm_format_name); | 218 | EXPORT_SYMBOL_GPL(snd_pcm_format_name); |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index a3b2a647924..134fc6c2e08 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -978,6 +978,10 @@ static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push) | |||
978 | { | 978 | { |
979 | if (substream->runtime->trigger_master != substream) | 979 | if (substream->runtime->trigger_master != substream) |
980 | return 0; | 980 | return 0; |
981 | /* some drivers might use hw_ptr to recover from the pause - | ||
982 | update the hw_ptr now */ | ||
983 | if (push) | ||
984 | snd_pcm_update_hw_ptr(substream); | ||
981 | /* The jiffies check in snd_pcm_update_hw_ptr*() is done by | 985 | /* The jiffies check in snd_pcm_update_hw_ptr*() is done by |
982 | * a delta betwen the current jiffies, this gives a large enough | 986 | * a delta betwen the current jiffies, this gives a large enough |
983 | * delta, effectively to skip the check once. | 987 | * delta, effectively to skip the check once. |
diff --git a/sound/oss/sound_timer.c b/sound/oss/sound_timer.c index f0f0c19fbff..48cda6c4c25 100644 --- a/sound/oss/sound_timer.c +++ b/sound/oss/sound_timer.c | |||
@@ -26,7 +26,7 @@ static unsigned long prev_event_time; | |||
26 | static volatile unsigned long usecs_per_tmr; /* Length of the current interval */ | 26 | static volatile unsigned long usecs_per_tmr; /* Length of the current interval */ |
27 | 27 | ||
28 | static struct sound_lowlev_timer *tmr; | 28 | static struct sound_lowlev_timer *tmr; |
29 | static spinlock_t lock; | 29 | static DEFINE_SPINLOCK(lock); |
30 | 30 | ||
31 | static unsigned long tmr2ticks(int tmr_value) | 31 | static unsigned long tmr2ticks(int tmr_value) |
32 | { | 32 | { |
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index 3b441344822..22c5fc62553 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c | |||
@@ -941,8 +941,7 @@ static void outstream_host_buffer_free(struct hpi_adapter_obj *pao, | |||
941 | 941 | ||
942 | } | 942 | } |
943 | 943 | ||
944 | static u32 outstream_get_space_available(struct hpi_hostbuffer_status | 944 | static u32 outstream_get_space_available(struct hpi_hostbuffer_status *status) |
945 | *status) | ||
946 | { | 945 | { |
947 | return status->size_in_bytes - (status->host_index - | 946 | return status->size_in_bytes - (status->host_index - |
948 | status->dSP_index); | 947 | status->dSP_index); |
@@ -987,6 +986,10 @@ static void outstream_write(struct hpi_adapter_obj *pao, | |||
987 | /* write it */ | 986 | /* write it */ |
988 | phm->function = HPI_OSTREAM_WRITE; | 987 | phm->function = HPI_OSTREAM_WRITE; |
989 | hw_message(pao, phm, phr); | 988 | hw_message(pao, phm, phr); |
989 | |||
990 | if (phr->error) | ||
991 | return; | ||
992 | |||
990 | /* update status information that the DSP would typically | 993 | /* update status information that the DSP would typically |
991 | * update (and will update next time the DSP | 994 | * update (and will update next time the DSP |
992 | * buffer update task reads data from the host BBM buffer) | 995 | * buffer update task reads data from the host BBM buffer) |
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c index 4203782d7cb..aff8387c45c 100644 --- a/sound/pci/emu10k1/emu10k1.c +++ b/sound/pci/emu10k1/emu10k1.c | |||
@@ -52,6 +52,7 @@ static int max_synth_voices[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 64}; | |||
52 | static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128}; | 52 | static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128}; |
53 | static int enable_ir[SNDRV_CARDS]; | 53 | static int enable_ir[SNDRV_CARDS]; |
54 | static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */ | 54 | static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */ |
55 | static uint delay_pcm_irq[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; | ||
55 | 56 | ||
56 | module_param_array(index, int, NULL, 0444); | 57 | module_param_array(index, int, NULL, 0444); |
57 | MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard."); | 58 | MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard."); |
@@ -73,6 +74,8 @@ module_param_array(enable_ir, bool, NULL, 0444); | |||
73 | MODULE_PARM_DESC(enable_ir, "Enable IR."); | 74 | MODULE_PARM_DESC(enable_ir, "Enable IR."); |
74 | module_param_array(subsystem, uint, NULL, 0444); | 75 | module_param_array(subsystem, uint, NULL, 0444); |
75 | MODULE_PARM_DESC(subsystem, "Force card subsystem model."); | 76 | MODULE_PARM_DESC(subsystem, "Force card subsystem model."); |
77 | module_param_array(delay_pcm_irq, uint, NULL, 0444); | ||
78 | MODULE_PARM_DESC(delay_pcm_irq, "Delay PCM interrupt by specified number of samples (default 0)."); | ||
76 | /* | 79 | /* |
77 | * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400 | 80 | * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400 |
78 | */ | 81 | */ |
@@ -127,6 +130,7 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci, | |||
127 | &emu)) < 0) | 130 | &emu)) < 0) |
128 | goto error; | 131 | goto error; |
129 | card->private_data = emu; | 132 | card->private_data = emu; |
133 | emu->delay_pcm_irq = delay_pcm_irq[dev] & 0x1f; | ||
130 | if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0) | 134 | if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0) |
131 | goto error; | 135 | goto error; |
132 | if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0) | 136 | if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0) |
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index 55b83ef73c6..622bace148e 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c | |||
@@ -332,7 +332,7 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu, | |||
332 | evoice->epcm->ccca_start_addr = start_addr + ccis; | 332 | evoice->epcm->ccca_start_addr = start_addr + ccis; |
333 | if (extra) { | 333 | if (extra) { |
334 | start_addr += ccis; | 334 | start_addr += ccis; |
335 | end_addr += ccis; | 335 | end_addr += ccis + emu->delay_pcm_irq; |
336 | } | 336 | } |
337 | if (stereo && !extra) { | 337 | if (stereo && !extra) { |
338 | snd_emu10k1_ptr_write(emu, CPF, voice, CPF_STEREO_MASK); | 338 | snd_emu10k1_ptr_write(emu, CPF, voice, CPF_STEREO_MASK); |
@@ -360,7 +360,9 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu, | |||
360 | /* Assumption that PT is already 0 so no harm overwriting */ | 360 | /* Assumption that PT is already 0 so no harm overwriting */ |
361 | snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]); | 361 | snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]); |
362 | snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24)); | 362 | snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24)); |
363 | snd_emu10k1_ptr_write(emu, PSST, voice, start_addr | (send_amount[2] << 24)); | 363 | snd_emu10k1_ptr_write(emu, PSST, voice, |
364 | (start_addr + (extra ? emu->delay_pcm_irq : 0)) | | ||
365 | (send_amount[2] << 24)); | ||
364 | if (emu->card_capabilities->emu_model) | 366 | if (emu->card_capabilities->emu_model) |
365 | pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */ | 367 | pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */ |
366 | else | 368 | else |
@@ -732,6 +734,23 @@ static void snd_emu10k1_playback_stop_voice(struct snd_emu10k1 *emu, struct snd_ | |||
732 | snd_emu10k1_ptr_write(emu, IP, voice, 0); | 734 | snd_emu10k1_ptr_write(emu, IP, voice, 0); |
733 | } | 735 | } |
734 | 736 | ||
737 | static inline void snd_emu10k1_playback_mangle_extra(struct snd_emu10k1 *emu, | ||
738 | struct snd_emu10k1_pcm *epcm, | ||
739 | struct snd_pcm_substream *substream, | ||
740 | struct snd_pcm_runtime *runtime) | ||
741 | { | ||
742 | unsigned int ptr, period_pos; | ||
743 | |||
744 | /* try to sychronize the current position for the interrupt | ||
745 | source voice */ | ||
746 | period_pos = runtime->status->hw_ptr - runtime->hw_ptr_interrupt; | ||
747 | period_pos %= runtime->period_size; | ||
748 | ptr = snd_emu10k1_ptr_read(emu, CCCA, epcm->extra->number); | ||
749 | ptr &= ~0x00ffffff; | ||
750 | ptr |= epcm->ccca_start_addr + period_pos; | ||
751 | snd_emu10k1_ptr_write(emu, CCCA, epcm->extra->number, ptr); | ||
752 | } | ||
753 | |||
735 | static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream, | 754 | static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream, |
736 | int cmd) | 755 | int cmd) |
737 | { | 756 | { |
@@ -753,6 +772,8 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream, | |||
753 | /* follow thru */ | 772 | /* follow thru */ |
754 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 773 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
755 | case SNDRV_PCM_TRIGGER_RESUME: | 774 | case SNDRV_PCM_TRIGGER_RESUME: |
775 | if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE) | ||
776 | snd_emu10k1_playback_mangle_extra(emu, epcm, substream, runtime); | ||
756 | mix = &emu->pcm_mixer[substream->number]; | 777 | mix = &emu->pcm_mixer[substream->number]; |
757 | snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0, mix); | 778 | snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0, mix); |
758 | snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, 0, mix); | 779 | snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, 0, mix); |
@@ -869,8 +890,9 @@ static snd_pcm_uframes_t snd_emu10k1_playback_pointer(struct snd_pcm_substream * | |||
869 | #endif | 890 | #endif |
870 | /* | 891 | /* |
871 | printk(KERN_DEBUG | 892 | printk(KERN_DEBUG |
872 | "ptr = 0x%x, buffer_size = 0x%x, period_size = 0x%x\n", | 893 | "ptr = 0x%lx, buffer_size = 0x%lx, period_size = 0x%lx\n", |
873 | ptr, runtime->buffer_size, runtime->period_size); | 894 | (long)ptr, (long)runtime->buffer_size, |
895 | (long)runtime->period_size); | ||
874 | */ | 896 | */ |
875 | return ptr; | 897 | return ptr; |
876 | } | 898 | } |
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c index ffb1ddb8dc2..957a311514c 100644 --- a/sound/pci/emu10k1/memory.c +++ b/sound/pci/emu10k1/memory.c | |||
@@ -310,8 +310,10 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst | |||
310 | if (snd_BUG_ON(!hdr)) | 310 | if (snd_BUG_ON(!hdr)) |
311 | return NULL; | 311 | return NULL; |
312 | 312 | ||
313 | idx = runtime->period_size >= runtime->buffer_size ? | ||
314 | (emu->delay_pcm_irq * 2) : 0; | ||
313 | mutex_lock(&hdr->block_mutex); | 315 | mutex_lock(&hdr->block_mutex); |
314 | blk = search_empty(emu, runtime->dma_bytes); | 316 | blk = search_empty(emu, runtime->dma_bytes + idx); |
315 | if (blk == NULL) { | 317 | if (blk == NULL) { |
316 | mutex_unlock(&hdr->block_mutex); | 318 | mutex_unlock(&hdr->block_mutex); |
317 | return NULL; | 319 | return NULL; |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index dd8fb86c842..3827092cc1d 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -589,6 +589,7 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card, | |||
589 | bus->ops = temp->ops; | 589 | bus->ops = temp->ops; |
590 | 590 | ||
591 | mutex_init(&bus->cmd_mutex); | 591 | mutex_init(&bus->cmd_mutex); |
592 | mutex_init(&bus->prepare_mutex); | ||
592 | INIT_LIST_HEAD(&bus->codec_list); | 593 | INIT_LIST_HEAD(&bus->codec_list); |
593 | 594 | ||
594 | snprintf(bus->workq_name, sizeof(bus->workq_name), | 595 | snprintf(bus->workq_name, sizeof(bus->workq_name), |
@@ -1068,7 +1069,6 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, | |||
1068 | codec->addr = codec_addr; | 1069 | codec->addr = codec_addr; |
1069 | mutex_init(&codec->spdif_mutex); | 1070 | mutex_init(&codec->spdif_mutex); |
1070 | mutex_init(&codec->control_mutex); | 1071 | mutex_init(&codec->control_mutex); |
1071 | mutex_init(&codec->prepare_mutex); | ||
1072 | init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); | 1072 | init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); |
1073 | init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); | 1073 | init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); |
1074 | snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32); | 1074 | snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32); |
@@ -1213,6 +1213,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
1213 | u32 stream_tag, | 1213 | u32 stream_tag, |
1214 | int channel_id, int format) | 1214 | int channel_id, int format) |
1215 | { | 1215 | { |
1216 | struct hda_codec *c; | ||
1216 | struct hda_cvt_setup *p; | 1217 | struct hda_cvt_setup *p; |
1217 | unsigned int oldval, newval; | 1218 | unsigned int oldval, newval; |
1218 | int i; | 1219 | int i; |
@@ -1253,10 +1254,12 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
1253 | p->dirty = 0; | 1254 | p->dirty = 0; |
1254 | 1255 | ||
1255 | /* make other inactive cvts with the same stream-tag dirty */ | 1256 | /* make other inactive cvts with the same stream-tag dirty */ |
1256 | for (i = 0; i < codec->cvt_setups.used; i++) { | 1257 | list_for_each_entry(c, &codec->bus->codec_list, list) { |
1257 | p = snd_array_elem(&codec->cvt_setups, i); | 1258 | for (i = 0; i < c->cvt_setups.used; i++) { |
1258 | if (!p->active && p->stream_tag == stream_tag) | 1259 | p = snd_array_elem(&c->cvt_setups, i); |
1259 | p->dirty = 1; | 1260 | if (!p->active && p->stream_tag == stream_tag) |
1261 | p->dirty = 1; | ||
1262 | } | ||
1260 | } | 1263 | } |
1261 | } | 1264 | } |
1262 | EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream); | 1265 | EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream); |
@@ -1306,12 +1309,16 @@ static void really_cleanup_stream(struct hda_codec *codec, | |||
1306 | /* clean up the all conflicting obsolete streams */ | 1309 | /* clean up the all conflicting obsolete streams */ |
1307 | static void purify_inactive_streams(struct hda_codec *codec) | 1310 | static void purify_inactive_streams(struct hda_codec *codec) |
1308 | { | 1311 | { |
1312 | struct hda_codec *c; | ||
1309 | int i; | 1313 | int i; |
1310 | 1314 | ||
1311 | for (i = 0; i < codec->cvt_setups.used; i++) { | 1315 | list_for_each_entry(c, &codec->bus->codec_list, list) { |
1312 | struct hda_cvt_setup *p = snd_array_elem(&codec->cvt_setups, i); | 1316 | for (i = 0; i < c->cvt_setups.used; i++) { |
1313 | if (p->dirty) | 1317 | struct hda_cvt_setup *p; |
1314 | really_cleanup_stream(codec, p); | 1318 | p = snd_array_elem(&c->cvt_setups, i); |
1319 | if (p->dirty) | ||
1320 | really_cleanup_stream(c, p); | ||
1321 | } | ||
1315 | } | 1322 | } |
1316 | } | 1323 | } |
1317 | 1324 | ||
@@ -3502,11 +3509,11 @@ int snd_hda_codec_prepare(struct hda_codec *codec, | |||
3502 | struct snd_pcm_substream *substream) | 3509 | struct snd_pcm_substream *substream) |
3503 | { | 3510 | { |
3504 | int ret; | 3511 | int ret; |
3505 | mutex_lock(&codec->prepare_mutex); | 3512 | mutex_lock(&codec->bus->prepare_mutex); |
3506 | ret = hinfo->ops.prepare(hinfo, codec, stream, format, substream); | 3513 | ret = hinfo->ops.prepare(hinfo, codec, stream, format, substream); |
3507 | if (ret >= 0) | 3514 | if (ret >= 0) |
3508 | purify_inactive_streams(codec); | 3515 | purify_inactive_streams(codec); |
3509 | mutex_unlock(&codec->prepare_mutex); | 3516 | mutex_unlock(&codec->bus->prepare_mutex); |
3510 | return ret; | 3517 | return ret; |
3511 | } | 3518 | } |
3512 | EXPORT_SYMBOL_HDA(snd_hda_codec_prepare); | 3519 | EXPORT_SYMBOL_HDA(snd_hda_codec_prepare); |
@@ -3515,9 +3522,9 @@ void snd_hda_codec_cleanup(struct hda_codec *codec, | |||
3515 | struct hda_pcm_stream *hinfo, | 3522 | struct hda_pcm_stream *hinfo, |
3516 | struct snd_pcm_substream *substream) | 3523 | struct snd_pcm_substream *substream) |
3517 | { | 3524 | { |
3518 | mutex_lock(&codec->prepare_mutex); | 3525 | mutex_lock(&codec->bus->prepare_mutex); |
3519 | hinfo->ops.cleanup(hinfo, codec, substream); | 3526 | hinfo->ops.cleanup(hinfo, codec, substream); |
3520 | mutex_unlock(&codec->prepare_mutex); | 3527 | mutex_unlock(&codec->bus->prepare_mutex); |
3521 | } | 3528 | } |
3522 | EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup); | 3529 | EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup); |
3523 | 3530 | ||
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 4303353feda..62c70224010 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -648,6 +648,7 @@ struct hda_bus { | |||
648 | struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; | 648 | struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; |
649 | 649 | ||
650 | struct mutex cmd_mutex; | 650 | struct mutex cmd_mutex; |
651 | struct mutex prepare_mutex; | ||
651 | 652 | ||
652 | /* unsolicited event queue */ | 653 | /* unsolicited event queue */ |
653 | struct hda_bus_unsolicited *unsol; | 654 | struct hda_bus_unsolicited *unsol; |
@@ -826,7 +827,6 @@ struct hda_codec { | |||
826 | 827 | ||
827 | struct mutex spdif_mutex; | 828 | struct mutex spdif_mutex; |
828 | struct mutex control_mutex; | 829 | struct mutex control_mutex; |
829 | struct mutex prepare_mutex; | ||
830 | unsigned int spdif_status; /* IEC958 status bits */ | 830 | unsigned int spdif_status; /* IEC958 status bits */ |
831 | unsigned short spdif_ctls; /* SPDIF control bits */ | 831 | unsigned short spdif_ctls; /* SPDIF control bits */ |
832 | unsigned int spdif_in_enable; /* SPDIF input enable? */ | 832 | unsigned int spdif_in_enable; /* SPDIF input enable? */ |
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 803b298f741..26c3ade7358 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c | |||
@@ -596,6 +596,8 @@ void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld) | |||
596 | } | 596 | } |
597 | EXPORT_SYMBOL_HDA(snd_hda_eld_proc_free); | 597 | EXPORT_SYMBOL_HDA(snd_hda_eld_proc_free); |
598 | 598 | ||
599 | #endif /* CONFIG_PROC_FS */ | ||
600 | |||
599 | /* update PCM info based on ELD */ | 601 | /* update PCM info based on ELD */ |
600 | void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, | 602 | void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, |
601 | struct hda_pcm_stream *codec_pars) | 603 | struct hda_pcm_stream *codec_pars) |
@@ -644,5 +646,3 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, | |||
644 | pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps); | 646 | pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps); |
645 | } | 647 | } |
646 | EXPORT_SYMBOL_HDA(hdmi_eld_update_pcm_info); | 648 | EXPORT_SYMBOL_HDA(hdmi_eld_update_pcm_info); |
647 | |||
648 | #endif /* CONFIG_PROC_FS */ | ||
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 31b5d9eeba6..5cdb80edbd7 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -3049,6 +3049,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
3049 | SND_PCI_QUIRK(0x1028, 0x02f5, "Dell", | 3049 | SND_PCI_QUIRK(0x1028, 0x02f5, "Dell", |
3050 | CXT5066_DELL_LAPTOP), | 3050 | CXT5066_DELL_LAPTOP), |
3051 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), | 3051 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), |
3052 | SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTO), | ||
3052 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), | 3053 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), |
3053 | SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), | 3054 | SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), |
3054 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), | 3055 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), |
@@ -3058,6 +3059,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
3058 | SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), | 3059 | SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), |
3059 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), | 3060 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), |
3060 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G series", CXT5066_IDEAPAD), | 3061 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G series", CXT5066_IDEAPAD), |
3062 | SND_PCI_QUIRK(0x17aa, 0x390a, "Lenovo S10-3t", CXT5066_IDEAPAD), | ||
3061 | SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G series (AMD)", CXT5066_IDEAPAD), | 3063 | SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G series (AMD)", CXT5066_IDEAPAD), |
3062 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), | 3064 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), |
3063 | {} | 3065 | {} |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 2bc0f07cf33..afd6022a96a 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -707,8 +707,6 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
707 | u32 stream_tag, int format) | 707 | u32 stream_tag, int format) |
708 | { | 708 | { |
709 | struct hdmi_spec *spec = codec->spec; | 709 | struct hdmi_spec *spec = codec->spec; |
710 | int tag; | ||
711 | int fmt; | ||
712 | int pinctl; | 710 | int pinctl; |
713 | int new_pinctl = 0; | 711 | int new_pinctl = 0; |
714 | int i; | 712 | int i; |
@@ -745,24 +743,7 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
745 | return -EINVAL; | 743 | return -EINVAL; |
746 | } | 744 | } |
747 | 745 | ||
748 | tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4; | 746 | snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); |
749 | fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0); | ||
750 | |||
751 | snd_printdd("hdmi_setup_stream: " | ||
752 | "NID=0x%x, %sstream=0x%x, %sformat=0x%x\n", | ||
753 | nid, | ||
754 | tag == stream_tag ? "" : "new-", | ||
755 | stream_tag, | ||
756 | fmt == format ? "" : "new-", | ||
757 | format); | ||
758 | |||
759 | if (tag != stream_tag) | ||
760 | snd_hda_codec_write(codec, nid, 0, | ||
761 | AC_VERB_SET_CHANNEL_STREAMID, | ||
762 | stream_tag << 4); | ||
763 | if (fmt != format) | ||
764 | snd_hda_codec_write(codec, nid, 0, | ||
765 | AC_VERB_SET_STREAM_FORMAT, format); | ||
766 | return 0; | 747 | return 0; |
767 | } | 748 | } |
768 | 749 | ||
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c index d382d3c81c0..36a9b83a617 100644 --- a/sound/pci/hda/patch_intelhdmi.c +++ b/sound/pci/hda/patch_intelhdmi.c | |||
@@ -69,20 +69,12 @@ static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
69 | return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); | 69 | return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); |
70 | } | 70 | } |
71 | 71 | ||
72 | static int intel_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
73 | struct hda_codec *codec, | ||
74 | struct snd_pcm_substream *substream) | ||
75 | { | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static struct hda_pcm_stream intel_hdmi_pcm_playback = { | 72 | static struct hda_pcm_stream intel_hdmi_pcm_playback = { |
80 | .substreams = 1, | 73 | .substreams = 1, |
81 | .channels_min = 2, | 74 | .channels_min = 2, |
82 | .ops = { | 75 | .ops = { |
83 | .open = hdmi_pcm_open, | 76 | .open = hdmi_pcm_open, |
84 | .prepare = intel_hdmi_playback_pcm_prepare, | 77 | .prepare = intel_hdmi_playback_pcm_prepare, |
85 | .cleanup = intel_hdmi_playback_pcm_cleanup, | ||
86 | }, | 78 | }, |
87 | }; | 79 | }; |
88 | 80 | ||
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c index f636870dc71..69b950d527c 100644 --- a/sound/pci/hda/patch_nvhdmi.c +++ b/sound/pci/hda/patch_nvhdmi.c | |||
@@ -326,13 +326,6 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo, | |||
326 | return 0; | 326 | return 0; |
327 | } | 327 | } |
328 | 328 | ||
329 | static int nvhdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
330 | struct hda_codec *codec, | ||
331 | struct snd_pcm_substream *substream) | ||
332 | { | ||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo, | 329 | static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo, |
337 | struct hda_codec *codec, | 330 | struct hda_codec *codec, |
338 | unsigned int stream_tag, | 331 | unsigned int stream_tag, |
@@ -350,7 +343,6 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_89 = { | |||
350 | .ops = { | 343 | .ops = { |
351 | .open = hdmi_pcm_open, | 344 | .open = hdmi_pcm_open, |
352 | .prepare = nvhdmi_dig_playback_pcm_prepare_8ch_89, | 345 | .prepare = nvhdmi_dig_playback_pcm_prepare_8ch_89, |
353 | .cleanup = nvhdmi_playback_pcm_cleanup, | ||
354 | }, | 346 | }, |
355 | }; | 347 | }; |
356 | 348 | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 2cd1ae809e4..627bf996336 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -14467,6 +14467,7 @@ static const struct alc_fixup alc269_fixups[] = { | |||
14467 | 14467 | ||
14468 | static struct snd_pci_quirk alc269_fixup_tbl[] = { | 14468 | static struct snd_pci_quirk alc269_fixup_tbl[] = { |
14469 | SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), | 14469 | SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), |
14470 | SND_PCI_QUIRK(0x104d, 0x9077, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), | ||
14470 | {} | 14471 | {} |
14471 | }; | 14472 | }; |
14472 | 14473 | ||
@@ -19030,6 +19031,7 @@ static int patch_alc888(struct hda_codec *codec) | |||
19030 | /* | 19031 | /* |
19031 | * ALC680 support | 19032 | * ALC680 support |
19032 | */ | 19033 | */ |
19034 | #define ALC680_DIGIN_NID ALC880_DIGIN_NID | ||
19033 | #define ALC680_DIGOUT_NID ALC880_DIGOUT_NID | 19035 | #define ALC680_DIGOUT_NID ALC880_DIGOUT_NID |
19034 | #define alc680_modes alc260_modes | 19036 | #define alc680_modes alc260_modes |
19035 | 19037 | ||
@@ -19044,23 +19046,93 @@ static hda_nid_t alc680_adc_nids[3] = { | |||
19044 | 0x07, 0x08, 0x09 | 19046 | 0x07, 0x08, 0x09 |
19045 | }; | 19047 | }; |
19046 | 19048 | ||
19049 | /* | ||
19050 | * Analog capture ADC cgange | ||
19051 | */ | ||
19052 | static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
19053 | struct hda_codec *codec, | ||
19054 | unsigned int stream_tag, | ||
19055 | unsigned int format, | ||
19056 | struct snd_pcm_substream *substream) | ||
19057 | { | ||
19058 | struct alc_spec *spec = codec->spec; | ||
19059 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
19060 | unsigned int pre_mic, pre_line; | ||
19061 | |||
19062 | pre_mic = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_MIC]); | ||
19063 | pre_line = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_LINE]); | ||
19064 | |||
19065 | spec->cur_adc_stream_tag = stream_tag; | ||
19066 | spec->cur_adc_format = format; | ||
19067 | |||
19068 | if (pre_mic || pre_line) { | ||
19069 | if (pre_mic) | ||
19070 | snd_hda_codec_setup_stream(codec, 0x08, stream_tag, 0, | ||
19071 | format); | ||
19072 | else | ||
19073 | snd_hda_codec_setup_stream(codec, 0x09, stream_tag, 0, | ||
19074 | format); | ||
19075 | } else | ||
19076 | snd_hda_codec_setup_stream(codec, 0x07, stream_tag, 0, format); | ||
19077 | return 0; | ||
19078 | } | ||
19079 | |||
19080 | static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
19081 | struct hda_codec *codec, | ||
19082 | struct snd_pcm_substream *substream) | ||
19083 | { | ||
19084 | snd_hda_codec_cleanup_stream(codec, 0x07); | ||
19085 | snd_hda_codec_cleanup_stream(codec, 0x08); | ||
19086 | snd_hda_codec_cleanup_stream(codec, 0x09); | ||
19087 | return 0; | ||
19088 | } | ||
19089 | |||
19090 | static struct hda_pcm_stream alc680_pcm_analog_auto_capture = { | ||
19091 | .substreams = 1, /* can be overridden */ | ||
19092 | .channels_min = 2, | ||
19093 | .channels_max = 2, | ||
19094 | /* NID is set in alc_build_pcms */ | ||
19095 | .ops = { | ||
19096 | .prepare = alc680_capture_pcm_prepare, | ||
19097 | .cleanup = alc680_capture_pcm_cleanup | ||
19098 | }, | ||
19099 | }; | ||
19100 | |||
19047 | static struct snd_kcontrol_new alc680_base_mixer[] = { | 19101 | static struct snd_kcontrol_new alc680_base_mixer[] = { |
19048 | /* output mixer control */ | 19102 | /* output mixer control */ |
19049 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), | 19103 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), |
19050 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 19104 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
19051 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT), | 19105 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT), |
19052 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT), | 19106 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT), |
19107 | HDA_CODEC_VOLUME("Int Mic Boost", 0x12, 0, HDA_INPUT), | ||
19053 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | 19108 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), |
19109 | HDA_CODEC_VOLUME("Line In Boost", 0x19, 0, HDA_INPUT), | ||
19054 | { } | 19110 | { } |
19055 | }; | 19111 | }; |
19056 | 19112 | ||
19057 | static struct snd_kcontrol_new alc680_capture_mixer[] = { | 19113 | static struct hda_bind_ctls alc680_bind_cap_vol = { |
19058 | HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), | 19114 | .ops = &snd_hda_bind_vol, |
19059 | HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), | 19115 | .values = { |
19060 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), | 19116 | HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), |
19061 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), | 19117 | HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), |
19062 | HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), | 19118 | HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), |
19063 | HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT), | 19119 | 0 |
19120 | }, | ||
19121 | }; | ||
19122 | |||
19123 | static struct hda_bind_ctls alc680_bind_cap_switch = { | ||
19124 | .ops = &snd_hda_bind_sw, | ||
19125 | .values = { | ||
19126 | HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), | ||
19127 | HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), | ||
19128 | HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), | ||
19129 | 0 | ||
19130 | }, | ||
19131 | }; | ||
19132 | |||
19133 | static struct snd_kcontrol_new alc680_master_capture_mixer[] = { | ||
19134 | HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol), | ||
19135 | HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch), | ||
19064 | { } /* end */ | 19136 | { } /* end */ |
19065 | }; | 19137 | }; |
19066 | 19138 | ||
@@ -19068,25 +19140,73 @@ static struct snd_kcontrol_new alc680_capture_mixer[] = { | |||
19068 | * generic initialization of ADC, input mixers and output mixers | 19140 | * generic initialization of ADC, input mixers and output mixers |
19069 | */ | 19141 | */ |
19070 | static struct hda_verb alc680_init_verbs[] = { | 19142 | static struct hda_verb alc680_init_verbs[] = { |
19071 | /* Unmute DAC0-1 and set vol = 0 */ | 19143 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
19072 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 19144 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
19073 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 19145 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
19074 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
19075 | 19146 | ||
19076 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | 19147 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
19077 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | 19148 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
19078 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, | 19149 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
19079 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | 19150 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
19080 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | 19151 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
19152 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
19081 | 19153 | ||
19082 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 19154 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
19083 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 19155 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
19084 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 19156 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
19085 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 19157 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
19086 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 19158 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
19159 | |||
19160 | {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | ||
19161 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, | ||
19162 | |||
19087 | { } | 19163 | { } |
19088 | }; | 19164 | }; |
19089 | 19165 | ||
19166 | /* toggle speaker-output according to the hp-jack state */ | ||
19167 | static void alc680_base_setup(struct hda_codec *codec) | ||
19168 | { | ||
19169 | struct alc_spec *spec = codec->spec; | ||
19170 | |||
19171 | spec->autocfg.hp_pins[0] = 0x16; | ||
19172 | spec->autocfg.speaker_pins[0] = 0x14; | ||
19173 | spec->autocfg.speaker_pins[1] = 0x15; | ||
19174 | spec->autocfg.input_pins[AUTO_PIN_MIC] = 0x18; | ||
19175 | spec->autocfg.input_pins[AUTO_PIN_LINE] = 0x19; | ||
19176 | } | ||
19177 | |||
19178 | static void alc680_rec_autoswitch(struct hda_codec *codec) | ||
19179 | { | ||
19180 | struct alc_spec *spec = codec->spec; | ||
19181 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
19182 | unsigned int present; | ||
19183 | hda_nid_t new_adc; | ||
19184 | |||
19185 | present = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_MIC]); | ||
19186 | |||
19187 | new_adc = present ? 0x8 : 0x7; | ||
19188 | __snd_hda_codec_cleanup_stream(codec, !present ? 0x8 : 0x7, 1); | ||
19189 | snd_hda_codec_setup_stream(codec, new_adc, | ||
19190 | spec->cur_adc_stream_tag, 0, | ||
19191 | spec->cur_adc_format); | ||
19192 | |||
19193 | } | ||
19194 | |||
19195 | static void alc680_unsol_event(struct hda_codec *codec, | ||
19196 | unsigned int res) | ||
19197 | { | ||
19198 | if ((res >> 26) == ALC880_HP_EVENT) | ||
19199 | alc_automute_amp(codec); | ||
19200 | if ((res >> 26) == ALC880_MIC_EVENT) | ||
19201 | alc680_rec_autoswitch(codec); | ||
19202 | } | ||
19203 | |||
19204 | static void alc680_inithook(struct hda_codec *codec) | ||
19205 | { | ||
19206 | alc_automute_amp(codec); | ||
19207 | alc680_rec_autoswitch(codec); | ||
19208 | } | ||
19209 | |||
19090 | /* create input playback/capture controls for the given pin */ | 19210 | /* create input playback/capture controls for the given pin */ |
19091 | static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid, | 19211 | static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid, |
19092 | const char *ctlname, int idx) | 19212 | const char *ctlname, int idx) |
@@ -19197,13 +19317,7 @@ static void alc680_auto_init_hp_out(struct hda_codec *codec) | |||
19197 | #define alc680_pcm_analog_capture alc880_pcm_analog_capture | 19317 | #define alc680_pcm_analog_capture alc880_pcm_analog_capture |
19198 | #define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture | 19318 | #define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture |
19199 | #define alc680_pcm_digital_playback alc880_pcm_digital_playback | 19319 | #define alc680_pcm_digital_playback alc880_pcm_digital_playback |
19200 | 19320 | #define alc680_pcm_digital_capture alc880_pcm_digital_capture | |
19201 | static struct hda_input_mux alc680_capture_source = { | ||
19202 | .num_items = 1, | ||
19203 | .items = { | ||
19204 | { "Mic", 0x0 }, | ||
19205 | }, | ||
19206 | }; | ||
19207 | 19321 | ||
19208 | /* | 19322 | /* |
19209 | * BIOS auto configuration | 19323 | * BIOS auto configuration |
@@ -19218,6 +19332,7 @@ static int alc680_parse_auto_config(struct hda_codec *codec) | |||
19218 | alc680_ignore); | 19332 | alc680_ignore); |
19219 | if (err < 0) | 19333 | if (err < 0) |
19220 | return err; | 19334 | return err; |
19335 | |||
19221 | if (!spec->autocfg.line_outs) { | 19336 | if (!spec->autocfg.line_outs) { |
19222 | if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { | 19337 | if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { |
19223 | spec->multiout.max_channels = 2; | 19338 | spec->multiout.max_channels = 2; |
@@ -19239,8 +19354,6 @@ static int alc680_parse_auto_config(struct hda_codec *codec) | |||
19239 | add_mixer(spec, spec->kctls.list); | 19354 | add_mixer(spec, spec->kctls.list); |
19240 | 19355 | ||
19241 | add_verb(spec, alc680_init_verbs); | 19356 | add_verb(spec, alc680_init_verbs); |
19242 | spec->num_mux_defs = 1; | ||
19243 | spec->input_mux = &alc680_capture_source; | ||
19244 | 19357 | ||
19245 | err = alc_auto_add_mic_boost(codec); | 19358 | err = alc_auto_add_mic_boost(codec); |
19246 | if (err < 0) | 19359 | if (err < 0) |
@@ -19279,17 +19392,17 @@ static struct snd_pci_quirk alc680_cfg_tbl[] = { | |||
19279 | static struct alc_config_preset alc680_presets[] = { | 19392 | static struct alc_config_preset alc680_presets[] = { |
19280 | [ALC680_BASE] = { | 19393 | [ALC680_BASE] = { |
19281 | .mixers = { alc680_base_mixer }, | 19394 | .mixers = { alc680_base_mixer }, |
19282 | .cap_mixer = alc680_capture_mixer, | 19395 | .cap_mixer = alc680_master_capture_mixer, |
19283 | .init_verbs = { alc680_init_verbs }, | 19396 | .init_verbs = { alc680_init_verbs }, |
19284 | .num_dacs = ARRAY_SIZE(alc680_dac_nids), | 19397 | .num_dacs = ARRAY_SIZE(alc680_dac_nids), |
19285 | .dac_nids = alc680_dac_nids, | 19398 | .dac_nids = alc680_dac_nids, |
19286 | .num_adc_nids = ARRAY_SIZE(alc680_adc_nids), | ||
19287 | .adc_nids = alc680_adc_nids, | ||
19288 | .hp_nid = 0x04, | ||
19289 | .dig_out_nid = ALC680_DIGOUT_NID, | 19399 | .dig_out_nid = ALC680_DIGOUT_NID, |
19290 | .num_channel_mode = ARRAY_SIZE(alc680_modes), | 19400 | .num_channel_mode = ARRAY_SIZE(alc680_modes), |
19291 | .channel_mode = alc680_modes, | 19401 | .channel_mode = alc680_modes, |
19292 | .input_mux = &alc680_capture_source, | 19402 | .unsol_event = alc680_unsol_event, |
19403 | .setup = alc680_base_setup, | ||
19404 | .init_hook = alc680_inithook, | ||
19405 | |||
19293 | }, | 19406 | }, |
19294 | }; | 19407 | }; |
19295 | 19408 | ||
@@ -19333,9 +19446,9 @@ static int patch_alc680(struct hda_codec *codec) | |||
19333 | setup_preset(codec, &alc680_presets[board_config]); | 19446 | setup_preset(codec, &alc680_presets[board_config]); |
19334 | 19447 | ||
19335 | spec->stream_analog_playback = &alc680_pcm_analog_playback; | 19448 | spec->stream_analog_playback = &alc680_pcm_analog_playback; |
19336 | spec->stream_analog_capture = &alc680_pcm_analog_capture; | 19449 | spec->stream_analog_capture = &alc680_pcm_analog_auto_capture; |
19337 | spec->stream_analog_alt_capture = &alc680_pcm_analog_alt_capture; | ||
19338 | spec->stream_digital_playback = &alc680_pcm_digital_playback; | 19450 | spec->stream_digital_playback = &alc680_pcm_digital_playback; |
19451 | spec->stream_digital_capture = &alc680_pcm_digital_capture; | ||
19339 | 19452 | ||
19340 | if (!spec->adc_nids) { | 19453 | if (!spec->adc_nids) { |
19341 | spec->adc_nids = alc680_adc_nids; | 19454 | spec->adc_nids = alc680_adc_nids; |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index f3f861bd1bf..95148e58026 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -6303,6 +6303,21 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = { | |||
6303 | { .id = 0x111d76b5, .name = "92HD71B6X", .patch = patch_stac92hd71bxx }, | 6303 | { .id = 0x111d76b5, .name = "92HD71B6X", .patch = patch_stac92hd71bxx }, |
6304 | { .id = 0x111d76b6, .name = "92HD71B5X", .patch = patch_stac92hd71bxx }, | 6304 | { .id = 0x111d76b6, .name = "92HD71B5X", .patch = patch_stac92hd71bxx }, |
6305 | { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx }, | 6305 | { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx }, |
6306 | { .id = 0x111d76c0, .name = "92HD89C3", .patch = patch_stac92hd73xx }, | ||
6307 | { .id = 0x111d76c1, .name = "92HD89C2", .patch = patch_stac92hd73xx }, | ||
6308 | { .id = 0x111d76c2, .name = "92HD89C1", .patch = patch_stac92hd73xx }, | ||
6309 | { .id = 0x111d76c3, .name = "92HD89B3", .patch = patch_stac92hd73xx }, | ||
6310 | { .id = 0x111d76c4, .name = "92HD89B2", .patch = patch_stac92hd73xx }, | ||
6311 | { .id = 0x111d76c5, .name = "92HD89B1", .patch = patch_stac92hd73xx }, | ||
6312 | { .id = 0x111d76c6, .name = "92HD89E3", .patch = patch_stac92hd73xx }, | ||
6313 | { .id = 0x111d76c7, .name = "92HD89E2", .patch = patch_stac92hd73xx }, | ||
6314 | { .id = 0x111d76c8, .name = "92HD89E1", .patch = patch_stac92hd73xx }, | ||
6315 | { .id = 0x111d76c9, .name = "92HD89D3", .patch = patch_stac92hd73xx }, | ||
6316 | { .id = 0x111d76ca, .name = "92HD89D2", .patch = patch_stac92hd73xx }, | ||
6317 | { .id = 0x111d76cb, .name = "92HD89D1", .patch = patch_stac92hd73xx }, | ||
6318 | { .id = 0x111d76cc, .name = "92HD89F3", .patch = patch_stac92hd73xx }, | ||
6319 | { .id = 0x111d76cd, .name = "92HD89F2", .patch = patch_stac92hd73xx }, | ||
6320 | { .id = 0x111d76ce, .name = "92HD89F1", .patch = patch_stac92hd73xx }, | ||
6306 | {} /* terminator */ | 6321 | {} /* terminator */ |
6307 | }; | 6322 | }; |
6308 | 6323 | ||
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 6433e65c950..46774924957 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -1776,6 +1776,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { | |||
1776 | }, | 1776 | }, |
1777 | { | 1777 | { |
1778 | .subvendor = 0x1014, | 1778 | .subvendor = 0x1014, |
1779 | .subdevice = 0x0534, | ||
1780 | .name = "ThinkPad X31", | ||
1781 | .type = AC97_TUNE_INV_EAPD | ||
1782 | }, | ||
1783 | { | ||
1784 | .subvendor = 0x1014, | ||
1779 | .subdevice = 0x1f00, | 1785 | .subdevice = 0x1f00, |
1780 | .name = "MS-9128", | 1786 | .name = "MS-9128", |
1781 | .type = AC97_TUNE_ALC_JACK | 1787 | .type = AC97_TUNE_ALC_JACK |
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index f64fb7d988c..ad5202efd7a 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c | |||
@@ -1224,15 +1224,14 @@ static int try_to_load_firmware(struct cmdif *cif, struct snd_riptide *chip) | |||
1224 | firmware.firmware.ASIC, firmware.firmware.CODEC, | 1224 | firmware.firmware.ASIC, firmware.firmware.CODEC, |
1225 | firmware.firmware.AUXDSP, firmware.firmware.PROG); | 1225 | firmware.firmware.AUXDSP, firmware.firmware.PROG); |
1226 | 1226 | ||
1227 | if (!chip) | ||
1228 | return 1; | ||
1229 | |||
1227 | for (i = 0; i < FIRMWARE_VERSIONS; i++) { | 1230 | for (i = 0; i < FIRMWARE_VERSIONS; i++) { |
1228 | if (!memcmp(&firmware_versions[i], &firmware, sizeof(firmware))) | 1231 | if (!memcmp(&firmware_versions[i], &firmware, sizeof(firmware))) |
1229 | break; | 1232 | return 1; /* OK */ |
1230 | } | ||
1231 | if (i >= FIRMWARE_VERSIONS) | ||
1232 | return 0; /* no match */ | ||
1233 | 1233 | ||
1234 | if (!chip) | 1234 | } |
1235 | return 1; /* OK */ | ||
1236 | 1235 | ||
1237 | snd_printdd("Writing Firmware\n"); | 1236 | snd_printdd("Writing Firmware\n"); |
1238 | if (!chip->fw_entry) { | 1237 | if (!chip->fw_entry) { |
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index 4e212ed62ea..f8154e66152 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c | |||
@@ -178,13 +178,6 @@ static int wm8776_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
178 | case SND_SOC_DAIFMT_LEFT_J: | 178 | case SND_SOC_DAIFMT_LEFT_J: |
179 | iface |= 0x0001; | 179 | iface |= 0x0001; |
180 | break; | 180 | break; |
181 | /* FIXME: CHECK A/B */ | ||
182 | case SND_SOC_DAIFMT_DSP_A: | ||
183 | iface |= 0x0003; | ||
184 | break; | ||
185 | case SND_SOC_DAIFMT_DSP_B: | ||
186 | iface |= 0x0007; | ||
187 | break; | ||
188 | default: | 181 | default: |
189 | return -EINVAL; | 182 | return -EINVAL; |
190 | } | 183 | } |
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index a11daa1e905..c81da05a4f1 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c | |||
@@ -254,6 +254,9 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream, | |||
254 | dma_data = &ssi->dma_params_rx; | 254 | dma_data = &ssi->dma_params_rx; |
255 | } | 255 | } |
256 | 256 | ||
257 | if (ssi->flags & IMX_SSI_SYN) | ||
258 | reg = SSI_STCCR; | ||
259 | |||
257 | snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); | 260 | snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); |
258 | 261 | ||
259 | sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK; | 262 | sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK; |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 844ae8221a3..acc91daa1c5 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -251,7 +251,7 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec) | |||
251 | printk(KERN_WARNING | 251 | printk(KERN_WARNING |
252 | "ASoC: Failed to create codec register debugfs file\n"); | 252 | "ASoC: Failed to create codec register debugfs file\n"); |
253 | 253 | ||
254 | codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0744, | 254 | codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0644, |
255 | codec->debugfs_codec_root, | 255 | codec->debugfs_codec_root, |
256 | &codec->pop_time); | 256 | &codec->pop_time); |
257 | if (!codec->debugfs_pop_time) | 257 | if (!codec->debugfs_pop_time) |
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 41abb90df50..4f1fa77c1fe 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
@@ -5,6 +5,12 @@ endif | |||
5 | # The default target of this Makefile is... | 5 | # The default target of this Makefile is... |
6 | all:: | 6 | all:: |
7 | 7 | ||
8 | ifneq ($(OUTPUT),) | ||
9 | # check that the output directory actually exists | ||
10 | OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd) | ||
11 | $(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist)) | ||
12 | endif | ||
13 | |||
8 | # Define V=1 to have a more verbose compile. | 14 | # Define V=1 to have a more verbose compile. |
9 | # Define V=2 to have an even more verbose compile. | 15 | # Define V=2 to have an even more verbose compile. |
10 | # | 16 | # |
@@ -157,10 +163,6 @@ all:: | |||
157 | # | 163 | # |
158 | # Define NO_DWARF if you do not want debug-info analysis feature at all. | 164 | # Define NO_DWARF if you do not want debug-info analysis feature at all. |
159 | 165 | ||
160 | $(shell sh -c 'mkdir -p $(OUTPUT)scripts/{perl,python}/Perf-Trace-Util/' 2> /dev/null) | ||
161 | $(shell sh -c 'mkdir -p $(OUTPUT)util/{ui/browsers,scripting-engines}/' 2> /dev/null) | ||
162 | $(shell sh -c 'mkdir $(OUTPUT)bench' 2> /dev/null) | ||
163 | |||
164 | $(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE | 166 | $(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE |
165 | @$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT) | 167 | @$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT) |
166 | -include $(OUTPUT)PERF-VERSION-FILE | 168 | -include $(OUTPUT)PERF-VERSION-FILE |
@@ -186,8 +188,6 @@ ifeq ($(ARCH),x86_64) | |||
186 | ARCH := x86 | 188 | ARCH := x86 |
187 | endif | 189 | endif |
188 | 190 | ||
189 | $(shell sh -c 'mkdir -p $(OUTPUT)arch/$(ARCH)/util/' 2> /dev/null) | ||
190 | |||
191 | # CFLAGS and LDFLAGS are for the users to override from the command line. | 191 | # CFLAGS and LDFLAGS are for the users to override from the command line. |
192 | 192 | ||
193 | # | 193 | # |
@@ -268,6 +268,7 @@ export prefix bindir sharedir sysconfdir | |||
268 | CC = $(CROSS_COMPILE)gcc | 268 | CC = $(CROSS_COMPILE)gcc |
269 | AR = $(CROSS_COMPILE)ar | 269 | AR = $(CROSS_COMPILE)ar |
270 | RM = rm -f | 270 | RM = rm -f |
271 | MKDIR = mkdir | ||
271 | TAR = tar | 272 | TAR = tar |
272 | FIND = find | 273 | FIND = find |
273 | INSTALL = install | 274 | INSTALL = install |
@@ -838,6 +839,7 @@ ifndef V | |||
838 | QUIET_CC = @echo ' ' CC $@; | 839 | QUIET_CC = @echo ' ' CC $@; |
839 | QUIET_AR = @echo ' ' AR $@; | 840 | QUIET_AR = @echo ' ' AR $@; |
840 | QUIET_LINK = @echo ' ' LINK $@; | 841 | QUIET_LINK = @echo ' ' LINK $@; |
842 | QUIET_MKDIR = @echo ' ' MKDIR $@; | ||
841 | QUIET_BUILT_IN = @echo ' ' BUILTIN $@; | 843 | QUIET_BUILT_IN = @echo ' ' BUILTIN $@; |
842 | QUIET_GEN = @echo ' ' GEN $@; | 844 | QUIET_GEN = @echo ' ' GEN $@; |
843 | QUIET_SUBDIR0 = +@subdir= | 845 | QUIET_SUBDIR0 = +@subdir= |
@@ -935,15 +937,15 @@ $(OUTPUT)common-cmds.h: $(wildcard Documentation/perf-*.txt) | |||
935 | $(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@ | 937 | $(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@ |
936 | 938 | ||
937 | $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh | 939 | $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh |
938 | $(QUIET_GEN)$(RM) $@ $@+ && \ | 940 | $(QUIET_GEN)$(RM) $(OUTPUT)$@ $(OUTPUT)$@+ && \ |
939 | sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ | 941 | sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ |
940 | -e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \ | 942 | -e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \ |
941 | -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \ | 943 | -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \ |
942 | -e 's/@@PERF_VERSION@@/$(PERF_VERSION)/g' \ | 944 | -e 's/@@PERF_VERSION@@/$(PERF_VERSION)/g' \ |
943 | -e 's/@@NO_CURL@@/$(NO_CURL)/g' \ | 945 | -e 's/@@NO_CURL@@/$(NO_CURL)/g' \ |
944 | $@.sh >$@+ && \ | 946 | $@.sh > $(OUTPUT)$@+ && \ |
945 | chmod +x $@+ && \ | 947 | chmod +x $(OUTPUT)$@+ && \ |
946 | mv $@+ $(OUTPUT)$@ | 948 | mv $(OUTPUT)$@+ $(OUTPUT)$@ |
947 | 949 | ||
948 | configure: configure.ac | 950 | configure: configure.ac |
949 | $(QUIET_GEN)$(RM) $@ $<+ && \ | 951 | $(QUIET_GEN)$(RM) $@ $<+ && \ |
@@ -1012,6 +1014,14 @@ $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H) | |||
1012 | $(patsubst perf-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h) | 1014 | $(patsubst perf-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h) |
1013 | builtin-revert.o wt-status.o: wt-status.h | 1015 | builtin-revert.o wt-status.o: wt-status.h |
1014 | 1016 | ||
1017 | # we compile into subdirectories. if the target directory is not the source directory, they might not exists. So | ||
1018 | # we depend the various files onto their directories. | ||
1019 | DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h | ||
1020 | $(DIRECTORY_DEPS): $(sort $(dir $(DIRECTORY_DEPS))) | ||
1021 | # In the second step, we make a rule to actually create these directories | ||
1022 | $(sort $(dir $(DIRECTORY_DEPS))): | ||
1023 | $(QUIET_MKDIR)$(MKDIR) -p $@ 2>/dev/null | ||
1024 | |||
1015 | $(LIB_FILE): $(LIB_OBJS) | 1025 | $(LIB_FILE): $(LIB_OBJS) |
1016 | $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS) | 1026 | $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS) |
1017 | 1027 | ||
diff --git a/tools/perf/feature-tests.mak b/tools/perf/feature-tests.mak index ddb68e601f0..7a7b6085905 100644 --- a/tools/perf/feature-tests.mak +++ b/tools/perf/feature-tests.mak | |||
@@ -113,7 +113,7 @@ endef | |||
113 | # try-cc | 113 | # try-cc |
114 | # Usage: option = $(call try-cc, source-to-build, cc-options) | 114 | # Usage: option = $(call try-cc, source-to-build, cc-options) |
115 | try-cc = $(shell sh -c \ | 115 | try-cc = $(shell sh -c \ |
116 | 'TMP="$(TMPOUT).$$$$"; \ | 116 | 'TMP="$(OUTPUT)$(TMPOUT).$$$$"; \ |
117 | echo "$(1)" | \ | 117 | echo "$(1)" | \ |
118 | $(CC) -x c - $(2) -o "$$TMP" > /dev/null 2>&1 && echo y; \ | 118 | $(CC) -x c - $(2) -o "$$TMP" > /dev/null 2>&1 && echo y; \ |
119 | rm -f "$$TMP"') | 119 | rm -f "$$TMP"') |
diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index 55ff792459a..a90273e63f4 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c | |||
@@ -146,6 +146,7 @@ static int annotate_browser__run(struct annotate_browser *self, | |||
146 | return -1; | 146 | return -1; |
147 | 147 | ||
148 | newtFormAddHotKey(self->b.form, NEWT_KEY_LEFT); | 148 | newtFormAddHotKey(self->b.form, NEWT_KEY_LEFT); |
149 | newtFormAddHotKey(self->b.form, NEWT_KEY_RIGHT); | ||
149 | 150 | ||
150 | nd = self->curr_hot; | 151 | nd = self->curr_hot; |
151 | if (nd) { | 152 | if (nd) { |
@@ -178,7 +179,7 @@ static int annotate_browser__run(struct annotate_browser *self, | |||
178 | } | 179 | } |
179 | out: | 180 | out: |
180 | ui_browser__hide(&self->b); | 181 | ui_browser__hide(&self->b); |
181 | return 0; | 182 | return es->u.key; |
182 | } | 183 | } |
183 | 184 | ||
184 | int hist_entry__tui_annotate(struct hist_entry *self) | 185 | int hist_entry__tui_annotate(struct hist_entry *self) |