diff --git a/[refs] b/[refs] index 858ff067e418..3cf26b88360c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 405d7ca51597645f3be850574d6c10f01be11e8d +refs/heads/master: e08afeb7e69f45e4ab9fbb8530fe433484b96606 diff --git a/trunk/Documentation/block/data-integrity.txt b/trunk/Documentation/block/data-integrity.txt index 2d735b0ae383..e8ca040ba2cf 100644 --- a/trunk/Documentation/block/data-integrity.txt +++ b/trunk/Documentation/block/data-integrity.txt @@ -50,7 +50,7 @@ encouraged them to allow separation of the data and integrity metadata scatter-gather lists. The controller will interleave the buffers on write and split them on -read. This means that Linux can DMA the data buffers to and from +read. This means that the Linux can DMA the data buffers to and from host memory without changes to the page cache. Also, the 16-bit CRC checksum mandated by both the SCSI and SATA specs @@ -66,7 +66,7 @@ software RAID5). The IP checksum is weaker than the CRC in terms of detecting bit errors. However, the strength is really in the separation of the data -buffers and the integrity metadata. These two distinct buffers must +buffers and the integrity metadata. These two distinct buffers much match up for an I/O to complete. The separation of the data and integrity metadata buffers as well as diff --git a/trunk/Documentation/cgroups/cpusets.txt b/trunk/Documentation/cgroups/cpusets.txt index 1d7e9784439a..f9ca389dddf4 100644 --- a/trunk/Documentation/cgroups/cpusets.txt +++ b/trunk/Documentation/cgroups/cpusets.txt @@ -777,18 +777,6 @@ in cpuset directories: # /bin/echo 1-4 > cpus -> set cpus list to cpus 1,2,3,4 # /bin/echo 1,2,3,4 > cpus -> set cpus list to cpus 1,2,3,4 -To add a CPU to a cpuset, write the new list of CPUs including the -CPU to be added. To add 6 to the above cpuset: - -# /bin/echo 1-4,6 > cpus -> set cpus list to cpus 1,2,3,4,6 - -Similarly to remove a CPU from a cpuset, write the new list of CPUs -without the CPU to be removed. - -To remove all the CPUs: - -# /bin/echo "" > cpus -> clear cpus list - 2.3 Setting flags ----------------- diff --git a/trunk/Documentation/gcov.txt b/trunk/Documentation/gcov.txt index 40ec63352760..e716aadb3a33 100644 --- a/trunk/Documentation/gcov.txt +++ b/trunk/Documentation/gcov.txt @@ -188,18 +188,13 @@ Solution: Exclude affected source files from profiling by specifying GCOV_PROFILE := n or GCOV_PROFILE_basename.o := n in the corresponding Makefile. -Problem: Files copied from sysfs appear empty or incomplete. -Cause: Due to the way seq_file works, some tools such as cp or tar - may not correctly copy files from sysfs. -Solution: Use 'cat' to read .gcda files and 'cp -d' to copy links. - Alternatively use the mechanism shown in Appendix B. - Appendix A: gather_on_build.sh ============================== Sample script to gather coverage meta files on the build machine (see 6a): + #!/bin/bash KSRC=$1 @@ -231,7 +226,7 @@ Appendix B: gather_on_test.sh Sample script to gather coverage data files on the test machine (see 6b): -#!/bin/bash -e +#!/bin/bash DEST=$1 GCDA=/sys/kernel/debug/gcov @@ -241,13 +236,11 @@ if [ -z "$DEST" ] ; then exit 1 fi -TEMPDIR=$(mktemp -d) -echo Collecting data.. -find $GCDA -type d -exec mkdir -p $TEMPDIR/\{\} \; -find $GCDA -name '*.gcda' -exec sh -c 'cat < $0 > '$TEMPDIR'/$0' {} \; -find $GCDA -name '*.gcno' -exec sh -c 'cp -d $0 '$TEMPDIR'/$0' {} \; -tar czf $DEST -C $TEMPDIR sys -rm -rf $TEMPDIR +find $GCDA -name '*.gcno' -o -name '*.gcda' | tar cfz $DEST -T - -echo "$DEST successfully created, copy to build system and unpack with:" -echo " tar xfz $DEST" +if [ $? -eq 0 ] ; then + echo "$DEST successfully created, copy to build system and unpack with:" + echo " tar xfz $DEST" +else + echo "Could not create file $DEST" +fi diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index d77fbd8b79ac..d08759aa0903 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -1915,12 +1915,6 @@ and is between 256 and 4096 characters. It is defined in the file Format: { 0 | 1 } See arch/parisc/kernel/pdc_chassis.c - percpu_alloc= [X86] Select which percpu first chunk allocator to use. - Allowed values are one of "lpage", "embed" and "4k". - See comments in arch/x86/kernel/setup_percpu.c for - details on each allocator. This parameter is primarily - for debugging and performance comparison. - pf. [PARIDE] See Documentation/blockdev/paride.txt. @@ -2473,8 +2467,7 @@ and is between 256 and 4096 characters. It is defined in the file tp720= [HW,PS2] - trace_buf_size=nn[KMG] - [FTRACE] will set tracing buffer size. + trace_buf_size=nn[KMG] [ftrace] will set tracing buffer size. trix= [HW,OSS] MediaTrix AudioTrix Pro Format: diff --git a/trunk/Documentation/kmemleak.txt b/trunk/Documentation/kmemleak.txt index 89068030b01b..0112da3b9ab8 100644 --- a/trunk/Documentation/kmemleak.txt +++ b/trunk/Documentation/kmemleak.txt @@ -16,17 +16,13 @@ Usage ----- CONFIG_DEBUG_KMEMLEAK in "Kernel hacking" has to be enabled. A kernel -thread scans the memory every 10 minutes (by default) and prints the -number of new unreferenced objects found. To display the details of all -the possible memory leaks: +thread scans the memory every 10 minutes (by default) and prints any new +unreferenced objects found. To trigger an intermediate scan and display +all the possible memory leaks: # mount -t debugfs nodev /sys/kernel/debug/ # cat /sys/kernel/debug/kmemleak -To trigger an intermediate memory scan: - - # echo scan > /sys/kernel/debug/kmemleak - Note that the orphan objects are listed in the order they were allocated and one object at the beginning of the list may cause other subsequent objects to be reported as orphan. @@ -35,21 +31,16 @@ Memory scanning parameters can be modified at run-time by writing to the /sys/kernel/debug/kmemleak file. The following parameters are supported: off - disable kmemleak (irreversible) - stack=on - enable the task stacks scanning (default) + stack=on - enable the task stacks scanning stack=off - disable the tasks stacks scanning - scan=on - start the automatic memory scanning thread (default) + scan=on - start the automatic memory scanning thread scan=off - stop the automatic memory scanning thread - scan= - set the automatic memory scanning period in seconds - (default 600, 0 to stop the automatic scanning) - scan - trigger a memory scan + scan= - set the automatic memory scanning period in seconds (0 + to disable it) Kmemleak can also be disabled at boot-time by passing "kmemleak=off" on the kernel command line. -Memory may be allocated or freed before kmemleak is initialised and -these actions are stored in an early log buffer. The size of this buffer -is configured via the CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE option. - Basic Algorithm --------------- diff --git a/trunk/Documentation/leds-lp3944.txt b/trunk/Documentation/leds-lp3944.txt deleted file mode 100644 index c6eda18b15ef..000000000000 --- a/trunk/Documentation/leds-lp3944.txt +++ /dev/null @@ -1,50 +0,0 @@ -Kernel driver lp3944 -==================== - - * National Semiconductor LP3944 Fun-light Chip - Prefix: 'lp3944' - Addresses scanned: None (see the Notes section below) - Datasheet: Publicly available at the National Semiconductor website - http://www.national.com/pf/LP/LP3944.html - -Authors: - Antonio Ospite - - -Description ------------ -The LP3944 is a helper chip that can drive up to 8 leds, with two programmable -DIM modes; it could even be used as a gpio expander but this driver assumes it -is used as a led controller. - -The DIM modes are used to set _blink_ patterns for leds, the pattern is -specified supplying two parameters: - - period: from 0s to 1.6s - - duty cycle: percentage of the period the led is on, from 0 to 100 - -Setting a led in DIM0 or DIM1 mode makes it blink according to the pattern. -See the datasheet for details. - -LP3944 can be found on Motorola A910 smartphone, where it drives the rgb -leds, the camera flash light and the lcds power. - - -Notes ------ -The chip is used mainly in embedded contexts, so this driver expects it is -registered using the i2c_board_info mechanism. - -To register the chip at address 0x60 on adapter 0, set the platform data -according to include/linux/leds-lp3944.h, set the i2c board info: - - static struct i2c_board_info __initdata a910_i2c_board_info[] = { - { - I2C_BOARD_INFO("lp3944", 0x60), - .platform_data = &a910_lp3944_leds, - }, - }; - -and register it in the platform init function - - i2c_register_board_info(0, a910_i2c_board_info, - ARRAY_SIZE(a910_i2c_board_info)); diff --git a/trunk/Documentation/powerpc/booting-without-of.txt b/trunk/Documentation/powerpc/booting-without-of.txt index 79f533f38c61..8d999d862d0e 100644 --- a/trunk/Documentation/powerpc/booting-without-of.txt +++ b/trunk/Documentation/powerpc/booting-without-of.txt @@ -1238,7 +1238,1122 @@ descriptions for the SOC devices for which new nodes have been defined; this list will expand as more and more SOC-containing platforms are moved over to use the flattened-device-tree model. -VII - Specifying interrupt information for devices + a) PHY nodes + + Required properties: + + - device_type : Should be "ethernet-phy" + - interrupts : where a is the interrupt number and b is a + field that represents an encoding of the sense and level + information for the interrupt. This should be encoded based on + the information in section 2) depending on the type of interrupt + controller you have. + - interrupt-parent : the phandle for the interrupt controller that + services interrupts for this device. + - reg : The ID number for the phy, usually a small integer + - linux,phandle : phandle for this node; likely referenced by an + ethernet controller node. + + + Example: + + ethernet-phy@0 { + linux,phandle = <2452000> + interrupt-parent = <40000>; + interrupts = <35 1>; + reg = <0>; + device_type = "ethernet-phy"; + }; + + + b) Interrupt controllers + + Some SOC devices contain interrupt controllers that are different + from the standard Open PIC specification. The SOC device nodes for + these types of controllers should be specified just like a standard + OpenPIC controller. Sense and level information should be encoded + as specified in section 2) of this chapter for each device that + specifies an interrupt. + + Example : + + pic@40000 { + linux,phandle = <40000>; + interrupt-controller; + #address-cells = <0>; + reg = <40000 40000>; + compatible = "chrp,open-pic"; + device_type = "open-pic"; + }; + + c) 4xx/Axon EMAC ethernet nodes + + The EMAC ethernet controller in IBM and AMCC 4xx chips, and also + the Axon bridge. To operate this needs to interact with a ths + special McMAL DMA controller, and sometimes an RGMII or ZMII + interface. In addition to the nodes and properties described + below, the node for the OPB bus on which the EMAC sits must have a + correct clock-frequency property. + + i) The EMAC node itself + + Required properties: + - device_type : "network" + + - compatible : compatible list, contains 2 entries, first is + "ibm,emac-CHIP" where CHIP is the host ASIC (440gx, + 405gp, Axon) and second is either "ibm,emac" or + "ibm,emac4". For Axon, thus, we have: "ibm,emac-axon", + "ibm,emac4" + - interrupts : + - interrupt-parent : optional, if needed for interrupt mapping + - reg : + - local-mac-address : 6 bytes, MAC address + - mal-device : phandle of the associated McMAL node + - mal-tx-channel : 1 cell, index of the tx channel on McMAL associated + with this EMAC + - mal-rx-channel : 1 cell, index of the rx channel on McMAL associated + with this EMAC + - cell-index : 1 cell, hardware index of the EMAC cell on a given + ASIC (typically 0x0 and 0x1 for EMAC0 and EMAC1 on + each Axon chip) + - max-frame-size : 1 cell, maximum frame size supported in bytes + - rx-fifo-size : 1 cell, Rx fifo size in bytes for 10 and 100 Mb/sec + operations. + For Axon, 2048 + - tx-fifo-size : 1 cell, Tx fifo size in bytes for 10 and 100 Mb/sec + operations. + For Axon, 2048. + - fifo-entry-size : 1 cell, size of a fifo entry (used to calculate + thresholds). + For Axon, 0x00000010 + - mal-burst-size : 1 cell, MAL burst size (used to calculate thresholds) + in bytes. + For Axon, 0x00000100 (I think ...) + - phy-mode : string, mode of operations of the PHY interface. + Supported values are: "mii", "rmii", "smii", "rgmii", + "tbi", "gmii", rtbi", "sgmii". + For Axon on CAB, it is "rgmii" + - mdio-device : 1 cell, required iff using shared MDIO registers + (440EP). phandle of the EMAC to use to drive the + MDIO lines for the PHY used by this EMAC. + - zmii-device : 1 cell, required iff connected to a ZMII. phandle of + the ZMII device node + - zmii-channel : 1 cell, required iff connected to a ZMII. Which ZMII + channel or 0xffffffff if ZMII is only used for MDIO. + - rgmii-device : 1 cell, required iff connected to an RGMII. phandle + of the RGMII device node. + For Axon: phandle of plb5/plb4/opb/rgmii + - rgmii-channel : 1 cell, required iff connected to an RGMII. Which + RGMII channel is used by this EMAC. + Fox Axon: present, whatever value is appropriate for each + EMAC, that is the content of the current (bogus) "phy-port" + property. + + Optional properties: + - phy-address : 1 cell, optional, MDIO address of the PHY. If absent, + a search is performed. + - phy-map : 1 cell, optional, bitmap of addresses to probe the PHY + for, used if phy-address is absent. bit 0x00000001 is + MDIO address 0. + For Axon it can be absent, though my current driver + doesn't handle phy-address yet so for now, keep + 0x00ffffff in it. + - rx-fifo-size-gige : 1 cell, Rx fifo size in bytes for 1000 Mb/sec + operations (if absent the value is the same as + rx-fifo-size). For Axon, either absent or 2048. + - tx-fifo-size-gige : 1 cell, Tx fifo size in bytes for 1000 Mb/sec + operations (if absent the value is the same as + tx-fifo-size). For Axon, either absent or 2048. + - tah-device : 1 cell, optional. If connected to a TAH engine for + offload, phandle of the TAH device node. + - tah-channel : 1 cell, optional. If appropriate, channel used on the + TAH engine. + + Example: + + EMAC0: ethernet@40000800 { + device_type = "network"; + compatible = "ibm,emac-440gp", "ibm,emac"; + interrupt-parent = <&UIC1>; + interrupts = <1c 4 1d 4>; + reg = <40000800 70>; + local-mac-address = [00 04 AC E3 1B 1E]; + mal-device = <&MAL0>; + mal-tx-channel = <0 1>; + mal-rx-channel = <0>; + cell-index = <0>; + max-frame-size = <5dc>; + rx-fifo-size = <1000>; + tx-fifo-size = <800>; + phy-mode = "rmii"; + phy-map = <00000001>; + zmii-device = <&ZMII0>; + zmii-channel = <0>; + }; + + ii) McMAL node + + Required properties: + - device_type : "dma-controller" + - compatible : compatible list, containing 2 entries, first is + "ibm,mcmal-CHIP" where CHIP is the host ASIC (like + emac) and the second is either "ibm,mcmal" or + "ibm,mcmal2". + For Axon, "ibm,mcmal-axon","ibm,mcmal2" + - interrupts : . + For Axon: This is _different_ from the current + firmware. We use the "delayed" interrupts for txeob + and rxeob. Thus we end up with mapping those 5 MPIC + interrupts, all level positive sensitive: 10, 11, 32, + 33, 34 (in decimal) + - dcr-reg : < DCR registers range > + - dcr-parent : if needed for dcr-reg + - num-tx-chans : 1 cell, number of Tx channels + - num-rx-chans : 1 cell, number of Rx channels + + iii) ZMII node + + Required properties: + - compatible : compatible list, containing 2 entries, first is + "ibm,zmii-CHIP" where CHIP is the host ASIC (like + EMAC) and the second is "ibm,zmii". + For Axon, there is no ZMII node. + - reg : + + iv) RGMII node + + Required properties: + - compatible : compatible list, containing 2 entries, first is + "ibm,rgmii-CHIP" where CHIP is the host ASIC (like + EMAC) and the second is "ibm,rgmii". + For Axon, "ibm,rgmii-axon","ibm,rgmii" + - reg : + - revision : as provided by the RGMII new version register if + available. + For Axon: 0x0000012a + + d) Xilinx IP cores + + The Xilinx EDK toolchain ships with a set of IP cores (devices) for use + in Xilinx Spartan and Virtex FPGAs. The devices cover the whole range + of standard device types (network, serial, etc.) and miscellaneous + devices (gpio, LCD, spi, etc). Also, since these devices are + implemented within the fpga fabric every instance of the device can be + synthesised with different options that change the behaviour. + + Each IP-core has a set of parameters which the FPGA designer can use to + control how the core is synthesized. Historically, the EDK tool would + extract the device parameters relevant to device drivers and copy them + into an 'xparameters.h' in the form of #define symbols. This tells the + device drivers how the IP cores are configured, but it requres the kernel + to be recompiled every time the FPGA bitstream is resynthesized. + + The new approach is to export the parameters into the device tree and + generate a new device tree each time the FPGA bitstream changes. The + parameters which used to be exported as #defines will now become + properties of the device node. In general, device nodes for IP-cores + will take the following form: + + (name): (generic-name)@(base-address) { + compatible = "xlnx,(ip-core-name)-(HW_VER)" + [, (list of compatible devices), ...]; + reg = <(baseaddr) (size)>; + interrupt-parent = <&interrupt-controller-phandle>; + interrupts = < ... >; + xlnx,(parameter1) = "(string-value)"; + xlnx,(parameter2) = <(int-value)>; + }; + + (generic-name): an open firmware-style name that describes the + generic class of device. Preferably, this is one word, such + as 'serial' or 'ethernet'. + (ip-core-name): the name of the ip block (given after the BEGIN + directive in system.mhs). Should be in lowercase + and all underscores '_' converted to dashes '-'. + (name): is derived from the "PARAMETER INSTANCE" value. + (parameter#): C_* parameters from system.mhs. The C_ prefix is + dropped from the parameter name, the name is converted + to lowercase and all underscore '_' characters are + converted to dashes '-'. + (baseaddr): the baseaddr parameter value (often named C_BASEADDR). + (HW_VER): from the HW_VER parameter. + (size): the address range size (often C_HIGHADDR - C_BASEADDR + 1). + + Typically, the compatible list will include the exact IP core version + followed by an older IP core version which implements the same + interface or any other device with the same interface. + + 'reg', 'interrupt-parent' and 'interrupts' are all optional properties. + + For example, the following block from system.mhs: + + BEGIN opb_uartlite + PARAMETER INSTANCE = opb_uartlite_0 + PARAMETER HW_VER = 1.00.b + PARAMETER C_BAUDRATE = 115200 + PARAMETER C_DATA_BITS = 8 + PARAMETER C_ODD_PARITY = 0 + PARAMETER C_USE_PARITY = 0 + PARAMETER C_CLK_FREQ = 50000000 + PARAMETER C_BASEADDR = 0xEC100000 + PARAMETER C_HIGHADDR = 0xEC10FFFF + BUS_INTERFACE SOPB = opb_7 + PORT OPB_Clk = CLK_50MHz + PORT Interrupt = opb_uartlite_0_Interrupt + PORT RX = opb_uartlite_0_RX + PORT TX = opb_uartlite_0_TX + PORT OPB_Rst = sys_bus_reset_0 + END + + becomes the following device tree node: + + opb_uartlite_0: serial@ec100000 { + device_type = "serial"; + compatible = "xlnx,opb-uartlite-1.00.b"; + reg = ; + interrupt-parent = <&opb_intc_0>; + interrupts = <1 0>; // got this from the opb_intc parameters + current-speed = ; // standard serial device prop + clock-frequency = ; // standard serial device prop + xlnx,data-bits = <8>; + xlnx,odd-parity = <0>; + xlnx,use-parity = <0>; + }; + + Some IP cores actually implement 2 or more logical devices. In + this case, the device should still describe the whole IP core with + a single node and add a child node for each logical device. The + ranges property can be used to translate from parent IP-core to the + registers of each device. In addition, the parent node should be + compatible with the bus type 'xlnx,compound', and should contain + #address-cells and #size-cells, as with any other bus. (Note: this + makes the assumption that both logical devices have the same bus + binding. If this is not true, then separate nodes should be used + for each logical device). The 'cell-index' property can be used to + enumerate logical devices within an IP core. For example, the + following is the system.mhs entry for the dual ps2 controller found + on the ml403 reference design. + + BEGIN opb_ps2_dual_ref + PARAMETER INSTANCE = opb_ps2_dual_ref_0 + PARAMETER HW_VER = 1.00.a + PARAMETER C_BASEADDR = 0xA9000000 + PARAMETER C_HIGHADDR = 0xA9001FFF + BUS_INTERFACE SOPB = opb_v20_0 + PORT Sys_Intr1 = ps2_1_intr + PORT Sys_Intr2 = ps2_2_intr + PORT Clkin1 = ps2_clk_rx_1 + PORT Clkin2 = ps2_clk_rx_2 + PORT Clkpd1 = ps2_clk_tx_1 + PORT Clkpd2 = ps2_clk_tx_2 + PORT Rx1 = ps2_d_rx_1 + PORT Rx2 = ps2_d_rx_2 + PORT Txpd1 = ps2_d_tx_1 + PORT Txpd2 = ps2_d_tx_2 + END + + It would result in the following device tree nodes: + + opb_ps2_dual_ref_0: opb-ps2-dual-ref@a9000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,compound"; + ranges = <0 a9000000 2000>; + // If this device had extra parameters, then they would + // go here. + ps2@0 { + compatible = "xlnx,opb-ps2-dual-ref-1.00.a"; + reg = <0 40>; + interrupt-parent = <&opb_intc_0>; + interrupts = <3 0>; + cell-index = <0>; + }; + ps2@1000 { + compatible = "xlnx,opb-ps2-dual-ref-1.00.a"; + reg = <1000 40>; + interrupt-parent = <&opb_intc_0>; + interrupts = <3 0>; + cell-index = <0>; + }; + }; + + Also, the system.mhs file defines bus attachments from the processor + to the devices. The device tree structure should reflect the bus + attachments. Again an example; this system.mhs fragment: + + BEGIN ppc405_virtex4 + PARAMETER INSTANCE = ppc405_0 + PARAMETER HW_VER = 1.01.a + BUS_INTERFACE DPLB = plb_v34_0 + BUS_INTERFACE IPLB = plb_v34_0 + END + + BEGIN opb_intc + PARAMETER INSTANCE = opb_intc_0 + PARAMETER HW_VER = 1.00.c + PARAMETER C_BASEADDR = 0xD1000FC0 + PARAMETER C_HIGHADDR = 0xD1000FDF + BUS_INTERFACE SOPB = opb_v20_0 + END + + BEGIN opb_uart16550 + PARAMETER INSTANCE = opb_uart16550_0 + PARAMETER HW_VER = 1.00.d + PARAMETER C_BASEADDR = 0xa0000000 + PARAMETER C_HIGHADDR = 0xa0001FFF + BUS_INTERFACE SOPB = opb_v20_0 + END + + BEGIN plb_v34 + PARAMETER INSTANCE = plb_v34_0 + PARAMETER HW_VER = 1.02.a + END + + BEGIN plb_bram_if_cntlr + PARAMETER INSTANCE = plb_bram_if_cntlr_0 + PARAMETER HW_VER = 1.00.b + PARAMETER C_BASEADDR = 0xFFFF0000 + PARAMETER C_HIGHADDR = 0xFFFFFFFF + BUS_INTERFACE SPLB = plb_v34_0 + END + + BEGIN plb2opb_bridge + PARAMETER INSTANCE = plb2opb_bridge_0 + PARAMETER HW_VER = 1.01.a + PARAMETER C_RNG0_BASEADDR = 0x20000000 + PARAMETER C_RNG0_HIGHADDR = 0x3FFFFFFF + PARAMETER C_RNG1_BASEADDR = 0x60000000 + PARAMETER C_RNG1_HIGHADDR = 0x7FFFFFFF + PARAMETER C_RNG2_BASEADDR = 0x80000000 + PARAMETER C_RNG2_HIGHADDR = 0xBFFFFFFF + PARAMETER C_RNG3_BASEADDR = 0xC0000000 + PARAMETER C_RNG3_HIGHADDR = 0xDFFFFFFF + BUS_INTERFACE SPLB = plb_v34_0 + BUS_INTERFACE MOPB = opb_v20_0 + END + + Gives this device tree (some properties removed for clarity): + + plb@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,plb-v34-1.02.a"; + device_type = "ibm,plb"; + ranges; // 1:1 translation + + plb_bram_if_cntrl_0: bram@ffff0000 { + reg = ; + } + + opb@20000000 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <20000000 20000000 20000000 + 60000000 60000000 20000000 + 80000000 80000000 40000000 + c0000000 c0000000 20000000>; + + opb_uart16550_0: serial@a0000000 { + reg = ; + }; + + opb_intc_0: interrupt-controller@d1000fc0 { + reg = ; + }; + }; + }; + + That covers the general approach to binding xilinx IP cores into the + device tree. The following are bindings for specific devices: + + i) Xilinx ML300 Framebuffer + + Simple framebuffer device from the ML300 reference design (also on the + ML403 reference design as well as others). + + Optional properties: + - resolution = : pixel resolution of framebuffer. Some + implementations use a different resolution. + Default is + - virt-resolution = : Size of framebuffer in memory. + Default is . + - rotate-display (empty) : rotate display 180 degrees. + + ii) Xilinx SystemACE + + The Xilinx SystemACE device is used to program FPGAs from an FPGA + bitstream stored on a CF card. It can also be used as a generic CF + interface device. + + Optional properties: + - 8-bit (empty) : Set this property for SystemACE in 8 bit mode + + iii) Xilinx EMAC and Xilinx TEMAC + + Xilinx Ethernet devices. In addition to general xilinx properties + listed above, nodes for these devices should include a phy-handle + property, and may include other common network device properties + like local-mac-address. + + iv) Xilinx Uartlite + + Xilinx uartlite devices are simple fixed speed serial ports. + + Required properties: + - current-speed : Baud rate of uartlite + + v) Xilinx hwicap + + Xilinx hwicap devices provide access to the configuration logic + of the FPGA through the Internal Configuration Access Port + (ICAP). The ICAP enables partial reconfiguration of the FPGA, + readback of the configuration information, and some control over + 'warm boots' of the FPGA fabric. + + Required properties: + - xlnx,family : The family of the FPGA, necessary since the + capabilities of the underlying ICAP hardware + differ between different families. May be + 'virtex2p', 'virtex4', or 'virtex5'. + + vi) Xilinx Uart 16550 + + Xilinx UART 16550 devices are very similar to the NS16550 but with + different register spacing and an offset from the base address. + + Required properties: + - clock-frequency : Frequency of the clock input + - reg-offset : A value of 3 is required + - reg-shift : A value of 2 is required + + e) USB EHCI controllers + + Required properties: + - compatible : should be "usb-ehci". + - reg : should contain at least address and length of the standard EHCI + register set for the device. Optional platform-dependent registers + (debug-port or other) can be also specified here, but only after + definition of standard EHCI registers. + - interrupts : one EHCI interrupt should be described here. + If device registers are implemented in big endian mode, the device + node should have "big-endian-regs" property. + If controller implementation operates with big endian descriptors, + "big-endian-desc" property should be specified. + If both big endian registers and descriptors are used by the controller + implementation, "big-endian" property can be specified instead of having + both "big-endian-regs" and "big-endian-desc". + + Example (Sequoia 440EPx): + ehci@e0000300 { + compatible = "ibm,usb-ehci-440epx", "usb-ehci"; + interrupt-parent = <&UIC0>; + interrupts = <1a 4>; + reg = <0 e0000300 90 0 e0000390 70>; + big-endian; + }; + + f) MDIO on GPIOs + + Currently defined compatibles: + - virtual,gpio-mdio + + MDC and MDIO lines connected to GPIO controllers are listed in the + gpios property as described in section VIII.1 in the following order: + + MDC, MDIO. + + Example: + + mdio { + compatible = "virtual,mdio-gpio"; + #address-cells = <1>; + #size-cells = <0>; + gpios = <&qe_pio_a 11 + &qe_pio_c 6>; + }; + + g) SPI (Serial Peripheral Interface) busses + + SPI busses can be described with a node for the SPI master device + and a set of child nodes for each SPI slave on the bus. For this + discussion, it is assumed that the system's SPI controller is in + SPI master mode. This binding does not describe SPI controllers + in slave mode. + + The SPI master node requires the following properties: + - #address-cells - number of cells required to define a chip select + address on the SPI bus. + - #size-cells - should be zero. + - compatible - name of SPI bus controller following generic names + recommended practice. + No other properties are required in the SPI bus node. It is assumed + that a driver for an SPI bus device will understand that it is an SPI bus. + However, the binding does not attempt to define the specific method for + assigning chip select numbers. Since SPI chip select configuration is + flexible and non-standardized, it is left out of this binding with the + assumption that board specific platform code will be used to manage + chip selects. Individual drivers can define additional properties to + support describing the chip select layout. + + SPI slave nodes must be children of the SPI master node and can + contain the following properties. + - reg - (required) chip select address of device. + - compatible - (required) name of SPI device following generic names + recommended practice + - spi-max-frequency - (required) Maximum SPI clocking speed of device in Hz + - spi-cpol - (optional) Empty property indicating device requires + inverse clock polarity (CPOL) mode + - spi-cpha - (optional) Empty property indicating device requires + shifted clock phase (CPHA) mode + - spi-cs-high - (optional) Empty property indicating device requires + chip select active high + + SPI example for an MPC5200 SPI bus: + spi@f00 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; + reg = <0xf00 0x20>; + interrupts = <2 13 0 2 14 0>; + interrupt-parent = <&mpc5200_pic>; + + ethernet-switch@0 { + compatible = "micrel,ks8995m"; + spi-max-frequency = <1000000>; + reg = <0>; + }; + + codec@1 { + compatible = "ti,tlv320aic26"; + spi-max-frequency = <100000>; + reg = <1>; + }; + }; + +VII - Marvell Discovery mv64[345]6x System Controller chips +=========================================================== + +The Marvell mv64[345]60 series of system controller chips contain +many of the peripherals needed to implement a complete computer +system. In this section, we define device tree nodes to describe +the system controller chip itself and each of the peripherals +which it contains. Compatible string values for each node are +prefixed with the string "marvell,", for Marvell Technology Group Ltd. + +1) The /system-controller node + + This node is used to represent the system-controller and must be + present when the system uses a system controller chip. The top-level + system-controller node contains information that is global to all + devices within the system controller chip. The node name begins + with "system-controller" followed by the unit address, which is + the base address of the memory-mapped register set for the system + controller chip. + + Required properties: + + - ranges : Describes the translation of system controller addresses + for memory mapped registers. + - clock-frequency: Contains the main clock frequency for the system + controller chip. + - reg : This property defines the address and size of the + memory-mapped registers contained within the system controller + chip. The address specified in the "reg" property should match + the unit address of the system-controller node. + - #address-cells : Address representation for system controller + devices. This field represents the number of cells needed to + represent the address of the memory-mapped registers of devices + within the system controller chip. + - #size-cells : Size representation for for the memory-mapped + registers within the system controller chip. + - #interrupt-cells : Defines the width of cells used to represent + interrupts. + + Optional properties: + + - model : The specific model of the system controller chip. Such + as, "mv64360", "mv64460", or "mv64560". + - compatible : A string identifying the compatibility identifiers + of the system controller chip. + + The system-controller node contains child nodes for each system + controller device that the platform uses. Nodes should not be created + for devices which exist on the system controller chip but are not used + + Example Marvell Discovery mv64360 system-controller node: + + system-controller@f1000000 { /* Marvell Discovery mv64360 */ + #address-cells = <1>; + #size-cells = <1>; + model = "mv64360"; /* Default */ + compatible = "marvell,mv64360"; + clock-frequency = <133333333>; + reg = <0xf1000000 0x10000>; + virtual-reg = <0xf1000000>; + ranges = <0x88000000 0x88000000 0x1000000 /* PCI 0 I/O Space */ + 0x80000000 0x80000000 0x8000000 /* PCI 0 MEM Space */ + 0xa0000000 0xa0000000 0x4000000 /* User FLASH */ + 0x00000000 0xf1000000 0x0010000 /* Bridge's regs */ + 0xf2000000 0xf2000000 0x0040000>;/* Integrated SRAM */ + + [ child node definitions... ] + } + +2) Child nodes of /system-controller + + a) Marvell Discovery MDIO bus + + The MDIO is a bus to which the PHY devices are connected. For each + device that exists on this bus, a child node should be created. See + the definition of the PHY node below for an example of how to define + a PHY. + + Required properties: + - #address-cells : Should be <1> + - #size-cells : Should be <0> + - device_type : Should be "mdio" + - compatible : Should be "marvell,mv64360-mdio" + + Example: + + mdio { + #address-cells = <1>; + #size-cells = <0>; + device_type = "mdio"; + compatible = "marvell,mv64360-mdio"; + + ethernet-phy@0 { + ...... + }; + }; + + + b) Marvell Discovery ethernet controller + + The Discover ethernet controller is described with two levels + of nodes. The first level describes an ethernet silicon block + and the second level describes up to 3 ethernet nodes within + that block. The reason for the multiple levels is that the + registers for the node are interleaved within a single set + of registers. The "ethernet-block" level describes the + shared register set, and the "ethernet" nodes describe ethernet + port-specific properties. + + Ethernet block node + + Required properties: + - #address-cells : <1> + - #size-cells : <0> + - compatible : "marvell,mv64360-eth-block" + - reg : Offset and length of the register set for this block + + Example Discovery Ethernet block node: + ethernet-block@2000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "marvell,mv64360-eth-block"; + reg = <0x2000 0x2000>; + ethernet@0 { + ....... + }; + }; + + Ethernet port node + + Required properties: + - device_type : Should be "network". + - compatible : Should be "marvell,mv64360-eth". + - reg : Should be <0>, <1>, or <2>, according to which registers + within the silicon block the device uses. + - interrupts : where a is the interrupt number for the port. + - interrupt-parent : the phandle for the interrupt controller + that services interrupts for this device. + - phy : the phandle for the PHY connected to this ethernet + controller. + - local-mac-address : 6 bytes, MAC address + + Example Discovery Ethernet port node: + ethernet@0 { + device_type = "network"; + compatible = "marvell,mv64360-eth"; + reg = <0>; + interrupts = <32>; + interrupt-parent = <&PIC>; + phy = <&PHY0>; + local-mac-address = [ 00 00 00 00 00 00 ]; + }; + + + + c) Marvell Discovery PHY nodes + + Required properties: + - device_type : Should be "ethernet-phy" + - interrupts : where a is the interrupt number for this phy. + - interrupt-parent : the phandle for the interrupt controller that + services interrupts for this device. + - reg : The ID number for the phy, usually a small integer + + Example Discovery PHY node: + ethernet-phy@1 { + device_type = "ethernet-phy"; + compatible = "broadcom,bcm5421"; + interrupts = <76>; /* GPP 12 */ + interrupt-parent = <&PIC>; + reg = <1>; + }; + + + d) Marvell Discovery SDMA nodes + + Represent DMA hardware associated with the MPSC (multiprotocol + serial controllers). + + Required properties: + - compatible : "marvell,mv64360-sdma" + - reg : Offset and length of the register set for this device + - interrupts : where a is the interrupt number for the DMA + device. + - interrupt-parent : the phandle for the interrupt controller + that services interrupts for this device. + + Example Discovery SDMA node: + sdma@4000 { + compatible = "marvell,mv64360-sdma"; + reg = <0x4000 0xc18>; + virtual-reg = <0xf1004000>; + interrupts = <36>; + interrupt-parent = <&PIC>; + }; + + + e) Marvell Discovery BRG nodes + + Represent baud rate generator hardware associated with the MPSC + (multiprotocol serial controllers). + + Required properties: + - compatible : "marvell,mv64360-brg" + - reg : Offset and length of the register set for this device + - clock-src : A value from 0 to 15 which selects the clock + source for the baud rate generator. This value corresponds + to the CLKS value in the BRGx configuration register. See + the mv64x60 User's Manual. + - clock-frequence : The frequency (in Hz) of the baud rate + generator's input clock. + - current-speed : The current speed setting (presumably by + firmware) of the baud rate generator. + + Example Discovery BRG node: + brg@b200 { + compatible = "marvell,mv64360-brg"; + reg = <0xb200 0x8>; + clock-src = <8>; + clock-frequency = <133333333>; + current-speed = <9600>; + }; + + + f) Marvell Discovery CUNIT nodes + + Represent the Serial Communications Unit device hardware. + + Required properties: + - reg : Offset and length of the register set for this device + + Example Discovery CUNIT node: + cunit@f200 { + reg = <0xf200 0x200>; + }; + + + g) Marvell Discovery MPSCROUTING nodes + + Represent the Discovery's MPSC routing hardware + + Required properties: + - reg : Offset and length of the register set for this device + + Example Discovery CUNIT node: + mpscrouting@b500 { + reg = <0xb400 0xc>; + }; + + + h) Marvell Discovery MPSCINTR nodes + + Represent the Discovery's MPSC DMA interrupt hardware registers + (SDMA cause and mask registers). + + Required properties: + - reg : Offset and length of the register set for this device + + Example Discovery MPSCINTR node: + mpsintr@b800 { + reg = <0xb800 0x100>; + }; + + + i) Marvell Discovery MPSC nodes + + Represent the Discovery's MPSC (Multiprotocol Serial Controller) + serial port. + + Required properties: + - device_type : "serial" + - compatible : "marvell,mv64360-mpsc" + - reg : Offset and length of the register set for this device + - sdma : the phandle for the SDMA node used by this port + - brg : the phandle for the BRG node used by this port + - cunit : the phandle for the CUNIT node used by this port + - mpscrouting : the phandle for the MPSCROUTING node used by this port + - mpscintr : the phandle for the MPSCINTR node used by this port + - cell-index : the hardware index of this cell in the MPSC core + - max_idle : value needed for MPSC CHR3 (Maximum Frame Length) + register + - interrupts : where a is the interrupt number for the MPSC. + - interrupt-parent : the phandle for the interrupt controller + that services interrupts for this device. + + Example Discovery MPSCINTR node: + mpsc@8000 { + device_type = "serial"; + compatible = "marvell,mv64360-mpsc"; + reg = <0x8000 0x38>; + virtual-reg = <0xf1008000>; + sdma = <&SDMA0>; + brg = <&BRG0>; + cunit = <&CUNIT>; + mpscrouting = <&MPSCROUTING>; + mpscintr = <&MPSCINTR>; + cell-index = <0>; + max_idle = <40>; + interrupts = <40>; + interrupt-parent = <&PIC>; + }; + + + j) Marvell Discovery Watch Dog Timer nodes + + Represent the Discovery's watchdog timer hardware + + Required properties: + - compatible : "marvell,mv64360-wdt" + - reg : Offset and length of the register set for this device + + Example Discovery Watch Dog Timer node: + wdt@b410 { + compatible = "marvell,mv64360-wdt"; + reg = <0xb410 0x8>; + }; + + + k) Marvell Discovery I2C nodes + + Represent the Discovery's I2C hardware + + Required properties: + - device_type : "i2c" + - compatible : "marvell,mv64360-i2c" + - reg : Offset and length of the register set for this device + - interrupts : where a is the interrupt number for the I2C. + - interrupt-parent : the phandle for the interrupt controller + that services interrupts for this device. + + Example Discovery I2C node: + compatible = "marvell,mv64360-i2c"; + reg = <0xc000 0x20>; + virtual-reg = <0xf100c000>; + interrupts = <37>; + interrupt-parent = <&PIC>; + }; + + + l) Marvell Discovery PIC (Programmable Interrupt Controller) nodes + + Represent the Discovery's PIC hardware + + Required properties: + - #interrupt-cells : <1> + - #address-cells : <0> + - compatible : "marvell,mv64360-pic" + - reg : Offset and length of the register set for this device + - interrupt-controller + + Example Discovery PIC node: + pic { + #interrupt-cells = <1>; + #address-cells = <0>; + compatible = "marvell,mv64360-pic"; + reg = <0x0 0x88>; + interrupt-controller; + }; + + + m) Marvell Discovery MPP (Multipurpose Pins) multiplexing nodes + + Represent the Discovery's MPP hardware + + Required properties: + - compatible : "marvell,mv64360-mpp" + - reg : Offset and length of the register set for this device + + Example Discovery MPP node: + mpp@f000 { + compatible = "marvell,mv64360-mpp"; + reg = <0xf000 0x10>; + }; + + + n) Marvell Discovery GPP (General Purpose Pins) nodes + + Represent the Discovery's GPP hardware + + Required properties: + - compatible : "marvell,mv64360-gpp" + - reg : Offset and length of the register set for this device + + Example Discovery GPP node: + gpp@f000 { + compatible = "marvell,mv64360-gpp"; + reg = <0xf100 0x20>; + }; + + + o) Marvell Discovery PCI host bridge node + + Represents the Discovery's PCI host bridge device. The properties + for this node conform to Rev 2.1 of the PCI Bus Binding to IEEE + 1275-1994. A typical value for the compatible property is + "marvell,mv64360-pci". + + Example Discovery PCI host bridge node + pci@80000000 { + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + compatible = "marvell,mv64360-pci"; + reg = <0xcf8 0x8>; + ranges = <0x01000000 0x0 0x0 + 0x88000000 0x0 0x01000000 + 0x02000000 0x0 0x80000000 + 0x80000000 0x0 0x08000000>; + bus-range = <0 255>; + clock-frequency = <66000000>; + interrupt-parent = <&PIC>; + interrupt-map-mask = <0xf800 0x0 0x0 0x7>; + interrupt-map = < + /* IDSEL 0x0a */ + 0x5000 0 0 1 &PIC 80 + 0x5000 0 0 2 &PIC 81 + 0x5000 0 0 3 &PIC 91 + 0x5000 0 0 4 &PIC 93 + + /* IDSEL 0x0b */ + 0x5800 0 0 1 &PIC 91 + 0x5800 0 0 2 &PIC 93 + 0x5800 0 0 3 &PIC 80 + 0x5800 0 0 4 &PIC 81 + + /* IDSEL 0x0c */ + 0x6000 0 0 1 &PIC 91 + 0x6000 0 0 2 &PIC 93 + 0x6000 0 0 3 &PIC 80 + 0x6000 0 0 4 &PIC 81 + + /* IDSEL 0x0d */ + 0x6800 0 0 1 &PIC 93 + 0x6800 0 0 2 &PIC 80 + 0x6800 0 0 3 &PIC 81 + 0x6800 0 0 4 &PIC 91 + >; + }; + + + p) Marvell Discovery CPU Error nodes + + Represent the Discovery's CPU error handler device. + + Required properties: + - compatible : "marvell,mv64360-cpu-error" + - reg : Offset and length of the register set for this device + - interrupts : the interrupt number for this device + - interrupt-parent : the phandle for the interrupt controller + that services interrupts for this device. + + Example Discovery CPU Error node: + cpu-error@0070 { + compatible = "marvell,mv64360-cpu-error"; + reg = <0x70 0x10 0x128 0x28>; + interrupts = <3>; + interrupt-parent = <&PIC>; + }; + + + q) Marvell Discovery SRAM Controller nodes + + Represent the Discovery's SRAM controller device. + + Required properties: + - compatible : "marvell,mv64360-sram-ctrl" + - reg : Offset and length of the register set for this device + - interrupts : the interrupt number for this device + - interrupt-parent : the phandle for the interrupt controller + that services interrupts for this device. + + Example Discovery SRAM Controller node: + sram-ctrl@0380 { + compatible = "marvell,mv64360-sram-ctrl"; + reg = <0x380 0x80>; + interrupts = <13>; + interrupt-parent = <&PIC>; + }; + + + r) Marvell Discovery PCI Error Handler nodes + + Represent the Discovery's PCI error handler device. + + Required properties: + - compatible : "marvell,mv64360-pci-error" + - reg : Offset and length of the register set for this device + - interrupts : the interrupt number for this device + - interrupt-parent : the phandle for the interrupt controller + that services interrupts for this device. + + Example Discovery PCI Error Handler node: + pci-error@1d40 { + compatible = "marvell,mv64360-pci-error"; + reg = <0x1d40 0x40 0xc28 0x4>; + interrupts = <12>; + interrupt-parent = <&PIC>; + }; + + + s) Marvell Discovery Memory Controller nodes + + Represent the Discovery's memory controller device. + + Required properties: + - compatible : "marvell,mv64360-mem-ctrl" + - reg : Offset and length of the register set for this device + - interrupts : the interrupt number for this device + - interrupt-parent : the phandle for the interrupt controller + that services interrupts for this device. + + Example Discovery Memory Controller node: + mem-ctrl@1400 { + compatible = "marvell,mv64360-mem-ctrl"; + reg = <0x1400 0x60>; + interrupts = <17>; + interrupt-parent = <&PIC>; + }; + + +VIII - Specifying interrupt information for devices =================================================== The device tree represents the busses and devices of a hardware @@ -1324,7 +2439,56 @@ encodings listed below: 2 = high to low edge sensitive type enabled 3 = low to high edge sensitive type enabled -VIII - Specifying Device Power Management Information (sleep property) +IX - Specifying GPIO information for devices +============================================ + +1) gpios property +----------------- + +Nodes that makes use of GPIOs should define them using `gpios' property, +format of which is: <&gpio-controller1-phandle gpio1-specifier + &gpio-controller2-phandle gpio2-specifier + 0 /* holes are permitted, means no GPIO 3 */ + &gpio-controller4-phandle gpio4-specifier + ...>; + +Note that gpio-specifier length is controller dependent. + +gpio-specifier may encode: bank, pin position inside the bank, +whether pin is open-drain and whether pin is logically inverted. + +Example of the node using GPIOs: + + node { + gpios = <&qe_pio_e 18 0>; + }; + +In this example gpio-specifier is "18 0" and encodes GPIO pin number, +and empty GPIO flags as accepted by the "qe_pio_e" gpio-controller. + +2) gpio-controller nodes +------------------------ + +Every GPIO controller node must have #gpio-cells property defined, +this information will be used to translate gpio-specifiers. + +Example of two SOC GPIO banks defined as gpio-controller nodes: + + qe_pio_a: gpio-controller@1400 { + #gpio-cells = <2>; + compatible = "fsl,qe-pario-bank-a", "fsl,qe-pario-bank"; + reg = <0x1400 0x18>; + gpio-controller; + }; + + qe_pio_e: gpio-controller@1460 { + #gpio-cells = <2>; + compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank"; + reg = <0x1460 0x18>; + gpio-controller; + }; + +X - Specifying Device Power Management Information (sleep property) =================================================================== Devices on SOCs often have mechanisms for placing devices into low-power diff --git a/trunk/Documentation/powerpc/dts-bindings/4xx/emac.txt b/trunk/Documentation/powerpc/dts-bindings/4xx/emac.txt deleted file mode 100644 index 2161334a7ca5..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/4xx/emac.txt +++ /dev/null @@ -1,148 +0,0 @@ - 4xx/Axon EMAC ethernet nodes - - The EMAC ethernet controller in IBM and AMCC 4xx chips, and also - the Axon bridge. To operate this needs to interact with a ths - special McMAL DMA controller, and sometimes an RGMII or ZMII - interface. In addition to the nodes and properties described - below, the node for the OPB bus on which the EMAC sits must have a - correct clock-frequency property. - - i) The EMAC node itself - - Required properties: - - device_type : "network" - - - compatible : compatible list, contains 2 entries, first is - "ibm,emac-CHIP" where CHIP is the host ASIC (440gx, - 405gp, Axon) and second is either "ibm,emac" or - "ibm,emac4". For Axon, thus, we have: "ibm,emac-axon", - "ibm,emac4" - - interrupts : - - interrupt-parent : optional, if needed for interrupt mapping - - reg : - - local-mac-address : 6 bytes, MAC address - - mal-device : phandle of the associated McMAL node - - mal-tx-channel : 1 cell, index of the tx channel on McMAL associated - with this EMAC - - mal-rx-channel : 1 cell, index of the rx channel on McMAL associated - with this EMAC - - cell-index : 1 cell, hardware index of the EMAC cell on a given - ASIC (typically 0x0 and 0x1 for EMAC0 and EMAC1 on - each Axon chip) - - max-frame-size : 1 cell, maximum frame size supported in bytes - - rx-fifo-size : 1 cell, Rx fifo size in bytes for 10 and 100 Mb/sec - operations. - For Axon, 2048 - - tx-fifo-size : 1 cell, Tx fifo size in bytes for 10 and 100 Mb/sec - operations. - For Axon, 2048. - - fifo-entry-size : 1 cell, size of a fifo entry (used to calculate - thresholds). - For Axon, 0x00000010 - - mal-burst-size : 1 cell, MAL burst size (used to calculate thresholds) - in bytes. - For Axon, 0x00000100 (I think ...) - - phy-mode : string, mode of operations of the PHY interface. - Supported values are: "mii", "rmii", "smii", "rgmii", - "tbi", "gmii", rtbi", "sgmii". - For Axon on CAB, it is "rgmii" - - mdio-device : 1 cell, required iff using shared MDIO registers - (440EP). phandle of the EMAC to use to drive the - MDIO lines for the PHY used by this EMAC. - - zmii-device : 1 cell, required iff connected to a ZMII. phandle of - the ZMII device node - - zmii-channel : 1 cell, required iff connected to a ZMII. Which ZMII - channel or 0xffffffff if ZMII is only used for MDIO. - - rgmii-device : 1 cell, required iff connected to an RGMII. phandle - of the RGMII device node. - For Axon: phandle of plb5/plb4/opb/rgmii - - rgmii-channel : 1 cell, required iff connected to an RGMII. Which - RGMII channel is used by this EMAC. - Fox Axon: present, whatever value is appropriate for each - EMAC, that is the content of the current (bogus) "phy-port" - property. - - Optional properties: - - phy-address : 1 cell, optional, MDIO address of the PHY. If absent, - a search is performed. - - phy-map : 1 cell, optional, bitmap of addresses to probe the PHY - for, used if phy-address is absent. bit 0x00000001 is - MDIO address 0. - For Axon it can be absent, though my current driver - doesn't handle phy-address yet so for now, keep - 0x00ffffff in it. - - rx-fifo-size-gige : 1 cell, Rx fifo size in bytes for 1000 Mb/sec - operations (if absent the value is the same as - rx-fifo-size). For Axon, either absent or 2048. - - tx-fifo-size-gige : 1 cell, Tx fifo size in bytes for 1000 Mb/sec - operations (if absent the value is the same as - tx-fifo-size). For Axon, either absent or 2048. - - tah-device : 1 cell, optional. If connected to a TAH engine for - offload, phandle of the TAH device node. - - tah-channel : 1 cell, optional. If appropriate, channel used on the - TAH engine. - - Example: - - EMAC0: ethernet@40000800 { - device_type = "network"; - compatible = "ibm,emac-440gp", "ibm,emac"; - interrupt-parent = <&UIC1>; - interrupts = <1c 4 1d 4>; - reg = <40000800 70>; - local-mac-address = [00 04 AC E3 1B 1E]; - mal-device = <&MAL0>; - mal-tx-channel = <0 1>; - mal-rx-channel = <0>; - cell-index = <0>; - max-frame-size = <5dc>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; - phy-mode = "rmii"; - phy-map = <00000001>; - zmii-device = <&ZMII0>; - zmii-channel = <0>; - }; - - ii) McMAL node - - Required properties: - - device_type : "dma-controller" - - compatible : compatible list, containing 2 entries, first is - "ibm,mcmal-CHIP" where CHIP is the host ASIC (like - emac) and the second is either "ibm,mcmal" or - "ibm,mcmal2". - For Axon, "ibm,mcmal-axon","ibm,mcmal2" - - interrupts : . - For Axon: This is _different_ from the current - firmware. We use the "delayed" interrupts for txeob - and rxeob. Thus we end up with mapping those 5 MPIC - interrupts, all level positive sensitive: 10, 11, 32, - 33, 34 (in decimal) - - dcr-reg : < DCR registers range > - - dcr-parent : if needed for dcr-reg - - num-tx-chans : 1 cell, number of Tx channels - - num-rx-chans : 1 cell, number of Rx channels - - iii) ZMII node - - Required properties: - - compatible : compatible list, containing 2 entries, first is - "ibm,zmii-CHIP" where CHIP is the host ASIC (like - EMAC) and the second is "ibm,zmii". - For Axon, there is no ZMII node. - - reg : - - iv) RGMII node - - Required properties: - - compatible : compatible list, containing 2 entries, first is - "ibm,rgmii-CHIP" where CHIP is the host ASIC (like - EMAC) and the second is "ibm,rgmii". - For Axon, "ibm,rgmii-axon","ibm,rgmii" - - reg : - - revision : as provided by the RGMII new version register if - available. - For Axon: 0x0000012a - diff --git a/trunk/Documentation/powerpc/dts-bindings/gpio/gpio.txt b/trunk/Documentation/powerpc/dts-bindings/gpio/gpio.txt deleted file mode 100644 index edaa84d288a1..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/gpio/gpio.txt +++ /dev/null @@ -1,50 +0,0 @@ -Specifying GPIO information for devices -============================================ - -1) gpios property ------------------ - -Nodes that makes use of GPIOs should define them using `gpios' property, -format of which is: <&gpio-controller1-phandle gpio1-specifier - &gpio-controller2-phandle gpio2-specifier - 0 /* holes are permitted, means no GPIO 3 */ - &gpio-controller4-phandle gpio4-specifier - ...>; - -Note that gpio-specifier length is controller dependent. - -gpio-specifier may encode: bank, pin position inside the bank, -whether pin is open-drain and whether pin is logically inverted. - -Example of the node using GPIOs: - - node { - gpios = <&qe_pio_e 18 0>; - }; - -In this example gpio-specifier is "18 0" and encodes GPIO pin number, -and empty GPIO flags as accepted by the "qe_pio_e" gpio-controller. - -2) gpio-controller nodes ------------------------- - -Every GPIO controller node must have #gpio-cells property defined, -this information will be used to translate gpio-specifiers. - -Example of two SOC GPIO banks defined as gpio-controller nodes: - - qe_pio_a: gpio-controller@1400 { - #gpio-cells = <2>; - compatible = "fsl,qe-pario-bank-a", "fsl,qe-pario-bank"; - reg = <0x1400 0x18>; - gpio-controller; - }; - - qe_pio_e: gpio-controller@1460 { - #gpio-cells = <2>; - compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank"; - reg = <0x1460 0x18>; - gpio-controller; - }; - - diff --git a/trunk/Documentation/powerpc/dts-bindings/gpio/led.txt b/trunk/Documentation/powerpc/dts-bindings/gpio/led.txt index 064db928c3c1..4fe14deedc0a 100644 --- a/trunk/Documentation/powerpc/dts-bindings/gpio/led.txt +++ b/trunk/Documentation/powerpc/dts-bindings/gpio/led.txt @@ -16,17 +16,10 @@ LED sub-node properties: string defining the trigger assigned to the LED. Current triggers are: "backlight" - LED will act as a back-light, controlled by the framebuffer system - "default-on" - LED will turn on, but see "default-state" below + "default-on" - LED will turn on "heartbeat" - LED "double" flashes at a load average based rate "ide-disk" - LED indicates disk activity "timer" - LED flashes at a fixed, configurable rate -- default-state: (optional) The initial state of the LED. Valid - values are "on", "off", and "keep". If the LED is already on or off - and the default-state property is set the to same value, then no - glitch should be produced where the LED momentarily turns off (or - on). The "keep" setting will keep the LED at whatever its current - state is, without producing a glitch. The default is off if this - property is not present. Examples: @@ -37,22 +30,14 @@ leds { gpios = <&mcu_pio 0 1>; /* Active low */ linux,default-trigger = "ide-disk"; }; - - fault { - gpios = <&mcu_pio 1 0>; - /* Keep LED on if BIOS detected hardware fault */ - default-state = "keep"; - }; }; run-control { compatible = "gpio-leds"; red { gpios = <&mpc8572 6 0>; - default-state = "off"; }; green { gpios = <&mpc8572 7 0>; - default-state = "on"; }; } diff --git a/trunk/Documentation/powerpc/dts-bindings/gpio/mdio.txt b/trunk/Documentation/powerpc/dts-bindings/gpio/mdio.txt deleted file mode 100644 index bc9549529014..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/gpio/mdio.txt +++ /dev/null @@ -1,19 +0,0 @@ -MDIO on GPIOs - -Currently defined compatibles: -- virtual,gpio-mdio - -MDC and MDIO lines connected to GPIO controllers are listed in the -gpios property as described in section VIII.1 in the following order: - -MDC, MDIO. - -Example: - -mdio { - compatible = "virtual,mdio-gpio"; - #address-cells = <1>; - #size-cells = <0>; - gpios = <&qe_pio_a 11 - &qe_pio_c 6>; -}; diff --git a/trunk/Documentation/powerpc/dts-bindings/marvell.txt b/trunk/Documentation/powerpc/dts-bindings/marvell.txt deleted file mode 100644 index 3708a2fd4747..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/marvell.txt +++ /dev/null @@ -1,521 +0,0 @@ -Marvell Discovery mv64[345]6x System Controller chips -=========================================================== - -The Marvell mv64[345]60 series of system controller chips contain -many of the peripherals needed to implement a complete computer -system. In this section, we define device tree nodes to describe -the system controller chip itself and each of the peripherals -which it contains. Compatible string values for each node are -prefixed with the string "marvell,", for Marvell Technology Group Ltd. - -1) The /system-controller node - - This node is used to represent the system-controller and must be - present when the system uses a system controller chip. The top-level - system-controller node contains information that is global to all - devices within the system controller chip. The node name begins - with "system-controller" followed by the unit address, which is - the base address of the memory-mapped register set for the system - controller chip. - - Required properties: - - - ranges : Describes the translation of system controller addresses - for memory mapped registers. - - clock-frequency: Contains the main clock frequency for the system - controller chip. - - reg : This property defines the address and size of the - memory-mapped registers contained within the system controller - chip. The address specified in the "reg" property should match - the unit address of the system-controller node. - - #address-cells : Address representation for system controller - devices. This field represents the number of cells needed to - represent the address of the memory-mapped registers of devices - within the system controller chip. - - #size-cells : Size representation for for the memory-mapped - registers within the system controller chip. - - #interrupt-cells : Defines the width of cells used to represent - interrupts. - - Optional properties: - - - model : The specific model of the system controller chip. Such - as, "mv64360", "mv64460", or "mv64560". - - compatible : A string identifying the compatibility identifiers - of the system controller chip. - - The system-controller node contains child nodes for each system - controller device that the platform uses. Nodes should not be created - for devices which exist on the system controller chip but are not used - - Example Marvell Discovery mv64360 system-controller node: - - system-controller@f1000000 { /* Marvell Discovery mv64360 */ - #address-cells = <1>; - #size-cells = <1>; - model = "mv64360"; /* Default */ - compatible = "marvell,mv64360"; - clock-frequency = <133333333>; - reg = <0xf1000000 0x10000>; - virtual-reg = <0xf1000000>; - ranges = <0x88000000 0x88000000 0x1000000 /* PCI 0 I/O Space */ - 0x80000000 0x80000000 0x8000000 /* PCI 0 MEM Space */ - 0xa0000000 0xa0000000 0x4000000 /* User FLASH */ - 0x00000000 0xf1000000 0x0010000 /* Bridge's regs */ - 0xf2000000 0xf2000000 0x0040000>;/* Integrated SRAM */ - - [ child node definitions... ] - } - -2) Child nodes of /system-controller - - a) Marvell Discovery MDIO bus - - The MDIO is a bus to which the PHY devices are connected. For each - device that exists on this bus, a child node should be created. See - the definition of the PHY node below for an example of how to define - a PHY. - - Required properties: - - #address-cells : Should be <1> - - #size-cells : Should be <0> - - device_type : Should be "mdio" - - compatible : Should be "marvell,mv64360-mdio" - - Example: - - mdio { - #address-cells = <1>; - #size-cells = <0>; - device_type = "mdio"; - compatible = "marvell,mv64360-mdio"; - - ethernet-phy@0 { - ...... - }; - }; - - - b) Marvell Discovery ethernet controller - - The Discover ethernet controller is described with two levels - of nodes. The first level describes an ethernet silicon block - and the second level describes up to 3 ethernet nodes within - that block. The reason for the multiple levels is that the - registers for the node are interleaved within a single set - of registers. The "ethernet-block" level describes the - shared register set, and the "ethernet" nodes describe ethernet - port-specific properties. - - Ethernet block node - - Required properties: - - #address-cells : <1> - - #size-cells : <0> - - compatible : "marvell,mv64360-eth-block" - - reg : Offset and length of the register set for this block - - Example Discovery Ethernet block node: - ethernet-block@2000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "marvell,mv64360-eth-block"; - reg = <0x2000 0x2000>; - ethernet@0 { - ....... - }; - }; - - Ethernet port node - - Required properties: - - device_type : Should be "network". - - compatible : Should be "marvell,mv64360-eth". - - reg : Should be <0>, <1>, or <2>, according to which registers - within the silicon block the device uses. - - interrupts : where a is the interrupt number for the port. - - interrupt-parent : the phandle for the interrupt controller - that services interrupts for this device. - - phy : the phandle for the PHY connected to this ethernet - controller. - - local-mac-address : 6 bytes, MAC address - - Example Discovery Ethernet port node: - ethernet@0 { - device_type = "network"; - compatible = "marvell,mv64360-eth"; - reg = <0>; - interrupts = <32>; - interrupt-parent = <&PIC>; - phy = <&PHY0>; - local-mac-address = [ 00 00 00 00 00 00 ]; - }; - - - - c) Marvell Discovery PHY nodes - - Required properties: - - device_type : Should be "ethernet-phy" - - interrupts : where a is the interrupt number for this phy. - - interrupt-parent : the phandle for the interrupt controller that - services interrupts for this device. - - reg : The ID number for the phy, usually a small integer - - Example Discovery PHY node: - ethernet-phy@1 { - device_type = "ethernet-phy"; - compatible = "broadcom,bcm5421"; - interrupts = <76>; /* GPP 12 */ - interrupt-parent = <&PIC>; - reg = <1>; - }; - - - d) Marvell Discovery SDMA nodes - - Represent DMA hardware associated with the MPSC (multiprotocol - serial controllers). - - Required properties: - - compatible : "marvell,mv64360-sdma" - - reg : Offset and length of the register set for this device - - interrupts : where a is the interrupt number for the DMA - device. - - interrupt-parent : the phandle for the interrupt controller - that services interrupts for this device. - - Example Discovery SDMA node: - sdma@4000 { - compatible = "marvell,mv64360-sdma"; - reg = <0x4000 0xc18>; - virtual-reg = <0xf1004000>; - interrupts = <36>; - interrupt-parent = <&PIC>; - }; - - - e) Marvell Discovery BRG nodes - - Represent baud rate generator hardware associated with the MPSC - (multiprotocol serial controllers). - - Required properties: - - compatible : "marvell,mv64360-brg" - - reg : Offset and length of the register set for this device - - clock-src : A value from 0 to 15 which selects the clock - source for the baud rate generator. This value corresponds - to the CLKS value in the BRGx configuration register. See - the mv64x60 User's Manual. - - clock-frequence : The frequency (in Hz) of the baud rate - generator's input clock. - - current-speed : The current speed setting (presumably by - firmware) of the baud rate generator. - - Example Discovery BRG node: - brg@b200 { - compatible = "marvell,mv64360-brg"; - reg = <0xb200 0x8>; - clock-src = <8>; - clock-frequency = <133333333>; - current-speed = <9600>; - }; - - - f) Marvell Discovery CUNIT nodes - - Represent the Serial Communications Unit device hardware. - - Required properties: - - reg : Offset and length of the register set for this device - - Example Discovery CUNIT node: - cunit@f200 { - reg = <0xf200 0x200>; - }; - - - g) Marvell Discovery MPSCROUTING nodes - - Represent the Discovery's MPSC routing hardware - - Required properties: - - reg : Offset and length of the register set for this device - - Example Discovery CUNIT node: - mpscrouting@b500 { - reg = <0xb400 0xc>; - }; - - - h) Marvell Discovery MPSCINTR nodes - - Represent the Discovery's MPSC DMA interrupt hardware registers - (SDMA cause and mask registers). - - Required properties: - - reg : Offset and length of the register set for this device - - Example Discovery MPSCINTR node: - mpsintr@b800 { - reg = <0xb800 0x100>; - }; - - - i) Marvell Discovery MPSC nodes - - Represent the Discovery's MPSC (Multiprotocol Serial Controller) - serial port. - - Required properties: - - device_type : "serial" - - compatible : "marvell,mv64360-mpsc" - - reg : Offset and length of the register set for this device - - sdma : the phandle for the SDMA node used by this port - - brg : the phandle for the BRG node used by this port - - cunit : the phandle for the CUNIT node used by this port - - mpscrouting : the phandle for the MPSCROUTING node used by this port - - mpscintr : the phandle for the MPSCINTR node used by this port - - cell-index : the hardware index of this cell in the MPSC core - - max_idle : value needed for MPSC CHR3 (Maximum Frame Length) - register - - interrupts : where a is the interrupt number for the MPSC. - - interrupt-parent : the phandle for the interrupt controller - that services interrupts for this device. - - Example Discovery MPSCINTR node: - mpsc@8000 { - device_type = "serial"; - compatible = "marvell,mv64360-mpsc"; - reg = <0x8000 0x38>; - virtual-reg = <0xf1008000>; - sdma = <&SDMA0>; - brg = <&BRG0>; - cunit = <&CUNIT>; - mpscrouting = <&MPSCROUTING>; - mpscintr = <&MPSCINTR>; - cell-index = <0>; - max_idle = <40>; - interrupts = <40>; - interrupt-parent = <&PIC>; - }; - - - j) Marvell Discovery Watch Dog Timer nodes - - Represent the Discovery's watchdog timer hardware - - Required properties: - - compatible : "marvell,mv64360-wdt" - - reg : Offset and length of the register set for this device - - Example Discovery Watch Dog Timer node: - wdt@b410 { - compatible = "marvell,mv64360-wdt"; - reg = <0xb410 0x8>; - }; - - - k) Marvell Discovery I2C nodes - - Represent the Discovery's I2C hardware - - Required properties: - - device_type : "i2c" - - compatible : "marvell,mv64360-i2c" - - reg : Offset and length of the register set for this device - - interrupts : where a is the interrupt number for the I2C. - - interrupt-parent : the phandle for the interrupt controller - that services interrupts for this device. - - Example Discovery I2C node: - compatible = "marvell,mv64360-i2c"; - reg = <0xc000 0x20>; - virtual-reg = <0xf100c000>; - interrupts = <37>; - interrupt-parent = <&PIC>; - }; - - - l) Marvell Discovery PIC (Programmable Interrupt Controller) nodes - - Represent the Discovery's PIC hardware - - Required properties: - - #interrupt-cells : <1> - - #address-cells : <0> - - compatible : "marvell,mv64360-pic" - - reg : Offset and length of the register set for this device - - interrupt-controller - - Example Discovery PIC node: - pic { - #interrupt-cells = <1>; - #address-cells = <0>; - compatible = "marvell,mv64360-pic"; - reg = <0x0 0x88>; - interrupt-controller; - }; - - - m) Marvell Discovery MPP (Multipurpose Pins) multiplexing nodes - - Represent the Discovery's MPP hardware - - Required properties: - - compatible : "marvell,mv64360-mpp" - - reg : Offset and length of the register set for this device - - Example Discovery MPP node: - mpp@f000 { - compatible = "marvell,mv64360-mpp"; - reg = <0xf000 0x10>; - }; - - - n) Marvell Discovery GPP (General Purpose Pins) nodes - - Represent the Discovery's GPP hardware - - Required properties: - - compatible : "marvell,mv64360-gpp" - - reg : Offset and length of the register set for this device - - Example Discovery GPP node: - gpp@f000 { - compatible = "marvell,mv64360-gpp"; - reg = <0xf100 0x20>; - }; - - - o) Marvell Discovery PCI host bridge node - - Represents the Discovery's PCI host bridge device. The properties - for this node conform to Rev 2.1 of the PCI Bus Binding to IEEE - 1275-1994. A typical value for the compatible property is - "marvell,mv64360-pci". - - Example Discovery PCI host bridge node - pci@80000000 { - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - device_type = "pci"; - compatible = "marvell,mv64360-pci"; - reg = <0xcf8 0x8>; - ranges = <0x01000000 0x0 0x0 - 0x88000000 0x0 0x01000000 - 0x02000000 0x0 0x80000000 - 0x80000000 0x0 0x08000000>; - bus-range = <0 255>; - clock-frequency = <66000000>; - interrupt-parent = <&PIC>; - interrupt-map-mask = <0xf800 0x0 0x0 0x7>; - interrupt-map = < - /* IDSEL 0x0a */ - 0x5000 0 0 1 &PIC 80 - 0x5000 0 0 2 &PIC 81 - 0x5000 0 0 3 &PIC 91 - 0x5000 0 0 4 &PIC 93 - - /* IDSEL 0x0b */ - 0x5800 0 0 1 &PIC 91 - 0x5800 0 0 2 &PIC 93 - 0x5800 0 0 3 &PIC 80 - 0x5800 0 0 4 &PIC 81 - - /* IDSEL 0x0c */ - 0x6000 0 0 1 &PIC 91 - 0x6000 0 0 2 &PIC 93 - 0x6000 0 0 3 &PIC 80 - 0x6000 0 0 4 &PIC 81 - - /* IDSEL 0x0d */ - 0x6800 0 0 1 &PIC 93 - 0x6800 0 0 2 &PIC 80 - 0x6800 0 0 3 &PIC 81 - 0x6800 0 0 4 &PIC 91 - >; - }; - - - p) Marvell Discovery CPU Error nodes - - Represent the Discovery's CPU error handler device. - - Required properties: - - compatible : "marvell,mv64360-cpu-error" - - reg : Offset and length of the register set for this device - - interrupts : the interrupt number for this device - - interrupt-parent : the phandle for the interrupt controller - that services interrupts for this device. - - Example Discovery CPU Error node: - cpu-error@0070 { - compatible = "marvell,mv64360-cpu-error"; - reg = <0x70 0x10 0x128 0x28>; - interrupts = <3>; - interrupt-parent = <&PIC>; - }; - - - q) Marvell Discovery SRAM Controller nodes - - Represent the Discovery's SRAM controller device. - - Required properties: - - compatible : "marvell,mv64360-sram-ctrl" - - reg : Offset and length of the register set for this device - - interrupts : the interrupt number for this device - - interrupt-parent : the phandle for the interrupt controller - that services interrupts for this device. - - Example Discovery SRAM Controller node: - sram-ctrl@0380 { - compatible = "marvell,mv64360-sram-ctrl"; - reg = <0x380 0x80>; - interrupts = <13>; - interrupt-parent = <&PIC>; - }; - - - r) Marvell Discovery PCI Error Handler nodes - - Represent the Discovery's PCI error handler device. - - Required properties: - - compatible : "marvell,mv64360-pci-error" - - reg : Offset and length of the register set for this device - - interrupts : the interrupt number for this device - - interrupt-parent : the phandle for the interrupt controller - that services interrupts for this device. - - Example Discovery PCI Error Handler node: - pci-error@1d40 { - compatible = "marvell,mv64360-pci-error"; - reg = <0x1d40 0x40 0xc28 0x4>; - interrupts = <12>; - interrupt-parent = <&PIC>; - }; - - - s) Marvell Discovery Memory Controller nodes - - Represent the Discovery's memory controller device. - - Required properties: - - compatible : "marvell,mv64360-mem-ctrl" - - reg : Offset and length of the register set for this device - - interrupts : the interrupt number for this device - - interrupt-parent : the phandle for the interrupt controller - that services interrupts for this device. - - Example Discovery Memory Controller node: - mem-ctrl@1400 { - compatible = "marvell,mv64360-mem-ctrl"; - reg = <0x1400 0x60>; - interrupts = <17>; - interrupt-parent = <&PIC>; - }; - - diff --git a/trunk/Documentation/powerpc/dts-bindings/phy.txt b/trunk/Documentation/powerpc/dts-bindings/phy.txt deleted file mode 100644 index bb8c742eb8c5..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/phy.txt +++ /dev/null @@ -1,25 +0,0 @@ -PHY nodes - -Required properties: - - - device_type : Should be "ethernet-phy" - - interrupts : where a is the interrupt number and b is a - field that represents an encoding of the sense and level - information for the interrupt. This should be encoded based on - the information in section 2) depending on the type of interrupt - controller you have. - - interrupt-parent : the phandle for the interrupt controller that - services interrupts for this device. - - reg : The ID number for the phy, usually a small integer - - linux,phandle : phandle for this node; likely referenced by an - ethernet controller node. - -Example: - -ethernet-phy@0 { - linux,phandle = <2452000> - interrupt-parent = <40000>; - interrupts = <35 1>; - reg = <0>; - device_type = "ethernet-phy"; -}; diff --git a/trunk/Documentation/powerpc/dts-bindings/spi-bus.txt b/trunk/Documentation/powerpc/dts-bindings/spi-bus.txt deleted file mode 100644 index e782add2e457..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/spi-bus.txt +++ /dev/null @@ -1,57 +0,0 @@ -SPI (Serial Peripheral Interface) busses - -SPI busses can be described with a node for the SPI master device -and a set of child nodes for each SPI slave on the bus. For this -discussion, it is assumed that the system's SPI controller is in -SPI master mode. This binding does not describe SPI controllers -in slave mode. - -The SPI master node requires the following properties: -- #address-cells - number of cells required to define a chip select - address on the SPI bus. -- #size-cells - should be zero. -- compatible - name of SPI bus controller following generic names - recommended practice. -No other properties are required in the SPI bus node. It is assumed -that a driver for an SPI bus device will understand that it is an SPI bus. -However, the binding does not attempt to define the specific method for -assigning chip select numbers. Since SPI chip select configuration is -flexible and non-standardized, it is left out of this binding with the -assumption that board specific platform code will be used to manage -chip selects. Individual drivers can define additional properties to -support describing the chip select layout. - -SPI slave nodes must be children of the SPI master node and can -contain the following properties. -- reg - (required) chip select address of device. -- compatible - (required) name of SPI device following generic names - recommended practice -- spi-max-frequency - (required) Maximum SPI clocking speed of device in Hz -- spi-cpol - (optional) Empty property indicating device requires - inverse clock polarity (CPOL) mode -- spi-cpha - (optional) Empty property indicating device requires - shifted clock phase (CPHA) mode -- spi-cs-high - (optional) Empty property indicating device requires - chip select active high - -SPI example for an MPC5200 SPI bus: - spi@f00 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; - reg = <0xf00 0x20>; - interrupts = <2 13 0 2 14 0>; - interrupt-parent = <&mpc5200_pic>; - - ethernet-switch@0 { - compatible = "micrel,ks8995m"; - spi-max-frequency = <1000000>; - reg = <0>; - }; - - codec@1 { - compatible = "ti,tlv320aic26"; - spi-max-frequency = <100000>; - reg = <1>; - }; - }; diff --git a/trunk/Documentation/powerpc/dts-bindings/usb-ehci.txt b/trunk/Documentation/powerpc/dts-bindings/usb-ehci.txt deleted file mode 100644 index fa18612f757b..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/usb-ehci.txt +++ /dev/null @@ -1,25 +0,0 @@ -USB EHCI controllers - -Required properties: - - compatible : should be "usb-ehci". - - reg : should contain at least address and length of the standard EHCI - register set for the device. Optional platform-dependent registers - (debug-port or other) can be also specified here, but only after - definition of standard EHCI registers. - - interrupts : one EHCI interrupt should be described here. -If device registers are implemented in big endian mode, the device -node should have "big-endian-regs" property. -If controller implementation operates with big endian descriptors, -"big-endian-desc" property should be specified. -If both big endian registers and descriptors are used by the controller -implementation, "big-endian" property can be specified instead of having -both "big-endian-regs" and "big-endian-desc". - -Example (Sequoia 440EPx): - ehci@e0000300 { - compatible = "ibm,usb-ehci-440epx", "usb-ehci"; - interrupt-parent = <&UIC0>; - interrupts = <1a 4>; - reg = <0 e0000300 90 0 e0000390 70>; - big-endian; - }; diff --git a/trunk/Documentation/powerpc/dts-bindings/xilinx.txt b/trunk/Documentation/powerpc/dts-bindings/xilinx.txt deleted file mode 100644 index 80339fe4300b..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/xilinx.txt +++ /dev/null @@ -1,295 +0,0 @@ - d) Xilinx IP cores - - The Xilinx EDK toolchain ships with a set of IP cores (devices) for use - in Xilinx Spartan and Virtex FPGAs. The devices cover the whole range - of standard device types (network, serial, etc.) and miscellaneous - devices (gpio, LCD, spi, etc). Also, since these devices are - implemented within the fpga fabric every instance of the device can be - synthesised with different options that change the behaviour. - - Each IP-core has a set of parameters which the FPGA designer can use to - control how the core is synthesized. Historically, the EDK tool would - extract the device parameters relevant to device drivers and copy them - into an 'xparameters.h' in the form of #define symbols. This tells the - device drivers how the IP cores are configured, but it requres the kernel - to be recompiled every time the FPGA bitstream is resynthesized. - - The new approach is to export the parameters into the device tree and - generate a new device tree each time the FPGA bitstream changes. The - parameters which used to be exported as #defines will now become - properties of the device node. In general, device nodes for IP-cores - will take the following form: - - (name): (generic-name)@(base-address) { - compatible = "xlnx,(ip-core-name)-(HW_VER)" - [, (list of compatible devices), ...]; - reg = <(baseaddr) (size)>; - interrupt-parent = <&interrupt-controller-phandle>; - interrupts = < ... >; - xlnx,(parameter1) = "(string-value)"; - xlnx,(parameter2) = <(int-value)>; - }; - - (generic-name): an open firmware-style name that describes the - generic class of device. Preferably, this is one word, such - as 'serial' or 'ethernet'. - (ip-core-name): the name of the ip block (given after the BEGIN - directive in system.mhs). Should be in lowercase - and all underscores '_' converted to dashes '-'. - (name): is derived from the "PARAMETER INSTANCE" value. - (parameter#): C_* parameters from system.mhs. The C_ prefix is - dropped from the parameter name, the name is converted - to lowercase and all underscore '_' characters are - converted to dashes '-'. - (baseaddr): the baseaddr parameter value (often named C_BASEADDR). - (HW_VER): from the HW_VER parameter. - (size): the address range size (often C_HIGHADDR - C_BASEADDR + 1). - - Typically, the compatible list will include the exact IP core version - followed by an older IP core version which implements the same - interface or any other device with the same interface. - - 'reg', 'interrupt-parent' and 'interrupts' are all optional properties. - - For example, the following block from system.mhs: - - BEGIN opb_uartlite - PARAMETER INSTANCE = opb_uartlite_0 - PARAMETER HW_VER = 1.00.b - PARAMETER C_BAUDRATE = 115200 - PARAMETER C_DATA_BITS = 8 - PARAMETER C_ODD_PARITY = 0 - PARAMETER C_USE_PARITY = 0 - PARAMETER C_CLK_FREQ = 50000000 - PARAMETER C_BASEADDR = 0xEC100000 - PARAMETER C_HIGHADDR = 0xEC10FFFF - BUS_INTERFACE SOPB = opb_7 - PORT OPB_Clk = CLK_50MHz - PORT Interrupt = opb_uartlite_0_Interrupt - PORT RX = opb_uartlite_0_RX - PORT TX = opb_uartlite_0_TX - PORT OPB_Rst = sys_bus_reset_0 - END - - becomes the following device tree node: - - opb_uartlite_0: serial@ec100000 { - device_type = "serial"; - compatible = "xlnx,opb-uartlite-1.00.b"; - reg = ; - interrupt-parent = <&opb_intc_0>; - interrupts = <1 0>; // got this from the opb_intc parameters - current-speed = ; // standard serial device prop - clock-frequency = ; // standard serial device prop - xlnx,data-bits = <8>; - xlnx,odd-parity = <0>; - xlnx,use-parity = <0>; - }; - - Some IP cores actually implement 2 or more logical devices. In - this case, the device should still describe the whole IP core with - a single node and add a child node for each logical device. The - ranges property can be used to translate from parent IP-core to the - registers of each device. In addition, the parent node should be - compatible with the bus type 'xlnx,compound', and should contain - #address-cells and #size-cells, as with any other bus. (Note: this - makes the assumption that both logical devices have the same bus - binding. If this is not true, then separate nodes should be used - for each logical device). The 'cell-index' property can be used to - enumerate logical devices within an IP core. For example, the - following is the system.mhs entry for the dual ps2 controller found - on the ml403 reference design. - - BEGIN opb_ps2_dual_ref - PARAMETER INSTANCE = opb_ps2_dual_ref_0 - PARAMETER HW_VER = 1.00.a - PARAMETER C_BASEADDR = 0xA9000000 - PARAMETER C_HIGHADDR = 0xA9001FFF - BUS_INTERFACE SOPB = opb_v20_0 - PORT Sys_Intr1 = ps2_1_intr - PORT Sys_Intr2 = ps2_2_intr - PORT Clkin1 = ps2_clk_rx_1 - PORT Clkin2 = ps2_clk_rx_2 - PORT Clkpd1 = ps2_clk_tx_1 - PORT Clkpd2 = ps2_clk_tx_2 - PORT Rx1 = ps2_d_rx_1 - PORT Rx2 = ps2_d_rx_2 - PORT Txpd1 = ps2_d_tx_1 - PORT Txpd2 = ps2_d_tx_2 - END - - It would result in the following device tree nodes: - - opb_ps2_dual_ref_0: opb-ps2-dual-ref@a9000000 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "xlnx,compound"; - ranges = <0 a9000000 2000>; - // If this device had extra parameters, then they would - // go here. - ps2@0 { - compatible = "xlnx,opb-ps2-dual-ref-1.00.a"; - reg = <0 40>; - interrupt-parent = <&opb_intc_0>; - interrupts = <3 0>; - cell-index = <0>; - }; - ps2@1000 { - compatible = "xlnx,opb-ps2-dual-ref-1.00.a"; - reg = <1000 40>; - interrupt-parent = <&opb_intc_0>; - interrupts = <3 0>; - cell-index = <0>; - }; - }; - - Also, the system.mhs file defines bus attachments from the processor - to the devices. The device tree structure should reflect the bus - attachments. Again an example; this system.mhs fragment: - - BEGIN ppc405_virtex4 - PARAMETER INSTANCE = ppc405_0 - PARAMETER HW_VER = 1.01.a - BUS_INTERFACE DPLB = plb_v34_0 - BUS_INTERFACE IPLB = plb_v34_0 - END - - BEGIN opb_intc - PARAMETER INSTANCE = opb_intc_0 - PARAMETER HW_VER = 1.00.c - PARAMETER C_BASEADDR = 0xD1000FC0 - PARAMETER C_HIGHADDR = 0xD1000FDF - BUS_INTERFACE SOPB = opb_v20_0 - END - - BEGIN opb_uart16550 - PARAMETER INSTANCE = opb_uart16550_0 - PARAMETER HW_VER = 1.00.d - PARAMETER C_BASEADDR = 0xa0000000 - PARAMETER C_HIGHADDR = 0xa0001FFF - BUS_INTERFACE SOPB = opb_v20_0 - END - - BEGIN plb_v34 - PARAMETER INSTANCE = plb_v34_0 - PARAMETER HW_VER = 1.02.a - END - - BEGIN plb_bram_if_cntlr - PARAMETER INSTANCE = plb_bram_if_cntlr_0 - PARAMETER HW_VER = 1.00.b - PARAMETER C_BASEADDR = 0xFFFF0000 - PARAMETER C_HIGHADDR = 0xFFFFFFFF - BUS_INTERFACE SPLB = plb_v34_0 - END - - BEGIN plb2opb_bridge - PARAMETER INSTANCE = plb2opb_bridge_0 - PARAMETER HW_VER = 1.01.a - PARAMETER C_RNG0_BASEADDR = 0x20000000 - PARAMETER C_RNG0_HIGHADDR = 0x3FFFFFFF - PARAMETER C_RNG1_BASEADDR = 0x60000000 - PARAMETER C_RNG1_HIGHADDR = 0x7FFFFFFF - PARAMETER C_RNG2_BASEADDR = 0x80000000 - PARAMETER C_RNG2_HIGHADDR = 0xBFFFFFFF - PARAMETER C_RNG3_BASEADDR = 0xC0000000 - PARAMETER C_RNG3_HIGHADDR = 0xDFFFFFFF - BUS_INTERFACE SPLB = plb_v34_0 - BUS_INTERFACE MOPB = opb_v20_0 - END - - Gives this device tree (some properties removed for clarity): - - plb@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "xlnx,plb-v34-1.02.a"; - device_type = "ibm,plb"; - ranges; // 1:1 translation - - plb_bram_if_cntrl_0: bram@ffff0000 { - reg = ; - } - - opb@20000000 { - #address-cells = <1>; - #size-cells = <1>; - ranges = <20000000 20000000 20000000 - 60000000 60000000 20000000 - 80000000 80000000 40000000 - c0000000 c0000000 20000000>; - - opb_uart16550_0: serial@a0000000 { - reg = ; - }; - - opb_intc_0: interrupt-controller@d1000fc0 { - reg = ; - }; - }; - }; - - That covers the general approach to binding xilinx IP cores into the - device tree. The following are bindings for specific devices: - - i) Xilinx ML300 Framebuffer - - Simple framebuffer device from the ML300 reference design (also on the - ML403 reference design as well as others). - - Optional properties: - - resolution = : pixel resolution of framebuffer. Some - implementations use a different resolution. - Default is - - virt-resolution = : Size of framebuffer in memory. - Default is . - - rotate-display (empty) : rotate display 180 degrees. - - ii) Xilinx SystemACE - - The Xilinx SystemACE device is used to program FPGAs from an FPGA - bitstream stored on a CF card. It can also be used as a generic CF - interface device. - - Optional properties: - - 8-bit (empty) : Set this property for SystemACE in 8 bit mode - - iii) Xilinx EMAC and Xilinx TEMAC - - Xilinx Ethernet devices. In addition to general xilinx properties - listed above, nodes for these devices should include a phy-handle - property, and may include other common network device properties - like local-mac-address. - - iv) Xilinx Uartlite - - Xilinx uartlite devices are simple fixed speed serial ports. - - Required properties: - - current-speed : Baud rate of uartlite - - v) Xilinx hwicap - - Xilinx hwicap devices provide access to the configuration logic - of the FPGA through the Internal Configuration Access Port - (ICAP). The ICAP enables partial reconfiguration of the FPGA, - readback of the configuration information, and some control over - 'warm boots' of the FPGA fabric. - - Required properties: - - xlnx,family : The family of the FPGA, necessary since the - capabilities of the underlying ICAP hardware - differ between different families. May be - 'virtex2p', 'virtex4', or 'virtex5'. - - vi) Xilinx Uart 16550 - - Xilinx UART 16550 devices are very similar to the NS16550 but with - different register spacing and an offset from the base address. - - Required properties: - - clock-frequency : Frequency of the clock input - - reg-offset : A value of 3 is required - - reg-shift : A value of 2 is required - - diff --git a/trunk/Documentation/sound/alsa/HD-Audio-Models.txt b/trunk/Documentation/sound/alsa/HD-Audio-Models.txt index 939a3dd58148..0d8d23581c44 100644 --- a/trunk/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/trunk/Documentation/sound/alsa/HD-Audio-Models.txt @@ -240,7 +240,6 @@ AD1986A laptop-automute 2-channel with EAPD and HP-automute (Lenovo N100) ultra 2-channel with EAPD (Samsung Ultra tablet PC) samsung 2-channel with EAPD (Samsung R65) - samsung-p50 2-channel with HP-automute (Samsung P50) AD1988/AD1988B/AD1989A/AD1989B ============================== diff --git a/trunk/Documentation/spi/spidev_test.c b/trunk/Documentation/spi/spidev_test.c index c1a5aad3c75a..cf0e3ce0d526 100644 --- a/trunk/Documentation/spi/spidev_test.c +++ b/trunk/Documentation/spi/spidev_test.c @@ -99,13 +99,11 @@ void parse_opts(int argc, char *argv[]) { "lsb", 0, 0, 'L' }, { "cs-high", 0, 0, 'C' }, { "3wire", 0, 0, '3' }, - { "no-cs", 0, 0, 'N' }, - { "ready", 0, 0, 'R' }, { NULL, 0, 0, 0 }, }; int c; - c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL); + c = getopt_long(argc, argv, "D:s:d:b:lHOLC3", lopts, NULL); if (c == -1) break; @@ -141,12 +139,6 @@ void parse_opts(int argc, char *argv[]) case '3': mode |= SPI_3WIRE; break; - case 'N': - mode |= SPI_NO_CS; - break; - case 'R': - mode |= SPI_READY; - break; default: print_usage(argv[0]); break; diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 381190c7949c..fa2a16def17a 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -867,22 +867,12 @@ M: alex@shark-linux.de W: http://www.shark-linux.de/shark.html S: Maintained -ARM/SAMSUNG ARM ARCHITECTURES -P: Ben Dooks -M: ben-linux@fluff.org -L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) -W: http://www.fluff.org/ben/linux/ -S: Maintained -F: arch/arm/plat-s3c/ -F: arch/arm/plat-s3c24xx/ - ARM/S3C2410 ARM ARCHITECTURE P: Ben Dooks M: ben-linux@fluff.org L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) W: http://www.fluff.org/ben/linux/ S: Maintained -F: arch/arm/mach-s3c2410/ ARM/S3C2440 ARM ARCHITECTURE P: Ben Dooks @@ -890,39 +880,6 @@ M: ben-linux@fluff.org L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) W: http://www.fluff.org/ben/linux/ S: Maintained -F: arch/arm/mach-s3c2440/ - -ARM/S3C2442 ARM ARCHITECTURE -P: Ben Dooks -M: ben-linux@fluff.org -L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) -W: http://www.fluff.org/ben/linux/ -S: Maintained -F: arch/arm/mach-s3c2442/ - -ARM/S3C2443 ARM ARCHITECTURE -P: Ben Dooks -M: ben-linux@fluff.org -L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) -W: http://www.fluff.org/ben/linux/ -S: Maintained -F: arch/arm/mach-s3c2443/ - -ARM/S3C6400 ARM ARCHITECTURE -P: Ben Dooks -M: ben-linux@fluff.org -L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) -W: http://www.fluff.org/ben/linux/ -S: Maintained -F: arch/arm/mach-s3c6400/ - -ARM/S3C6410 ARM ARCHITECTURE -P: Ben Dooks -M: ben-linux@fluff.org -L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) -W: http://www.fluff.org/ben/linux/ -S: Maintained -F: arch/arm/mach-s3c6410/ ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT P: Lennert Buytenhek @@ -2130,9 +2087,9 @@ F: drivers/edac/i5400_edac.c EDAC-I82975X P: Ranganathan Desikan -M: ravi@jetztechnologies.com +M: rdesikan@jetzbroadband.com P: Arvind R. -M: arvind@jetztechnologies.com +M: arvind@acarlab.com L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) W: bluesmoke.sourceforge.net S: Maintained @@ -2851,9 +2808,7 @@ S: Maintained IA64 (Itanium) PLATFORM P: Tony Luck -P: Fenghua Yu M: tony.luck@intel.com -M: fenghua.yu@intel.com L: linux-ia64@vger.kernel.org W: http://www.ia64-linux.org/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6.git @@ -2931,7 +2886,7 @@ P: Dmitry Eremin-Solenikov M: dbaryshkov@gmail.com P: Sergey Lapin M: slapin@ossfans.org -L: linux-zigbee-devel@lists.sourceforge.net (moderated for non-subscribers) +L: linux-zigbee-devel@lists.sourceforge.net W: http://apps.sourceforge.net/trac/linux-zigbee T: git git://git.kernel.org/pub/scm/linux/kernel/git/lowpan/lowpan.git S: Maintained @@ -5578,8 +5533,8 @@ F: drivers/staging/ STARFIRE/DURALAN NETWORK DRIVER P: Ion Badulescu -M: ionut@badula.org -S: Odd Fixes +M: ionut@cs.columbia.edu +S: Maintained F: drivers/net/starfire* STARMODE RADIO IP (STRIP) PROTOCOL DRIVER @@ -5713,13 +5668,6 @@ F: drivers/misc/tifm* F: drivers/mmc/host/tifm_sd.c F: include/linux/tifm.h -TI TWL4030 SERIES SOC CODEC DRIVER -P: Peter Ujfalusi -M: peter.ujfalusi@nokia.com -L: alsa-devel@alsa-project.org (moderated for non-subscribers) -S: Maintained -F: sound/soc/codecs/twl4030* - TIPC NETWORK LAYER P: Per Liden M: per.liden@ericsson.com diff --git a/trunk/arch/alpha/include/asm/percpu.h b/trunk/arch/alpha/include/asm/percpu.h index b663f1f10b6a..06c5c7a4afd3 100644 --- a/trunk/arch/alpha/include/asm/percpu.h +++ b/trunk/arch/alpha/include/asm/percpu.h @@ -30,7 +30,7 @@ extern unsigned long __per_cpu_offset[NR_CPUS]; #ifndef MODULE #define SHIFT_PERCPU_PTR(var, offset) RELOC_HIDE(&per_cpu_var(var), (offset)) -#define PER_CPU_DEF_ATTRIBUTES +#define PER_CPU_ATTRIBUTES #else /* * To calculate addresses of locally defined variables, GCC uses 32-bit @@ -49,7 +49,7 @@ extern unsigned long __per_cpu_offset[NR_CPUS]; : "=&r"(__ptr), "=&r"(tmp_gp)); \ (typeof(&per_cpu_var(var)))(__ptr + (offset)); }) -#define PER_CPU_DEF_ATTRIBUTES __used +#define PER_CPU_ATTRIBUTES __used #endif /* MODULE */ @@ -71,7 +71,7 @@ extern unsigned long __per_cpu_offset[NR_CPUS]; #define __get_cpu_var(var) per_cpu_var(var) #define __raw_get_cpu_var(var) per_cpu_var(var) -#define PER_CPU_DEF_ATTRIBUTES +#define PER_CPU_ATTRIBUTES #endif /* SMP */ diff --git a/trunk/arch/arm/Kconfig.debug b/trunk/arch/arm/Kconfig.debug index a89e4734b8f0..a71fd941ade7 100644 --- a/trunk/arch/arm/Kconfig.debug +++ b/trunk/arch/arm/Kconfig.debug @@ -99,6 +99,14 @@ config DEBUG_CLPS711X_UART2 output to the second serial port on these devices. Saying N will cause the debug messages to appear on the first serial port. +config DEBUG_S3C_PORT + depends on DEBUG_LL && PLAT_S3C + bool "Kernel low-level debugging messages via S3C UART" + help + Say Y here if you want debug print routines to go to one of the + S3C internal UARTs. The chosen UART must have been configured + before it is used. + config DEBUG_S3C_UART depends on PLAT_S3C int "S3C UART to use for low-level debug" diff --git a/trunk/arch/arm/configs/s3c2410_defconfig b/trunk/arch/arm/configs/s3c2410_defconfig index b49810461e41..2d58b8fe59be 100644 --- a/trunk/arch/arm/configs/s3c2410_defconfig +++ b/trunk/arch/arm/configs/s3c2410_defconfig @@ -260,7 +260,6 @@ CONFIG_MACH_NEXCODER_2440=y CONFIG_SMDK2440_CPU2440=y CONFIG_MACH_AT2440EVB=y CONFIG_CPU_S3C2442=y -CONFIG_MACH_MINI2440=y # # S3C2442 Machines @@ -2299,6 +2298,7 @@ CONFIG_DEBUG_ERRORS=y # CONFIG_DEBUG_STACK_USAGE is not set CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set +CONFIG_DEBUG_S3C_PORT=y CONFIG_DEBUG_S3C_UART=0 # diff --git a/trunk/arch/arm/configs/s3c6400_defconfig b/trunk/arch/arm/configs/s3c6400_defconfig index 32860609e057..2e8fa50e9a09 100644 --- a/trunk/arch/arm/configs/s3c6400_defconfig +++ b/trunk/arch/arm/configs/s3c6400_defconfig @@ -816,6 +816,7 @@ CONFIG_DEBUG_ERRORS=y # CONFIG_DEBUG_STACK_USAGE is not set CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set +CONFIG_DEBUG_S3C_PORT=y CONFIG_DEBUG_S3C_UART=0 # diff --git a/trunk/arch/arm/configs/tct_hammer_defconfig b/trunk/arch/arm/configs/tct_hammer_defconfig index 9d32faef05f6..07dfb98df4f0 100644 --- a/trunk/arch/arm/configs/tct_hammer_defconfig +++ b/trunk/arch/arm/configs/tct_hammer_defconfig @@ -857,6 +857,7 @@ CONFIG_DEBUG_ERRORS=y # CONFIG_DEBUG_STACK_USAGE is not set CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set +# CONFIG_DEBUG_S3C_PORT is not set CONFIG_DEBUG_S3C_UART=0 # diff --git a/trunk/arch/arm/include/asm/page.h b/trunk/arch/arm/include/asm/page.h index 9c746af1bf6e..be962c1349c4 100644 --- a/trunk/arch/arm/include/asm/page.h +++ b/trunk/arch/arm/include/asm/page.h @@ -12,7 +12,7 @@ /* PAGE_SHIFT determines the page size */ #define PAGE_SHIFT 12 -#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) +#define PAGE_SIZE (1UL << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) #ifndef __ASSEMBLY__ diff --git a/trunk/arch/arm/kernel/irq.c b/trunk/arch/arm/kernel/irq.c index b7c3490eaa24..096f600dc8d8 100644 --- a/trunk/arch/arm/kernel/irq.c +++ b/trunk/arch/arm/kernel/irq.c @@ -98,6 +98,17 @@ int show_interrupts(struct seq_file *p, void *v) return 0; } +/* Handle bad interrupts */ +static struct irq_desc bad_irq_desc = { + .handle_irq = handle_bad_irq, + .lock = __SPIN_LOCK_UNLOCKED(bad_irq_desc.lock), +}; + +#ifdef CONFIG_CPUMASK_OFFSTACK +/* We are not allocating bad_irq_desc.affinity or .pending_mask */ +#error "ARM architecture does not support CONFIG_CPUMASK_OFFSTACK." +#endif + /* * do_IRQ handles all hardware IRQ's. Decoded IRQs should not * come via this function. Instead, they should provide their @@ -113,13 +124,10 @@ asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs) * Some hardware gives randomly wrong interrupts. Rather * than crashing, do something sensible. */ - if (unlikely(irq >= NR_IRQS)) { - if (printk_ratelimit()) - printk(KERN_WARNING "Bad IRQ%u\n", irq); - ack_bad_irq(irq); - } else { + if (irq >= NR_IRQS) + handle_bad_irq(irq, &bad_irq_desc); + else generic_handle_irq(irq); - } /* AT91 specific workaround */ irq_finish(irq); @@ -157,6 +165,10 @@ void __init init_IRQ(void) for (irq = 0; irq < NR_IRQS; irq++) irq_desc[irq].status |= IRQ_NOREQUEST | IRQ_NOPROBE; +#ifdef CONFIG_SMP + cpumask_setall(bad_irq_desc.affinity); + bad_irq_desc.node = smp_processor_id(); +#endif init_arch_irq(); } diff --git a/trunk/arch/arm/kernel/vmlinux.lds.S b/trunk/arch/arm/kernel/vmlinux.lds.S index 69371028a202..4340bf3d2c84 100644 --- a/trunk/arch/arm/kernel/vmlinux.lds.S +++ b/trunk/arch/arm/kernel/vmlinux.lds.S @@ -6,7 +6,6 @@ #include #include #include -#include OUTPUT_ARCH(arm) ENTRY(stext) @@ -64,7 +63,7 @@ SECTIONS usr/built-in.o(.init.ramfs) __initramfs_end = .; #endif - . = ALIGN(PAGE_SIZE); + . = ALIGN(4096); __per_cpu_load = .; __per_cpu_start = .; *(.data.percpu.page_aligned) @@ -74,7 +73,7 @@ SECTIONS #ifndef CONFIG_XIP_KERNEL __init_begin = _stext; INIT_DATA - . = ALIGN(PAGE_SIZE); + . = ALIGN(4096); __init_end = .; #endif } @@ -119,7 +118,7 @@ SECTIONS *(.got) /* Global offset table */ } - RO_DATA(PAGE_SIZE) + RODATA _etext = .; /* End of text and rodata section */ @@ -159,17 +158,17 @@ SECTIONS *(.data.init_task) #ifdef CONFIG_XIP_KERNEL - . = ALIGN(PAGE_SIZE); + . = ALIGN(4096); __init_begin = .; INIT_DATA - . = ALIGN(PAGE_SIZE); + . = ALIGN(4096); __init_end = .; #endif - . = ALIGN(PAGE_SIZE); + . = ALIGN(4096); __nosave_begin = .; *(.data.nosave) - . = ALIGN(PAGE_SIZE); + . = ALIGN(4096); __nosave_end = .; /* diff --git a/trunk/arch/arm/mach-at91/board-sam9g20ek.c b/trunk/arch/arm/mach-at91/board-sam9g20ek.c index a55398ed1211..cc270beadd5d 100644 --- a/trunk/arch/arm/mach-at91/board-sam9g20ek.c +++ b/trunk/arch/arm/mach-at91/board-sam9g20ek.c @@ -24,8 +24,6 @@ #include #include #include -#include -#include #include #include @@ -220,56 +218,6 @@ static struct gpio_led ek_leds[] = { } }; - -/* - * GPIO Buttons - */ -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -static struct gpio_keys_button ek_buttons[] = { - { - .gpio = AT91_PIN_PA30, - .code = BTN_3, - .desc = "Button 3", - .active_low = 1, - .wakeup = 1, - }, - { - .gpio = AT91_PIN_PA31, - .code = BTN_4, - .desc = "Button 4", - .active_low = 1, - .wakeup = 1, - } -}; - -static struct gpio_keys_platform_data ek_button_data = { - .buttons = ek_buttons, - .nbuttons = ARRAY_SIZE(ek_buttons), -}; - -static struct platform_device ek_button_device = { - .name = "gpio-keys", - .id = -1, - .num_resources = 0, - .dev = { - .platform_data = &ek_button_data, - } -}; - -static void __init ek_add_device_buttons(void) -{ - at91_set_gpio_input(AT91_PIN_PA30, 1); /* btn3 */ - at91_set_deglitch(AT91_PIN_PA30, 1); - at91_set_gpio_input(AT91_PIN_PA31, 1); /* btn4 */ - at91_set_deglitch(AT91_PIN_PA31, 1); - - platform_device_register(&ek_button_device); -} -#else -static void __init ek_add_device_buttons(void) {} -#endif - - static struct i2c_board_info __initdata ek_i2c_devices[] = { { I2C_BOARD_INFO("24c512", 0x50), @@ -297,8 +245,6 @@ static void __init ek_board_init(void) at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices)); /* LEDs */ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); - /* Push Buttons */ - ek_add_device_buttons(); /* PCK0 provides MCLK to the WM8731 */ at91_set_B_periph(AT91_PIN_PC1, 0); /* SSC (for WM8731) */ diff --git a/trunk/arch/arm/mach-at91/board-sam9rlek.c b/trunk/arch/arm/mach-at91/board-sam9rlek.c index f6b5672cabd6..35e12a49d1a6 100644 --- a/trunk/arch/arm/mach-at91/board-sam9rlek.c +++ b/trunk/arch/arm/mach-at91/board-sam9rlek.c @@ -186,21 +186,19 @@ static struct fb_monspecs at91fb_default_monspecs = { static void at91_lcdc_power_control(int on) { if (on) - at91_set_gpio_value(AT91_PIN_PC1, 0); /* power up */ + at91_set_gpio_value(AT91_PIN_PA30, 0); /* power up */ else - at91_set_gpio_value(AT91_PIN_PC1, 1); /* power down */ + at91_set_gpio_value(AT91_PIN_PA30, 1); /* power down */ } /* Driver datas */ static struct atmel_lcdfb_info __initdata ek_lcdc_data = { - .lcdcon_is_backlight = true, .default_bpp = 16, .default_dmacon = ATMEL_LCDC_DMAEN, .default_lcdcon2 = AT91SAM9RL_DEFAULT_LCDCON2, .default_monspecs = &at91fb_default_monspecs, .atmel_lcdfb_power_control = at91_lcdc_power_control, .guard_time = 1, - .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB, }; #else diff --git a/trunk/arch/arm/mach-omap1/board-nokia770.c b/trunk/arch/arm/mach-omap1/board-nokia770.c index ed2a48a9ce74..e70fc7c66bbb 100644 --- a/trunk/arch/arm/mach-omap1/board-nokia770.c +++ b/trunk/arch/arm/mach-omap1/board-nokia770.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #define ADS7846_PENDOWN_GPIO 15 @@ -204,11 +205,9 @@ static int nokia770_mmc_get_cover_state(struct device *dev, int slot) static struct omap_mmc_platform_data nokia770_mmc2_data = { .nr_slots = 1, .dma_mask = 0xffffffff, - .max_freq = 12000000, .slots[0] = { .set_power = nokia770_mmc_set_power, .get_cover_state = nokia770_mmc_get_cover_state, - .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .name = "mmcblk", }, }; diff --git a/trunk/arch/arm/mach-omap1/mailbox.c b/trunk/arch/arm/mach-omap1/mailbox.c index 6810b4aeb02c..0af4d6c85b47 100644 --- a/trunk/arch/arm/mach-omap1/mailbox.c +++ b/trunk/arch/arm/mach-omap1/mailbox.c @@ -203,5 +203,5 @@ module_exit(omap1_mbox_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("omap mailbox: omap1 architecture specific functions"); -MODULE_AUTHOR("Hiroshi DOYU "); +MODULE_AUTHOR("Hiroshi DOYU" ); MODULE_ALIAS("platform:omap1-mailbox"); diff --git a/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c b/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c index 9a0bf6744a05..da93b86234ed 100644 --- a/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -362,7 +362,6 @@ static struct omap_onenand_platform_data board_onenand_data = { .gpio_irq = 65, .parts = onenand_partitions, .nr_parts = ARRAY_SIZE(onenand_partitions), - .flags = ONENAND_SYNC_READWRITE, }; static void __init board_onenand_init(void) diff --git a/trunk/arch/arm/mach-omap2/gpmc-onenand.c b/trunk/arch/arm/mach-omap2/gpmc-onenand.c index 54fec53a48e7..2fd22f9c5f0e 100644 --- a/trunk/arch/arm/mach-omap2/gpmc-onenand.c +++ b/trunk/arch/arm/mach-omap2/gpmc-onenand.c @@ -31,8 +31,6 @@ static struct platform_device gpmc_onenand_device = { static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base) { struct gpmc_timings t; - u32 reg; - int err; const int t_cer = 15; const int t_avdp = 12; @@ -45,11 +43,6 @@ static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base) const int t_wpl = 40; const int t_wph = 30; - /* Ensure sync read and sync write are disabled */ - reg = readw(onenand_base + ONENAND_REG_SYS_CFG1); - reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE; - writew(reg, onenand_base + ONENAND_REG_SYS_CFG1); - memset(&t, 0, sizeof(t)); t.sync_clk = 0; t.cs_on = 0; @@ -81,16 +74,7 @@ static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base) GPMC_CONFIG1_DEVICESIZE_16 | GPMC_CONFIG1_MUXADDDATA); - err = gpmc_cs_set_timings(cs, &t); - if (err) - return err; - - /* Ensure sync read and sync write are disabled */ - reg = readw(onenand_base + ONENAND_REG_SYS_CFG1); - reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE; - writew(reg, onenand_base + ONENAND_REG_SYS_CFG1); - - return 0; + return gpmc_cs_set_timings(cs, &t); } static void set_onenand_cfg(void __iomem *onenand_base, int latency, @@ -140,8 +124,7 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg, } else if (cfg->flags & ONENAND_SYNC_READWRITE) { sync_read = 1; sync_write = 1; - } else - return omap2_onenand_set_async_mode(cs, onenand_base); + } if (!freq) { /* Very first call freq is not known */ diff --git a/trunk/arch/arm/mach-omap2/id.c b/trunk/arch/arm/mach-omap2/id.c index a98201cc265c..458990e20c60 100644 --- a/trunk/arch/arm/mach-omap2/id.c +++ b/trunk/arch/arm/mach-omap2/id.c @@ -48,28 +48,6 @@ int omap_chip_is(struct omap_chip_id oci) } EXPORT_SYMBOL(omap_chip_is); -int omap_type(void) -{ - u32 val = 0; - - if (cpu_is_omap24xx()) - val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS); - else if (cpu_is_omap34xx()) - val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS); - else { - pr_err("Cannot detect omap type!\n"); - goto out; - } - - val &= OMAP2_DEVICETYPE_MASK; - val >>= 8; - -out: - return val; -} -EXPORT_SYMBOL(omap_type); - - /*----------------------------------------------------------------------------*/ #define OMAP_TAP_IDCODE 0x0204 diff --git a/trunk/arch/arm/mach-omap2/mailbox.c b/trunk/arch/arm/mach-omap2/mailbox.c index 6f71f3730c97..fd5b8a5925cc 100644 --- a/trunk/arch/arm/mach-omap2/mailbox.c +++ b/trunk/arch/arm/mach-omap2/mailbox.c @@ -282,12 +282,12 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev) return -ENOMEM; /* DSP or IVA2 IRQ */ - ret = platform_get_irq(pdev, 0); - if (ret < 0) { + mbox_dsp_info.irq = platform_get_irq(pdev, 0); + if (mbox_dsp_info.irq < 0) { dev_err(&pdev->dev, "invalid irq resource\n"); + ret = -ENODEV; goto err_dsp; } - mbox_dsp_info.irq = ret; ret = omap_mbox_register(&pdev->dev, &mbox_dsp_info); if (ret) diff --git a/trunk/arch/arm/mach-omap2/mmc-twl4030.c b/trunk/arch/arm/mach-omap2/mmc-twl4030.c index 1541fd4c8d0f..9756a878fd90 100644 --- a/trunk/arch/arm/mach-omap2/mmc-twl4030.c +++ b/trunk/arch/arm/mach-omap2/mmc-twl4030.c @@ -263,19 +263,8 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int vdd) { int ret = 0; - struct twl_mmc_controller *c = NULL; + struct twl_mmc_controller *c = &hsmmc[1]; struct omap_mmc_platform_data *mmc = dev->platform_data; - int i; - - for (i = 1; i < ARRAY_SIZE(hsmmc); i++) { - if (mmc == hsmmc[i].mmc) { - c = &hsmmc[i]; - break; - } - } - - if (c == NULL) - return -ENODEV; /* If we don't see a Vcc regulator, assume it's a fixed * voltage always-on regulator. diff --git a/trunk/arch/arm/mach-s3c2440/mach-mini2440.c b/trunk/arch/arm/mach-s3c2440/mach-mini2440.c index ec71a6965786..6a5bc3021bdb 100644 --- a/trunk/arch/arm/mach-s3c2440/mach-mini2440.c +++ b/trunk/arch/arm/mach-s3c2440/mach-mini2440.c @@ -48,6 +48,8 @@ #include #include +#include + #include #include #include @@ -273,7 +275,6 @@ static struct s3c2410_nand_set mini2440_nand_sets[] __initdata = { .nr_chips = 1, .nr_partitions = ARRAY_SIZE(mini2440_default_nand_part), .partitions = mini2440_default_nand_part, - .flash_bbt = 1, /* we use u-boot to create a BBT */ }, }; diff --git a/trunk/arch/arm/mach-s3c2442/mach-gta02.c b/trunk/arch/arm/mach-s3c2442/mach-gta02.c index 0fb385bd9cd9..e23b581aa0e1 100644 --- a/trunk/arch/arm/mach-s3c2442/mach-gta02.c +++ b/trunk/arch/arm/mach-s3c2442/mach-gta02.c @@ -433,7 +433,8 @@ static struct s3c2410_nand_set gta02_nand_sets[] = { */ .name = "neo1973-nand", .nr_chips = 1, - .flash_bbt = 1, + .use_bbt = 1, + .force_soft_ecc = 1, }, }; diff --git a/trunk/arch/arm/plat-omap/dma.c b/trunk/arch/arm/plat-omap/dma.c index 7677a4a1cef2..def14ec265b3 100644 --- a/trunk/arch/arm/plat-omap/dma.c +++ b/trunk/arch/arm/plat-omap/dma.c @@ -2457,19 +2457,6 @@ static int __init omap_init_dma(void) setup_irq(irq, &omap24xx_dma_irq); } - /* Enable smartidle idlemodes and autoidle */ - if (cpu_is_omap34xx()) { - u32 v = dma_read(OCP_SYSCONFIG); - v &= ~(DMA_SYSCONFIG_MIDLEMODE_MASK | - DMA_SYSCONFIG_SIDLEMODE_MASK | - DMA_SYSCONFIG_AUTOIDLE); - v |= (DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_SMARTIDLE) | - DMA_SYSCONFIG_SIDLEMODE(DMA_IDLEMODE_SMARTIDLE) | - DMA_SYSCONFIG_AUTOIDLE); - dma_write(v , OCP_SYSCONFIG); - } - - /* FIXME: Update LCD DMA to work on 24xx */ if (cpu_class_is_omap1()) { r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0, diff --git a/trunk/arch/arm/plat-omap/gpio.c b/trunk/arch/arm/plat-omap/gpio.c index 26b387c12423..7fd89ba8d3b5 100644 --- a/trunk/arch/arm/plat-omap/gpio.c +++ b/trunk/arch/arm/plat-omap/gpio.c @@ -1585,7 +1585,6 @@ static int __init _omap_gpio_init(void) __raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_IRQENABLE1); __raw_writel(0xffffffff, bank->base + OMAP24XX_GPIO_IRQSTATUS1); __raw_writew(0x0015, bank->base + OMAP24XX_GPIO_SYSCONFIG); - __raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_DEBOUNCE_EN); /* Initialize interface clock ungated, module enabled */ __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL); diff --git a/trunk/arch/arm/plat-omap/include/mach/cpu.h b/trunk/arch/arm/plat-omap/include/mach/cpu.h index 285eaa3a8275..fc60c4ebcc28 100644 --- a/trunk/arch/arm/plat-omap/include/mach/cpu.h +++ b/trunk/arch/arm/plat-omap/include/mach/cpu.h @@ -30,17 +30,6 @@ #ifndef __ASM_ARCH_OMAP_CPU_H #define __ASM_ARCH_OMAP_CPU_H -/* - * Omap device type i.e. EMU/HS/TST/GP/BAD - */ -#define OMAP2_DEVICE_TYPE_TEST 0 -#define OMAP2_DEVICE_TYPE_EMU 1 -#define OMAP2_DEVICE_TYPE_SEC 2 -#define OMAP2_DEVICE_TYPE_GP 3 -#define OMAP2_DEVICE_TYPE_BAD 4 - -int omap_type(void); - struct omap_chip_id { u8 oc; u8 type; @@ -435,6 +424,17 @@ IS_OMAP_TYPE(3430, 0x3430) int omap_chip_is(struct omap_chip_id oci); +int omap_type(void); + +/* + * Macro to detect device type i.e. EMU/HS/TST/GP/BAD + */ +#define OMAP2_DEVICE_TYPE_TEST 0 +#define OMAP2_DEVICE_TYPE_EMU 1 +#define OMAP2_DEVICE_TYPE_SEC 2 +#define OMAP2_DEVICE_TYPE_GP 3 +#define OMAP2_DEVICE_TYPE_BAD 4 + void omap2_check_revision(void); #endif /* defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) */ diff --git a/trunk/arch/arm/plat-omap/include/mach/dma.h b/trunk/arch/arm/plat-omap/include/mach/dma.h index 7b939cc01962..8c1eae88737e 100644 --- a/trunk/arch/arm/plat-omap/include/mach/dma.h +++ b/trunk/arch/arm/plat-omap/include/mach/dma.h @@ -389,21 +389,6 @@ #define DMA_THREAD_FIFO_25 (0x02 << 14) #define DMA_THREAD_FIFO_50 (0x03 << 14) -/* DMA4_OCP_SYSCONFIG bits */ -#define DMA_SYSCONFIG_MIDLEMODE_MASK (3 << 12) -#define DMA_SYSCONFIG_CLOCKACTIVITY_MASK (3 << 8) -#define DMA_SYSCONFIG_EMUFREE (1 << 5) -#define DMA_SYSCONFIG_SIDLEMODE_MASK (3 << 3) -#define DMA_SYSCONFIG_SOFTRESET (1 << 2) -#define DMA_SYSCONFIG_AUTOIDLE (1 << 0) - -#define DMA_SYSCONFIG_MIDLEMODE(n) ((n) << 12) -#define DMA_SYSCONFIG_SIDLEMODE(n) ((n) << 3) - -#define DMA_IDLEMODE_SMARTIDLE 0x2 -#define DMA_IDLEMODE_NO_IDLE 0x1 -#define DMA_IDLEMODE_FORCE_IDLE 0x0 - /* Chaining modes*/ #ifndef CONFIG_ARCH_OMAP1 #define OMAP_DMA_STATIC_CHAIN 0x1 diff --git a/trunk/arch/arm/plat-omap/include/mach/io.h b/trunk/arch/arm/plat-omap/include/mach/io.h index 73f483d56ca6..3b2814720569 100644 --- a/trunk/arch/arm/plat-omap/include/mach/io.h +++ b/trunk/arch/arm/plat-omap/include/mach/io.h @@ -201,7 +201,7 @@ #define OMAP2_IO_ADDRESS(pa) IOMEM(__OMAP2_IO_ADDRESS(pa)) #ifdef __ASSEMBLER__ -#define IOMEM(x) (x) +#define IOMEM(x) x #else #define IOMEM(x) ((void __force __iomem *)(x)) diff --git a/trunk/arch/arm/plat-omap/iommu.c b/trunk/arch/arm/plat-omap/iommu.c index 4a0301399013..4cf449fa2cb5 100644 --- a/trunk/arch/arm/plat-omap/iommu.c +++ b/trunk/arch/arm/plat-omap/iommu.c @@ -298,7 +298,7 @@ void flush_iotlb_page(struct iommu *obj, u32 da) if ((start <= da) && (da < start + bytes)) { dev_dbg(obj->dev, "%s: %08x<=%08x(%x)\n", __func__, start, da, bytes); - iotlb_load_cr(obj, &cr); + iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY); } } diff --git a/trunk/arch/arm/plat-omap/sram.c b/trunk/arch/arm/plat-omap/sram.c index 4ea73804d21e..65006df3f1b7 100644 --- a/trunk/arch/arm/plat-omap/sram.c +++ b/trunk/arch/arm/plat-omap/sram.c @@ -133,12 +133,7 @@ void __init omap_detect_sram(void) if (cpu_is_omap34xx()) { omap_sram_base = OMAP3_SRAM_PUB_VA; omap_sram_start = OMAP3_SRAM_PUB_PA; - if ((omap_type() == OMAP2_DEVICE_TYPE_EMU) || - (omap_type() == OMAP2_DEVICE_TYPE_SEC)) { - omap_sram_size = 0x7000; /* 28K */ - } else { - omap_sram_size = 0x8000; /* 32K */ - } + omap_sram_size = 0x8000; /* 32K */ } else { omap_sram_base = OMAP2_SRAM_PUB_VA; omap_sram_start = OMAP2_SRAM_PUB_PA; diff --git a/trunk/arch/arm/plat-s3c/Makefile b/trunk/arch/arm/plat-s3c/Makefile index 0761766b1833..74bb7cb5da49 100644 --- a/trunk/arch/arm/plat-s3c/Makefile +++ b/trunk/arch/arm/plat-s3c/Makefile @@ -34,7 +34,7 @@ obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o obj-y += dev-i2c0.o obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o -obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += dev-audio.o +obj-$(CONFIG_SND_S3C24XX_SOC) += dev-audio.o obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o diff --git a/trunk/arch/arm/plat-s3c/include/plat/devs.h b/trunk/arch/arm/plat-s3c/include/plat/devs.h index 2e170827e0b0..b5b9c4d46e9a 100644 --- a/trunk/arch/arm/plat-s3c/include/plat/devs.h +++ b/trunk/arch/arm/plat-s3c/include/plat/devs.h @@ -37,7 +37,6 @@ extern struct platform_device s3c_device_i2c1; extern struct platform_device s3c_device_rtc; extern struct platform_device s3c_device_adc; extern struct platform_device s3c_device_sdi; -extern struct platform_device s3c_device_iis; extern struct platform_device s3c_device_hwmon; extern struct platform_device s3c_device_hsmmc0; extern struct platform_device s3c_device_hsmmc1; diff --git a/trunk/arch/arm/plat-s3c24xx/Makefile b/trunk/arch/arm/plat-s3c24xx/Makefile index 579a165c2827..636cb12711df 100644 --- a/trunk/arch/arm/plat-s3c24xx/Makefile +++ b/trunk/arch/arm/plat-s3c24xx/Makefile @@ -29,7 +29,7 @@ obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_PM) += irq-pm.o obj-$(CONFIG_PM) += sleep.o -obj-$(CONFIG_S3C24XX_PWM) += pwm.o +obj-$(CONFIG_HAVE_PWM) += pwm.o obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o obj-$(CONFIG_S3C2410_DMA) += dma.o obj-$(CONFIG_S3C24XX_ADC) += adc.o diff --git a/trunk/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c b/trunk/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c index da7a61728c18..9edf7894eedd 100644 --- a/trunk/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c +++ b/trunk/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c @@ -12,7 +12,8 @@ */ #include -#include + +#include #include #include diff --git a/trunk/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c b/trunk/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c index 86b9edc67413..f34d0fc69ad8 100644 --- a/trunk/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c +++ b/trunk/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c @@ -12,7 +12,8 @@ */ #include -#include + +#include #include #include diff --git a/trunk/arch/frv/Kconfig b/trunk/arch/frv/Kconfig index b86e19c9b5b0..8a5bd7a9c6f5 100644 --- a/trunk/arch/frv/Kconfig +++ b/trunk/arch/frv/Kconfig @@ -7,7 +7,6 @@ config FRV default y select HAVE_IDE select HAVE_ARCH_TRACEHOOK - select HAVE_PERF_COUNTERS config ZONE_DMA bool diff --git a/trunk/arch/frv/include/asm/atomic.h b/trunk/arch/frv/include/asm/atomic.h index 00a57af79afc..0409d981fd39 100644 --- a/trunk/arch/frv/include/asm/atomic.h +++ b/trunk/arch/frv/include/asm/atomic.h @@ -121,72 +121,10 @@ static inline void atomic_dec(atomic_t *v) #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) #define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0) -/* - * 64-bit atomic ops - */ -typedef struct { - volatile long long counter; -} atomic64_t; - -#define ATOMIC64_INIT(i) { (i) } - -static inline long long atomic64_read(atomic64_t *v) -{ - long long counter; - - asm("ldd%I1 %M1,%0" - : "=e"(counter) - : "m"(v->counter)); - return counter; -} - -static inline void atomic64_set(atomic64_t *v, long long i) -{ - asm volatile("std%I0 %1,%M0" - : "=m"(v->counter) - : "e"(i)); -} - -extern long long atomic64_inc_return(atomic64_t *v); -extern long long atomic64_dec_return(atomic64_t *v); -extern long long atomic64_add_return(long long i, atomic64_t *v); -extern long long atomic64_sub_return(long long i, atomic64_t *v); - -static inline long long atomic64_add_negative(long long i, atomic64_t *v) -{ - return atomic64_add_return(i, v) < 0; -} - -static inline void atomic64_add(long long i, atomic64_t *v) -{ - atomic64_add_return(i, v); -} - -static inline void atomic64_sub(long long i, atomic64_t *v) -{ - atomic64_sub_return(i, v); -} - -static inline void atomic64_inc(atomic64_t *v) -{ - atomic64_inc_return(v); -} - -static inline void atomic64_dec(atomic64_t *v) -{ - atomic64_dec_return(v); -} - -#define atomic64_sub_and_test(i,v) (atomic64_sub_return((i), (v)) == 0) -#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0) -#define atomic64_inc_and_test(v) (atomic64_inc_return((v)) == 0) - /*****************************************************************************/ /* * exchange value with memory */ -extern uint64_t __xchg_64(uint64_t i, volatile void *v); - #ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS #define xchg(ptr, x) \ @@ -236,10 +174,8 @@ extern uint32_t __xchg_32(uint32_t i, volatile void *v); #define tas(ptr) (xchg((ptr), 1)) -#define atomic_cmpxchg(v, old, new) (cmpxchg(&(v)->counter, old, new)) -#define atomic_xchg(v, new) (xchg(&(v)->counter, new)) -#define atomic64_cmpxchg(v, old, new) (__cmpxchg_64(old, new, &(v)->counter)) -#define atomic64_xchg(v, new) (__xchg_64(new, &(v)->counter)) +#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new)) +#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) { diff --git a/trunk/arch/frv/include/asm/perf_counter.h b/trunk/arch/frv/include/asm/perf_counter.h deleted file mode 100644 index ccf726e61b2e..000000000000 --- a/trunk/arch/frv/include/asm/perf_counter.h +++ /dev/null @@ -1,17 +0,0 @@ -/* FRV performance counter support - * - * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public Licence - * as published by the Free Software Foundation; either version - * 2 of the Licence, or (at your option) any later version. - */ - -#ifndef _ASM_PERF_COUNTER_H -#define _ASM_PERF_COUNTER_H - -#define PERF_COUNTER_INDEX_OFFSET 0 - -#endif /* _ASM_PERF_COUNTER_H */ diff --git a/trunk/arch/frv/include/asm/system.h b/trunk/arch/frv/include/asm/system.h index efd22d9077ac..7742ec000cc4 100644 --- a/trunk/arch/frv/include/asm/system.h +++ b/trunk/arch/frv/include/asm/system.h @@ -208,8 +208,6 @@ extern void free_initmem(void); * - if (*ptr == test) then orig = *ptr; *ptr = test; * - if (*ptr != test) then orig = *ptr; */ -extern uint64_t __cmpxchg_64(uint64_t test, uint64_t new, volatile uint64_t *v); - #ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS #define cmpxchg(ptr, test, new) \ diff --git a/trunk/arch/frv/include/asm/unistd.h b/trunk/arch/frv/include/asm/unistd.h index 4a8fb427ce0a..96d78d5d2c41 100644 --- a/trunk/arch/frv/include/asm/unistd.h +++ b/trunk/arch/frv/include/asm/unistd.h @@ -341,12 +341,10 @@ #define __NR_inotify_init1 332 #define __NR_preadv 333 #define __NR_pwritev 334 -#define __NR_rt_tgsigqueueinfo 335 -#define __NR_perf_counter_open 336 #ifdef __KERNEL__ -#define NR_syscalls 337 +#define NR_syscalls 335 #define __ARCH_WANT_IPC_PARSE_VERSION /* #define __ARCH_WANT_OLD_READDIR */ diff --git a/trunk/arch/frv/kernel/entry.S b/trunk/arch/frv/kernel/entry.S index fde1e446b440..356e0e327a89 100644 --- a/trunk/arch/frv/kernel/entry.S +++ b/trunk/arch/frv/kernel/entry.S @@ -1524,7 +1524,5 @@ sys_call_table: .long sys_inotify_init1 .long sys_preadv .long sys_pwritev - .long sys_rt_tgsigqueueinfo /* 335 */ - .long sys_perf_counter_open syscall_table_size = (. - sys_call_table) diff --git a/trunk/arch/frv/kernel/frv_ksyms.c b/trunk/arch/frv/kernel/frv_ksyms.c index a89803b58b9a..0316b3c50eff 100644 --- a/trunk/arch/frv/kernel/frv_ksyms.c +++ b/trunk/arch/frv/kernel/frv_ksyms.c @@ -67,10 +67,6 @@ EXPORT_SYMBOL(atomic_sub_return); EXPORT_SYMBOL(__xchg_32); EXPORT_SYMBOL(__cmpxchg_32); #endif -EXPORT_SYMBOL(atomic64_add_return); -EXPORT_SYMBOL(atomic64_sub_return); -EXPORT_SYMBOL(__xchg_64); -EXPORT_SYMBOL(__cmpxchg_64); EXPORT_SYMBOL(__debug_bug_printk); EXPORT_SYMBOL(__delay_loops_MHz); diff --git a/trunk/arch/frv/lib/Makefile b/trunk/arch/frv/lib/Makefile index 0a377210c89b..08be305c9f44 100644 --- a/trunk/arch/frv/lib/Makefile +++ b/trunk/arch/frv/lib/Makefile @@ -4,5 +4,5 @@ lib-y := \ __ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o __ucmpdi2.o \ - checksum.o memcpy.o memset.o atomic-ops.o atomic64-ops.o \ - outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o perf_counter.o + checksum.o memcpy.o memset.o atomic-ops.o \ + outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o diff --git a/trunk/arch/frv/lib/atomic-ops.S b/trunk/arch/frv/lib/atomic-ops.S index 5e9e6ab5dd0e..ee0ac905fb08 100644 --- a/trunk/arch/frv/lib/atomic-ops.S +++ b/trunk/arch/frv/lib/atomic-ops.S @@ -163,10 +163,11 @@ __cmpxchg_32: ld.p @(gr11,gr0),gr8 orcr cc7,cc7,cc3 subcc gr8,gr9,gr7,icc0 - bnelr icc0,#0 + bne icc0,#0,1f cst.p gr10,@(gr11,gr0) ,cc3,#1 corcc gr29,gr29,gr0 ,cc3,#1 beq icc3,#0,0b +1: bralr .size __cmpxchg_32, .-__cmpxchg_32 diff --git a/trunk/arch/frv/lib/atomic64-ops.S b/trunk/arch/frv/lib/atomic64-ops.S deleted file mode 100644 index b6194eeac127..000000000000 --- a/trunk/arch/frv/lib/atomic64-ops.S +++ /dev/null @@ -1,162 +0,0 @@ -/* kernel atomic64 operations - * - * For an explanation of how atomic ops work in this arch, see: - * Documentation/frv/atomic-ops.txt - * - * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include - - .text - .balign 4 - - -############################################################################### -# -# long long atomic64_inc_return(atomic64_t *v) -# -############################################################################### - .globl atomic64_inc_return - .type atomic64_inc_return,@function -atomic64_inc_return: - or.p gr8,gr8,gr10 -0: - orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ - ckeq icc3,cc7 - ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */ - orcr cc7,cc7,cc3 /* set CC3 to true */ - addicc gr9,#1,gr9,icc0 - addxi gr8,#0,gr8,icc0 - cstd.p gr8,@(gr10,gr0) ,cc3,#1 - corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ - beq icc3,#0,0b - bralr - - .size atomic64_inc_return, .-atomic64_inc_return - -############################################################################### -# -# long long atomic64_dec_return(atomic64_t *v) -# -############################################################################### - .globl atomic64_dec_return - .type atomic64_dec_return,@function -atomic64_dec_return: - or.p gr8,gr8,gr10 -0: - orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ - ckeq icc3,cc7 - ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */ - orcr cc7,cc7,cc3 /* set CC3 to true */ - subicc gr9,#1,gr9,icc0 - subxi gr8,#0,gr8,icc0 - cstd.p gr8,@(gr10,gr0) ,cc3,#1 - corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ - beq icc3,#0,0b - bralr - - .size atomic64_dec_return, .-atomic64_dec_return - -############################################################################### -# -# long long atomic64_add_return(long long i, atomic64_t *v) -# -############################################################################### - .globl atomic64_add_return - .type atomic64_add_return,@function -atomic64_add_return: - or.p gr8,gr8,gr4 - or gr9,gr9,gr5 -0: - orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ - ckeq icc3,cc7 - ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */ - orcr cc7,cc7,cc3 /* set CC3 to true */ - addcc gr9,gr5,gr9,icc0 - addx gr8,gr4,gr8,icc0 - cstd.p gr8,@(gr10,gr0) ,cc3,#1 - corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ - beq icc3,#0,0b - bralr - - .size atomic64_add_return, .-atomic64_add_return - -############################################################################### -# -# long long atomic64_sub_return(long long i, atomic64_t *v) -# -############################################################################### - .globl atomic64_sub_return - .type atomic64_sub_return,@function -atomic64_sub_return: - or.p gr8,gr8,gr4 - or gr9,gr9,gr5 -0: - orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ - ckeq icc3,cc7 - ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */ - orcr cc7,cc7,cc3 /* set CC3 to true */ - subcc gr9,gr5,gr9,icc0 - subx gr8,gr4,gr8,icc0 - cstd.p gr8,@(gr10,gr0) ,cc3,#1 - corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ - beq icc3,#0,0b - bralr - - .size atomic64_sub_return, .-atomic64_sub_return - -############################################################################### -# -# uint64_t __xchg_64(uint64_t i, uint64_t *v) -# -############################################################################### - .globl __xchg_64 - .type __xchg_64,@function -__xchg_64: - or.p gr8,gr8,gr4 - or gr9,gr9,gr5 -0: - orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ - ckeq icc3,cc7 - ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */ - orcr cc7,cc7,cc3 /* set CC3 to true */ - cstd.p gr4,@(gr10,gr0) ,cc3,#1 - corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ - beq icc3,#0,0b - bralr - - .size __xchg_64, .-__xchg_64 - -############################################################################### -# -# uint64_t __cmpxchg_64(uint64_t test, uint64_t new, uint64_t *v) -# -############################################################################### - .globl __cmpxchg_64 - .type __cmpxchg_64,@function -__cmpxchg_64: - or.p gr8,gr8,gr4 - or gr9,gr9,gr5 -0: - orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ - ckeq icc3,cc7 - ldd.p @(gr12,gr0),gr8 /* LDD.P/ORCR must be atomic */ - orcr cc7,cc7,cc3 - subcc gr8,gr4,gr0,icc0 - subcc.p gr9,gr5,gr0,icc1 - bnelr icc0,#0 - bnelr icc1,#0 - cstd.p gr10,@(gr12,gr0) ,cc3,#1 - corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ - beq icc3,#0,0b - bralr - - .size __cmpxchg_64, .-__cmpxchg_64 - diff --git a/trunk/arch/frv/lib/perf_counter.c b/trunk/arch/frv/lib/perf_counter.c deleted file mode 100644 index 2000feecd571..000000000000 --- a/trunk/arch/frv/lib/perf_counter.c +++ /dev/null @@ -1,19 +0,0 @@ -/* Performance counter handling - * - * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public Licence - * as published by the Free Software Foundation; either version - * 2 of the Licence, or (at your option) any later version. - */ - -#include - -/* - * mark the performance counter as pending - */ -void set_perf_counter_pending(void) -{ -} diff --git a/trunk/arch/ia64/kernel/esi.c b/trunk/arch/ia64/kernel/esi.c index d5764a3d74af..ebf4e988e78c 100644 --- a/trunk/arch/ia64/kernel/esi.c +++ b/trunk/arch/ia64/kernel/esi.c @@ -65,7 +65,7 @@ static int __init esi_init (void) } if (!esi) - return -ENODEV; + return -ENODEV;; systab = __va(esi); diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index f1782705b1f7..abce2468a40b 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -5603,7 +5603,7 @@ pfm_interrupt_handler(int irq, void *arg) * /proc/perfmon interface, for debug only */ -#define PFM_PROC_SHOW_HEADER ((void *)(long)nr_cpu_ids+1) +#define PFM_PROC_SHOW_HEADER ((void *)nr_cpu_ids+1) static void * pfm_proc_start(struct seq_file *m, loff_t *pos) diff --git a/trunk/arch/ia64/kernel/salinfo.c b/trunk/arch/ia64/kernel/salinfo.c index e6676fca4828..7053c55b7649 100644 --- a/trunk/arch/ia64/kernel/salinfo.c +++ b/trunk/arch/ia64/kernel/salinfo.c @@ -192,7 +192,7 @@ struct salinfo_platform_oemdata_parms { static void salinfo_work_to_do(struct salinfo_data *data) { - (void)(down_trylock(&data->mutex) ?: 0); + down_trylock(&data->mutex); up(&data->mutex); } diff --git a/trunk/arch/ia64/kvm/kvm_lib.c b/trunk/arch/ia64/kvm/kvm_lib.c index f1268b8e6f9e..a85cb611ecd7 100644 --- a/trunk/arch/ia64/kvm/kvm_lib.c +++ b/trunk/arch/ia64/kvm/kvm_lib.c @@ -11,11 +11,5 @@ * */ #undef CONFIG_MODULES -#include -#undef CONFIG_KALLSYMS -#undef EXPORT_SYMBOL -#undef EXPORT_SYMBOL_GPL -#define EXPORT_SYMBOL(sym) -#define EXPORT_SYMBOL_GPL(sym) #include "../../../lib/vsprintf.c" #include "../../../lib/ctype.c" diff --git a/trunk/arch/ia64/kvm/process.c b/trunk/arch/ia64/kvm/process.c index bb862fb224f2..a8f84da04b49 100644 --- a/trunk/arch/ia64/kvm/process.c +++ b/trunk/arch/ia64/kvm/process.c @@ -130,7 +130,7 @@ static void collect_interruption(struct kvm_vcpu *vcpu) if (vdcr & IA64_DCR_PP) { vpsr |= IA64_PSR_PP; } else { - vpsr &= ~IA64_PSR_PP; + vpsr &= ~IA64_PSR_PP;; } vcpu_set_psr(vcpu, vpsr); @@ -594,11 +594,11 @@ static void set_pal_call_data(struct kvm_vcpu *vcpu) p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30); break; case PAL_BRAND_INFO: - p->u.pal_data.gr29 = gr29; + p->u.pal_data.gr29 = gr29;; p->u.pal_data.gr30 = kvm_trans_pal_call_args(vcpu, gr30); break; default: - p->u.pal_data.gr29 = gr29; + p->u.pal_data.gr29 = gr29;; p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30); } p->u.pal_data.gr28 = gr28; diff --git a/trunk/arch/ia64/kvm/vcpu.c b/trunk/arch/ia64/kvm/vcpu.c index 46b02cbcc874..a2c6c15e4761 100644 --- a/trunk/arch/ia64/kvm/vcpu.c +++ b/trunk/arch/ia64/kvm/vcpu.c @@ -406,7 +406,7 @@ void getreg(unsigned long regnum, unsigned long *val, * Now look at registers in [0-31] range and init correct UNAT */ addr = (unsigned long)regs; - unat = ®s->eml_unat; + unat = ®s->eml_unat;; addr += gr_info[regnum]; diff --git a/trunk/arch/ia64/kvm/vtlb.c b/trunk/arch/ia64/kvm/vtlb.c index 20b3852f7a6e..4290a429bf7c 100644 --- a/trunk/arch/ia64/kvm/vtlb.c +++ b/trunk/arch/ia64/kvm/vtlb.c @@ -135,7 +135,7 @@ struct thash_data *__vtr_lookup(struct kvm_vcpu *vcpu, u64 va, int type) u64 rid; rid = vcpu_get_rr(vcpu, va); - rid = rid & RR_RID_MASK; + rid = rid & RR_RID_MASK;; if (type == D_TLB) { if (vcpu_quick_region_check(vcpu->arch.dtr_regions, va)) { for (trp = (struct thash_data *)&vcpu->arch.dtrs, i = 0; @@ -518,7 +518,7 @@ struct thash_data *vtlb_lookup(struct kvm_vcpu *v, u64 va, int is_data) struct thash_cb *hcb = &v->arch.vtlb; - cch = __vtr_lookup(v, va, is_data); + cch = __vtr_lookup(v, va, is_data);; if (cch) return cch; diff --git a/trunk/arch/ia64/sn/kernel/io_common.c b/trunk/arch/ia64/sn/kernel/io_common.c index 25831c47c579..76645cf6ac5d 100644 --- a/trunk/arch/ia64/sn/kernel/io_common.c +++ b/trunk/arch/ia64/sn/kernel/io_common.c @@ -435,8 +435,7 @@ void sn_generate_path(struct pci_bus *pci_bus, char *address) bricktype = MODULE_GET_BTYPE(moduleid); if ((bricktype == L1_BRICKTYPE_191010) || (bricktype == L1_BRICKTYPE_1932)) - sprintf(address + strlen(address), "^%d", - geo_slot(geoid)); + sprintf(address, "%s^%d", address, geo_slot(geoid)); } void __devinit diff --git a/trunk/arch/mn10300/include/asm/unistd.h b/trunk/arch/mn10300/include/asm/unistd.h index fad68616af32..fef5b434dadc 100644 --- a/trunk/arch/mn10300/include/asm/unistd.h +++ b/trunk/arch/mn10300/include/asm/unistd.h @@ -346,12 +346,10 @@ #define __NR_inotify_init1 333 #define __NR_preadv 334 #define __NR_pwritev 335 -#define __NR_rt_tgsigqueueinfo 336 -#define __NR_perf_counter_open 337 #ifdef __KERNEL__ -#define NR_syscalls 338 +#define NR_syscalls 326 /* * specify the deprecated syscalls we want to support on this arch diff --git a/trunk/arch/mn10300/kernel/entry.S b/trunk/arch/mn10300/kernel/entry.S index e0d2563af4f2..7408a27199f3 100644 --- a/trunk/arch/mn10300/kernel/entry.S +++ b/trunk/arch/mn10300/kernel/entry.S @@ -722,8 +722,6 @@ ENTRY(sys_call_table) .long sys_inotify_init1 .long sys_preadv .long sys_pwritev /* 335 */ - .long sys_rt_tgsigqueueinfo - .long sys_perf_counter_open nr_syscalls=(.-sys_call_table)/4 diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index d00131ca0835..bf6cedfa05db 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -62,6 +62,7 @@ config HAVE_LATENCYTOP_SUPPORT config TRACE_IRQFLAGS_SUPPORT bool + depends on PPC64 default y config LOCKDEP_SUPPORT diff --git a/trunk/arch/powerpc/boot/.gitignore b/trunk/arch/powerpc/boot/.gitignore index 3d80c3e9cf60..2f50acd11a60 100644 --- a/trunk/arch/powerpc/boot/.gitignore +++ b/trunk/arch/powerpc/boot/.gitignore @@ -36,13 +36,3 @@ zImage.pseries zconf.h zlib.h zutil.h -fdt.c -fdt.h -fdt_ro.c -fdt_rw.c -fdt_strerror.c -fdt_sw.c -fdt_wip.c -libfdt.h -libfdt_internal.h - diff --git a/trunk/arch/powerpc/boot/dts/amigaone.dts b/trunk/arch/powerpc/boot/dts/amigaone.dts index 49ac36b16dd7..26549fca2ed4 100644 --- a/trunk/arch/powerpc/boot/dts/amigaone.dts +++ b/trunk/arch/powerpc/boot/dts/amigaone.dts @@ -70,8 +70,8 @@ devsel-speed = <0x00000001>; min-grant = <0>; max-latency = <0>; - /* First 4k for I/O at 0x0 on PCI mapped to 0x0 on ISA. */ - ranges = <0x00000001 0 0x01000000 0 0x00000000 0x00001000>; + /* First 64k for I/O at 0x0 on PCI mapped to 0x0 on ISA. */ + ranges = <0x00000001 0 0x01000000 0 0x00000000 0x00010000>; interrupt-parent = <&i8259>; #interrupt-cells = <2>; #address-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/mpc8569mds.dts b/trunk/arch/powerpc/boot/dts/mpc8569mds.dts index a680165292f2..a8dcb018c4a5 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8569mds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8569mds.dts @@ -253,7 +253,6 @@ /* Filled in by U-Boot */ clock-frequency = <0>; status = "disabled"; - sdhci,1-bit-only; }; crypto@30000 { diff --git a/trunk/arch/powerpc/include/asm/cpm1.h b/trunk/arch/powerpc/include/asm/cpm1.h index 7685ffde8821..2ff798744c1d 100644 --- a/trunk/arch/powerpc/include/asm/cpm1.h +++ b/trunk/arch/powerpc/include/asm/cpm1.h @@ -598,6 +598,8 @@ typedef struct risc_timer_pram { #define CICR_IEN ((uint)0x00000080) /* Int. enable */ #define CICR_SPS ((uint)0x00000001) /* SCC Spread */ +#define IMAP_ADDR (get_immrbase()) + #define CPM_PIN_INPUT 0 #define CPM_PIN_OUTPUT 1 #define CPM_PIN_PRIMARY 0 diff --git a/trunk/arch/powerpc/include/asm/dma-mapping.h b/trunk/arch/powerpc/include/asm/dma-mapping.h index b44aaabdd1a6..3d9e887c3c0c 100644 --- a/trunk/arch/powerpc/include/asm/dma-mapping.h +++ b/trunk/arch/powerpc/include/asm/dma-mapping.h @@ -309,9 +309,7 @@ static inline void dma_sync_single_for_cpu(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); - - if (dma_ops->sync_single_range_for_cpu) - dma_ops->sync_single_range_for_cpu(dev, dma_handle, 0, + dma_ops->sync_single_range_for_cpu(dev, dma_handle, 0, size, direction); } @@ -322,9 +320,7 @@ static inline void dma_sync_single_for_device(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); - - if (dma_ops->sync_single_range_for_device) - dma_ops->sync_single_range_for_device(dev, dma_handle, + dma_ops->sync_single_range_for_device(dev, dma_handle, 0, size, direction); } @@ -335,9 +331,7 @@ static inline void dma_sync_sg_for_cpu(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); - - if (dma_ops->sync_sg_for_cpu) - dma_ops->sync_sg_for_cpu(dev, sgl, nents, direction); + dma_ops->sync_sg_for_cpu(dev, sgl, nents, direction); } static inline void dma_sync_sg_for_device(struct device *dev, @@ -347,9 +341,7 @@ static inline void dma_sync_sg_for_device(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); - - if (dma_ops->sync_sg_for_device) - dma_ops->sync_sg_for_device(dev, sgl, nents, direction); + dma_ops->sync_sg_for_device(dev, sgl, nents, direction); } static inline void dma_sync_single_range_for_cpu(struct device *dev, @@ -359,9 +351,7 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); - - if (dma_ops->sync_single_range_for_cpu) - dma_ops->sync_single_range_for_cpu(dev, dma_handle, + dma_ops->sync_single_range_for_cpu(dev, dma_handle, offset, size, direction); } @@ -372,9 +362,7 @@ static inline void dma_sync_single_range_for_device(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); - - if (dma_ops->sync_single_range_for_device) - dma_ops->sync_single_range_for_device(dev, dma_handle, offset, + dma_ops->sync_single_range_for_device(dev, dma_handle, offset, size, direction); } #else /* CONFIG_PPC_NEED_DMA_SYNC_OPS */ diff --git a/trunk/arch/powerpc/include/asm/highmem.h b/trunk/arch/powerpc/include/asm/highmem.h index a74c4ee6c020..684a73f4324f 100644 --- a/trunk/arch/powerpc/include/asm/highmem.h +++ b/trunk/arch/powerpc/include/asm/highmem.h @@ -22,7 +22,9 @@ #ifdef __KERNEL__ +#include #include +#include #include #include #include @@ -60,9 +62,6 @@ extern pte_t *pkmap_page_table; extern void *kmap_high(struct page *page); extern void kunmap_high(struct page *page); -extern void *kmap_atomic_prot(struct page *page, enum km_type type, - pgprot_t prot); -extern void kunmap_atomic(void *kvaddr, enum km_type type); static inline void *kmap(struct page *page) { @@ -80,11 +79,62 @@ static inline void kunmap(struct page *page) kunmap_high(page); } +/* + * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap + * gives a more generic (and caching) interface. But kmap_atomic can + * be used in IRQ contexts, so in some (very limited) cases we need + * it. + */ +static inline void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) +{ + unsigned int idx; + unsigned long vaddr; + + /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ + pagefault_disable(); + if (!PageHighMem(page)) + return page_address(page); + + debug_kmap_atomic(type); + idx = type + KM_TYPE_NR*smp_processor_id(); + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); +#ifdef CONFIG_DEBUG_HIGHMEM + BUG_ON(!pte_none(*(kmap_pte-idx))); +#endif + __set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot), 1); + local_flush_tlb_page(NULL, vaddr); + + return (void*) vaddr; +} + static inline void *kmap_atomic(struct page *page, enum km_type type) { return kmap_atomic_prot(page, type, kmap_prot); } +static inline void kunmap_atomic(void *kvaddr, enum km_type type) +{ +#ifdef CONFIG_DEBUG_HIGHMEM + unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; + enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); + + if (vaddr < __fix_to_virt(FIX_KMAP_END)) { + pagefault_enable(); + return; + } + + BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); + + /* + * force other mappings to Oops if they'll try to access + * this pte without first remap it + */ + pte_clear(&init_mm, vaddr, kmap_pte-idx); + local_flush_tlb_page(NULL, vaddr); +#endif + pagefault_enable(); +} + static inline struct page *kmap_atomic_to_page(void *ptr) { unsigned long idx, vaddr = (unsigned long) ptr; @@ -98,7 +148,6 @@ static inline struct page *kmap_atomic_to_page(void *ptr) return pte_page(*pte); } - #define flush_cache_kmaps() flush_cache_all() #endif /* __KERNEL__ */ diff --git a/trunk/arch/powerpc/include/asm/hw_irq.h b/trunk/arch/powerpc/include/asm/hw_irq.h index 8b505eaaa38a..867ab8ed69b3 100644 --- a/trunk/arch/powerpc/include/asm/hw_irq.h +++ b/trunk/arch/powerpc/include/asm/hw_irq.h @@ -68,13 +68,13 @@ static inline int irqs_disabled_flags(unsigned long flags) #if defined(CONFIG_BOOKE) #define SET_MSR_EE(x) mtmsr(x) -#define raw_local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory") +#define local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory") #else #define SET_MSR_EE(x) mtmsr(x) -#define raw_local_irq_restore(flags) mtmsr(flags) +#define local_irq_restore(flags) mtmsr(flags) #endif -static inline void raw_local_irq_disable(void) +static inline void local_irq_disable(void) { #ifdef CONFIG_BOOKE __asm__ __volatile__("wrteei 0": : :"memory"); @@ -86,7 +86,7 @@ static inline void raw_local_irq_disable(void) #endif } -static inline void raw_local_irq_enable(void) +static inline void local_irq_enable(void) { #ifdef CONFIG_BOOKE __asm__ __volatile__("wrteei 1": : :"memory"); @@ -98,7 +98,7 @@ static inline void raw_local_irq_enable(void) #endif } -static inline void raw_local_irq_save_ptr(unsigned long *flags) +static inline void local_irq_save_ptr(unsigned long *flags) { unsigned long msr; msr = mfmsr(); @@ -110,12 +110,12 @@ static inline void raw_local_irq_save_ptr(unsigned long *flags) #endif } -#define raw_local_save_flags(flags) ((flags) = mfmsr()) -#define raw_local_irq_save(flags) raw_local_irq_save_ptr(&flags) -#define raw_irqs_disabled() ((mfmsr() & MSR_EE) == 0) -#define raw_irqs_disabled_flags(flags) (((flags) & MSR_EE) == 0) +#define local_save_flags(flags) ((flags) = mfmsr()) +#define local_irq_save(flags) local_irq_save_ptr(&flags) +#define irqs_disabled() ((mfmsr() & MSR_EE) == 0) -#define hard_irq_disable() raw_local_irq_disable() +#define hard_irq_enable() local_irq_enable() +#define hard_irq_disable() local_irq_disable() static inline int irqs_disabled_flags(unsigned long flags) { diff --git a/trunk/arch/powerpc/include/asm/perf_counter.h b/trunk/arch/powerpc/include/asm/perf_counter.h index 0ea0639fcf75..8ccd4e155768 100644 --- a/trunk/arch/powerpc/include/asm/perf_counter.h +++ b/trunk/arch/powerpc/include/asm/perf_counter.h @@ -61,8 +61,6 @@ struct pt_regs; extern unsigned long perf_misc_flags(struct pt_regs *regs); extern unsigned long perf_instruction_pointer(struct pt_regs *regs); -#define PERF_COUNTER_INDEX_OFFSET 1 - /* * Only override the default definitions in include/linux/perf_counter.h * if we have hardware PMU support. diff --git a/trunk/arch/powerpc/include/asm/pte-hash64-64k.h b/trunk/arch/powerpc/include/asm/pte-hash64-64k.h index 82b72207c51c..e05d26fa372f 100644 --- a/trunk/arch/powerpc/include/asm/pte-hash64-64k.h +++ b/trunk/arch/powerpc/include/asm/pte-hash64-64k.h @@ -47,8 +47,7 @@ * generic accessors and iterators here */ #define __real_pte(e,p) ((real_pte_t) { \ - (e), ((e) & _PAGE_COMBO) ? \ - (pte_val(*((p) + PTRS_PER_PTE))) : 0 }) + (e), pte_val(*((p) + PTRS_PER_PTE)) }) #define __rpte_to_hidx(r,index) ((pte_val((r).pte) & _PAGE_COMBO) ? \ (((r).hidx >> ((index)<<2)) & 0xf) : ((pte_val((r).pte) >> 12) & 0xf)) #define __rpte_to_pte(r) ((r).pte) diff --git a/trunk/arch/powerpc/include/asm/rtas.h b/trunk/arch/powerpc/include/asm/rtas.h index 168fce726201..01c12339b304 100644 --- a/trunk/arch/powerpc/include/asm/rtas.h +++ b/trunk/arch/powerpc/include/asm/rtas.h @@ -58,7 +58,7 @@ struct rtas_t { unsigned long entry; /* physical address pointer */ unsigned long base; /* physical address pointer */ unsigned long size; - raw_spinlock_t lock; + spinlock_t lock; struct rtas_args args; struct device_node *dev; /* virtual address pointer */ }; @@ -245,8 +245,5 @@ static inline u32 rtas_config_addr(int busno, int devfn, int reg) (devfn << 8) | (reg & 0xff); } -extern void __cpuinit rtas_give_timebase(void); -extern void __cpuinit rtas_take_timebase(void); - #endif /* __KERNEL__ */ #endif /* _POWERPC_RTAS_H */ diff --git a/trunk/arch/powerpc/kernel/entry_32.S b/trunk/arch/powerpc/kernel/entry_32.S index 3cadba60a4b6..4dd38f129153 100644 --- a/trunk/arch/powerpc/kernel/entry_32.S +++ b/trunk/arch/powerpc/kernel/entry_32.S @@ -191,49 +191,11 @@ transfer_to_handler_cont: mflr r9 lwz r11,0(r9) /* virtual address of handler */ lwz r9,4(r9) /* where to go when done */ -#ifdef CONFIG_TRACE_IRQFLAGS - lis r12,reenable_mmu@h - ori r12,r12,reenable_mmu@l - mtspr SPRN_SRR0,r12 - mtspr SPRN_SRR1,r10 - SYNC - RFI -reenable_mmu: /* re-enable mmu so we can */ - mfmsr r10 - lwz r12,_MSR(r1) - xor r10,r10,r12 - andi. r10,r10,MSR_EE /* Did EE change? */ - beq 1f - - /* Save handler and return address into the 2 unused words - * of the STACK_FRAME_OVERHEAD (sneak sneak sneak). Everything - * else can be recovered from the pt_regs except r3 which for - * normal interrupts has been set to pt_regs and for syscalls - * is an argument, so we temporarily use ORIG_GPR3 to save it - */ - stw r9,8(r1) - stw r11,12(r1) - stw r3,ORIG_GPR3(r1) - bl trace_hardirqs_off - lwz r0,GPR0(r1) - lwz r3,ORIG_GPR3(r1) - lwz r4,GPR4(r1) - lwz r5,GPR5(r1) - lwz r6,GPR6(r1) - lwz r7,GPR7(r1) - lwz r8,GPR8(r1) - lwz r9,8(r1) - lwz r11,12(r1) -1: mtctr r11 - mtlr r9 - bctr /* jump to handler */ -#else /* CONFIG_TRACE_IRQFLAGS */ mtspr SPRN_SRR0,r11 mtspr SPRN_SRR1,r10 mtlr r9 SYNC RFI /* jump to handler, enable MMU */ -#endif /* CONFIG_TRACE_IRQFLAGS */ #if defined (CONFIG_6xx) || defined(CONFIG_E500) 4: rlwinm r12,r12,0,~_TLF_NAPPING @@ -289,31 +251,6 @@ _GLOBAL(DoSyscall) #ifdef SHOW_SYSCALLS bl do_show_syscall #endif /* SHOW_SYSCALLS */ -#ifdef CONFIG_TRACE_IRQFLAGS - /* Return from syscalls can (and generally will) hard enable - * interrupts. You aren't supposed to call a syscall with - * interrupts disabled in the first place. However, to ensure - * that we get it right vs. lockdep if it happens, we force - * that hard enable here with appropriate tracing if we see - * that we have been called with interrupts off - */ - mfmsr r11 - andi. r12,r11,MSR_EE - bne+ 1f - /* We came in with interrupts disabled, we enable them now */ - bl trace_hardirqs_on - mfmsr r11 - lwz r0,GPR0(r1) - lwz r3,GPR3(r1) - lwz r4,GPR4(r1) - ori r11,r11,MSR_EE - lwz r5,GPR5(r1) - lwz r6,GPR6(r1) - lwz r7,GPR7(r1) - lwz r8,GPR8(r1) - mtmsr r11 -1: -#endif /* CONFIG_TRACE_IRQFLAGS */ rlwinm r10,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ lwz r11,TI_FLAGS(r10) andi. r11,r11,_TIF_SYSCALL_T_OR_A @@ -338,7 +275,6 @@ ret_from_syscall: rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ /* disable interrupts so current_thread_info()->flags can't change */ LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ - /* Note: We don't bother telling lockdep about it */ SYNC MTMSRD(r10) lwz r9,TI_FLAGS(r12) @@ -352,19 +288,6 @@ ret_from_syscall: oris r11,r11,0x1000 /* Set SO bit in CR */ stw r11,_CCR(r1) syscall_exit_cont: - lwz r8,_MSR(r1) -#ifdef CONFIG_TRACE_IRQFLAGS - /* If we are going to return from the syscall with interrupts - * off, we trace that here. It shouldn't happen though but we - * want to catch the bugger if it does right ? - */ - andi. r10,r8,MSR_EE - bne+ 1f - stw r3,GPR3(r1) - bl trace_hardirqs_off - lwz r3,GPR3(r1) -1: -#endif /* CONFIG_TRACE_IRQFLAGS */ #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) /* If the process has its own DBCR0 value, load it up. The internal debug mode bit tells us that dbcr0 should be loaded. */ @@ -388,6 +311,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) mtlr r4 mtcr r5 lwz r7,_NIP(r1) + lwz r8,_MSR(r1) FIX_SRR1(r8, r0) lwz r2,GPR2(r1) lwz r1,GPR1(r1) @@ -470,9 +394,7 @@ syscall_exit_work: andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) beq ret_from_except - /* Re-enable interrupts. There is no need to trace that with - * lockdep as we are supposed to have IRQs on at this point - */ + /* Re-enable interrupts */ ori r10,r10,MSR_EE SYNC MTMSRD(r10) @@ -783,7 +705,6 @@ ret_from_except: /* Hard-disable interrupts so that current_thread_info()->flags * can't change between when we test it and when we return * from the interrupt. */ - /* Note: We don't bother telling lockdep about it */ LOAD_MSR_KERNEL(r10,MSR_KERNEL) SYNC /* Some chip revs have problems here... */ MTMSRD(r10) /* disable interrupts */ @@ -823,24 +744,11 @@ resume_kernel: beq+ restore andi. r0,r3,MSR_EE /* interrupts off? */ beq restore /* don't schedule if so */ -#ifdef CONFIG_TRACE_IRQFLAGS - /* Lockdep thinks irqs are enabled, we need to call - * preempt_schedule_irq with IRQs off, so we inform lockdep - * now that we -did- turn them off already - */ - bl trace_hardirqs_off -#endif 1: bl preempt_schedule_irq rlwinm r9,r1,0,0,(31-THREAD_SHIFT) lwz r3,TI_FLAGS(r9) andi. r0,r3,_TIF_NEED_RESCHED bne- 1b -#ifdef CONFIG_TRACE_IRQFLAGS - /* And now, to properly rebalance the above, we tell lockdep they - * are being turned back on, which will happen when we return - */ - bl trace_hardirqs_on -#endif #else resume_kernel: #endif /* CONFIG_PREEMPT */ @@ -857,28 +765,6 @@ restore: stw r6,icache_44x_need_flush@l(r4) 1: #endif /* CONFIG_44x */ - - lwz r9,_MSR(r1) -#ifdef CONFIG_TRACE_IRQFLAGS - /* Lockdep doesn't know about the fact that IRQs are temporarily turned - * off in this assembly code while peeking at TI_FLAGS() and such. However - * we need to inform it if the exception turned interrupts off, and we - * are about to trun them back on. - * - * The problem here sadly is that we don't know whether the exceptions was - * one that turned interrupts off or not. So we always tell lockdep about - * turning them on here when we go back to wherever we came from with EE - * on, even if that may meen some redudant calls being tracked. Maybe later - * we could encode what the exception did somewhere or test the exception - * type in the pt_regs but that sounds overkill - */ - andi. r10,r9,MSR_EE - beq 1f - bl trace_hardirqs_on - lwz r9,_MSR(r1) -1: -#endif /* CONFIG_TRACE_IRQFLAGS */ - lwz r0,GPR0(r1) lwz r2,GPR2(r1) REST_4GPRS(3, r1) @@ -896,6 +782,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) stwcx. r0,0,r1 /* to clear the reservation */ #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) + lwz r9,_MSR(r1) andi. r10,r9,MSR_RI /* check if this exception occurred */ beql nonrecoverable /* at a bad place (MSR:RI = 0) */ @@ -918,6 +805,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) MTMSRD(r10) /* clear the RI bit */ .globl exc_exit_restart exc_exit_restart: + lwz r9,_MSR(r1) lwz r12,_NIP(r1) FIX_SRR1(r9,r10) mtspr SPRN_SRR0,r12 @@ -1147,18 +1035,11 @@ do_work: /* r10 contains MSR_KERNEL here */ beq do_user_signal do_resched: /* r10 contains MSR_KERNEL here */ - /* Note: We don't need to inform lockdep that we are enabling - * interrupts here. As far as it knows, they are already enabled - */ ori r10,r10,MSR_EE SYNC MTMSRD(r10) /* hard-enable interrupts */ bl schedule recheck: - /* Note: And we don't tell it we are disabling them again - * neither. Those disable/enable cycles used to peek at - * TI_FLAGS aren't advertised. - */ LOAD_MSR_KERNEL(r10,MSR_KERNEL) SYNC MTMSRD(r10) /* disable interrupts */ diff --git a/trunk/arch/powerpc/kernel/head_32.S b/trunk/arch/powerpc/kernel/head_32.S index fc2132942754..48469463f89e 100644 --- a/trunk/arch/powerpc/kernel/head_32.S +++ b/trunk/arch/powerpc/kernel/head_32.S @@ -1124,8 +1124,9 @@ mmu_off: RFI /* - * On 601, we use 3 BATs to map up to 24M of RAM at _PAGE_OFFSET - * (we keep one for debugging) and on others, we use one 256M BAT. + * Use the first pair of BAT registers to map the 1st 16MB + * of RAM to PAGE_OFFSET. From this point on we can't safely + * call OF any more. */ initial_bats: lis r11,PAGE_OFFSET@h @@ -1135,16 +1136,12 @@ initial_bats: bne 4f ori r11,r11,4 /* set up BAT registers for 601 */ li r8,0x7f /* valid, block length = 8MB */ + oris r9,r11,0x800000@h /* set up BAT reg for 2nd 8M */ + oris r10,r8,0x800000@h /* set up BAT reg for 2nd 8M */ mtspr SPRN_IBAT0U,r11 /* N.B. 601 has valid bit in */ mtspr SPRN_IBAT0L,r8 /* lower BAT register */ - addis r11,r11,0x800000@h - addis r8,r8,0x800000@h - mtspr SPRN_IBAT1U,r11 - mtspr SPRN_IBAT1L,r8 - addis r11,r11,0x800000@h - addis r8,r8,0x800000@h - mtspr SPRN_IBAT2U,r11 - mtspr SPRN_IBAT2L,r8 + mtspr SPRN_IBAT1U,r9 + mtspr SPRN_IBAT1L,r10 isync blr diff --git a/trunk/arch/powerpc/kernel/of_device.c b/trunk/arch/powerpc/kernel/of_device.c index a359cb08e900..fa983a59c4ce 100644 --- a/trunk/arch/powerpc/kernel/of_device.c +++ b/trunk/arch/powerpc/kernel/of_device.c @@ -76,7 +76,7 @@ struct of_device *of_device_alloc(struct device_node *np, dev->dev.archdata.of_node = np; if (bus_id) - dev_set_name(&dev->dev, "%s", bus_id); + dev_set_name(&dev->dev, bus_id); else of_device_make_bus_id(dev); diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index 892a9f2e6d76..3e7135bbe40f 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -528,7 +528,7 @@ void show_regs(struct pt_regs * regs) for (i = 0; i < 32; i++) { if ((i % REGS_PER_LINE) == 0) - printk("\nGPR%02d: ", i); + printk("\n" KERN_INFO "GPR%02d: ", i); printk(REG " ", regs->gpr[i]); if (i == LAST_VOLATILE && !FULL_REGS(regs)) break; diff --git a/trunk/arch/powerpc/kernel/rtas.c b/trunk/arch/powerpc/kernel/rtas.c index c434823b8c83..ee4c7609b649 100644 --- a/trunk/arch/powerpc/kernel/rtas.c +++ b/trunk/arch/powerpc/kernel/rtas.c @@ -38,10 +38,9 @@ #include #include #include -#include struct rtas_t rtas = { - .lock = __RAW_SPIN_LOCK_UNLOCKED + .lock = SPIN_LOCK_UNLOCKED }; EXPORT_SYMBOL(rtas); @@ -68,28 +67,6 @@ unsigned long rtas_rmo_buf; void (*rtas_flash_term_hook)(int); EXPORT_SYMBOL(rtas_flash_term_hook); -/* RTAS use home made raw locking instead of spin_lock_irqsave - * because those can be called from within really nasty contexts - * such as having the timebase stopped which would lockup with - * normal locks and spinlock debugging enabled - */ -static unsigned long lock_rtas(void) -{ - unsigned long flags; - - local_irq_save(flags); - preempt_disable(); - __raw_spin_lock_flags(&rtas.lock, flags); - return flags; -} - -static void unlock_rtas(unsigned long flags) -{ - __raw_spin_unlock(&rtas.lock); - local_irq_restore(flags); - preempt_enable(); -} - /* * call_rtas_display_status and call_rtas_display_status_delay * are designed only for very early low-level debugging, which @@ -102,7 +79,7 @@ static void call_rtas_display_status(char c) if (!rtas.base) return; - s = lock_rtas(); + spin_lock_irqsave(&rtas.lock, s); args->token = 10; args->nargs = 1; @@ -112,7 +89,7 @@ static void call_rtas_display_status(char c) enter_rtas(__pa(args)); - unlock_rtas(s); + spin_unlock_irqrestore(&rtas.lock, s); } static void call_rtas_display_status_delay(char c) @@ -434,7 +411,8 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE) return -1; - s = lock_rtas(); + /* Gotta do something different here, use global lock for now... */ + spin_lock_irqsave(&rtas.lock, s); rtas_args = &rtas.args; rtas_args->token = token; @@ -461,7 +439,8 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) outputs[i] = rtas_args->rets[i+1]; ret = (nret > 0)? rtas_args->rets[0]: 0; - unlock_rtas(s); + /* Gotta do something different here, use global lock for now... */ + spin_unlock_irqrestore(&rtas.lock, s); if (buff_copy) { log_error(buff_copy, ERR_TYPE_RTAS_LOG, 0); @@ -858,7 +837,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) buff_copy = get_errorlog_buffer(); - flags = lock_rtas(); + spin_lock_irqsave(&rtas.lock, flags); rtas.args = args; enter_rtas(__pa(&rtas.args)); @@ -869,7 +848,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) if (args.rets[0] == -1) errbuf = __fetch_rtas_last_error(buff_copy); - unlock_rtas(flags); + spin_unlock_irqrestore(&rtas.lock, flags); if (buff_copy) { if (errbuf) @@ -972,33 +951,3 @@ int __init early_init_dt_scan_rtas(unsigned long node, /* break now */ return 1; } - -static raw_spinlock_t timebase_lock; -static u64 timebase = 0; - -void __cpuinit rtas_give_timebase(void) -{ - unsigned long flags; - - local_irq_save(flags); - hard_irq_disable(); - __raw_spin_lock(&timebase_lock); - rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); - timebase = get_tb(); - __raw_spin_unlock(&timebase_lock); - - while (timebase) - barrier(); - rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); - local_irq_restore(flags); -} - -void __cpuinit rtas_take_timebase(void) -{ - while (!timebase) - barrier(); - __raw_spin_lock(&timebase_lock); - set_tb(timebase >> 32, timebase & 0xffffffff); - timebase = 0; - __raw_spin_unlock(&timebase_lock); -} diff --git a/trunk/arch/powerpc/kernel/setup_32.c b/trunk/arch/powerpc/kernel/setup_32.c index e1e3059cf34b..1d154248cf40 100644 --- a/trunk/arch/powerpc/kernel/setup_32.c +++ b/trunk/arch/powerpc/kernel/setup_32.c @@ -119,8 +119,6 @@ notrace unsigned long __init early_init(unsigned long dt_ptr) */ notrace void __init machine_init(unsigned long dt_ptr) { - lockdep_init(); - /* Enable early debugging if any specified (see udbg.h) */ udbg_early_init(); diff --git a/trunk/arch/powerpc/kernel/smp.c b/trunk/arch/powerpc/kernel/smp.c index 0b47de07302d..65484b2200b3 100644 --- a/trunk/arch/powerpc/kernel/smp.c +++ b/trunk/arch/powerpc/kernel/smp.c @@ -68,8 +68,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_core_map); /* SMP operations for this machine */ struct smp_ops_t *smp_ops; -/* Can't be static due to PowerMac hackery */ -volatile unsigned int cpu_callin_map[NR_CPUS]; +static volatile unsigned int cpu_callin_map[NR_CPUS]; int smt_enabled_at_boot = 1; diff --git a/trunk/arch/powerpc/kernel/udbg_16550.c b/trunk/arch/powerpc/kernel/udbg_16550.c index acb74a17bbbf..0362a891e54e 100644 --- a/trunk/arch/powerpc/kernel/udbg_16550.c +++ b/trunk/arch/powerpc/kernel/udbg_16550.c @@ -219,7 +219,7 @@ void udbg_init_pas_realmode(void) #ifdef CONFIG_PPC_EARLY_DEBUG_44x #include -static void udbg_44x_as1_flush(void) +static int udbg_44x_as1_flush(void) { if (udbg_comport) { while ((as1_readb(&udbg_comport->lsr) & LSR_THRE) == 0) diff --git a/trunk/arch/powerpc/mm/Makefile b/trunk/arch/powerpc/mm/Makefile index 3e68363405b7..2d2192e48de7 100644 --- a/trunk/arch/powerpc/mm/Makefile +++ b/trunk/arch/powerpc/mm/Makefile @@ -30,4 +30,3 @@ obj-$(CONFIG_PPC_MM_SLICES) += slice.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_PPC_SUBPAGE_PROT) += subpage-prot.o obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o -obj-$(CONFIG_HIGHMEM) += highmem.o diff --git a/trunk/arch/powerpc/mm/highmem.c b/trunk/arch/powerpc/mm/highmem.c deleted file mode 100644 index c2186c74c85a..000000000000 --- a/trunk/arch/powerpc/mm/highmem.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * highmem.c: virtual kernel memory mappings for high memory - * - * PowerPC version, stolen from the i386 version. - * - * Used in CONFIG_HIGHMEM systems for memory pages which - * are not addressable by direct kernel virtual addresses. - * - * Copyright (C) 1999 Gerhard Wichert, Siemens AG - * Gerhard.Wichert@pdb.siemens.de - * - * - * Redesigned the x86 32-bit VM architecture to deal with - * up to 16 Terrabyte physical memory. With current x86 CPUs - * we now support up to 64 Gigabytes physical RAM. - * - * Copyright (C) 1999 Ingo Molnar - * - * Reworked for PowerPC by various contributors. Moved from - * highmem.h by Benjamin Herrenschmidt (c) 2009 IBM Corp. - */ - -#include -#include - -/* - * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap - * gives a more generic (and caching) interface. But kmap_atomic can - * be used in IRQ contexts, so in some (very limited) cases we need - * it. - */ -void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) -{ - unsigned int idx; - unsigned long vaddr; - - /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ - pagefault_disable(); - if (!PageHighMem(page)) - return page_address(page); - - debug_kmap_atomic(type); - idx = type + KM_TYPE_NR*smp_processor_id(); - vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); -#ifdef CONFIG_DEBUG_HIGHMEM - BUG_ON(!pte_none(*(kmap_pte-idx))); -#endif - __set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot), 1); - local_flush_tlb_page(NULL, vaddr); - - return (void*) vaddr; -} -EXPORT_SYMBOL(kmap_atomic_prot); - -void kunmap_atomic(void *kvaddr, enum km_type type) -{ -#ifdef CONFIG_DEBUG_HIGHMEM - unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; - enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); - - if (vaddr < __fix_to_virt(FIX_KMAP_END)) { - pagefault_enable(); - return; - } - - BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); - - /* - * force other mappings to Oops if they'll try to access - * this pte without first remap it - */ - pte_clear(&init_mm, vaddr, kmap_pte-idx); - local_flush_tlb_page(NULL, vaddr); -#endif - pagefault_enable(); -} -EXPORT_SYMBOL(kunmap_atomic); diff --git a/trunk/arch/powerpc/platforms/44x/warp.c b/trunk/arch/powerpc/platforms/44x/warp.c index 0362c88f47d7..42e09a9f77e2 100644 --- a/trunk/arch/powerpc/platforms/44x/warp.c +++ b/trunk/arch/powerpc/platforms/44x/warp.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -66,6 +65,7 @@ define_machine(warp) { static u32 post_info; +/* I am not sure this is the best place for this... */ static int __init warp_post_info(void) { struct device_node *np; @@ -194,9 +194,9 @@ static int pika_setup_leds(void) return 0; } -static void pika_setup_critical_temp(struct device_node *np, - struct i2c_client *client) +static void pika_setup_critical_temp(struct i2c_client *client) { + struct device_node *np; int irq, rc; /* Do this before enabling critical temp interrupt since we @@ -208,7 +208,14 @@ static void pika_setup_critical_temp(struct device_node *np, i2c_smbus_write_byte_data(client, 2, 65); /* Thigh */ i2c_smbus_write_byte_data(client, 3, 0); /* Tlow */ + np = of_find_compatible_node(NULL, NULL, "adi,ad7414"); + if (np == NULL) { + printk(KERN_ERR __FILE__ ": Unable to find ad7414\n"); + return; + } + irq = irq_of_parse_and_map(np, 0); + of_node_put(np); if (irq == NO_IRQ) { printk(KERN_ERR __FILE__ ": Unable to get ad7414 irq\n"); return; @@ -237,24 +244,32 @@ static inline void pika_dtm_check_fan(void __iomem *fpga) static int pika_dtm_thread(void __iomem *fpga) { - struct device_node *np; + struct i2c_adapter *adap; struct i2c_client *client; - np = of_find_compatible_node(NULL, NULL, "adi,ad7414"); - if (np == NULL) - return -ENOENT; + /* We loop in case either driver was compiled as a module and + * has not been insmoded yet. + */ + while (!(adap = i2c_get_adapter(0))) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ); + } - client = of_find_i2c_device_by_node(np); - if (client == NULL) { - of_node_put(np); - return -ENOENT; + while (1) { + list_for_each_entry(client, &adap->clients, list) + if (client->addr == 0x4a) + goto found_it; + + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ); } - pika_setup_critical_temp(np, client); +found_it: + pika_setup_critical_temp(client); - of_node_put(np); + i2c_put_adapter(adap); - printk(KERN_INFO "Warp DTM thread running.\n"); + printk(KERN_INFO "PIKA DTM thread running.\n"); while (!kthread_should_stop()) { int val; @@ -276,6 +291,7 @@ static int pika_dtm_thread(void __iomem *fpga) return 0; } + static int __init pika_dtm_start(void) { struct task_struct *dtm_thread; diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c index 60ed9c067b1d..77f90b356356 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -285,7 +285,6 @@ static struct of_device_id mpc85xx_ids[] = { { .type = "qe", }, { .compatible = "fsl,qe", }, { .compatible = "gianfar", }, - { .compatible = "fsl,rapidio-delta", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/85xx/smp.c b/trunk/arch/powerpc/platforms/85xx/smp.c index 62c592ede641..cc0b0db8a6f3 100644 --- a/trunk/arch/powerpc/platforms/85xx/smp.c +++ b/trunk/arch/powerpc/platforms/85xx/smp.c @@ -52,19 +52,20 @@ smp_85xx_kick_cpu(int nr) pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr); + local_irq_save(flags); + np = of_get_cpu_node(nr, NULL); cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL); if (cpu_rel_addr == NULL) { printk(KERN_ERR "No cpu-release-addr for cpu %d\n", nr); + local_irq_restore(flags); return; } /* Map the spin table */ bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY); - local_irq_save(flags); - out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr); out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start)); @@ -72,10 +73,10 @@ smp_85xx_kick_cpu(int nr) while ((__secondary_hold_acknowledge != nr) && (++n < 1000)) mdelay(1); - local_irq_restore(flags); - iounmap(bptr_vaddr); + local_irq_restore(flags); + pr_debug("waited %d msecs for CPU #%d.\n", n, nr); } diff --git a/trunk/arch/powerpc/platforms/85xx/socrates.c b/trunk/arch/powerpc/platforms/85xx/socrates.c index 747d8fb3ab82..d0e8443b12c6 100644 --- a/trunk/arch/powerpc/platforms/85xx/socrates.c +++ b/trunk/arch/powerpc/platforms/85xx/socrates.c @@ -102,11 +102,10 @@ static struct of_device_id __initdata socrates_of_bus_ids[] = { {}, }; -static int __init socrates_publish_devices(void) +static void __init socrates_init(void) { - return of_platform_bus_probe(NULL, socrates_of_bus_ids, NULL); + of_platform_bus_probe(NULL, socrates_of_bus_ids, NULL); } -machine_device_initcall(socrates, socrates_publish_devices); /* * Called very early, device-tree isn't unflattened @@ -125,6 +124,7 @@ define_machine(socrates) { .name = "Socrates", .probe = socrates_probe, .setup_arch = socrates_setup_arch, + .init = socrates_init, .init_IRQ = socrates_pic_init, .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, diff --git a/trunk/arch/powerpc/platforms/85xx/xes_mpc85xx.c b/trunk/arch/powerpc/platforms/85xx/xes_mpc85xx.c index 1b426050a2f9..ee01532786e4 100644 --- a/trunk/arch/powerpc/platforms/85xx/xes_mpc85xx.c +++ b/trunk/arch/powerpc/platforms/85xx/xes_mpc85xx.c @@ -32,6 +32,7 @@ #include #include +#include /* A few bit definitions needed for fixups on some boards */ #define MPC85xx_L2CTL_L2E 0x80000000 /* L2 enable */ diff --git a/trunk/arch/powerpc/platforms/cell/smp.c b/trunk/arch/powerpc/platforms/cell/smp.c index bc97fada48c6..9046803c8276 100644 --- a/trunk/arch/powerpc/platforms/cell/smp.c +++ b/trunk/arch/powerpc/platforms/cell/smp.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -139,6 +140,31 @@ static void __devinit smp_cell_setup_cpu(int cpu) mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER); } +static DEFINE_SPINLOCK(timebase_lock); +static unsigned long timebase = 0; + +static void __devinit cell_give_timebase(void) +{ + spin_lock(&timebase_lock); + rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); + timebase = get_tb(); + spin_unlock(&timebase_lock); + + while (timebase) + barrier(); + rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); +} + +static void __devinit cell_take_timebase(void) +{ + while (!timebase) + barrier(); + spin_lock(&timebase_lock); + set_tb(timebase >> 32, timebase & 0xffffffff); + timebase = 0; + spin_unlock(&timebase_lock); +} + static void __devinit smp_cell_kick_cpu(int nr) { BUG_ON(nr < 0 || nr >= NR_CPUS); @@ -198,8 +224,8 @@ void __init smp_init_cell(void) /* Non-lpar has additional take/give timebase */ if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { - smp_ops->give_timebase = rtas_give_timebase; - smp_ops->take_timebase = rtas_take_timebase; + smp_ops->give_timebase = cell_give_timebase; + smp_ops->take_timebase = cell_take_timebase; } DBG(" <- smp_init_cell()\n"); diff --git a/trunk/arch/powerpc/platforms/chrp/smp.c b/trunk/arch/powerpc/platforms/chrp/smp.c index 02cafecc90e3..10a4a4d063b6 100644 --- a/trunk/arch/powerpc/platforms/chrp/smp.c +++ b/trunk/arch/powerpc/platforms/chrp/smp.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -41,12 +42,40 @@ static void __devinit smp_chrp_setup_cpu(int cpu_nr) mpic_setup_this_cpu(); } +static DEFINE_SPINLOCK(timebase_lock); +static unsigned int timebase_upper = 0, timebase_lower = 0; + +void __devinit smp_chrp_give_timebase(void) +{ + spin_lock(&timebase_lock); + rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); + timebase_upper = get_tbu(); + timebase_lower = get_tbl(); + spin_unlock(&timebase_lock); + + while (timebase_upper || timebase_lower) + barrier(); + rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); +} + +void __devinit smp_chrp_take_timebase(void) +{ + while (!(timebase_upper || timebase_lower)) + barrier(); + spin_lock(&timebase_lock); + set_tb(timebase_upper, timebase_lower); + timebase_upper = 0; + timebase_lower = 0; + spin_unlock(&timebase_lock); + printk("CPU %i taken timebase\n", smp_processor_id()); +} + /* CHRP with openpic */ struct smp_ops_t chrp_smp_ops = { .message_pass = smp_mpic_message_pass, .probe = smp_mpic_probe, .kick_cpu = smp_chrp_kick_cpu, .setup_cpu = smp_chrp_setup_cpu, - .give_timebase = rtas_give_timebase, - .take_timebase = rtas_take_timebase, + .give_timebase = smp_chrp_give_timebase, + .take_timebase = smp_chrp_take_timebase, }; diff --git a/trunk/arch/powerpc/platforms/pasemi/setup.c b/trunk/arch/powerpc/platforms/pasemi/setup.c index a4619347aa7e..153051eb6d93 100644 --- a/trunk/arch/powerpc/platforms/pasemi/setup.c +++ b/trunk/arch/powerpc/platforms/pasemi/setup.c @@ -71,25 +71,20 @@ static void pas_restart(char *cmd) } #ifdef CONFIG_SMP -static raw_spinlock_t timebase_lock; +static DEFINE_SPINLOCK(timebase_lock); static unsigned long timebase; static void __devinit pas_give_timebase(void) { - unsigned long flags; - - local_irq_save(flags); - hard_irq_disable(); - __raw_spin_lock(&timebase_lock); + spin_lock(&timebase_lock); mtspr(SPRN_TBCTL, TBCTL_FREEZE); isync(); timebase = get_tb(); - __raw_spin_unlock(&timebase_lock); + spin_unlock(&timebase_lock); while (timebase) barrier(); mtspr(SPRN_TBCTL, TBCTL_RESTART); - local_irq_restore(flags); } static void __devinit pas_take_timebase(void) @@ -97,10 +92,10 @@ static void __devinit pas_take_timebase(void) while (!timebase) smp_rmb(); - __raw_spin_lock(&timebase_lock); + spin_lock(&timebase_lock); set_tb(timebase >> 32, timebase & 0xffffffff); timebase = 0; - __raw_spin_unlock(&timebase_lock); + spin_unlock(&timebase_lock); } struct smp_ops_t pas_smp_ops = { diff --git a/trunk/arch/powerpc/platforms/powermac/setup.c b/trunk/arch/powerpc/platforms/powermac/setup.c index c20522656367..86f69a4eb49b 100644 --- a/trunk/arch/powerpc/platforms/powermac/setup.c +++ b/trunk/arch/powerpc/platforms/powermac/setup.c @@ -103,6 +103,11 @@ unsigned long smu_cmdbuf_abs; EXPORT_SYMBOL(smu_cmdbuf_abs); #endif +#ifdef CONFIG_SMP +extern struct smp_ops_t psurge_smp_ops; +extern struct smp_ops_t core99_smp_ops; +#endif /* CONFIG_SMP */ + static void pmac_show_cpuinfo(struct seq_file *m) { struct device_node *np; @@ -336,6 +341,34 @@ static void __init pmac_setup_arch(void) ROOT_DEV = DEFAULT_ROOT_DEVICE; #endif +#ifdef CONFIG_SMP + /* Check for Core99 */ + ic = of_find_node_by_name(NULL, "uni-n"); + if (!ic) + ic = of_find_node_by_name(NULL, "u3"); + if (!ic) + ic = of_find_node_by_name(NULL, "u4"); + if (ic) { + of_node_put(ic); + smp_ops = &core99_smp_ops; + } +#ifdef CONFIG_PPC32 + else { + /* + * We have to set bits in cpu_possible_map here since the + * secondary CPU(s) aren't in the device tree, and + * setup_per_cpu_areas only allocates per-cpu data for + * CPUs in the cpu_possible_map. + */ + int cpu; + + for (cpu = 1; cpu < 4 && cpu < NR_CPUS; ++cpu) + cpu_set(cpu, cpu_possible_map); + smp_ops = &psurge_smp_ops; + } +#endif +#endif /* CONFIG_SMP */ + #ifdef CONFIG_ADB if (strstr(cmd_line, "adb_sync")) { extern int __adb_probe_sync; @@ -479,14 +512,6 @@ static void __init pmac_init_early(void) #ifdef CONFIG_PPC64 iommu_init_early_dart(); #endif - - /* SMP Init has to be done early as we need to patch up - * cpu_possible_map before interrupt stacks are allocated - * or kaboom... - */ -#ifdef CONFIG_SMP - pmac_setup_smp(); -#endif } static int __init pmac_declare_of_platform_devices(void) diff --git a/trunk/arch/powerpc/platforms/powermac/smp.c b/trunk/arch/powerpc/platforms/powermac/smp.c index 6d4da7b46b41..cf1dbe758890 100644 --- a/trunk/arch/powerpc/platforms/powermac/smp.c +++ b/trunk/arch/powerpc/platforms/powermac/smp.c @@ -64,12 +64,11 @@ extern void __secondary_start_pmac_0(void); extern int pmac_pfunc_base_install(void); -static void (*pmac_tb_freeze)(int freeze); -static u64 timebase; -static int tb_req; - #ifdef CONFIG_PPC32 +/* Sync flag for HW tb sync */ +static volatile int sec_tb_reset = 0; + /* * Powersurge (old powermac SMP) support. */ @@ -295,9 +294,6 @@ static int __init smp_psurge_probe(void) psurge_quad_init(); /* All released cards using this HW design have 4 CPUs */ ncpus = 4; - /* No sure how timebase sync works on those, let's use SW */ - smp_ops->give_timebase = smp_generic_give_timebase; - smp_ops->take_timebase = smp_generic_take_timebase; } else { iounmap(quad_base); if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) { @@ -312,15 +308,18 @@ static int __init smp_psurge_probe(void) psurge_start = ioremap(PSURGE_START, 4); psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); - /* This is necessary because OF doesn't know about the + /* + * This is necessary because OF doesn't know about the * secondary cpu(s), and thus there aren't nodes in the * device tree for them, and smp_setup_cpu_maps hasn't - * set their bits in cpu_present_map. + * set their bits in cpu_possible_map and cpu_present_map. */ if (ncpus > NR_CPUS) ncpus = NR_CPUS; - for (i = 1; i < ncpus ; ++i) + for (i = 1; i < ncpus ; ++i) { cpu_set(i, cpu_present_map); + set_hard_smp_processor_id(i, i); + } if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352); @@ -330,14 +329,8 @@ static int __init smp_psurge_probe(void) static void __init smp_psurge_kick_cpu(int nr) { unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8; - unsigned long a, flags; - int i, j; - - /* Defining this here is evil ... but I prefer hiding that - * crap to avoid giving people ideas that they can do the - * same. - */ - extern volatile unsigned int cpu_callin_map[NR_CPUS]; + unsigned long a; + int i; /* may need to flush here if secondary bats aren't setup */ for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32) @@ -346,52 +339,47 @@ static void __init smp_psurge_kick_cpu(int nr) if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353); - /* This is going to freeze the timeebase, we disable interrupts */ - local_irq_save(flags); - out_be32(psurge_start, start); mb(); psurge_set_ipi(nr); - /* * We can't use udelay here because the timebase is now frozen. */ for (i = 0; i < 2000; ++i) - asm volatile("nop" : : : "memory"); + barrier(); psurge_clr_ipi(nr); - /* - * Also, because the timebase is frozen, we must not return to the - * caller which will try to do udelay's etc... Instead, we wait -here- - * for the CPU to callin. - */ - for (i = 0; i < 100000 && !cpu_callin_map[nr]; ++i) { - for (j = 1; j < 10000; j++) - asm volatile("nop" : : : "memory"); - asm volatile("sync" : : : "memory"); - } - if (!cpu_callin_map[nr]) - goto stuck; - - /* And we do the TB sync here too for standard dual CPU cards */ - if (psurge_type == PSURGE_DUAL) { - while(!tb_req) - barrier(); - tb_req = 0; - mb(); - timebase = get_tb(); - mb(); - while (timebase) - barrier(); + if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354); +} + +/* + * With the dual-cpu powersurge board, the decrementers and timebases + * of both cpus are frozen after the secondary cpu is started up, + * until we give the secondary cpu another interrupt. This routine + * uses this to get the timebases synchronized. + * -- paulus. + */ +static void __init psurge_dual_sync_tb(int cpu_nr) +{ + int t; + + set_dec(tb_ticks_per_jiffy); + /* XXX fixme */ + set_tb(0, 0); + + if (cpu_nr > 0) { mb(); + sec_tb_reset = 1; + return; } - stuck: - /* now interrupt the secondary, restarting both TBs */ - if (psurge_type == PSURGE_DUAL) - psurge_set_ipi(1); - if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354); + /* wait for the secondary to have reset its TB before proceeding */ + for (t = 10000000; t > 0 && !sec_tb_reset; --t) + ; + + /* now interrupt the secondary, starting both TBs */ + psurge_set_ipi(1); } static struct irqaction psurge_irqaction = { @@ -402,35 +390,36 @@ static struct irqaction psurge_irqaction = { static void __init smp_psurge_setup_cpu(int cpu_nr) { - if (cpu_nr != 0) - return; - /* reset the entry point so if we get another intr we won't - * try to startup again */ - out_be32(psurge_start, 0x100); - if (setup_irq(30, &psurge_irqaction)) - printk(KERN_ERR "Couldn't get primary IPI interrupt"); + if (cpu_nr == 0) { + /* If we failed to start the second CPU, we should still + * send it an IPI to start the timebase & DEC or we might + * have them stuck. + */ + if (num_online_cpus() < 2) { + if (psurge_type == PSURGE_DUAL) + psurge_set_ipi(1); + return; + } + /* reset the entry point so if we get another intr we won't + * try to startup again */ + out_be32(psurge_start, 0x100); + if (setup_irq(30, &psurge_irqaction)) + printk(KERN_ERR "Couldn't get primary IPI interrupt"); + } + + if (psurge_type == PSURGE_DUAL) + psurge_dual_sync_tb(cpu_nr); } void __init smp_psurge_take_timebase(void) { - if (psurge_type != PSURGE_DUAL) - return; - - tb_req = 1; - mb(); - while (!timebase) - barrier(); - mb(); - set_tb(timebase >> 32, timebase & 0xffffffff); - timebase = 0; - mb(); - set_dec(tb_ticks_per_jiffy/2); + /* Dummy implementation */ } void __init smp_psurge_give_timebase(void) { - /* Nothing to do here */ + /* Dummy implementation */ } /* PowerSurge-style Macs */ @@ -448,6 +437,9 @@ struct smp_ops_t psurge_smp_ops = { * Core 99 and later support */ +static void (*pmac_tb_freeze)(int freeze); +static u64 timebase; +static int tb_req; static void smp_core99_give_timebase(void) { @@ -486,6 +478,7 @@ static void __devinit smp_core99_take_timebase(void) set_tb(timebase >> 32, timebase & 0xffffffff); timebase = 0; mb(); + set_dec(tb_ticks_per_jiffy/2); local_irq_restore(flags); } @@ -927,34 +920,3 @@ struct smp_ops_t core99_smp_ops = { # endif #endif }; - -void __init pmac_setup_smp(void) -{ - struct device_node *np; - - /* Check for Core99 */ - np = of_find_node_by_name(NULL, "uni-n"); - if (!np) - np = of_find_node_by_name(NULL, "u3"); - if (!np) - np = of_find_node_by_name(NULL, "u4"); - if (np) { - of_node_put(np); - smp_ops = &core99_smp_ops; - } -#ifdef CONFIG_PPC32 - else { - /* We have to set bits in cpu_possible_map here since the - * secondary CPU(s) aren't in the device tree. Various - * things won't be initialized for CPUs not in the possible - * map, so we really need to fix it up here. - */ - int cpu; - - for (cpu = 1; cpu < 4 && cpu < NR_CPUS; ++cpu) - cpu_set(cpu, cpu_possible_map); - smp_ops = &psurge_smp_ops; - } -#endif /* CONFIG_PPC32 */ -} - diff --git a/trunk/arch/powerpc/platforms/pseries/smp.c b/trunk/arch/powerpc/platforms/pseries/smp.c index 1f8f6cfb94f7..1a231c389ba0 100644 --- a/trunk/arch/powerpc/platforms/pseries/smp.c +++ b/trunk/arch/powerpc/platforms/pseries/smp.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -117,6 +118,31 @@ static void __devinit smp_xics_setup_cpu(int cpu) } #endif /* CONFIG_XICS */ +static DEFINE_SPINLOCK(timebase_lock); +static unsigned long timebase = 0; + +static void __devinit pSeries_give_timebase(void) +{ + spin_lock(&timebase_lock); + rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); + timebase = get_tb(); + spin_unlock(&timebase_lock); + + while (timebase) + barrier(); + rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); +} + +static void __devinit pSeries_take_timebase(void) +{ + while (!timebase) + barrier(); + spin_lock(&timebase_lock); + set_tb(timebase >> 32, timebase & 0xffffffff); + timebase = 0; + spin_unlock(&timebase_lock); +} + static void __devinit smp_pSeries_kick_cpu(int nr) { BUG_ON(nr < 0 || nr >= NR_CPUS); @@ -183,8 +209,8 @@ static void __init smp_init_pseries(void) /* Non-lpar has additional take/give timebase */ if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { - smp_ops->give_timebase = rtas_give_timebase; - smp_ops->take_timebase = rtas_take_timebase; + smp_ops->give_timebase = pSeries_give_timebase; + smp_ops->take_timebase = pSeries_take_timebase; } pr_debug(" <- smp_init_pSeries()\n"); diff --git a/trunk/arch/powerpc/sysdev/mpic.c b/trunk/arch/powerpc/sysdev/mpic.c index d46de1f0f3ee..9c3af5045495 100644 --- a/trunk/arch/powerpc/sysdev/mpic.c +++ b/trunk/arch/powerpc/sysdev/mpic.c @@ -279,29 +279,28 @@ static void _mpic_map_mmio(struct mpic *mpic, phys_addr_t phys_addr, } #ifdef CONFIG_PPC_DCR -static void _mpic_map_dcr(struct mpic *mpic, struct device_node *node, - struct mpic_reg_bank *rb, +static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb, unsigned int offset, unsigned int size) { const u32 *dbasep; - dbasep = of_get_property(node, "dcr-reg", NULL); + dbasep = of_get_property(mpic->irqhost->of_node, "dcr-reg", NULL); - rb->dhost = dcr_map(node, *dbasep + offset, size); + rb->dhost = dcr_map(mpic->irqhost->of_node, *dbasep + offset, size); BUG_ON(!DCR_MAP_OK(rb->dhost)); } -static inline void mpic_map(struct mpic *mpic, struct device_node *node, - phys_addr_t phys_addr, struct mpic_reg_bank *rb, - unsigned int offset, unsigned int size) +static inline void mpic_map(struct mpic *mpic, phys_addr_t phys_addr, + struct mpic_reg_bank *rb, unsigned int offset, + unsigned int size) { if (mpic->flags & MPIC_USES_DCR) - _mpic_map_dcr(mpic, node, rb, offset, size); + _mpic_map_dcr(mpic, rb, offset, size); else _mpic_map_mmio(mpic, phys_addr, rb, offset, size); } #else /* CONFIG_PPC_DCR */ -#define mpic_map(m,n,p,b,o,s) _mpic_map_mmio(m,p,b,o,s) +#define mpic_map(m,p,b,o,s) _mpic_map_mmio(m,p,b,o,s) #endif /* !CONFIG_PPC_DCR */ @@ -1053,10 +1052,11 @@ struct mpic * __init mpic_alloc(struct device_node *node, int intvec_top; u64 paddr = phys_addr; - mpic = kzalloc(sizeof(struct mpic), GFP_KERNEL); + mpic = alloc_bootmem(sizeof(struct mpic)); if (mpic == NULL) return NULL; - + + memset(mpic, 0, sizeof(struct mpic)); mpic->name = name; mpic->hc_irq = mpic_irq_chip; @@ -1152,8 +1152,8 @@ struct mpic * __init mpic_alloc(struct device_node *node, } /* Map the global registers */ - mpic_map(mpic, node, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000); - mpic_map(mpic, node, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); + mpic_map(mpic, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000); + mpic_map(mpic, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); /* Reset */ if (flags & MPIC_WANTS_RESET) { @@ -1194,7 +1194,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, /* Map the per-CPU registers */ for (i = 0; i < mpic->num_cpus; i++) { - mpic_map(mpic, node, paddr, &mpic->cpuregs[i], + mpic_map(mpic, paddr, &mpic->cpuregs[i], MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE), 0x1000); } @@ -1202,7 +1202,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, /* Initialize main ISU if none provided */ if (mpic->isu_size == 0) { mpic->isu_size = mpic->num_sources; - mpic_map(mpic, node, paddr, &mpic->isus[0], + mpic_map(mpic, paddr, &mpic->isus[0], MPIC_INFO(IRQ_BASE), MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); } mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); @@ -1256,10 +1256,8 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, BUG_ON(isu_num >= MPIC_MAX_ISU); - mpic_map(mpic, mpic->irqhost->of_node, - paddr, &mpic->isus[isu_num], 0, + mpic_map(mpic, paddr, &mpic->isus[isu_num], 0, MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); - if ((isu_first + mpic->isu_size) > mpic->num_sources) mpic->num_sources = isu_first + mpic->isu_size; } diff --git a/trunk/arch/powerpc/sysdev/qe_lib/qe.c b/trunk/arch/powerpc/sysdev/qe_lib/qe.c index 237e3654f48c..b28b0e512d67 100644 --- a/trunk/arch/powerpc/sysdev/qe_lib/qe.c +++ b/trunk/arch/powerpc/sysdev/qe_lib/qe.c @@ -112,7 +112,6 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input) { unsigned long flags; u8 mcn_shift = 0, dev_shift = 0; - u32 ret; spin_lock_irqsave(&qe_lock, flags); if (cmd == QE_RESET) { @@ -140,13 +139,11 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input) } /* wait for the QE_CR_FLG to clear */ - ret = spin_event_timeout((in_be32(&qe_immr->cp.cecr) & QE_CR_FLG) == 0, - 100, 0); - /* On timeout (e.g. failure), the expression will be false (ret == 0), - otherwise it will be true (ret == 1). */ + while(in_be32(&qe_immr->cp.cecr) & QE_CR_FLG) + cpu_relax(); spin_unlock_irqrestore(&qe_lock, flags); - return ret == 1; + return 0; } EXPORT_SYMBOL(qe_issue_cmd); diff --git a/trunk/arch/s390/include/asm/kvm_host.h b/trunk/arch/s390/include/asm/kvm_host.h index 1cd02f6073a0..a27d0d5a6f86 100644 --- a/trunk/arch/s390/include/asm/kvm_host.h +++ b/trunk/arch/s390/include/asm/kvm_host.h @@ -99,9 +99,7 @@ struct kvm_s390_sie_block { __u8 reservedd0[48]; /* 0x00d0 */ __u64 gcr[16]; /* 0x0100 */ __u64 gbea; /* 0x0180 */ - __u8 reserved188[24]; /* 0x0188 */ - __u32 fac; /* 0x01a0 */ - __u8 reserved1a4[92]; /* 0x01a4 */ + __u8 reserved188[120]; /* 0x0188 */ } __attribute__((packed)); struct kvm_vcpu_stat { diff --git a/trunk/arch/s390/kvm/kvm-s390.c b/trunk/arch/s390/kvm/kvm-s390.c index 90d9d1ba258b..c18b21d6991c 100644 --- a/trunk/arch/s390/kvm/kvm-s390.c +++ b/trunk/arch/s390/kvm/kvm-s390.c @@ -25,7 +25,6 @@ #include #include #include -#include #include "kvm-s390.h" #include "gaccess.h" @@ -70,7 +69,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { NULL } }; -static unsigned long long *facilities; /* Section: not file related */ void kvm_arch_hardware_enable(void *garbage) @@ -290,7 +288,6 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) vcpu->arch.sie_block->gmsor = vcpu->kvm->arch.guest_origin; vcpu->arch.sie_block->ecb = 2; vcpu->arch.sie_block->eca = 0xC1002001U; - vcpu->arch.sie_block->fac = (int) (long) facilities; hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet, (unsigned long) vcpu); @@ -742,29 +739,11 @@ gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) static int __init kvm_s390_init(void) { - int ret; - ret = kvm_init(NULL, sizeof(struct kvm_vcpu), THIS_MODULE); - if (ret) - return ret; - - /* - * guests can ask for up to 255+1 double words, we need a full page - * to hold the maximum amount of facilites. On the other hand, we - * only set facilities that are known to work in KVM. - */ - facilities = (unsigned long long *) get_zeroed_page(GFP_DMA); - if (!facilities) { - kvm_exit(); - return -ENOMEM; - } - stfle(facilities, 1); - facilities[0] &= 0xff00fff3f0700000ULL; - return 0; + return kvm_init(NULL, sizeof(struct kvm_vcpu), THIS_MODULE); } static void __exit kvm_s390_exit(void) { - free_page((unsigned long) facilities); kvm_exit(); } diff --git a/trunk/arch/s390/kvm/priv.c b/trunk/arch/s390/kvm/priv.c index d426aac8095d..93ecd06e1a74 100644 --- a/trunk/arch/s390/kvm/priv.c +++ b/trunk/arch/s390/kvm/priv.c @@ -158,7 +158,7 @@ static int handle_stfl(struct kvm_vcpu *vcpu) vcpu->stat.instruction_stfl++; /* only pass the facility bits, which we can handle */ - facility_list &= 0xff00fff3; + facility_list &= 0xfe00fff3; rc = copy_to_guest(vcpu, offsetof(struct _lowcore, stfl_fac_list), &facility_list, sizeof(facility_list)); diff --git a/trunk/arch/sh/Kconfig.debug b/trunk/arch/sh/Kconfig.debug index 39224b57c6ef..8ece0b5bd028 100644 --- a/trunk/arch/sh/Kconfig.debug +++ b/trunk/arch/sh/Kconfig.debug @@ -61,6 +61,10 @@ config EARLY_PRINTK select both the EARLY_SCIF_CONSOLE and SH_STANDARD_BIOS, using the kernel command line option to toggle back and forth. +config DEBUG_BOOTMEM + depends on DEBUG_KERNEL + bool "Debug BOOTMEM initialization" + config DEBUG_STACKOVERFLOW bool "Check for stack overflows" depends on DEBUG_KERNEL && SUPERH32 diff --git a/trunk/arch/sh/boards/mach-se/7206/io.c b/trunk/arch/sh/boards/mach-se/7206/io.c index 180455642a43..9c3a33210d61 100644 --- a/trunk/arch/sh/boards/mach-se/7206/io.c +++ b/trunk/arch/sh/boards/mach-se/7206/io.c @@ -50,7 +50,7 @@ unsigned char se7206_inb_p(unsigned long port) unsigned short se7206_inw(unsigned long port) { - return *port2adr(port); + return *port2adr(port);; } void se7206_outb(unsigned char value, unsigned long port) diff --git a/trunk/arch/sh/boards/mach-se/7724/setup.c b/trunk/arch/sh/boards/mach-se/7724/setup.c index c050a8d76dfd..9cd04bd558b8 100644 --- a/trunk/arch/sh/boards/mach-se/7724/setup.c +++ b/trunk/arch/sh/boards/mach-se/7724/setup.c @@ -23,8 +23,6 @@ #include #include #include -#include -#include #include #include #include @@ -274,34 +272,6 @@ static struct platform_device keysc_device = { }, }; -/* SH Eth */ -static struct resource sh_eth_resources[] = { - [0] = { - .start = SH_ETH_ADDR, - .end = SH_ETH_ADDR + 0x1FC, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 91, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -struct sh_eth_plat_data sh_eth_plat = { - .phy = 0x1f, /* SMSC LAN8187 */ - .edmac_endian = EDMAC_LITTLE_ENDIAN, -}; - -static struct platform_device sh_eth_device = { - .name = "sh-eth", - .id = 0, - .dev = { - .platform_data = &sh_eth_plat, - }, - .num_resources = ARRAY_SIZE(sh_eth_resources), - .resource = sh_eth_resources, -}; - static struct platform_device *ms7724se_devices[] __initdata = { &heartbeat_device, &smc91x_eth_device, @@ -310,57 +280,8 @@ static struct platform_device *ms7724se_devices[] __initdata = { &ceu0_device, &ceu1_device, &keysc_device, - &sh_eth_device, }; -#define EEPROM_OP 0xBA206000 -#define EEPROM_ADR 0xBA206004 -#define EEPROM_DATA 0xBA20600C -#define EEPROM_STAT 0xBA206010 -#define EEPROM_STRT 0xBA206014 -static int __init sh_eth_is_eeprom_ready(void) -{ - int t = 10000; - - while (t--) { - if (!ctrl_inw(EEPROM_STAT)) - return 1; - cpu_relax(); - } - - printk(KERN_ERR "ms7724se can not access to eeprom\n"); - return 0; -} - -static void __init sh_eth_init(void) -{ - int i; - u16 mac[3]; - - /* check EEPROM status */ - if (!sh_eth_is_eeprom_ready()) - return; - - /* read MAC addr from EEPROM */ - for (i = 0 ; i < 3 ; i++) { - ctrl_outw(0x0, EEPROM_OP); /* read */ - ctrl_outw(i*2, EEPROM_ADR); - ctrl_outw(0x1, EEPROM_STRT); - if (!sh_eth_is_eeprom_ready()) - return; - - mac[i] = ctrl_inw(EEPROM_DATA); - mac[i] = ((mac[i] & 0xFF) << 8) | (mac[i] >> 8); /* swap */ - } - - /* reset sh-eth */ - ctrl_outl(0x1, SH_ETH_ADDR + 0x0); - - /* set MAC addr */ - ctrl_outl(((mac[0] << 16) | (mac[1])), SH_ETH_MAHR); - ctrl_outl((mac[2]), SH_ETH_MALR); -} - #define SW4140 0xBA201000 #define FPGA_OUT 0xBA200400 #define PORT_HIZA 0xA4050158 @@ -381,8 +302,7 @@ static int __init devices_setup(void) ctrl_outw(ctrl_inw(FPGA_OUT) & ~((1 << 1) | /* LAN */ (1 << 6) | /* VIDEO DAC */ - (1 << 12) | /* USB0 */ - (1 << 14)), /* RMII */ + (1 << 12)), /* USB0 */ FPGA_OUT); /* enable IRQ 0,1,2 */ @@ -454,7 +374,7 @@ static int __init devices_setup(void) gpio_request(GPIO_FN_VIO0_CLK, NULL); gpio_request(GPIO_FN_VIO0_FLD, NULL); gpio_request(GPIO_FN_VIO0_HD, NULL); - platform_resource_setup_memory(&ceu0_device, "ceu0", 4 << 20); + platform_resource_setup_memory(&ceu0_device, "ceu", 4 << 20); /* enable CEU1 */ gpio_request(GPIO_FN_VIO1_D7, NULL); @@ -469,7 +389,7 @@ static int __init devices_setup(void) gpio_request(GPIO_FN_VIO1_HD, NULL); gpio_request(GPIO_FN_VIO1_VD, NULL); gpio_request(GPIO_FN_VIO1_CLK, NULL); - platform_resource_setup_memory(&ceu1_device, "ceu1", 4 << 20); + platform_resource_setup_memory(&ceu1_device, "ceu", 4 << 20); /* KEYSC */ gpio_request(GPIO_FN_KEYOUT5_IN5, NULL); @@ -484,28 +404,6 @@ static int __init devices_setup(void) gpio_request(GPIO_FN_KEYOUT1, NULL); gpio_request(GPIO_FN_KEYOUT0, NULL); - /* - * enable SH-Eth - * - * please remove J33 pin from your board !! - * - * ms7724 board should not use GPIO_FN_LNKSTA pin - * So, This time PTX5 is set to input pin - */ - gpio_request(GPIO_FN_RMII_RXD0, NULL); - gpio_request(GPIO_FN_RMII_RXD1, NULL); - gpio_request(GPIO_FN_RMII_TXD0, NULL); - gpio_request(GPIO_FN_RMII_TXD1, NULL); - gpio_request(GPIO_FN_RMII_REF_CLK, NULL); - gpio_request(GPIO_FN_RMII_TX_EN, NULL); - gpio_request(GPIO_FN_RMII_RX_ER, NULL); - gpio_request(GPIO_FN_RMII_CRS_DV, NULL); - gpio_request(GPIO_FN_MDIO, NULL); - gpio_request(GPIO_FN_MDC, NULL); - gpio_request(GPIO_PTX5, NULL); - gpio_direction_input(GPIO_PTX5); - sh_eth_init(); - if (sw & SW41_B) { /* SVGA */ lcdc_info.ch[0].lcd_cfg.xres = 800; @@ -539,7 +437,7 @@ static int __init devices_setup(void) } return platform_add_devices(ms7724se_devices, - ARRAY_SIZE(ms7724se_devices)); + ARRAY_SIZE(ms7724se_devices)); } device_initcall(devices_setup); diff --git a/trunk/arch/sh/configs/migor_defconfig b/trunk/arch/sh/configs/migor_defconfig index b18cfd39cac6..da627d22c009 100644 --- a/trunk/arch/sh/configs/migor_defconfig +++ b/trunk/arch/sh/configs/migor_defconfig @@ -309,7 +309,7 @@ CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x00800000 CONFIG_ENTRY_OFFSET=0x00001000 CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 earlyprintk=serial ip=on root=/dev/nfs ip=dhcp" +CONFIG_CMDLINE="console=ttySC0,115200 earlyprintk=serial ip=on root=/dev/nfs ip=dhcp" # # Bus options @@ -858,35 +858,7 @@ CONFIG_VIDEO_SH_MOBILE_CEU=y # # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set -CONFIG_FB=y -# CONFIG_FIRMWARE_EDID is not set -# CONFIG_FB_DDC is not set -# CONFIG_FB_BOOT_VESA_SUPPORT is not set -# CONFIG_FB_CFB_FILLRECT is not set -# CONFIG_FB_CFB_COPYAREA is not set -# CONFIG_FB_CFB_IMAGEBLIT is not set -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -CONFIG_FB_SYS_FILLRECT=y -CONFIG_FB_SYS_COPYAREA=y -CONFIG_FB_SYS_IMAGEBLIT=y -# CONFIG_FB_FOREIGN_ENDIAN is not set -CONFIG_FB_SYS_FOPS=y -CONFIG_FB_DEFERRED_IO=y -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set - -# -# Frame buffer hardware drivers -# -# CONFIG_FB_S1D13XXX is not set -CONFIG_FB_SH_MOBILE_LCDC=y -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FB_METRONOME is not set -# CONFIG_FB_MB862XX is not set -# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -898,27 +870,6 @@ CONFIG_FB_SH_MOBILE_LCDC=y # Console display driver support # CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -CONFIG_FONTS=y -# CONFIG_FONT_8x8 is not set -# CONFIG_FONT_8x16 is not set -# CONFIG_FONT_6x11 is not set -# CONFIG_FONT_7x14 is not set -# CONFIG_FONT_PEARL_8x8 is not set -# CONFIG_FONT_ACORN_8x8 is not set -CONFIG_FONT_MINI_4x6=y -# CONFIG_FONT_SUN8x16 is not set -# CONFIG_FONT_SUN12x22 is not set -# CONFIG_FONT_10x18 is not set -CONFIG_LOGO=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -# CONFIG_LOGO_LINUX_CLUT224 is not set -# CONFIG_LOGO_SUPERH_MONO is not set -CONFIG_LOGO_SUPERH_VGA16=y -# CONFIG_LOGO_SUPERH_CLUT224 is not set # CONFIG_SOUND is not set CONFIG_HID_SUPPORT=y CONFIG_HID=y diff --git a/trunk/arch/sh/configs/se7724_defconfig b/trunk/arch/sh/configs/se7724_defconfig index 3ee783a0a075..3840270283e4 100644 --- a/trunk/arch/sh/configs/se7724_defconfig +++ b/trunk/arch/sh/configs/se7724_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.30 -# Mon Jun 29 16:28:43 2009 +# Thu Jun 18 16:09:05 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -14,7 +14,6 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_IRQ_PER_CPU=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -29,9 +28,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y -CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -CONFIG_CONSTRUCTORS=y # # General setup @@ -91,12 +88,10 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y -CONFIG_HAVE_PERF_COUNTERS=y # # Performance Counters # -# CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y # CONFIG_STRIP_ASM_SYMS is not set CONFIG_COMPAT_BRK=y @@ -112,10 +107,6 @@ CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y - -# -# GCOV-based kernel profiling -# # CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y @@ -128,7 +119,7 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y -CONFIG_LBDAF=y +# CONFIG_LBD is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -593,6 +584,7 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_SRP_ATTRS is not set CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_BNX2_ISCSI is not set # CONFIG_LIBFC is not set # CONFIG_LIBFCOE is not set # CONFIG_SCSI_DEBUG is not set @@ -632,7 +624,7 @@ CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_AX88796 is not set # CONFIG_STNIC is not set -CONFIG_SH_ETH=y +# CONFIG_SH_ETH is not set CONFIG_SMC91X=y # CONFIG_ENC28J60 is not set # CONFIG_ETHOC is not set @@ -809,11 +801,6 @@ CONFIG_SPI_BITBANG=y # # CONFIG_SPI_SPIDEV is not set # CONFIG_SPI_TLE62X0 is not set - -# -# PPS support -# -# CONFIG_PPS is not set CONFIG_ARCH_REQUIRE_GPIOLIB=y CONFIG_GPIOLIB=y # CONFIG_GPIO_SYSFS is not set @@ -864,8 +851,6 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set -# CONFIG_AB3100_CORE is not set -# CONFIG_EZX_PCAP is not set # CONFIG_REGULATOR is not set CONFIG_MEDIA_SUPPORT=y @@ -1211,7 +1196,6 @@ CONFIG_RTC_DRV_PCF8563=y # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set -# CONFIG_RTC_DRV_RX8025 is not set # # SPI RTC drivers @@ -1276,7 +1260,6 @@ CONFIG_FS_MBCACHE=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_BTRFS_FS is not set CONFIG_FILE_LOCKING=y diff --git a/trunk/arch/sh/include/asm/perf_counter.h b/trunk/arch/sh/include/asm/perf_counter.h index 61c2b40c802c..a8153c2aa6fa 100644 --- a/trunk/arch/sh/include/asm/perf_counter.h +++ b/trunk/arch/sh/include/asm/perf_counter.h @@ -2,6 +2,6 @@ #define __ASM_SH_PERF_COUNTER_H /* SH only supports software counters through this interface. */ -static inline void set_perf_counter_pending(void) {} +#define set_perf_counter_pending() do { } while (0) #endif /* __ASM_SH_PERF_COUNTER_H */ diff --git a/trunk/arch/sh/include/asm/syscall_32.h b/trunk/arch/sh/include/asm/syscall_32.h index 6f83f2cc45c1..5bc34681d994 100644 --- a/trunk/arch/sh/include/asm/syscall_32.h +++ b/trunk/arch/sh/include/asm/syscall_32.h @@ -3,7 +3,6 @@ #include #include -#include #include /* The system call number is given by the user in R3 */ diff --git a/trunk/arch/sh/include/mach-se/mach/se7724.h b/trunk/arch/sh/include/mach-se/mach/se7724.h index 29514a39d0f5..74164b60d0db 100644 --- a/trunk/arch/sh/include/mach-se/mach/se7724.h +++ b/trunk/arch/sh/include/mach-se/mach/se7724.h @@ -20,11 +20,6 @@ */ #include -/* SH Eth */ -#define SH_ETH_ADDR (0xA4600000) -#define SH_ETH_MAHR (SH_ETH_ADDR + 0x1C0) -#define SH_ETH_MALR (SH_ETH_ADDR + 0x1C8) - #define PA_LED (0xba203000) /* 8bit LED */ #define IRQ_MODE (0xba200010) #define IRQ0_SR (0xba200014) diff --git a/trunk/arch/sh/mm/fault_32.c b/trunk/arch/sh/mm/fault_32.c index 71925946f1e1..cc8ddbdf3d7a 100644 --- a/trunk/arch/sh/mm/fault_32.c +++ b/trunk/arch/sh/mm/fault_32.c @@ -15,28 +15,12 @@ #include #include #include -#include +#include #include #include #include #include -static inline int notify_page_fault(struct pt_regs *regs, int trap) -{ - int ret = 0; - -#ifdef CONFIG_KPROBES - if (!user_mode(regs)) { - preempt_disable(); - if (kprobe_running() && kprobe_fault_handler(regs, trap)) - ret = 1; - preempt_enable(); - } -#endif - - return ret; -} - /* * This routine handles page faults. It determines the address, * and the problem, and then passes it off to one of the appropriate @@ -103,16 +87,13 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, return; } - mm = tsk->mm; - - if (unlikely(notify_page_fault(regs, lookup_exception_vector()))) - return; - /* Only enable interrupts if they were on before the fault */ - if ((regs->sr & SR_IMASK) != SR_IMASK) + if ((regs->sr & SR_IMASK) != SR_IMASK) { + trace_hardirqs_on(); local_irq_enable(); + } - perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address); + mm = tsk->mm; /* * If we're in an interrupt or have no user @@ -160,15 +141,10 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, goto do_sigbus; BUG(); } - if (fault & VM_FAULT_MAJOR) { + if (fault & VM_FAULT_MAJOR) tsk->maj_flt++; - perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0, - regs, address); - } else { + else tsk->min_flt++; - perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0, - regs, address); - } up_read(&mm->mmap_sem); return; @@ -269,6 +245,22 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, goto no_context; } +static inline int notify_page_fault(struct pt_regs *regs, int trap) +{ + int ret = 0; + +#ifdef CONFIG_KPROBES + if (!user_mode(regs)) { + preempt_disable(); + if (kprobe_running() && kprobe_fault_handler(regs, trap)) + ret = 1; + preempt_enable(); + } +#endif + + return ret; +} + /* * Called with interrupts disabled. */ @@ -281,7 +273,12 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs, pmd_t *pmd; pte_t *pte; pte_t entry; - int ret = 1; + int ret = 0; + + if (notify_page_fault(regs, lookup_exception_vector())) + goto out; + + ret = 1; /* * We don't take page faults for P1, P2, and parts of P4, these diff --git a/trunk/arch/sh/mm/tlbflush_64.c b/trunk/arch/sh/mm/tlbflush_64.c index 3ce40ea34824..fcbb6e135cef 100644 --- a/trunk/arch/sh/mm/tlbflush_64.c +++ b/trunk/arch/sh/mm/tlbflush_64.c @@ -3,7 +3,7 @@ * * Copyright (C) 2000, 2001 Paolo Alberelli * Copyright (C) 2003 Richard Curnow (/proc/tlb, bug fixes) - * Copyright (C) 2003 - 2009 Paul Mundt + * Copyright (C) 2003 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -116,8 +115,6 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, /* Not an IO address, so reenable interrupts */ local_irq_enable(); - perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address); - /* * If we're in an interrupt or have no user * context, we must not take the fault.. @@ -198,16 +195,10 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, goto do_sigbus; BUG(); } - - if (fault & VM_FAULT_MAJOR) { + if (fault & VM_FAULT_MAJOR) tsk->maj_flt++; - perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0, - regs, address); - } else { + else tsk->min_flt++; - perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0, - regs, address); - } /* If we get here, the page fault has been handled. Do the TLB refill now from the newly-setup PTE, to avoid having to fault again right diff --git a/trunk/arch/sparc/boot/Makefile b/trunk/arch/sparc/boot/Makefile index 1ff0fd924756..96041a8d39e8 100644 --- a/trunk/arch/sparc/boot/Makefile +++ b/trunk/arch/sparc/boot/Makefile @@ -15,7 +15,7 @@ quiet_cmd_elftoaout = ELFTOAOUT $@ ifeq ($(CONFIG_SPARC32),y) quiet_cmd_piggy = PIGGY $@ - cmd_piggy = $(obj)/piggyback_32 $@ System.map $(ROOT_IMG) + cmd_piggy = $(obj)/piggyback_32 $@ $(obj)/System.map $(ROOT_IMG) quiet_cmd_btfix = BTFIX $@ cmd_btfix = $(OBJDUMP) -x vmlinux | $(obj)/btfixupprep > $@ quiet_cmd_sysmap = SYSMAP $(obj)/System.map @@ -58,7 +58,7 @@ $(obj)/image: $(obj)/btfix.o FORCE $(obj)/zImage: $(obj)/image $(call if_changed,strip) -$(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback_32 System.map $(ROOT_IMG) FORCE +$(obj)/tftpboot.img: $(obj)/piggyback $(obj)/System.map $(obj)/image FORCE $(call if_changed,elftoaout) $(call if_changed,piggy) @@ -79,7 +79,7 @@ $(obj)/image: vmlinux FORCE $(call if_changed,strip) @echo ' kernel: $@ is ready' -$(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback_64 System.map $(ROOT_IMG) FORCE +$(obj)/tftpboot.img: vmlinux $(obj)/piggyback_64 System.map $(ROOT_IMG) FORCE $(call if_changed,elftoaout) $(call if_changed,piggy) @echo ' kernel: $@ is ready' diff --git a/trunk/arch/sparc/boot/piggyback_32.c b/trunk/arch/sparc/boot/piggyback_32.c index e8dc9adfcd61..c9f500c1a8b2 100644 --- a/trunk/arch/sparc/boot/piggyback_32.c +++ b/trunk/arch/sparc/boot/piggyback_32.c @@ -70,7 +70,7 @@ void die(char *str) int main(int argc,char **argv) { static char aout_magic[] = { 0x01, 0x03, 0x01, 0x07 }; - char buffer[1024], *q, *r; + unsigned char buffer[1024], *q, *r; unsigned int i, j, k, start, end, offset; FILE *map; struct stat s; @@ -84,7 +84,7 @@ int main(int argc,char **argv) while (fgets (buffer, 1024, map)) { if (!strcmp (buffer + 8, " T start\n") || !strcmp (buffer + 16, " T start\n")) start = strtoul (buffer, NULL, 16); - else if (!strcmp (buffer + 8, " A _end\n") || !strcmp (buffer + 16, " A _end\n")) + else if (!strcmp (buffer + 8, " A end\n") || !strcmp (buffer + 16, " A end\n")) end = strtoul (buffer, NULL, 16); } fclose (map); diff --git a/trunk/arch/sparc/boot/piggyback_64.c b/trunk/arch/sparc/boot/piggyback_64.c index c63fd1b6bdd4..de364bfed0bb 100644 --- a/trunk/arch/sparc/boot/piggyback_64.c +++ b/trunk/arch/sparc/boot/piggyback_64.c @@ -46,7 +46,6 @@ int main(int argc,char **argv) struct stat s; int image, tail; - start = end = 0; if (stat (argv[3], &s) < 0) die (argv[3]); map = fopen (argv[2], "r"); if (!map) die(argv[2]); diff --git a/trunk/arch/sparc/kernel/irq_64.c b/trunk/arch/sparc/kernel/irq_64.c index f0ee79055409..bd075054942b 100644 --- a/trunk/arch/sparc/kernel/irq_64.c +++ b/trunk/arch/sparc/kernel/irq_64.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -913,19 +914,25 @@ void __cpuinit notrace sun4v_register_mondo_queues(int this_cpu) tb->nonresum_qmask); } -/* Each queue region must be a power of 2 multiple of 64 bytes in - * size. The base real address must be aligned to the size of the - * region. Thus, an 8KB queue must be 8KB aligned, for example. - */ -static void __init alloc_one_queue(unsigned long *pa_ptr, unsigned long qmask) +static void __init alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask) +{ + unsigned long size = PAGE_ALIGN(qmask + 1); + void *p = __alloc_bootmem(size, size, 0); + if (!p) { + prom_printf("SUN4V: Error, cannot allocate mondo queue.\n"); + prom_halt(); + } + + *pa_ptr = __pa(p); +} + +static void __init alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask) { unsigned long size = PAGE_ALIGN(qmask + 1); - unsigned long order = get_order(size); - unsigned long p; + void *p = __alloc_bootmem(size, size, 0); - p = __get_free_pages(GFP_KERNEL, order); if (!p) { - prom_printf("SUN4V: Error, cannot allocate queue.\n"); + prom_printf("SUN4V: Error, cannot allocate kbuf page.\n"); prom_halt(); } @@ -935,11 +942,11 @@ static void __init alloc_one_queue(unsigned long *pa_ptr, unsigned long qmask) static void __init init_cpu_send_mondo_info(struct trap_per_cpu *tb) { #ifdef CONFIG_SMP - unsigned long page; + void *page; BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64)); - page = get_zeroed_page(GFP_KERNEL); + page = alloc_bootmem_pages(PAGE_SIZE); if (!page) { prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n"); prom_halt(); @@ -958,13 +965,13 @@ static void __init sun4v_init_mondo_queues(void) for_each_possible_cpu(cpu) { struct trap_per_cpu *tb = &trap_block[cpu]; - alloc_one_queue(&tb->cpu_mondo_pa, tb->cpu_mondo_qmask); - alloc_one_queue(&tb->dev_mondo_pa, tb->dev_mondo_qmask); - alloc_one_queue(&tb->resum_mondo_pa, tb->resum_qmask); - alloc_one_queue(&tb->resum_kernel_buf_pa, tb->resum_qmask); - alloc_one_queue(&tb->nonresum_mondo_pa, tb->nonresum_qmask); - alloc_one_queue(&tb->nonresum_kernel_buf_pa, - tb->nonresum_qmask); + alloc_one_mondo(&tb->cpu_mondo_pa, tb->cpu_mondo_qmask); + alloc_one_mondo(&tb->dev_mondo_pa, tb->dev_mondo_qmask); + alloc_one_mondo(&tb->resum_mondo_pa, tb->resum_qmask); + alloc_one_kbuf(&tb->resum_kernel_buf_pa, tb->resum_qmask); + alloc_one_mondo(&tb->nonresum_mondo_pa, tb->nonresum_qmask); + alloc_one_kbuf(&tb->nonresum_kernel_buf_pa, + tb->nonresum_qmask); } } @@ -992,7 +999,7 @@ void __init init_IRQ(void) kill_prom_timer(); size = sizeof(struct ino_bucket) * NUM_IVECS; - ivector_table = kzalloc(size, GFP_KERNEL); + ivector_table = alloc_bootmem(size); if (!ivector_table) { prom_printf("Fatal error, cannot allocate ivector_table\n"); prom_halt(); diff --git a/trunk/arch/um/drivers/slip_kern.c b/trunk/arch/um/drivers/slip_kern.c index dd2aadc14af0..5ec17563142e 100644 --- a/trunk/arch/um/drivers/slip_kern.c +++ b/trunk/arch/um/drivers/slip_kern.c @@ -30,6 +30,7 @@ static void slip_init(struct net_device *dev, void *data) slip_proto_init(&spri->slip); + dev->init = NULL; dev->hard_header_len = 0; dev->header_ops = NULL; dev->addr_len = 0; diff --git a/trunk/arch/um/drivers/slirp_kern.c b/trunk/arch/um/drivers/slirp_kern.c index e376284f0fb7..f15a6e7654f3 100644 --- a/trunk/arch/um/drivers/slirp_kern.c +++ b/trunk/arch/um/drivers/slirp_kern.c @@ -32,6 +32,7 @@ void slirp_init(struct net_device *dev, void *data) slip_proto_init(&spri->slip); + dev->init = NULL; dev->hard_header_len = 0; dev->header_ops = NULL; dev->addr_len = 0; diff --git a/trunk/arch/um/include/asm/dma-mapping.h b/trunk/arch/um/include/asm/dma-mapping.h index 378de4bbf49f..90fc708b320e 100644 --- a/trunk/arch/um/include/asm/dma-mapping.h +++ b/trunk/arch/um/include/asm/dma-mapping.h @@ -79,14 +79,14 @@ dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, } static inline void -dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, +dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { BUG(); } static inline void -dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, +dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction) { BUG(); diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index c07f72205909..d1430ef6b4f9 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -1913,14 +1913,25 @@ config DMAR_DEFAULT_ON recommended you say N here while the DMAR code remains experimental. +config DMAR_GFX_WA + def_bool y + prompt "Support for Graphics workaround" + depends on DMAR + ---help--- + Current Graphics drivers tend to use physical address + for DMA and avoid using DMA APIs. Setting this config + option permits the IOMMU driver to set a unity map for + all the OS-visible memory. Hence the driver can continue + to use physical addresses for DMA. + config DMAR_FLOPPY_WA def_bool y depends on DMAR ---help--- - Floppy disk drivers are known to bypass DMA API calls + Floppy disk drivers are know to bypass DMA API calls thereby failing to work when IOMMU is enabled. This workaround will setup a 1:1 mapping for the first - 16MiB to make floppy (an ISA device) work. + 16M to make floppy (an ISA device) work. config INTR_REMAP bool "Support for Interrupt Remapping (EXPERIMENTAL)" diff --git a/trunk/arch/x86/include/asm/boot.h b/trunk/arch/x86/include/asm/boot.h index 7a1065958ba9..418e632d4a80 100644 --- a/trunk/arch/x86/include/asm/boot.h +++ b/trunk/arch/x86/include/asm/boot.h @@ -8,7 +8,7 @@ #ifdef __KERNEL__ -#include +#include /* Physical address where kernel should be loaded. */ #define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \ @@ -16,10 +16,10 @@ & ~(CONFIG_PHYSICAL_ALIGN - 1)) /* Minimum kernel alignment, as a power of two */ -#ifdef CONFIG_X86_64 +#ifdef CONFIG_x86_64 #define MIN_KERNEL_ALIGN_LG2 PMD_SHIFT #else -#define MIN_KERNEL_ALIGN_LG2 (PAGE_SHIFT + THREAD_ORDER) +#define MIN_KERNEL_ALIGN_LG2 (PAGE_SHIFT+1) #endif #define MIN_KERNEL_ALIGN (_AC(1, UL) << MIN_KERNEL_ALIGN_LG2) diff --git a/trunk/arch/x86/include/asm/pci.h b/trunk/arch/x86/include/asm/pci.h index 1ff685ca221c..927958d13c19 100644 --- a/trunk/arch/x86/include/asm/pci.h +++ b/trunk/arch/x86/include/asm/pci.h @@ -91,7 +91,7 @@ extern void pci_iommu_alloc(void); #define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys) -#if defined(CONFIG_X86_64) || defined(CONFIG_DMAR) || defined(CONFIG_DMA_API_DEBUG) +#if defined(CONFIG_X86_64) || defined(CONFIG_DMA_API_DEBUG) #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ dma_addr_t ADDR_NAME; diff --git a/trunk/arch/x86/include/asm/percpu.h b/trunk/arch/x86/include/asm/percpu.h index 103f1ddb0d85..02ecb30982a3 100644 --- a/trunk/arch/x86/include/asm/percpu.h +++ b/trunk/arch/x86/include/asm/percpu.h @@ -42,7 +42,6 @@ #else /* ...!ASSEMBLY */ -#include #include #ifdef CONFIG_SMP @@ -156,15 +155,6 @@ do { \ /* We can use this directly for local CPU (faster). */ DECLARE_PER_CPU(unsigned long, this_cpu_off); -#ifdef CONFIG_NEED_MULTIPLE_NODES -void *pcpu_lpage_remapped(void *kaddr); -#else -static inline void *pcpu_lpage_remapped(void *kaddr) -{ - return NULL; -} -#endif - #endif /* !__ASSEMBLY__ */ #ifdef CONFIG_SMP diff --git a/trunk/arch/x86/include/asm/perf_counter.h b/trunk/arch/x86/include/asm/perf_counter.h index fa64e401589d..5fb33e160ea0 100644 --- a/trunk/arch/x86/include/asm/perf_counter.h +++ b/trunk/arch/x86/include/asm/perf_counter.h @@ -87,9 +87,6 @@ union cpuid10_edx { #ifdef CONFIG_PERF_COUNTERS extern void init_hw_perf_counters(void); extern void perf_counters_lapic_init(void); - -#define PERF_COUNTER_INDEX_OFFSET 0 - #else static inline void init_hw_perf_counters(void) { } static inline void perf_counters_lapic_init(void) { } diff --git a/trunk/arch/x86/include/asm/proto.h b/trunk/arch/x86/include/asm/proto.h index 621f56d73121..49fb3ecf3bb3 100644 --- a/trunk/arch/x86/include/asm/proto.h +++ b/trunk/arch/x86/include/asm/proto.h @@ -22,14 +22,7 @@ extern int reboot_force; long do_arch_prctl(struct task_struct *task, int code, unsigned long addr); -/* - * This looks more complex than it should be. But we need to - * get the type for the ~ right in round_down (it needs to be - * as wide as the result!), and we want to evaluate the macro - * arguments just once each. - */ -#define __round_mask(x,y) ((__typeof__(x))((y)-1)) -#define round_up(x,y) ((((x)-1) | __round_mask(x,y))+1) -#define round_down(x,y) ((x) & ~__round_mask(x,y)) +#define round_up(x, y) (((x) + (y) - 1) & ~((y) - 1)) +#define round_down(x, y) ((x) & ~((y) - 1)) #endif /* _ASM_X86_PROTO_H */ diff --git a/trunk/arch/x86/kernel/cpu/amd.c b/trunk/arch/x86/kernel/cpu/amd.c index 28e5f5956042..e5b27d8f1b47 100644 --- a/trunk/arch/x86/kernel/cpu/amd.c +++ b/trunk/arch/x86/kernel/cpu/amd.c @@ -258,15 +258,13 @@ static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c) { #ifdef CONFIG_X86_HT unsigned bits; - int cpu = smp_processor_id(); bits = c->x86_coreid_bits; + /* Low order bits define the core id (index of core in socket) */ c->cpu_core_id = c->initial_apicid & ((1 << bits)-1); /* Convert the initial APIC ID into the socket ID */ c->phys_proc_id = c->initial_apicid >> bits; - /* use socket ID also for last level cache */ - per_cpu(cpu_llc_id, cpu) = c->phys_proc_id; #endif } diff --git a/trunk/arch/x86/kernel/cpu/common.c b/trunk/arch/x86/kernel/cpu/common.c index f1961c07af9a..6b26d4deada0 100644 --- a/trunk/arch/x86/kernel/cpu/common.c +++ b/trunk/arch/x86/kernel/cpu/common.c @@ -848,6 +848,9 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) #if defined(CONFIG_NUMA) && defined(CONFIG_X86_64) numa_add_cpu(smp_processor_id()); #endif + + /* Cap the iomem address space to what is addressable on all CPUs */ + iomem_resource.end &= (1ULL << c->x86_phys_bits) - 1; } #ifdef CONFIG_X86_64 diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce.c b/trunk/arch/x86/kernel/cpu/mcheck/mce.c index af425b83202b..284d1de968bc 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/mce.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/mce.c @@ -1117,7 +1117,7 @@ static void mcheck_timer(unsigned long data) *n = min(*n*2, (int)round_jiffies_relative(check_interval*HZ)); t->expires = jiffies + *n; - add_timer_on(t, smp_processor_id()); + add_timer(t); } static void mce_do_trigger(struct work_struct *work) @@ -1321,7 +1321,7 @@ static void mce_init_timer(void) return; setup_timer(t, mcheck_timer, smp_processor_id()); t->expires = round_jiffies(jiffies + *n); - add_timer_on(t, smp_processor_id()); + add_timer(t); } /* diff --git a/trunk/arch/x86/kernel/cpu/perf_counter.c b/trunk/arch/x86/kernel/cpu/perf_counter.c index d4cf4ce19aac..76dfef23f789 100644 --- a/trunk/arch/x86/kernel/cpu/perf_counter.c +++ b/trunk/arch/x86/kernel/cpu/perf_counter.c @@ -401,7 +401,7 @@ static const u64 amd_hw_cache_event_ids [ C(RESULT_MISS) ] = 0x0041, /* Data Cache Misses */ }, [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = 0x0142, /* Data Cache Refills :system */ + [ C(RESULT_ACCESS) ] = 0x0042, /* Data Cache Refills from L2 */ [ C(RESULT_MISS) ] = 0, }, [ C(OP_PREFETCH) ] = { @@ -912,8 +912,6 @@ x86_perf_counter_set_period(struct perf_counter *counter, err = checking_wrmsrl(hwc->counter_base + idx, (u64)(-left) & x86_pmu.counter_mask); - perf_counter_update_userpage(counter); - return ret; } @@ -971,6 +969,13 @@ fixed_mode_idx(struct perf_counter *counter, struct hw_perf_counter *hwc) if (!x86_pmu.num_counters_fixed) return -1; + /* + * Quirk, IA32_FIXED_CTRs do not work on current Atom processors: + */ + if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && + boot_cpu_data.x86_model == 28) + return -1; + event = hwc->config & ARCH_PERFMON_EVENT_MASK; if (unlikely(event == x86_pmu.event_map(PERF_COUNT_HW_INSTRUCTIONS))) @@ -1036,8 +1041,6 @@ static int x86_pmu_enable(struct perf_counter *counter) x86_perf_counter_set_period(counter, hwc, idx); x86_pmu.enable(hwc, idx); - perf_counter_update_userpage(counter); - return 0; } @@ -1130,8 +1133,6 @@ static void x86_pmu_disable(struct perf_counter *counter) x86_perf_counter_update(counter, hwc, idx); cpuc->counters[idx] = NULL; clear_bit(idx, cpuc->used_mask); - - perf_counter_update_userpage(counter); } /* @@ -1427,6 +1428,8 @@ static int intel_pmu_init(void) */ x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3); + rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl); + /* * Install the hw-cache-events table: */ @@ -1496,22 +1499,21 @@ void __init init_hw_perf_counters(void) pr_cont("%s PMU driver.\n", x86_pmu.name); if (x86_pmu.num_counters > X86_PMC_MAX_GENERIC) { + x86_pmu.num_counters = X86_PMC_MAX_GENERIC; WARN(1, KERN_ERR "hw perf counters %d > max(%d), clipping!", x86_pmu.num_counters, X86_PMC_MAX_GENERIC); - x86_pmu.num_counters = X86_PMC_MAX_GENERIC; } perf_counter_mask = (1 << x86_pmu.num_counters) - 1; perf_max_counters = x86_pmu.num_counters; if (x86_pmu.num_counters_fixed > X86_PMC_MAX_FIXED) { + x86_pmu.num_counters_fixed = X86_PMC_MAX_FIXED; WARN(1, KERN_ERR "hw perf counters fixed %d > max(%d), clipping!", x86_pmu.num_counters_fixed, X86_PMC_MAX_FIXED); - x86_pmu.num_counters_fixed = X86_PMC_MAX_FIXED; } perf_counter_mask |= ((1LL << x86_pmu.num_counters_fixed)-1) << X86_PMC_IDX_FIXED; - x86_pmu.intel_ctrl = perf_counter_mask; perf_counters_lapic_init(); register_die_notifier(&perf_counter_nmi_notifier); diff --git a/trunk/arch/x86/kernel/dumpstack.c b/trunk/arch/x86/kernel/dumpstack.c index c8405718a4c3..95ea5fa7d444 100644 --- a/trunk/arch/x86/kernel/dumpstack.c +++ b/trunk/arch/x86/kernel/dumpstack.c @@ -22,7 +22,6 @@ #include "dumpstack.h" int panic_on_unrecovered_nmi; -int panic_on_io_nmi; unsigned int code_bytes = 64; int kstack_depth_to_print = 3 * STACKSLOTS_PER_LINE; static int die_counter; diff --git a/trunk/arch/x86/kernel/e820.c b/trunk/arch/x86/kernel/e820.c index c4ca89d9aaf4..7271fa33d791 100644 --- a/trunk/arch/x86/kernel/e820.c +++ b/trunk/arch/x86/kernel/e820.c @@ -1383,8 +1383,6 @@ static unsigned long ram_alignment(resource_size_t pos) return 32*1024*1024; } -#define MAX_RESOURCE_SIZE ((resource_size_t)-1) - void __init e820_reserve_resources_late(void) { int i; @@ -1402,19 +1400,17 @@ void __init e820_reserve_resources_late(void) * avoid stolen RAM: */ for (i = 0; i < e820.nr_map; i++) { - struct e820entry *entry = &e820.map[i]; - u64 start, end; + struct e820entry *entry = &e820_saved.map[i]; + resource_size_t start, end; if (entry->type != E820_RAM) continue; start = entry->addr + entry->size; - end = round_up(start, ram_alignment(start)) - 1; - if (end > MAX_RESOURCE_SIZE) - end = MAX_RESOURCE_SIZE; - if (start >= end) + end = round_up(start, ram_alignment(start)); + if (start == end) continue; - reserve_region_with_split(&iomem_resource, start, end, - "RAM buffer"); + reserve_region_with_split(&iomem_resource, start, + end - 1, "RAM buffer"); } } diff --git a/trunk/arch/x86/kernel/pci-dma.c b/trunk/arch/x86/kernel/pci-dma.c index 1a041bcf506b..47630479b067 100644 --- a/trunk/arch/x86/kernel/pci-dma.c +++ b/trunk/arch/x86/kernel/pci-dma.c @@ -211,11 +211,11 @@ static __init int iommu_setup(char *p) #ifdef CONFIG_SWIOTLB if (!strncmp(p, "soft", 4)) swiotlb = 1; -#endif if (!strncmp(p, "pt", 2)) { iommu_pass_through = 1; return 1; } +#endif gart_parse_options(p); diff --git a/trunk/arch/x86/kernel/setup.c b/trunk/arch/x86/kernel/setup.c index de2cab132844..be5ae80f897f 100644 --- a/trunk/arch/x86/kernel/setup.c +++ b/trunk/arch/x86/kernel/setup.c @@ -289,20 +289,6 @@ void * __init extend_brk(size_t size, size_t align) return ret; } -#ifdef CONFIG_X86_64 -static void __init init_gbpages(void) -{ - if (direct_gbpages && cpu_has_gbpages) - printk(KERN_INFO "Using GB pages for direct mapping\n"); - else - direct_gbpages = 0; -} -#else -static inline void init_gbpages(void) -{ -} -#endif - static void __init reserve_brk(void) { if (_brk_end > _brk_start) @@ -885,8 +871,6 @@ void __init setup_arch(char **cmdline_p) reserve_brk(); - init_gbpages(); - /* max_pfn_mapped is updated here */ max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<= pcpul_size) + if (off >= pcpur_size) return NULL; - return virt_to_page(pcpul_map[cpu].ptr + off); + return virt_to_page(pcpur_ptrs[cpu] + off); } -static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen) +static ssize_t __init setup_pcpu_remap(size_t static_size) { - size_t map_size, dyn_size; + static struct vm_struct vm; + size_t ptrs_size, dyn_size; unsigned int cpu; - int i, j; ssize_t ret; - if (!chosen) { - size_t vm_size = VMALLOC_END - VMALLOC_START; - size_t tot_size = num_possible_cpus() * PMD_SIZE; - - /* on non-NUMA, embedding is better */ - if (!pcpu_need_numa()) - return -EINVAL; - - /* don't consume more than 20% of vmalloc area */ - if (tot_size > vm_size / 5) { - pr_info("PERCPU: too large chunk size %zuMB for " - "large page remap\n", tot_size >> 20); - return -EINVAL; - } - } - - /* need PSE */ - if (!cpu_has_pse) { - pr_warning("PERCPU: lpage allocator requires PSE\n"); + /* + * If large page isn't supported, there's no benefit in doing + * this. Also, on non-NUMA, embedding is better. + * + * NOTE: disabled for now. + */ + if (true || !cpu_has_pse || !pcpu_need_numa()) return -EINVAL; - } /* * Currently supports only single page. Supporting multiple * pages won't be too difficult if it ever becomes necessary. */ - pcpul_size = PFN_ALIGN(static_size + PERCPU_MODULE_RESERVE + + pcpur_size = PFN_ALIGN(static_size + PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE); - if (pcpul_size > PMD_SIZE) { + if (pcpur_size > PMD_SIZE) { pr_warning("PERCPU: static data is larger than large page, " "can't use large page\n"); return -EINVAL; } - dyn_size = pcpul_size - static_size - PERCPU_FIRST_CHUNK_RESERVE; + dyn_size = pcpur_size - static_size - PERCPU_FIRST_CHUNK_RESERVE; /* allocate pointer array and alloc large pages */ - map_size = PFN_ALIGN(num_possible_cpus() * sizeof(pcpul_map[0])); - pcpul_map = alloc_bootmem(map_size); + ptrs_size = PFN_ALIGN(num_possible_cpus() * sizeof(pcpur_ptrs[0])); + pcpur_ptrs = alloc_bootmem(ptrs_size); for_each_possible_cpu(cpu) { - pcpul_map[cpu].cpu = cpu; - pcpul_map[cpu].ptr = pcpu_alloc_bootmem(cpu, PMD_SIZE, - PMD_SIZE); - if (!pcpul_map[cpu].ptr) { - pr_warning("PERCPU: failed to allocate large page " - "for cpu%u\n", cpu); + pcpur_ptrs[cpu] = pcpu_alloc_bootmem(cpu, PMD_SIZE, PMD_SIZE); + if (!pcpur_ptrs[cpu]) goto enomem; - } /* - * Only use pcpul_size bytes and give back the rest. + * Only use pcpur_size bytes and give back the rest. * * Ingo: The 2MB up-rounding bootmem is needed to make * sure the partial 2MB page is still fully RAM - it's * not well-specified to have a PAT-incompatible area * (unmapped RAM, device memory, etc.) in that hole. */ - free_bootmem(__pa(pcpul_map[cpu].ptr + pcpul_size), - PMD_SIZE - pcpul_size); + free_bootmem(__pa(pcpur_ptrs[cpu] + pcpur_size), + PMD_SIZE - pcpur_size); - memcpy(pcpul_map[cpu].ptr, __per_cpu_load, static_size); + memcpy(pcpur_ptrs[cpu], __per_cpu_load, static_size); } /* allocate address and map */ - pcpul_vm.flags = VM_ALLOC; - pcpul_vm.size = num_possible_cpus() * PMD_SIZE; - vm_area_register_early(&pcpul_vm, PMD_SIZE); + vm.flags = VM_ALLOC; + vm.size = num_possible_cpus() * PMD_SIZE; + vm_area_register_early(&vm, PMD_SIZE); for_each_possible_cpu(cpu) { - pmd_t *pmd, pmd_v; + pmd_t *pmd; - pmd = populate_extra_pmd((unsigned long)pcpul_vm.addr + - cpu * PMD_SIZE); - pmd_v = pfn_pmd(page_to_pfn(virt_to_page(pcpul_map[cpu].ptr)), - PAGE_KERNEL_LARGE); - set_pmd(pmd, pmd_v); + pmd = populate_extra_pmd((unsigned long)vm.addr + + cpu * PMD_SIZE); + set_pmd(pmd, pfn_pmd(page_to_pfn(virt_to_page(pcpur_ptrs[cpu])), + PAGE_KERNEL_LARGE)); } /* we're ready, commit */ pr_info("PERCPU: Remapped at %p with large pages, static data " - "%zu bytes\n", pcpul_vm.addr, static_size); + "%zu bytes\n", vm.addr, static_size); - ret = pcpu_setup_first_chunk(pcpul_get_page, static_size, + ret = pcpu_setup_first_chunk(pcpur_get_page, static_size, PERCPU_FIRST_CHUNK_RESERVE, dyn_size, - PMD_SIZE, pcpul_vm.addr, NULL); - - /* sort pcpul_map array for pcpu_lpage_remapped() */ - for (i = 0; i < num_possible_cpus() - 1; i++) - for (j = i + 1; j < num_possible_cpus(); j++) - if (pcpul_map[i].ptr > pcpul_map[j].ptr) { - struct pcpul_ent tmp = pcpul_map[i]; - pcpul_map[i] = pcpul_map[j]; - pcpul_map[j] = tmp; - } - - return ret; + PMD_SIZE, vm.addr, NULL); + goto out_free_ar; enomem: for_each_possible_cpu(cpu) - if (pcpul_map[cpu].ptr) - free_bootmem(__pa(pcpul_map[cpu].ptr), pcpul_size); - free_bootmem(__pa(pcpul_map), map_size); - return -ENOMEM; -} - -/** - * pcpu_lpage_remapped - determine whether a kaddr is in pcpul recycled area - * @kaddr: the kernel address in question - * - * Determine whether @kaddr falls in the pcpul recycled area. This is - * used by pageattr to detect VM aliases and break up the pcpu PMD - * mapping such that the same physical page is not mapped under - * different attributes. - * - * The recycled area is always at the tail of a partially used PMD - * page. - * - * RETURNS: - * Address of corresponding remapped pcpu address if match is found; - * otherwise, NULL. - */ -void *pcpu_lpage_remapped(void *kaddr) -{ - void *pmd_addr = (void *)((unsigned long)kaddr & PMD_MASK); - unsigned long offset = (unsigned long)kaddr & ~PMD_MASK; - int left = 0, right = num_possible_cpus() - 1; - int pos; - - /* pcpul in use at all? */ - if (!pcpul_map) - return NULL; - - /* okay, perform binary search */ - while (left <= right) { - pos = (left + right) / 2; - - if (pcpul_map[pos].ptr < pmd_addr) - left = pos + 1; - else if (pcpul_map[pos].ptr > pmd_addr) - right = pos - 1; - else { - /* it shouldn't be in the area for the first chunk */ - WARN_ON(offset < pcpul_size); - - return pcpul_vm.addr + - pcpul_map[pos].cpu * PMD_SIZE + offset; - } - } - - return NULL; + if (pcpur_ptrs[cpu]) + free_bootmem(__pa(pcpur_ptrs[cpu]), PMD_SIZE); + ret = -ENOMEM; +out_free_ar: + free_bootmem(__pa(pcpur_ptrs), ptrs_size); + return ret; } #else -static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen) +static ssize_t __init setup_pcpu_remap(size_t static_size) { return -EINVAL; } @@ -329,7 +249,7 @@ static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen) * mapping so that it can use PMD mapping without additional TLB * pressure. */ -static ssize_t __init setup_pcpu_embed(size_t static_size, bool chosen) +static ssize_t __init setup_pcpu_embed(size_t static_size) { size_t reserve = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE; @@ -338,7 +258,7 @@ static ssize_t __init setup_pcpu_embed(size_t static_size, bool chosen) * this. Also, embedding allocation doesn't play well with * NUMA. */ - if (!chosen && (!cpu_has_pse || pcpu_need_numa())) + if (!cpu_has_pse || pcpu_need_numa()) return -EINVAL; return pcpu_embed_first_chunk(static_size, PERCPU_FIRST_CHUNK_RESERVE, @@ -388,11 +308,8 @@ static ssize_t __init setup_pcpu_4k(size_t static_size) void *ptr; ptr = pcpu_alloc_bootmem(cpu, PAGE_SIZE, PAGE_SIZE); - if (!ptr) { - pr_warning("PERCPU: failed to allocate " - "4k page for cpu%u\n", cpu); + if (!ptr) goto enomem; - } memcpy(ptr, __per_cpu_load + i * PAGE_SIZE, PAGE_SIZE); pcpu4k_pages[j++] = virt_to_page(ptr); @@ -416,16 +333,6 @@ static ssize_t __init setup_pcpu_4k(size_t static_size) return ret; } -/* for explicit first chunk allocator selection */ -static char pcpu_chosen_alloc[16] __initdata; - -static int __init percpu_alloc_setup(char *str) -{ - strncpy(pcpu_chosen_alloc, str, sizeof(pcpu_chosen_alloc) - 1); - return 0; -} -early_param("percpu_alloc", percpu_alloc_setup); - static inline void setup_percpu_segment(int cpu) { #ifdef CONFIG_X86_32 @@ -439,6 +346,11 @@ static inline void setup_percpu_segment(int cpu) #endif } +/* + * Great future plan: + * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data. + * Always point %gs to its beginning + */ void __init setup_per_cpu_areas(void) { size_t static_size = __per_cpu_end - __per_cpu_start; @@ -455,26 +367,9 @@ void __init setup_per_cpu_areas(void) * of large page mappings. Please read comments on top of * each allocator for details. */ - ret = -EINVAL; - if (strlen(pcpu_chosen_alloc)) { - if (strcmp(pcpu_chosen_alloc, "4k")) { - if (!strcmp(pcpu_chosen_alloc, "lpage")) - ret = setup_pcpu_lpage(static_size, true); - else if (!strcmp(pcpu_chosen_alloc, "embed")) - ret = setup_pcpu_embed(static_size, true); - else - pr_warning("PERCPU: unknown allocator %s " - "specified\n", pcpu_chosen_alloc); - if (ret < 0) - pr_warning("PERCPU: %s allocator failed (%zd), " - "falling back to 4k\n", - pcpu_chosen_alloc, ret); - } - } else { - ret = setup_pcpu_lpage(static_size, false); - if (ret < 0) - ret = setup_pcpu_embed(static_size, false); - } + ret = setup_pcpu_remap(static_size); + if (ret < 0) + ret = setup_pcpu_embed(static_size); if (ret < 0) ret = setup_pcpu_4k(static_size); if (ret < 0) diff --git a/trunk/arch/x86/kernel/tlb_uv.c b/trunk/arch/x86/kernel/tlb_uv.c index 8ccabb8a2f6a..124d40c575df 100644 --- a/trunk/arch/x86/kernel/tlb_uv.c +++ b/trunk/arch/x86/kernel/tlb_uv.c @@ -711,6 +711,7 @@ uv_activation_descriptor_init(int node, int pnode) unsigned long pa; unsigned long m; unsigned long n; + unsigned long mmr_image; struct bau_desc *adp; struct bau_desc *ad2; @@ -726,8 +727,12 @@ uv_activation_descriptor_init(int node, int pnode) n = pa >> uv_nshift; m = pa & uv_mmask; - uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE, - (n << UV_DESC_BASE_PNODE_SHIFT | m)); + mmr_image = uv_read_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE); + if (mmr_image) { + uv_write_global_mmr64(pnode, (unsigned long) + UVH_LB_BAU_SB_DESCRIPTOR_BASE, + (n << UV_DESC_BASE_PNODE_SHIFT | m)); + } /* * initializing all 8 (UV_ITEMS_PER_DESCRIPTOR) descriptors for each diff --git a/trunk/arch/x86/kernel/traps.c b/trunk/arch/x86/kernel/traps.c index 5204332f475d..a0f48f5671c0 100644 --- a/trunk/arch/x86/kernel/traps.c +++ b/trunk/arch/x86/kernel/traps.c @@ -346,9 +346,6 @@ io_check_error(unsigned char reason, struct pt_regs *regs) printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n"); show_registers(regs); - if (panic_on_io_nmi) - panic("NMI IOCK error: Not continuing"); - /* Re-enable the IOCK line, wait for a few seconds */ reason = (reason & 0xf) | 8; outb(reason, 0x61); diff --git a/trunk/arch/x86/kvm/mmu.c b/trunk/arch/x86/kvm/mmu.c index 7030b5f911bf..5c3d6e81a7dc 100644 --- a/trunk/arch/x86/kvm/mmu.c +++ b/trunk/arch/x86/kvm/mmu.c @@ -2157,7 +2157,7 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level) else /* 32 bits PSE 4MB page */ context->rsvd_bits_mask[1][1] = rsvd_bits(13, 21); - context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[1][0]; + context->rsvd_bits_mask[1][0] = ~0ull; break; case PT32E_ROOT_LEVEL: context->rsvd_bits_mask[0][2] = @@ -2170,7 +2170,7 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level) context->rsvd_bits_mask[1][1] = exb_bit_rsvd | rsvd_bits(maxphyaddr, 62) | rsvd_bits(13, 20); /* large page */ - context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[1][0]; + context->rsvd_bits_mask[1][0] = ~0ull; break; case PT64_ROOT_LEVEL: context->rsvd_bits_mask[0][3] = exb_bit_rsvd | @@ -2186,7 +2186,7 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level) context->rsvd_bits_mask[1][1] = exb_bit_rsvd | rsvd_bits(maxphyaddr, 51) | rsvd_bits(13, 20); /* large page */ - context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[1][0]; + context->rsvd_bits_mask[1][0] = ~0ull; break; } } diff --git a/trunk/arch/x86/kvm/paging_tmpl.h b/trunk/arch/x86/kvm/paging_tmpl.h index 67785f635399..258e4591e1ca 100644 --- a/trunk/arch/x86/kvm/paging_tmpl.h +++ b/trunk/arch/x86/kvm/paging_tmpl.h @@ -281,7 +281,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, { unsigned access = gw->pt_access; struct kvm_mmu_page *shadow_page; - u64 spte, *sptep = NULL; + u64 spte, *sptep; int direct; gfn_t table_gfn; int r; diff --git a/trunk/arch/x86/kvm/vmx.c b/trunk/arch/x86/kvm/vmx.c index 356a0ce85c68..e770bf349ec4 100644 --- a/trunk/arch/x86/kvm/vmx.c +++ b/trunk/arch/x86/kvm/vmx.c @@ -3012,12 +3012,6 @@ static int handle_vmcall(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) return 1; } -static int handle_vmx_insn(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) -{ - kvm_queue_exception(vcpu, UD_VECTOR); - return 1; -} - static int handle_invlpg(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); @@ -3204,15 +3198,6 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu, [EXIT_REASON_HLT] = handle_halt, [EXIT_REASON_INVLPG] = handle_invlpg, [EXIT_REASON_VMCALL] = handle_vmcall, - [EXIT_REASON_VMCLEAR] = handle_vmx_insn, - [EXIT_REASON_VMLAUNCH] = handle_vmx_insn, - [EXIT_REASON_VMPTRLD] = handle_vmx_insn, - [EXIT_REASON_VMPTRST] = handle_vmx_insn, - [EXIT_REASON_VMREAD] = handle_vmx_insn, - [EXIT_REASON_VMRESUME] = handle_vmx_insn, - [EXIT_REASON_VMWRITE] = handle_vmx_insn, - [EXIT_REASON_VMOFF] = handle_vmx_insn, - [EXIT_REASON_VMON] = handle_vmx_insn, [EXIT_REASON_TPR_BELOW_THRESHOLD] = handle_tpr_below_threshold, [EXIT_REASON_APIC_ACCESS] = handle_apic_access, [EXIT_REASON_WBINVD] = handle_wbinvd, diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index fe5474aec41a..249540f98513 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -898,7 +898,6 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) case MSR_VM_HSAVE_PA: case MSR_P6_EVNTSEL0: case MSR_P6_EVNTSEL1: - case MSR_K7_EVNTSEL0: data = 0; break; case MSR_MTRRcap: diff --git a/trunk/arch/x86/kvm/x86_emulate.c b/trunk/arch/x86/kvm/x86_emulate.c index 616de4628d60..c1b6c232e02b 100644 --- a/trunk/arch/x86/kvm/x86_emulate.c +++ b/trunk/arch/x86/kvm/x86_emulate.c @@ -1361,7 +1361,7 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt, return 0; } -static void toggle_interruptibility(struct x86_emulate_ctxt *ctxt, u32 mask) +void toggle_interruptibility(struct x86_emulate_ctxt *ctxt, u32 mask) { u32 int_shadow = kvm_x86_ops->get_interrupt_shadow(ctxt->vcpu, mask); /* diff --git a/trunk/arch/x86/lib/delay.c b/trunk/arch/x86/lib/delay.c index ff485d361182..f4568605d7d5 100644 --- a/trunk/arch/x86/lib/delay.c +++ b/trunk/arch/x86/lib/delay.c @@ -55,10 +55,8 @@ static void delay_tsc(unsigned long loops) preempt_disable(); cpu = smp_processor_id(); - rdtsc_barrier(); rdtscl(bclock); for (;;) { - rdtsc_barrier(); rdtscl(now); if ((now - bclock) >= loops) break; @@ -80,7 +78,6 @@ static void delay_tsc(unsigned long loops) if (unlikely(cpu != smp_processor_id())) { loops -= (now - bclock); cpu = smp_processor_id(); - rdtsc_barrier(); rdtscl(bclock); } } diff --git a/trunk/arch/x86/mm/init.c b/trunk/arch/x86/mm/init.c index 47ce9a2ce5e7..f53b57e4086f 100644 --- a/trunk/arch/x86/mm/init.c +++ b/trunk/arch/x86/mm/init.c @@ -177,6 +177,20 @@ static int __meminit save_mr(struct map_range *mr, int nr_range, return nr_range; } +#ifdef CONFIG_X86_64 +static void __init init_gbpages(void) +{ + if (direct_gbpages && cpu_has_gbpages) + printk(KERN_INFO "Using GB pages for direct mapping\n"); + else + direct_gbpages = 0; +} +#else +static inline void init_gbpages(void) +{ +} +#endif + /* * Setup the direct mapping of the physical memory at PAGE_OFFSET. * This runs before bootmem is initialized and gets pages directly from @@ -196,6 +210,9 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, printk(KERN_INFO "init_memory_mapping: %016lx-%016lx\n", start, end); + if (!after_bootmem) + init_gbpages(); + #if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KMEMCHECK) /* * For CONFIG_DEBUG_PAGEALLOC, identity mapping will use small pages. diff --git a/trunk/arch/x86/mm/init_64.c b/trunk/arch/x86/mm/init_64.c index b177652251a4..c4378f4fd4a5 100644 --- a/trunk/arch/x86/mm/init_64.c +++ b/trunk/arch/x86/mm/init_64.c @@ -598,8 +598,6 @@ void __init paging_init(void) sparse_memory_present_with_active_regions(MAX_NUMNODES); sparse_init(); - /* clear the default setting with node 0 */ - nodes_clear(node_states[N_NORMAL_MEMORY]); free_area_init_nodes(max_zone_pfns); } diff --git a/trunk/arch/x86/mm/pageattr.c b/trunk/arch/x86/mm/pageattr.c index 1b734d7a8966..3cfe9ced8a4c 100644 --- a/trunk/arch/x86/mm/pageattr.c +++ b/trunk/arch/x86/mm/pageattr.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -682,9 +681,8 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias); static int cpa_process_alias(struct cpa_data *cpa) { struct cpa_data alias_cpa; - unsigned long laddr = (unsigned long)__va(cpa->pfn << PAGE_SHIFT); - unsigned long vaddr, remapped; - int ret; + int ret = 0; + unsigned long temp_cpa_vaddr, vaddr; if (cpa->pfn >= max_pfn_mapped) return 0; @@ -708,55 +706,42 @@ static int cpa_process_alias(struct cpa_data *cpa) PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT)))) { alias_cpa = *cpa; - alias_cpa.vaddr = &laddr; + temp_cpa_vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT); + alias_cpa.vaddr = &temp_cpa_vaddr; alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); + ret = __change_page_attr_set_clr(&alias_cpa, 0); - if (ret) - return ret; } #ifdef CONFIG_X86_64 + if (ret) + return ret; /* - * If the primary call didn't touch the high mapping already - * and the physical address is inside the kernel map, we need + * No need to redo, when the primary call touched the high + * mapping already: + */ + if (within(vaddr, (unsigned long) _text, _brk_end)) + return 0; + + /* + * If the physical address is inside the kernel map, we need * to touch the high mapped kernel as well: */ - if (!within(vaddr, (unsigned long)_text, _brk_end) && - within(cpa->pfn, highmap_start_pfn(), highmap_end_pfn())) { - unsigned long temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) + - __START_KERNEL_map - phys_base; - alias_cpa = *cpa; - alias_cpa.vaddr = &temp_cpa_vaddr; - alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); + if (!within(cpa->pfn, highmap_start_pfn(), highmap_end_pfn())) + return 0; - /* - * The high mapping range is imprecise, so ignore the - * return value. - */ - __change_page_attr_set_clr(&alias_cpa, 0); - } -#endif + alias_cpa = *cpa; + temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) + __START_KERNEL_map - phys_base; + alias_cpa.vaddr = &temp_cpa_vaddr; + alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); /* - * If the PMD page was partially used for per-cpu remapping, - * the recycled area needs to be split and modified. Because - * the area is always proper subset of a PMD page - * cpa->numpages is guaranteed to be 1 for these areas, so - * there's no need to loop over and check for further remaps. + * The high mapping range is imprecise, so ignore the return value. */ - remapped = (unsigned long)pcpu_lpage_remapped((void *)laddr); - if (remapped) { - WARN_ON(cpa->numpages > 1); - alias_cpa = *cpa; - alias_cpa.vaddr = &remapped; - alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); - ret = __change_page_attr_set_clr(&alias_cpa, 0); - if (ret) - return ret; - } - - return 0; + __change_page_attr_set_clr(&alias_cpa, 0); +#endif + return ret; } static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) diff --git a/trunk/arch/x86/power/cpu.c b/trunk/arch/x86/power/cpu.c index b3d20b9cac63..d277ef1eea51 100644 --- a/trunk/arch/x86/power/cpu.c +++ b/trunk/arch/x86/power/cpu.c @@ -244,7 +244,7 @@ static void __restore_processor_state(struct saved_context *ctxt) do_fpu_end(); mtrr_ap_init(); -#ifdef CONFIG_X86_OLD_MCE +#ifdef CONFIG_X86_32 mcheck_init(&boot_cpu_data); #endif } diff --git a/trunk/block/Makefile b/trunk/block/Makefile index 6c54ed0ff755..e9fa4dd690f2 100644 --- a/trunk/block/Makefile +++ b/trunk/block/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_BLOCK) := elevator.o blk-core.o blk-tag.o blk-sysfs.o \ blk-barrier.o blk-settings.o blk-ioc.o blk-map.o \ blk-exec.o blk-merge.o blk-softirq.o blk-timeout.o \ - ioctl.o genhd.o scsi_ioctl.o + ioctl.o genhd.o scsi_ioctl.o cmd-filter.o obj-$(CONFIG_BLK_DEV_BSG) += bsg.o obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index 4b45435c6eaf..b06cf5c2a829 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -595,6 +595,8 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id) q->sg_reserved_size = INT_MAX; + blk_set_cmd_filter_defaults(&q->cmd_filter); + /* * all done */ @@ -1170,11 +1172,6 @@ static int __make_request(struct request_queue *q, struct bio *bio) const int unplug = bio_unplug(bio); int rw_flags; - if (bio_barrier(bio) && bio_has_data(bio) && - (q->next_ordered == QUEUE_ORDERED_NONE)) { - bio_endio(bio, -EOPNOTSUPP); - return 0; - } /* * low level driver can indicate that it wants pages above a * certain limit bounced to low memory (ie for highmem, or even @@ -1475,6 +1472,11 @@ static inline void __generic_make_request(struct bio *bio) err = -EOPNOTSUPP; goto end_io; } + if (bio_barrier(bio) && bio_has_data(bio) && + (q->next_ordered == QUEUE_ORDERED_NONE)) { + err = -EOPNOTSUPP; + goto end_io; + } ret = q->make_request_fn(q, bio); } while (ret); @@ -2363,7 +2365,7 @@ int blk_rq_prep_clone(struct request *rq, struct request *rq_src, __bio_clone(bio, bio_src); if (bio_integrity(bio_src) && - bio_integrity_clone(bio, bio_src, gfp_mask, bs)) + bio_integrity_clone(bio, bio_src, gfp_mask)) goto free_and_out; if (bio_ctr && bio_ctr(bio, bio_src, data)) diff --git a/trunk/block/bsg.c b/trunk/block/bsg.c index 5f184bb3ff9e..e7d475254248 100644 --- a/trunk/block/bsg.c +++ b/trunk/block/bsg.c @@ -186,7 +186,7 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq, return -EFAULT; if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) { - if (blk_verify_command(rq->cmd, has_write_perm)) + if (blk_verify_command(&q->cmd_filter, rq->cmd, has_write_perm)) return -EPERM; } else if (!capable(CAP_SYS_RAWIO)) return -EPERM; diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index 87276eb83f7f..833ec18eaa63 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -70,51 +70,6 @@ struct cfq_rb_root { }; #define CFQ_RB_ROOT (struct cfq_rb_root) { RB_ROOT, NULL, } -/* - * Per process-grouping structure - */ -struct cfq_queue { - /* reference count */ - atomic_t ref; - /* various state flags, see below */ - unsigned int flags; - /* parent cfq_data */ - struct cfq_data *cfqd; - /* service_tree member */ - struct rb_node rb_node; - /* service_tree key */ - unsigned long rb_key; - /* prio tree member */ - struct rb_node p_node; - /* prio tree root we belong to, if any */ - struct rb_root *p_root; - /* sorted list of pending requests */ - struct rb_root sort_list; - /* if fifo isn't expired, next request to serve */ - struct request *next_rq; - /* requests queued in sort_list */ - int queued[2]; - /* currently allocated requests */ - int allocated[2]; - /* fifo list of requests in sort_list */ - struct list_head fifo; - - unsigned long slice_end; - long slice_resid; - unsigned int slice_dispatch; - - /* pending metadata requests */ - int meta_pending; - /* number of requests that are on the dispatch list or inside driver */ - int dispatched; - - /* io prio of this group */ - unsigned short ioprio, org_ioprio; - unsigned short ioprio_class, org_ioprio_class; - - pid_t pid; -}; - /* * Per block device queue structure */ @@ -180,11 +135,51 @@ struct cfq_data { unsigned int cfq_slice_idle; struct list_head cic_list; +}; - /* - * Fallback dummy cfqq for extreme OOM conditions - */ - struct cfq_queue oom_cfqq; +/* + * Per process-grouping structure + */ +struct cfq_queue { + /* reference count */ + atomic_t ref; + /* various state flags, see below */ + unsigned int flags; + /* parent cfq_data */ + struct cfq_data *cfqd; + /* service_tree member */ + struct rb_node rb_node; + /* service_tree key */ + unsigned long rb_key; + /* prio tree member */ + struct rb_node p_node; + /* prio tree root we belong to, if any */ + struct rb_root *p_root; + /* sorted list of pending requests */ + struct rb_root sort_list; + /* if fifo isn't expired, next request to serve */ + struct request *next_rq; + /* requests queued in sort_list */ + int queued[2]; + /* currently allocated requests */ + int allocated[2]; + /* fifo list of requests in sort_list */ + struct list_head fifo; + + unsigned long slice_end; + long slice_resid; + unsigned int slice_dispatch; + + /* pending metadata requests */ + int meta_pending; + /* number of requests that are on the dispatch list or inside driver */ + int dispatched; + + /* io prio of this group */ + unsigned short ioprio, org_ioprio; + unsigned short ioprio_class, org_ioprio_class; + + pid_t pid; }; enum cfqq_state_flags { @@ -1646,26 +1641,6 @@ static void cfq_ioc_set_ioprio(struct io_context *ioc) ioc->ioprio_changed = 0; } -static void cfq_init_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq, - pid_t pid, int is_sync) -{ - RB_CLEAR_NODE(&cfqq->rb_node); - RB_CLEAR_NODE(&cfqq->p_node); - INIT_LIST_HEAD(&cfqq->fifo); - - atomic_set(&cfqq->ref, 0); - cfqq->cfqd = cfqd; - - cfq_mark_cfqq_prio_changed(cfqq); - - if (is_sync) { - if (!cfq_class_idle(cfqq)) - cfq_mark_cfqq_idle_window(cfqq); - cfq_mark_cfqq_sync(cfqq); - } - cfqq->pid = pid; -} - static struct cfq_queue * cfq_find_alloc_queue(struct cfq_data *cfqd, int is_sync, struct io_context *ioc, gfp_t gfp_mask) @@ -1678,40 +1653,56 @@ cfq_find_alloc_queue(struct cfq_data *cfqd, int is_sync, /* cic always exists here */ cfqq = cic_to_cfqq(cic, is_sync); - /* - * Always try a new alloc if we fell back to the OOM cfqq - * originally, since it should just be a temporary situation. - */ - if (!cfqq || cfqq == &cfqd->oom_cfqq) { - cfqq = NULL; + if (!cfqq) { if (new_cfqq) { cfqq = new_cfqq; new_cfqq = NULL; } else if (gfp_mask & __GFP_WAIT) { + /* + * Inform the allocator of the fact that we will + * just repeat this allocation if it fails, to allow + * the allocator to do whatever it needs to attempt to + * free memory. + */ spin_unlock_irq(cfqd->queue->queue_lock); new_cfqq = kmem_cache_alloc_node(cfq_pool, - gfp_mask | __GFP_ZERO, + gfp_mask | __GFP_NOFAIL | __GFP_ZERO, cfqd->queue->node); spin_lock_irq(cfqd->queue->queue_lock); - if (new_cfqq) - goto retry; + goto retry; } else { cfqq = kmem_cache_alloc_node(cfq_pool, gfp_mask | __GFP_ZERO, cfqd->queue->node); + if (!cfqq) + goto out; } - if (cfqq) { - cfq_init_cfqq(cfqd, cfqq, current->pid, is_sync); - cfq_init_prio_data(cfqq, ioc); - cfq_log_cfqq(cfqd, cfqq, "alloced"); - } else - cfqq = &cfqd->oom_cfqq; + RB_CLEAR_NODE(&cfqq->rb_node); + RB_CLEAR_NODE(&cfqq->p_node); + INIT_LIST_HEAD(&cfqq->fifo); + + atomic_set(&cfqq->ref, 0); + cfqq->cfqd = cfqd; + + cfq_mark_cfqq_prio_changed(cfqq); + + cfq_init_prio_data(cfqq, ioc); + + if (is_sync) { + if (!cfq_class_idle(cfqq)) + cfq_mark_cfqq_idle_window(cfqq); + cfq_mark_cfqq_sync(cfqq); + } + cfqq->pid = current->pid; + cfq_log_cfqq(cfqd, cfqq, "alloced"); } if (new_cfqq) kmem_cache_free(cfq_pool, new_cfqq); +out: + WARN_ON((gfp_mask & __GFP_WAIT) && !cfqq); return cfqq; } @@ -1744,8 +1735,11 @@ cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct io_context *ioc, cfqq = *async_cfqq; } - if (!cfqq) + if (!cfqq) { cfqq = cfq_find_alloc_queue(cfqd, is_sync, ioc, gfp_mask); + if (!cfqq) + return NULL; + } /* * pin the queue now that it's allocated, scheduler exit will prune it @@ -2313,6 +2307,10 @@ cfq_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask) cfqq = cic_to_cfqq(cic, is_sync); if (!cfqq) { cfqq = cfq_get_queue(cfqd, is_sync, cic->ioc, gfp_mask); + + if (!cfqq) + goto queue_fail; + cic_set_cfqq(cic, cfqq, is_sync); } @@ -2467,14 +2465,6 @@ static void *cfq_init_queue(struct request_queue *q) for (i = 0; i < CFQ_PRIO_LISTS; i++) cfqd->prio_trees[i] = RB_ROOT; - /* - * Our fallback cfqq if cfq_find_alloc_queue() runs into OOM issues. - * Grab a permanent reference to it, so that the normal code flow - * will not attempt to free it. - */ - cfq_init_cfqq(cfqd, &cfqd->oom_cfqq, 1, 0); - atomic_inc(&cfqd->oom_cfqq.ref); - INIT_LIST_HEAD(&cfqd->cic_list); cfqd->queue = q; diff --git a/trunk/block/cmd-filter.c b/trunk/block/cmd-filter.c new file mode 100644 index 000000000000..572bbc2f900d --- /dev/null +++ b/trunk/block/cmd-filter.c @@ -0,0 +1,233 @@ +/* + * Copyright 2004 Peter M. Jones + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public Licens + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111- + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +int blk_verify_command(struct blk_cmd_filter *filter, + unsigned char *cmd, fmode_t has_write_perm) +{ + /* root can do any command. */ + if (capable(CAP_SYS_RAWIO)) + return 0; + + /* if there's no filter set, assume we're filtering everything out */ + if (!filter) + return -EPERM; + + /* Anybody who can open the device can do a read-safe command */ + if (test_bit(cmd[0], filter->read_ok)) + return 0; + + /* Write-safe commands require a writable open */ + if (test_bit(cmd[0], filter->write_ok) && has_write_perm) + return 0; + + return -EPERM; +} +EXPORT_SYMBOL(blk_verify_command); + +#if 0 +/* and now, the sysfs stuff */ +static ssize_t rcf_cmds_show(struct blk_cmd_filter *filter, char *page, + int rw) +{ + char *npage = page; + unsigned long *okbits; + int i; + + if (rw == READ) + okbits = filter->read_ok; + else + okbits = filter->write_ok; + + for (i = 0; i < BLK_SCSI_MAX_CMDS; i++) { + if (test_bit(i, okbits)) { + npage += sprintf(npage, "0x%02x", i); + if (i < BLK_SCSI_MAX_CMDS - 1) + sprintf(npage++, " "); + } + } + + if (npage != page) + npage += sprintf(npage, "\n"); + + return npage - page; +} + +static ssize_t rcf_readcmds_show(struct blk_cmd_filter *filter, char *page) +{ + return rcf_cmds_show(filter, page, READ); +} + +static ssize_t rcf_writecmds_show(struct blk_cmd_filter *filter, + char *page) +{ + return rcf_cmds_show(filter, page, WRITE); +} + +static ssize_t rcf_cmds_store(struct blk_cmd_filter *filter, + const char *page, size_t count, int rw) +{ + unsigned long okbits[BLK_SCSI_CMD_PER_LONG], *target_okbits; + int cmd, set; + char *p, *status; + + if (rw == READ) { + memcpy(&okbits, filter->read_ok, sizeof(okbits)); + target_okbits = filter->read_ok; + } else { + memcpy(&okbits, filter->write_ok, sizeof(okbits)); + target_okbits = filter->write_ok; + } + + while ((p = strsep((char **)&page, " ")) != NULL) { + set = 1; + + if (p[0] == '+') { + p++; + } else if (p[0] == '-') { + set = 0; + p++; + } + + cmd = simple_strtol(p, &status, 16); + + /* either of these cases means invalid input, so do nothing. */ + if ((status == p) || cmd >= BLK_SCSI_MAX_CMDS) + return -EINVAL; + + if (set) + __set_bit(cmd, okbits); + else + __clear_bit(cmd, okbits); + } + + memcpy(target_okbits, okbits, sizeof(okbits)); + return count; +} + +static ssize_t rcf_readcmds_store(struct blk_cmd_filter *filter, + const char *page, size_t count) +{ + return rcf_cmds_store(filter, page, count, READ); +} + +static ssize_t rcf_writecmds_store(struct blk_cmd_filter *filter, + const char *page, size_t count) +{ + return rcf_cmds_store(filter, page, count, WRITE); +} + +struct rcf_sysfs_entry { + struct attribute attr; + ssize_t (*show)(struct blk_cmd_filter *, char *); + ssize_t (*store)(struct blk_cmd_filter *, const char *, size_t); +}; + +static struct rcf_sysfs_entry rcf_readcmds_entry = { + .attr = { .name = "read_table", .mode = S_IRUGO | S_IWUSR }, + .show = rcf_readcmds_show, + .store = rcf_readcmds_store, +}; + +static struct rcf_sysfs_entry rcf_writecmds_entry = { + .attr = {.name = "write_table", .mode = S_IRUGO | S_IWUSR }, + .show = rcf_writecmds_show, + .store = rcf_writecmds_store, +}; + +static struct attribute *default_attrs[] = { + &rcf_readcmds_entry.attr, + &rcf_writecmds_entry.attr, + NULL, +}; + +#define to_rcf(atr) container_of((atr), struct rcf_sysfs_entry, attr) + +static ssize_t +rcf_attr_show(struct kobject *kobj, struct attribute *attr, char *page) +{ + struct rcf_sysfs_entry *entry = to_rcf(attr); + struct blk_cmd_filter *filter; + + filter = container_of(kobj, struct blk_cmd_filter, kobj); + if (entry->show) + return entry->show(filter, page); + + return 0; +} + +static ssize_t +rcf_attr_store(struct kobject *kobj, struct attribute *attr, + const char *page, size_t length) +{ + struct rcf_sysfs_entry *entry = to_rcf(attr); + struct blk_cmd_filter *filter; + + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + + if (!entry->store) + return -EINVAL; + + filter = container_of(kobj, struct blk_cmd_filter, kobj); + return entry->store(filter, page, length); +} + +static struct sysfs_ops rcf_sysfs_ops = { + .show = rcf_attr_show, + .store = rcf_attr_store, +}; + +static struct kobj_type rcf_ktype = { + .sysfs_ops = &rcf_sysfs_ops, + .default_attrs = default_attrs, +}; + +int blk_register_filter(struct gendisk *disk) +{ + int ret; + struct blk_cmd_filter *filter = &disk->queue->cmd_filter; + + ret = kobject_init_and_add(&filter->kobj, &rcf_ktype, + &disk_to_dev(disk)->kobj, + "%s", "cmd_filter"); + if (ret < 0) + return ret; + + return 0; +} +EXPORT_SYMBOL(blk_register_filter); + +void blk_unregister_filter(struct gendisk *disk) +{ + struct blk_cmd_filter *filter = &disk->queue->cmd_filter; + + kobject_put(&filter->kobj); +} +EXPORT_SYMBOL(blk_unregister_filter); +#endif diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index f0e0ce0a607d..5f8e798ede4e 100644 --- a/trunk/block/scsi_ioctl.c +++ b/trunk/block/scsi_ioctl.c @@ -32,11 +32,6 @@ #include #include -struct blk_cmd_filter { - unsigned long read_ok[BLK_SCSI_CMD_PER_LONG]; - unsigned long write_ok[BLK_SCSI_CMD_PER_LONG]; -} blk_default_cmd_filter; - /* Command group 3 is reserved and should never be used. */ const unsigned char scsi_command_size_tbl[8] = { @@ -110,7 +105,7 @@ static int sg_emulated_host(struct request_queue *q, int __user *p) return put_user(1, p); } -static void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter) +void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter) { /* Basic read-only commands */ __set_bit(TEST_UNIT_READY, filter->read_ok); @@ -192,37 +187,14 @@ static void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter) __set_bit(GPCMD_SET_STREAMING, filter->write_ok); __set_bit(GPCMD_SET_READ_AHEAD, filter->write_ok); } - -int blk_verify_command(unsigned char *cmd, fmode_t has_write_perm) -{ - struct blk_cmd_filter *filter = &blk_default_cmd_filter; - - /* root can do any command. */ - if (capable(CAP_SYS_RAWIO)) - return 0; - - /* if there's no filter set, assume we're filtering everything out */ - if (!filter) - return -EPERM; - - /* Anybody who can open the device can do a read-safe command */ - if (test_bit(cmd[0], filter->read_ok)) - return 0; - - /* Write-safe commands require a writable open */ - if (test_bit(cmd[0], filter->write_ok) && has_write_perm) - return 0; - - return -EPERM; -} -EXPORT_SYMBOL(blk_verify_command); +EXPORT_SYMBOL_GPL(blk_set_cmd_filter_defaults); static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq, struct sg_io_hdr *hdr, fmode_t mode) { if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len)) return -EFAULT; - if (blk_verify_command(rq->cmd, mode & FMODE_WRITE)) + if (blk_verify_command(&q->cmd_filter, rq->cmd, mode & FMODE_WRITE)) return -EPERM; /* @@ -455,7 +427,7 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len)) goto error; - err = blk_verify_command(rq->cmd, mode & FMODE_WRITE); + err = blk_verify_command(&q->cmd_filter, rq->cmd, mode & FMODE_WRITE); if (err) goto error; @@ -673,10 +645,5 @@ int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mod blk_put_queue(q); return err; } -EXPORT_SYMBOL(scsi_cmd_ioctl); -int __init blk_scsi_ioctl_init(void) -{ - blk_set_cmd_filter_defaults(&blk_default_cmd_filter); - return 0; -} +EXPORT_SYMBOL(scsi_cmd_ioctl); diff --git a/trunk/drivers/acpi/pci_root.c b/trunk/drivers/acpi/pci_root.c index 55b5b90c2a44..8a5bf3b356fa 100644 --- a/trunk/drivers/acpi/pci_root.c +++ b/trunk/drivers/acpi/pci_root.c @@ -395,7 +395,7 @@ struct pci_dev *acpi_get_pci_dev(acpi_handle handle) fn = adr & 0xffff; pdev = pci_get_slot(pbus, PCI_DEVFN(dev, fn)); - if (!pdev || hnd == handle) + if (hnd == handle) break; pbus = pdev->subordinate; diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index 91b753013780..862b40c90181 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -3327,10 +3327,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g, if (!capable(CAP_SYS_ADMIN)) return -EPERM; mutex_lock(&open_lock); - if (lock_fdc(drive, 1)) { - mutex_unlock(&open_lock); - return -EINTR; - } + LOCK_FDC(drive, 1); floppy_type[type] = *g; floppy_type[type].name = "user format"; for (cnt = type << 2; cnt < (type << 2) + 4; cnt++) diff --git a/trunk/drivers/char/bsr.c b/trunk/drivers/char/bsr.c index c02db01f736e..140ea10ecb88 100644 --- a/trunk/drivers/char/bsr.c +++ b/trunk/drivers/char/bsr.c @@ -27,7 +27,6 @@ #include #include #include -#include #include /* @@ -76,13 +75,12 @@ static struct class *bsr_class; static int bsr_major; enum { - BSR_8 = 0, - BSR_16 = 1, - BSR_64 = 2, - BSR_128 = 3, - BSR_4096 = 4, - BSR_UNKNOWN = 5, - BSR_MAX = 6, + BSR_8 = 0, + BSR_16 = 1, + BSR_64 = 2, + BSR_128 = 3, + BSR_UNKNOWN = 4, + BSR_MAX = 5, }; static unsigned bsr_types[BSR_MAX]; @@ -119,22 +117,15 @@ static int bsr_mmap(struct file *filp, struct vm_area_struct *vma) { unsigned long size = vma->vm_end - vma->vm_start; struct bsr_dev *dev = filp->private_data; - int ret; - - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - /* check for the case of a small BSR device and map one 4k page for it*/ - if (dev->bsr_len < PAGE_SIZE && size == PAGE_SIZE) - ret = remap_4k_pfn(vma, vma->vm_start, dev->bsr_addr >> 12, - vma->vm_page_prot); - else if (size <= dev->bsr_len) - ret = io_remap_pfn_range(vma, vma->vm_start, - dev->bsr_addr >> PAGE_SHIFT, - size, vma->vm_page_prot); - else + if (size > dev->bsr_len || (size & (PAGE_SIZE-1))) return -EINVAL; - if (ret) + vma->vm_flags |= (VM_IO | VM_DONTEXPAND); + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + if (io_remap_pfn_range(vma, vma->vm_start, dev->bsr_addr >> PAGE_SHIFT, + size, vma->vm_page_prot)) return -EAGAIN; return 0; @@ -214,11 +205,6 @@ static int bsr_add_node(struct device_node *bn) cur->bsr_stride = bsr_stride[i]; cur->bsr_dev = MKDEV(bsr_major, i + total_bsr_devs); - /* if we have a bsr_len of > 4k and less then PAGE_SIZE (64k pages) */ - /* we can only map 4k of it, so only advertise the 4k in sysfs */ - if (cur->bsr_len > 4096 && cur->bsr_len < PAGE_SIZE) - cur->bsr_len = 4096; - switch(cur->bsr_bytes) { case 8: cur->bsr_type = BSR_8; @@ -232,11 +218,9 @@ static int bsr_add_node(struct device_node *bn) case 128: cur->bsr_type = BSR_128; break; - case 4096: - cur->bsr_type = BSR_4096; - break; default: cur->bsr_type = BSR_UNKNOWN; + printk(KERN_INFO "unknown BSR size %d\n",cur->bsr_bytes); } cur->bsr_num = bsr_types[cur->bsr_type]; diff --git a/trunk/drivers/char/tty_ldisc.c b/trunk/drivers/char/tty_ldisc.c index 913aa8d3f1c5..a19e935847b0 100644 --- a/trunk/drivers/char/tty_ldisc.c +++ b/trunk/drivers/char/tty_ldisc.c @@ -867,22 +867,15 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) tty_ldisc_wait_idle(tty); /* - * Now kill off the ldisc + * Shutdown the current line discipline, and reset it to N_TTY. + * + * FIXME: this MUST get fixed for the new reflocking */ - tty_ldisc_close(tty, tty->ldisc); - tty_ldisc_put(tty->ldisc); - /* Force an oops if we mess this up */ - tty->ldisc = NULL; - - /* Ensure the next open requests the N_TTY ldisc */ - tty_set_termios_ldisc(tty, N_TTY); + tty_ldisc_reinit(tty); /* This will need doing differently if we need to lock */ if (o_tty) tty_ldisc_release(o_tty, NULL); - - /* And the memory resources remaining (buffers, termios) will be - disposed of when the kref hits zero */ } /** diff --git a/trunk/drivers/clocksource/sh_tmu.c b/trunk/drivers/clocksource/sh_tmu.c index 93c2322feab7..9ffb05f4095d 100644 --- a/trunk/drivers/clocksource/sh_tmu.c +++ b/trunk/drivers/clocksource/sh_tmu.c @@ -161,7 +161,7 @@ static void sh_tmu_set_next(struct sh_tmu_priv *p, unsigned long delta, if (periodic) sh_tmu_write(p, TCOR, delta); else - sh_tmu_write(p, TCOR, 0xffffffff); + sh_tmu_write(p, TCOR, 0); sh_tmu_write(p, TCNT, delta); diff --git a/trunk/drivers/edac/amd64_edac.c b/trunk/drivers/edac/amd64_edac.c index 858fe6037223..c36bf40568cf 100644 --- a/trunk/drivers/edac/amd64_edac.c +++ b/trunk/drivers/edac/amd64_edac.c @@ -754,13 +754,13 @@ static void amd64_cpu_display_info(struct amd64_pvt *pvt) static enum edac_type amd64_determine_edac_cap(struct amd64_pvt *pvt) { int bit; - enum dev_type edac_cap = EDAC_FLAG_NONE; + enum dev_type edac_cap = EDAC_NONE; bit = (boot_cpu_data.x86 > 0xf || pvt->ext_model >= OPTERON_CPU_REV_F) ? 19 : 17; - if (pvt->dclr0 & BIT(bit)) + if (pvt->dclr0 >> BIT(bit)) edac_cap = EDAC_FLAG_SECDED; return edac_cap; @@ -1269,7 +1269,7 @@ static int f10_early_channel_count(struct amd64_pvt *pvt) if (channels == 0) channels = 1; - debugf0("MCT channel count: %d\n", channels); + debugf0("DIMM count= %d\n", channels); return channels; @@ -2966,12 +2966,7 @@ static int amd64_check_ecc_enabled(struct amd64_pvt *pvt) " Use of the override can cause " "unknown side effects.\n"); ret = -ENODEV; - } else - /* - * enable further driver loading if ECC enable is - * overridden. - */ - ret = 0; + } } else { amd64_printk(KERN_INFO, "ECC is enabled by BIOS, Proceeding " @@ -3011,6 +3006,7 @@ static void amd64_setup_mci_misc_attributes(struct mem_ctl_info *mci) mci->mtype_cap = MEM_FLAG_DDR2 | MEM_FLAG_RDDR2; mci->edac_ctl_cap = EDAC_FLAG_NONE; + mci->edac_cap = EDAC_FLAG_NONE; if (pvt->nbcap & K8_NBCAP_SECDED) mci->edac_ctl_cap |= EDAC_FLAG_SECDED; @@ -3056,7 +3052,7 @@ static int amd64_probe_one_instance(struct pci_dev *dram_f2_ctl, if (!pvt) goto err_exit; - pvt->mc_node_id = get_node_id(dram_f2_ctl); + pvt->mc_node_id = get_mc_node_id_from_pdev(dram_f2_ctl); pvt->dram_f2_ctl = dram_f2_ctl; pvt->ext_model = boot_cpu_data.x86_model >> 4; @@ -3183,7 +3179,8 @@ static int __devinit amd64_init_one_instance(struct pci_dev *pdev, { int ret = 0; - debugf0("(MC node=%d,mc_type='%s')\n", get_node_id(pdev), + debugf0("(MC node=%d,mc_type='%s')\n", + get_mc_node_id_from_pdev(pdev), get_amd_family_name(mc_type->driver_data)); ret = pci_enable_device(pdev); @@ -3322,17 +3319,15 @@ static int __init amd64_edac_init(void) err = amd64_init_2nd_stage(pvt_lookup[nb]); if (err) - goto err_2nd_stage; + goto err_exit; } amd64_setup_pci_device(); return 0; -err_2nd_stage: - debugf0("2nd stage failed\n"); - err_exit: + debugf0("'finish_setup' stage failed\n"); pci_unregister_driver(&amd64_pci_driver); return err; diff --git a/trunk/drivers/edac/amd64_edac.h b/trunk/drivers/edac/amd64_edac.h index ba73015af8e4..a159957e167b 100644 --- a/trunk/drivers/edac/amd64_edac.h +++ b/trunk/drivers/edac/amd64_edac.h @@ -444,7 +444,7 @@ enum { #define K8_MSR_MC4ADDR 0x0412 /* AMD sets the first MC device at device ID 0x18. */ -static inline int get_node_id(struct pci_dev *pdev) +static inline int get_mc_node_id_from_pdev(struct pci_dev *pdev) { return PCI_SLOT(pdev->devfn) - 0x18; } diff --git a/trunk/drivers/edac/edac_core.h b/trunk/drivers/edac/edac_core.h index 871c13b4c148..3493c6bdb820 100644 --- a/trunk/drivers/edac/edac_core.h +++ b/trunk/drivers/edac/edac_core.h @@ -150,8 +150,6 @@ enum mem_type { MEM_FB_DDR2, /* fully buffered DDR2 */ MEM_RDDR2, /* Registered DDR2 RAM */ MEM_XDR, /* Rambus XDR */ - MEM_DDR3, /* DDR3 RAM */ - MEM_RDDR3, /* Registered DDR3 RAM */ }; #define MEM_FLAG_EMPTY BIT(MEM_EMPTY) @@ -169,8 +167,6 @@ enum mem_type { #define MEM_FLAG_FB_DDR2 BIT(MEM_FB_DDR2) #define MEM_FLAG_RDDR2 BIT(MEM_RDDR2) #define MEM_FLAG_XDR BIT(MEM_XDR) -#define MEM_FLAG_DDR3 BIT(MEM_DDR3) -#define MEM_FLAG_RDDR3 BIT(MEM_RDDR3) /* chipset Error Detection and Correction capabilities and mode */ enum edac_type { diff --git a/trunk/drivers/edac/edac_mc_sysfs.c b/trunk/drivers/edac/edac_mc_sysfs.c index e1d4ce083481..ad218fe4942d 100644 --- a/trunk/drivers/edac/edac_mc_sysfs.c +++ b/trunk/drivers/edac/edac_mc_sysfs.c @@ -94,9 +94,7 @@ static const char *mem_types[] = { [MEM_DDR2] = "Unbuffered-DDR2", [MEM_FB_DDR2] = "FullyBuffered-DDR2", [MEM_RDDR2] = "Registered-DDR2", - [MEM_XDR] = "XDR", - [MEM_DDR3] = "Unbuffered-DDR3", - [MEM_RDDR3] = "Registered-DDR3" + [MEM_XDR] = "XDR" }; static const char *dev_types[] = { diff --git a/trunk/drivers/edac/mpc85xx_edac.c b/trunk/drivers/edac/mpc85xx_edac.c index 3f2ccfc6407c..7c8c2d72916f 100644 --- a/trunk/drivers/edac/mpc85xx_edac.c +++ b/trunk/drivers/edac/mpc85xx_edac.c @@ -757,9 +757,6 @@ static void __devinit mpc85xx_init_csrows(struct mem_ctl_info *mci) case DSC_SDTYPE_DDR2: mtype = MEM_RDDR2; break; - case DSC_SDTYPE_DDR3: - mtype = MEM_RDDR3; - break; default: mtype = MEM_UNKNOWN; break; @@ -772,9 +769,6 @@ static void __devinit mpc85xx_init_csrows(struct mem_ctl_info *mci) case DSC_SDTYPE_DDR2: mtype = MEM_DDR2; break; - case DSC_SDTYPE_DDR3: - mtype = MEM_DDR3; - break; default: mtype = MEM_UNKNOWN; break; diff --git a/trunk/drivers/edac/mpc85xx_edac.h b/trunk/drivers/edac/mpc85xx_edac.h index 52432ee7c4b9..135b3539a030 100644 --- a/trunk/drivers/edac/mpc85xx_edac.h +++ b/trunk/drivers/edac/mpc85xx_edac.h @@ -53,7 +53,6 @@ #define DSC_SDTYPE_DDR 0x02000000 #define DSC_SDTYPE_DDR2 0x03000000 -#define DSC_SDTYPE_DDR3 0x07000000 #define DSC_X32_EN 0x00000020 /* Err_Int_En */ diff --git a/trunk/drivers/gpio/pl061.c b/trunk/drivers/gpio/pl061.c index 4ee4c8367a3f..aa8e7cb020d9 100644 --- a/trunk/drivers/gpio/pl061.c +++ b/trunk/drivers/gpio/pl061.c @@ -109,16 +109,6 @@ static void pl061_set_value(struct gpio_chip *gc, unsigned offset, int value) writeb(!!value << offset, chip->base + (1 << (offset + 2))); } -static int pl061_to_irq(struct gpio_chip *gc, unsigned offset) -{ - struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); - - if (chip->irq_base == (unsigned) -1) - return -EINVAL; - - return chip->irq_base + offset; -} - /* * PL061 GPIO IRQ */ @@ -210,7 +200,7 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) desc->chip->ack(irq); list_for_each(ptr, chip_list) { unsigned long pending; - int offset; + int gpio; chip = list_entry(ptr, struct pl061_gpio, list); pending = readb(chip->base + GPIOMIS); @@ -219,8 +209,8 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) if (pending == 0) continue; - for_each_bit(offset, &pending, PL061_GPIO_NR) - generic_handle_irq(pl061_to_irq(&chip->gc, offset)); + for_each_bit(gpio, &pending, PL061_GPIO_NR) + generic_handle_irq(gpio_to_irq(gpio)); } desc->chip->unmask(irq); } @@ -231,7 +221,7 @@ static int __init pl061_probe(struct amba_device *dev, struct amba_id *id) struct pl061_gpio *chip; struct list_head *chip_list; int ret, irq, i; - static DECLARE_BITMAP(init_irq, NR_IRQS); + static unsigned long init_irq[BITS_TO_LONGS(NR_IRQS)]; pdata = dev->dev.platform_data; if (pdata == NULL) @@ -261,7 +251,6 @@ static int __init pl061_probe(struct amba_device *dev, struct amba_id *id) chip->gc.direction_output = pl061_direction_output; chip->gc.get = pl061_get_value; chip->gc.set = pl061_set_value; - chip->gc.to_irq = pl061_to_irq; chip->gc.base = pdata->gpio_base; chip->gc.ngpio = PL061_GPIO_NR; chip->gc.label = dev_name(&dev->dev); @@ -291,7 +280,6 @@ static int __init pl061_probe(struct amba_device *dev, struct amba_id *id) if (!test_and_set_bit(irq, init_irq)) { /* list initialized? */ chip_list = kmalloc(sizeof(*chip_list), GFP_KERNEL); if (chip_list == NULL) { - clear_bit(irq, init_irq); ret = -ENOMEM; goto iounmap; } diff --git a/trunk/drivers/gpu/drm/Kconfig b/trunk/drivers/gpu/drm/Kconfig index 39b393d38bb3..c961fe415aef 100644 --- a/trunk/drivers/gpu/drm/Kconfig +++ b/trunk/drivers/gpu/drm/Kconfig @@ -81,7 +81,6 @@ config DRM_I830 config DRM_I915 tristate "i915 driver" - depends on AGP_INTEL select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT diff --git a/trunk/drivers/gpu/drm/Makefile b/trunk/drivers/gpu/drm/Makefile index fe23f29f7cba..4e89ab08b7b8 100644 --- a/trunk/drivers/gpu/drm/Makefile +++ b/trunk/drivers/gpu/drm/Makefile @@ -16,7 +16,6 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ drm-$(CONFIG_COMPAT) += drm_ioc32.o obj-$(CONFIG_DRM) += drm.o -obj-$(CONFIG_DRM_TTM) += ttm/ obj-$(CONFIG_DRM_TDFX) += tdfx/ obj-$(CONFIG_DRM_R128) += r128/ obj-$(CONFIG_DRM_RADEON)+= radeon/ @@ -27,3 +26,4 @@ obj-$(CONFIG_DRM_I915) += i915/ obj-$(CONFIG_DRM_SIS) += sis/ obj-$(CONFIG_DRM_SAVAGE)+= savage/ obj-$(CONFIG_DRM_VIA) +=via/ +obj-$(CONFIG_DRM_TTM) += ttm/ diff --git a/trunk/drivers/gpu/drm/drm_edid.c b/trunk/drivers/gpu/drm/drm_edid.c index 80cc6d06d61b..7d0835226f6e 100644 --- a/trunk/drivers/gpu/drm/drm_edid.c +++ b/trunk/drivers/gpu/drm/drm_edid.c @@ -294,10 +294,10 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, unsigned vactive = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo; unsigned hblank = (pt->hactive_hblank_hi & 0xf) << 8 | pt->hblank_lo; unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo; - unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2 | pt->hsync_offset_lo; - unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) << 4 | pt->hsync_pulse_width_lo; - unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) >> 2 | pt->vsync_offset_pulse_width_lo >> 4; - unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 4 | (pt->vsync_offset_pulse_width_lo & 0xf); + unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 8 | pt->hsync_offset_lo; + unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) << 6 | pt->hsync_pulse_width_lo; + unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) | (pt->vsync_offset_pulse_width_lo & 0xf); + unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) >> 2 | pt->vsync_offset_pulse_width_lo >> 4; /* ignore tiny modes */ if (hactive < 64 || vactive < 64) @@ -347,8 +347,8 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ? DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; - mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4; - mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf) << 8; + mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf) << 8; + mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4; if (quirks & EDID_QUIRK_DETAILED_IN_CM) { mode->width_mm *= 10; diff --git a/trunk/drivers/gpu/drm/i915/Makefile b/trunk/drivers/gpu/drm/i915/Makefile index 30d6b99fb302..51c5a050aa73 100644 --- a/trunk/drivers/gpu/drm/i915/Makefile +++ b/trunk/drivers/gpu/drm/i915/Makefile @@ -13,8 +13,6 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ intel_crt.o \ intel_lvds.o \ intel_bios.o \ - intel_dp.o \ - intel_dp_i2c.o \ intel_hdmi.o \ intel_sdvo.o \ intel_modes.o \ diff --git a/trunk/drivers/gpu/drm/i915/dvo.h b/trunk/drivers/gpu/drm/i915/dvo.h index 288fc50627e2..e747ac42fe3a 100644 --- a/trunk/drivers/gpu/drm/i915/dvo.h +++ b/trunk/drivers/gpu/drm/i915/dvo.h @@ -37,7 +37,7 @@ struct intel_dvo_device { /* GPIO register used for i2c bus to control this device */ u32 gpio; int slave_addr; - struct i2c_adapter *i2c_bus; + struct intel_i2c_chan *i2c_bus; const struct intel_dvo_dev_ops *dev_ops; void *dev_priv; @@ -52,7 +52,7 @@ struct intel_dvo_dev_ops { * Returns NULL if the device does not exist. */ bool (*init)(struct intel_dvo_device *dvo, - struct i2c_adapter *i2cbus); + struct intel_i2c_chan *i2cbus); /* * Called to allow the output a chance to create properties after the diff --git a/trunk/drivers/gpu/drm/i915/dvo_ch7017.c b/trunk/drivers/gpu/drm/i915/dvo_ch7017.c index 621815b531db..03d4b4973b02 100644 --- a/trunk/drivers/gpu/drm/i915/dvo_ch7017.c +++ b/trunk/drivers/gpu/drm/i915/dvo_ch7017.c @@ -176,20 +176,19 @@ static void ch7017_dpms(struct intel_dvo_device *dvo, int mode); static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val) { - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; u8 out_buf[2]; u8 in_buf[2]; struct i2c_msg msgs[] = { { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = 0, .len = 1, .buf = out_buf, }, { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = I2C_M_RD, .len = 1, .buf = in_buf, @@ -209,11 +208,10 @@ static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val) static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val) { - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; uint8_t out_buf[2]; struct i2c_msg msg = { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = 0, .len = 2, .buf = out_buf, @@ -230,9 +228,8 @@ static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val) /** Probes for a CH7017 on the given bus and slave address. */ static bool ch7017_init(struct intel_dvo_device *dvo, - struct i2c_adapter *adapter) + struct intel_i2c_chan *i2cbus) { - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); struct ch7017_priv *priv; uint8_t val; @@ -240,7 +237,8 @@ static bool ch7017_init(struct intel_dvo_device *dvo, if (priv == NULL) return false; - dvo->i2c_bus = adapter; + dvo->i2c_bus = i2cbus; + dvo->i2c_bus->slave_addr = dvo->slave_addr; dvo->dev_priv = priv; if (!ch7017_read(dvo, CH7017_DEVICE_ID, &val)) @@ -250,7 +248,7 @@ static bool ch7017_init(struct intel_dvo_device *dvo, val != CH7018_DEVICE_ID_VALUE && val != CH7019_DEVICE_ID_VALUE) { DRM_DEBUG("ch701x not detected, got %d: from %s Slave %d.\n", - val, i2cbus->adapter.name,dvo->slave_addr); + val, i2cbus->adapter.name,i2cbus->slave_addr); goto fail; } diff --git a/trunk/drivers/gpu/drm/i915/dvo_ch7xxx.c b/trunk/drivers/gpu/drm/i915/dvo_ch7xxx.c index a9b896289680..d2fd95dbd034 100644 --- a/trunk/drivers/gpu/drm/i915/dvo_ch7xxx.c +++ b/trunk/drivers/gpu/drm/i915/dvo_ch7xxx.c @@ -123,20 +123,19 @@ static char *ch7xxx_get_id(uint8_t vid) static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) { struct ch7xxx_priv *ch7xxx= dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; u8 out_buf[2]; u8 in_buf[2]; struct i2c_msg msgs[] = { { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = 0, .len = 1, .buf = out_buf, }, { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = I2C_M_RD, .len = 1, .buf = in_buf, @@ -153,7 +152,7 @@ static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) if (!ch7xxx->quiet) { DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", - addr, i2cbus->adapter.name, dvo->slave_addr); + addr, i2cbus->adapter.name, i2cbus->slave_addr); } return false; } @@ -162,11 +161,10 @@ static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) { struct ch7xxx_priv *ch7xxx = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; uint8_t out_buf[2]; struct i2c_msg msg = { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = 0, .len = 2, .buf = out_buf, @@ -180,14 +178,14 @@ static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) if (!ch7xxx->quiet) { DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", - addr, i2cbus->adapter.name, dvo->slave_addr); + addr, i2cbus->adapter.name, i2cbus->slave_addr); } return false; } static bool ch7xxx_init(struct intel_dvo_device *dvo, - struct i2c_adapter *adapter) + struct intel_i2c_chan *i2cbus) { /* this will detect the CH7xxx chip on the specified i2c bus */ struct ch7xxx_priv *ch7xxx; @@ -198,7 +196,8 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo, if (ch7xxx == NULL) return false; - dvo->i2c_bus = adapter; + dvo->i2c_bus = i2cbus; + dvo->i2c_bus->slave_addr = dvo->slave_addr; dvo->dev_priv = ch7xxx; ch7xxx->quiet = true; @@ -208,7 +207,7 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo, name = ch7xxx_get_id(vendor); if (!name) { DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n", - vendor, adapter->name, dvo->slave_addr); + vendor, i2cbus->adapter.name, i2cbus->slave_addr); goto out; } @@ -218,7 +217,7 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo, if (device != CH7xxx_DID) { DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n", - vendor, adapter->name, dvo->slave_addr); + vendor, i2cbus->adapter.name, i2cbus->slave_addr); goto out; } diff --git a/trunk/drivers/gpu/drm/i915/dvo_ivch.c b/trunk/drivers/gpu/drm/i915/dvo_ivch.c index aa176f9921fe..0c8d375e8e37 100644 --- a/trunk/drivers/gpu/drm/i915/dvo_ivch.c +++ b/trunk/drivers/gpu/drm/i915/dvo_ivch.c @@ -169,14 +169,13 @@ static void ivch_dump_regs(struct intel_dvo_device *dvo); static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) { struct ivch_priv *priv = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; u8 out_buf[1]; u8 in_buf[2]; struct i2c_msg msgs[] = { { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = I2C_M_RD, .len = 0, }, @@ -187,7 +186,7 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) .buf = out_buf, }, { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = I2C_M_RD | I2C_M_NOSTART, .len = 2, .buf = in_buf, @@ -203,7 +202,7 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) if (!priv->quiet) { DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", - addr, i2cbus->adapter.name, dvo->slave_addr); + addr, i2cbus->adapter.name, i2cbus->slave_addr); } return false; } @@ -212,11 +211,10 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data) { struct ivch_priv *priv = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; u8 out_buf[3]; struct i2c_msg msg = { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = 0, .len = 3, .buf = out_buf, @@ -231,7 +229,7 @@ static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data) if (!priv->quiet) { DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", - addr, i2cbus->adapter.name, dvo->slave_addr); + addr, i2cbus->adapter.name, i2cbus->slave_addr); } return false; @@ -239,7 +237,7 @@ static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data) /** Probes the given bus and slave address for an ivch */ static bool ivch_init(struct intel_dvo_device *dvo, - struct i2c_adapter *adapter) + struct intel_i2c_chan *i2cbus) { struct ivch_priv *priv; uint16_t temp; @@ -248,7 +246,8 @@ static bool ivch_init(struct intel_dvo_device *dvo, if (priv == NULL) return false; - dvo->i2c_bus = adapter; + dvo->i2c_bus = i2cbus; + dvo->i2c_bus->slave_addr = dvo->slave_addr; dvo->dev_priv = priv; priv->quiet = true; diff --git a/trunk/drivers/gpu/drm/i915/dvo_sil164.c b/trunk/drivers/gpu/drm/i915/dvo_sil164.c index e1c1f7341e5c..033a4bb070b2 100644 --- a/trunk/drivers/gpu/drm/i915/dvo_sil164.c +++ b/trunk/drivers/gpu/drm/i915/dvo_sil164.c @@ -76,20 +76,19 @@ struct sil164_priv { static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) { struct sil164_priv *sil = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; u8 out_buf[2]; u8 in_buf[2]; struct i2c_msg msgs[] = { { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = 0, .len = 1, .buf = out_buf, }, { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = I2C_M_RD, .len = 1, .buf = in_buf, @@ -106,7 +105,7 @@ static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) if (!sil->quiet) { DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", - addr, i2cbus->adapter.name, dvo->slave_addr); + addr, i2cbus->adapter.name, i2cbus->slave_addr); } return false; } @@ -114,11 +113,10 @@ static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) { struct sil164_priv *sil= dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; uint8_t out_buf[2]; struct i2c_msg msg = { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = 0, .len = 2, .buf = out_buf, @@ -132,7 +130,7 @@ static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) if (!sil->quiet) { DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", - addr, i2cbus->adapter.name, dvo->slave_addr); + addr, i2cbus->adapter.name, i2cbus->slave_addr); } return false; @@ -140,7 +138,7 @@ static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) /* Silicon Image 164 driver for chip on i2c bus */ static bool sil164_init(struct intel_dvo_device *dvo, - struct i2c_adapter *adapter) + struct intel_i2c_chan *i2cbus) { /* this will detect the SIL164 chip on the specified i2c bus */ struct sil164_priv *sil; @@ -150,7 +148,8 @@ static bool sil164_init(struct intel_dvo_device *dvo, if (sil == NULL) return false; - dvo->i2c_bus = adapter; + dvo->i2c_bus = i2cbus; + dvo->i2c_bus->slave_addr = dvo->slave_addr; dvo->dev_priv = sil; sil->quiet = true; @@ -159,7 +158,7 @@ static bool sil164_init(struct intel_dvo_device *dvo, if (ch != (SIL164_VID & 0xff)) { DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n", - ch, adapter->name, dvo->slave_addr); + ch, i2cbus->adapter.name, i2cbus->slave_addr); goto out; } @@ -168,7 +167,7 @@ static bool sil164_init(struct intel_dvo_device *dvo, if (ch != (SIL164_DID & 0xff)) { DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n", - ch, adapter->name, dvo->slave_addr); + ch, i2cbus->adapter.name, i2cbus->slave_addr); goto out; } sil->quiet = false; diff --git a/trunk/drivers/gpu/drm/i915/dvo_tfp410.c b/trunk/drivers/gpu/drm/i915/dvo_tfp410.c index 9ecc907384ec..207fda806ebf 100644 --- a/trunk/drivers/gpu/drm/i915/dvo_tfp410.c +++ b/trunk/drivers/gpu/drm/i915/dvo_tfp410.c @@ -101,20 +101,19 @@ struct tfp410_priv { static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) { struct tfp410_priv *tfp = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; u8 out_buf[2]; u8 in_buf[2]; struct i2c_msg msgs[] = { { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = 0, .len = 1, .buf = out_buf, }, { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = I2C_M_RD, .len = 1, .buf = in_buf, @@ -131,7 +130,7 @@ static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) if (!tfp->quiet) { DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", - addr, i2cbus->adapter.name, dvo->slave_addr); + addr, i2cbus->adapter.name, i2cbus->slave_addr); } return false; } @@ -139,11 +138,10 @@ static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) { struct tfp410_priv *tfp = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; uint8_t out_buf[2]; struct i2c_msg msg = { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = 0, .len = 2, .buf = out_buf, @@ -157,7 +155,7 @@ static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) if (!tfp->quiet) { DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", - addr, i2cbus->adapter.name, dvo->slave_addr); + addr, i2cbus->adapter.name, i2cbus->slave_addr); } return false; @@ -176,7 +174,7 @@ static int tfp410_getid(struct intel_dvo_device *dvo, int addr) /* Ti TFP410 driver for chip on i2c bus */ static bool tfp410_init(struct intel_dvo_device *dvo, - struct i2c_adapter *adapter) + struct intel_i2c_chan *i2cbus) { /* this will detect the tfp410 chip on the specified i2c bus */ struct tfp410_priv *tfp; @@ -186,19 +184,20 @@ static bool tfp410_init(struct intel_dvo_device *dvo, if (tfp == NULL) return false; - dvo->i2c_bus = adapter; + dvo->i2c_bus = i2cbus; + dvo->i2c_bus->slave_addr = dvo->slave_addr; dvo->dev_priv = tfp; tfp->quiet = true; if ((id = tfp410_getid(dvo, TFP410_VID_LO)) != TFP410_VID) { DRM_DEBUG("tfp410 not detected got VID %X: from %s Slave %d.\n", - id, adapter->name, dvo->slave_addr); + id, i2cbus->adapter.name, i2cbus->slave_addr); goto out; } if ((id = tfp410_getid(dvo, TFP410_DID_LO)) != TFP410_DID) { DRM_DEBUG("tfp410 not detected got DID %X: from %s Slave %d.\n", - id, adapter->name, dvo->slave_addr); + id, i2cbus->adapter.name, i2cbus->slave_addr); goto out; } tfp->quiet = false; diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index e3cb4025e323..98560e1e899a 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -67,6 +67,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) pci_save_state(dev->pdev); + i915_save_state(dev); + /* If KMS is active, we do the leavevt stuff here */ if (drm_core_check_feature(dev, DRIVER_MODESET)) { if (i915_gem_idle(dev)) @@ -75,8 +77,6 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) drm_irq_uninstall(dev); } - i915_save_state(dev); - intel_opregion_free(dev, 1); if (state.event == PM_EVENT_SUSPEND) { diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index bb4c2d387b6c..7a84f04e8439 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -306,17 +306,6 @@ typedef struct drm_i915_private { u32 saveCURBPOS; u32 saveCURBBASE; u32 saveCURSIZE; - u32 saveDP_B; - u32 saveDP_C; - u32 saveDP_D; - u32 savePIPEA_GMCH_DATA_M; - u32 savePIPEB_GMCH_DATA_M; - u32 savePIPEA_GMCH_DATA_N; - u32 savePIPEB_GMCH_DATA_N; - u32 savePIPEA_DP_LINK_M; - u32 savePIPEB_DP_LINK_M; - u32 savePIPEA_DP_LINK_N; - u32 savePIPEB_DP_LINK_N; struct { struct drm_mm gtt_space; @@ -868,7 +857,6 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \ IS_I915GM(dev))) #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) -#define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev)) #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) #define PRIMARY_RINGBUFFER_SIZE (128*1024) diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index 876b65cb7629..fd2b8bdffe3f 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -1006,7 +1006,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, mutex_lock(&dev->struct_mutex); #if WATCH_BUF - DRM_INFO("set_domain_ioctl %p(%zd), %08x %08x\n", + DRM_INFO("set_domain_ioctl %p(%d), %08x %08x\n", obj, obj->size, read_domains, write_domain); #endif if (read_domains & I915_GEM_DOMAIN_GTT) { @@ -1050,7 +1050,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, } #if WATCH_BUF - DRM_INFO("%s: sw_finish %d (%p %zd)\n", + DRM_INFO("%s: sw_finish %d (%p %d)\n", __func__, args->handle, obj, obj->size); #endif obj_priv = obj->driver_private; @@ -2423,7 +2423,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) } #if WATCH_BUF - DRM_INFO("Binding object of size %zd at 0x%08x\n", + DRM_INFO("Binding object of size %d at 0x%08x\n", obj->size, obj_priv->gtt_offset); #endif ret = i915_gem_object_get_pages(obj); @@ -4227,7 +4227,6 @@ i915_gem_lastclose(struct drm_device *dev) void i915_gem_load(struct drm_device *dev) { - int i; drm_i915_private_t *dev_priv = dev->dev_private; spin_lock_init(&dev_priv->mm.active_list_lock); @@ -4247,18 +4246,6 @@ i915_gem_load(struct drm_device *dev) else dev_priv->num_fence_regs = 8; - /* Initialize fence registers to zero */ - if (IS_I965G(dev)) { - for (i = 0; i < 16; i++) - I915_WRITE64(FENCE_REG_965_0 + (i * 8), 0); - } else { - for (i = 0; i < 8; i++) - I915_WRITE(FENCE_REG_830_0 + (i * 4), 0); - if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) - for (i = 0; i < 8; i++) - I915_WRITE(FENCE_REG_945_8 + (i * 4), 0); - } - i915_gem_detect_bit_6_swizzle(dev); } diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_debug.c b/trunk/drivers/gpu/drm/i915/i915_gem_debug.c index e602614bd3f8..8d0b943e2c5a 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_debug.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_debug.c @@ -87,7 +87,7 @@ i915_gem_dump_object(struct drm_gem_object *obj, int len, chunk_len = page_len - chunk; if (chunk_len > 128) chunk_len = 128; - i915_gem_dump_page(obj_priv->pages[page], + i915_gem_dump_page(obj_priv->page_list[page], chunk, chunk + chunk_len, obj_priv->gtt_offset + page * PAGE_SIZE, @@ -143,7 +143,7 @@ i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) uint32_t *backing_map = NULL; int bad_count = 0; - DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %zdkb):\n", + DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %dkb):\n", __func__, obj, obj_priv->gtt_offset, handle, obj->size / 1024); @@ -157,7 +157,7 @@ i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) for (page = 0; page < obj->size / PAGE_SIZE; page++) { int i; - backing_map = kmap_atomic(obj_priv->pages[page], KM_USER0); + backing_map = kmap_atomic(obj_priv->page_list[page], KM_USER0); if (backing_map == NULL) { DRM_ERROR("failed to map backing page\n"); diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c b/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c index daeae62e1c28..5c1ceec49f5b 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -114,13 +114,11 @@ intel_alloc_mchbar_resource(struct drm_device *dev) mchbar_addr = ((u64)temp_hi << 32) | temp_lo; /* If ACPI doesn't have it, assume we need to allocate it ourselves */ -#ifdef CONFIG_PNP if (mchbar_addr && pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) { ret = 0; goto out_put; } -#endif /* Get some space for it */ ret = pci_bus_alloc_resource(bridge_dev->bus, &dev_priv->mch_res, diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c index 228546f6eaa4..b86b7b7130c6 100644 --- a/trunk/drivers/gpu/drm/i915/i915_irq.c +++ b/trunk/drivers/gpu/drm/i915/i915_irq.c @@ -232,17 +232,7 @@ static void i915_hotplug_work_func(struct work_struct *work) drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, hotplug_work); struct drm_device *dev = dev_priv->dev; - struct drm_mode_config *mode_config = &dev->mode_config; - struct drm_connector *connector; - - if (mode_config->num_connector) { - list_for_each_entry(connector, &mode_config->connector_list, head) { - struct intel_output *intel_output = to_intel_output(connector); - - if (intel_output->hot_plug) - (*intel_output->hot_plug) (intel_output); - } - } + /* Just fire off a uevent and let userspace tell us what to do */ drm_sysfs_hotplug_event(dev); } diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index 88bf7521405f..f6237a0b1133 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -569,19 +569,6 @@ #define C0DRB3 0x10206 #define C1DRB3 0x10606 -/* Clocking configuration register */ -#define CLKCFG 0x10c00 -#define CLKCFG_FSB_400 (0 << 0) /* hrawclk 100 */ -#define CLKCFG_FSB_533 (1 << 0) /* hrawclk 133 */ -#define CLKCFG_FSB_667 (3 << 0) /* hrawclk 166 */ -#define CLKCFG_FSB_800 (2 << 0) /* hrawclk 200 */ -#define CLKCFG_FSB_1067 (6 << 0) /* hrawclk 266 */ -#define CLKCFG_FSB_1333 (7 << 0) /* hrawclk 333 */ -/* this is a guess, could be 5 as well */ -#define CLKCFG_FSB_1600 (4 << 0) /* hrawclk 400 */ -#define CLKCFG_FSB_1600_ALT (5 << 0) /* hrawclk 400 */ -#define CLKCFG_FSB_MASK (7 << 0) - /** GM965 GM45 render standby register */ #define MCHBAR_RENDER_STANDBY 0x111B8 @@ -847,25 +834,9 @@ #define HORIZ_INTERP_MASK (3 << 6) #define HORIZ_AUTO_SCALE (1 << 5) #define PANEL_8TO6_DITHER_ENABLE (1 << 3) -#define PFIT_FILTER_FUZZY (0 << 24) -#define PFIT_SCALING_AUTO (0 << 26) -#define PFIT_SCALING_PROGRAMMED (1 << 26) -#define PFIT_SCALING_PILLAR (2 << 26) -#define PFIT_SCALING_LETTER (3 << 26) #define PFIT_PGM_RATIOS 0x61234 #define PFIT_VERT_SCALE_MASK 0xfff00000 #define PFIT_HORIZ_SCALE_MASK 0x0000fff0 -/* Pre-965 */ -#define PFIT_VERT_SCALE_SHIFT 20 -#define PFIT_VERT_SCALE_MASK 0xfff00000 -#define PFIT_HORIZ_SCALE_SHIFT 4 -#define PFIT_HORIZ_SCALE_MASK 0x0000fff0 -/* 965+ */ -#define PFIT_VERT_SCALE_SHIFT_965 16 -#define PFIT_VERT_SCALE_MASK_965 0x1fff0000 -#define PFIT_HORIZ_SCALE_SHIFT_965 0 -#define PFIT_HORIZ_SCALE_MASK_965 0x00001fff - #define PFIT_AUTO_RATIOS 0x61238 /* Backlight control */ diff --git a/trunk/drivers/gpu/drm/i915/i915_suspend.c b/trunk/drivers/gpu/drm/i915/i915_suspend.c index 8d8e083d14ab..a98e2831ed31 100644 --- a/trunk/drivers/gpu/drm/i915/i915_suspend.c +++ b/trunk/drivers/gpu/drm/i915/i915_suspend.c @@ -322,20 +322,6 @@ int i915_save_state(struct drm_device *dev) dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); - /* Display Port state */ - if (SUPPORTS_INTEGRATED_DP(dev)) { - dev_priv->saveDP_B = I915_READ(DP_B); - dev_priv->saveDP_C = I915_READ(DP_C); - dev_priv->saveDP_D = I915_READ(DP_D); - dev_priv->savePIPEA_GMCH_DATA_M = I915_READ(PIPEA_GMCH_DATA_M); - dev_priv->savePIPEB_GMCH_DATA_M = I915_READ(PIPEB_GMCH_DATA_M); - dev_priv->savePIPEA_GMCH_DATA_N = I915_READ(PIPEA_GMCH_DATA_N); - dev_priv->savePIPEB_GMCH_DATA_N = I915_READ(PIPEB_GMCH_DATA_N); - dev_priv->savePIPEA_DP_LINK_M = I915_READ(PIPEA_DP_LINK_M); - dev_priv->savePIPEB_DP_LINK_M = I915_READ(PIPEB_DP_LINK_M); - dev_priv->savePIPEA_DP_LINK_N = I915_READ(PIPEA_DP_LINK_N); - dev_priv->savePIPEB_DP_LINK_N = I915_READ(PIPEB_DP_LINK_N); - } /* FIXME: save TV & SDVO state */ /* FBC state */ @@ -418,19 +404,7 @@ int i915_restore_state(struct drm_device *dev) for (i = 0; i < 8; i++) I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); } - - /* Display port ratios (must be done before clock is set) */ - if (SUPPORTS_INTEGRATED_DP(dev)) { - I915_WRITE(PIPEA_GMCH_DATA_M, dev_priv->savePIPEA_GMCH_DATA_M); - I915_WRITE(PIPEB_GMCH_DATA_M, dev_priv->savePIPEB_GMCH_DATA_M); - I915_WRITE(PIPEA_GMCH_DATA_N, dev_priv->savePIPEA_GMCH_DATA_N); - I915_WRITE(PIPEB_GMCH_DATA_N, dev_priv->savePIPEB_GMCH_DATA_N); - I915_WRITE(PIPEA_DP_LINK_M, dev_priv->savePIPEA_DP_LINK_M); - I915_WRITE(PIPEB_DP_LINK_M, dev_priv->savePIPEB_DP_LINK_M); - I915_WRITE(PIPEA_DP_LINK_N, dev_priv->savePIPEA_DP_LINK_N); - I915_WRITE(PIPEB_DP_LINK_N, dev_priv->savePIPEB_DP_LINK_N); - } - + /* Pipe & plane A info */ /* Prime the clock */ if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { @@ -544,12 +518,6 @@ int i915_restore_state(struct drm_device *dev) I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); - /* Display Port state */ - if (SUPPORTS_INTEGRATED_DP(dev)) { - I915_WRITE(DP_B, dev_priv->saveDP_B); - I915_WRITE(DP_C, dev_priv->saveDP_C); - I915_WRITE(DP_D, dev_priv->saveDP_D); - } /* FIXME: restore TV & SDVO state */ /* FBC info */ diff --git a/trunk/drivers/gpu/drm/i915/intel_bios.c b/trunk/drivers/gpu/drm/i915/intel_bios.c index 716409a57244..cdd126d068a7 100644 --- a/trunk/drivers/gpu/drm/i915/intel_bios.c +++ b/trunk/drivers/gpu/drm/i915/intel_bios.c @@ -99,11 +99,9 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, { struct bdb_lvds_options *lvds_options; struct bdb_lvds_lfp_data *lvds_lfp_data; - struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs; struct bdb_lvds_lfp_data_entry *entry; struct lvds_dvo_timing *dvo_timing; struct drm_display_mode *panel_fixed_mode; - int lfp_data_size; /* Defaults if we can't find VBT info */ dev_priv->lvds_dither = 0; @@ -121,17 +119,9 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, if (!lvds_lfp_data) return; - lvds_lfp_data_ptrs = find_section(bdb, BDB_LVDS_LFP_DATA_PTRS); - if (!lvds_lfp_data_ptrs) - return; - dev_priv->lvds_vbt = 1; - lfp_data_size = lvds_lfp_data_ptrs->ptr[1].dvo_timing_offset - - lvds_lfp_data_ptrs->ptr[0].dvo_timing_offset; - entry = (struct bdb_lvds_lfp_data_entry *) - ((uint8_t *)lvds_lfp_data->data + (lfp_data_size * - lvds_options->panel_type)); + entry = &lvds_lfp_data->data[lvds_options->panel_type]; dvo_timing = &entry->dvo_timing; panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 73e7b9cecac8..3e1c78162119 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -29,7 +29,6 @@ #include "intel_drv.h" #include "i915_drm.h" #include "i915_drv.h" -#include "intel_dp.h" #include "drm_crtc_helper.h" @@ -128,6 +127,19 @@ struct intel_limit { #define I9XX_P2_LVDS_FAST 7 #define I9XX_P2_LVDS_SLOW_LIMIT 112000 +#define INTEL_LIMIT_I8XX_DVO_DAC 0 +#define INTEL_LIMIT_I8XX_LVDS 1 +#define INTEL_LIMIT_I9XX_SDVO_DAC 2 +#define INTEL_LIMIT_I9XX_LVDS 3 +#define INTEL_LIMIT_G4X_SDVO 4 +#define INTEL_LIMIT_G4X_HDMI_DAC 5 +#define INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS 6 +#define INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS 7 +#define INTEL_LIMIT_IGD_SDVO_DAC 8 +#define INTEL_LIMIT_IGD_LVDS 9 +#define INTEL_LIMIT_IGDNG_SDVO_DAC 10 +#define INTEL_LIMIT_IGDNG_LVDS 11 + /*The parameter is for SDVO on G4x platform*/ #define G4X_DOT_SDVO_MIN 25000 #define G4X_DOT_SDVO_MAX 270000 @@ -206,25 +218,6 @@ struct intel_limit { #define G4X_P2_DUAL_CHANNEL_LVDS_FAST 7 #define G4X_P2_DUAL_CHANNEL_LVDS_LIMIT 0 -/*The parameter is for DISPLAY PORT on G4x platform*/ -#define G4X_DOT_DISPLAY_PORT_MIN 161670 -#define G4X_DOT_DISPLAY_PORT_MAX 227000 -#define G4X_N_DISPLAY_PORT_MIN 1 -#define G4X_N_DISPLAY_PORT_MAX 2 -#define G4X_M_DISPLAY_PORT_MIN 97 -#define G4X_M_DISPLAY_PORT_MAX 108 -#define G4X_M1_DISPLAY_PORT_MIN 0x10 -#define G4X_M1_DISPLAY_PORT_MAX 0x12 -#define G4X_M2_DISPLAY_PORT_MIN 0x05 -#define G4X_M2_DISPLAY_PORT_MAX 0x06 -#define G4X_P_DISPLAY_PORT_MIN 10 -#define G4X_P_DISPLAY_PORT_MAX 20 -#define G4X_P1_DISPLAY_PORT_MIN 1 -#define G4X_P1_DISPLAY_PORT_MAX 2 -#define G4X_P2_DISPLAY_PORT_SLOW 10 -#define G4X_P2_DISPLAY_PORT_FAST 10 -#define G4X_P2_DISPLAY_PORT_LIMIT 0 - /* IGDNG */ /* as we calculate clock using (register_value + 2) for N/M1/M2, so here the range value for them is (actual_value-2). @@ -263,11 +256,8 @@ static bool intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, int target, int refclk, intel_clock_t *best_clock); -static bool -intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock); - -static const intel_limit_t intel_limits_i8xx_dvo = { +static const intel_limit_t intel_limits[] = { + { /* INTEL_LIMIT_I8XX_DVO_DAC */ .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, @@ -279,9 +269,8 @@ static const intel_limit_t intel_limits_i8xx_dvo = { .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, .find_pll = intel_find_best_PLL, -}; - -static const intel_limit_t intel_limits_i8xx_lvds = { + }, + { /* INTEL_LIMIT_I8XX_LVDS */ .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, @@ -293,9 +282,8 @@ static const intel_limit_t intel_limits_i8xx_lvds = { .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, .find_pll = intel_find_best_PLL, -}; - -static const intel_limit_t intel_limits_i9xx_sdvo = { + }, + { /* INTEL_LIMIT_I9XX_SDVO_DAC */ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, @@ -307,9 +295,8 @@ static const intel_limit_t intel_limits_i9xx_sdvo = { .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, .find_pll = intel_find_best_PLL, -}; - -static const intel_limit_t intel_limits_i9xx_lvds = { + }, + { /* INTEL_LIMIT_I9XX_LVDS */ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, @@ -324,10 +311,9 @@ static const intel_limit_t intel_limits_i9xx_lvds = { .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, .find_pll = intel_find_best_PLL, -}; - + }, /* below parameter and function is for G4X Chipset Family*/ -static const intel_limit_t intel_limits_g4x_sdvo = { + { /* INTEL_LIMIT_G4X_SDVO */ .dot = { .min = G4X_DOT_SDVO_MIN, .max = G4X_DOT_SDVO_MAX }, .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, .n = { .min = G4X_N_SDVO_MIN, .max = G4X_N_SDVO_MAX }, @@ -341,9 +327,8 @@ static const intel_limit_t intel_limits_g4x_sdvo = { .p2_fast = G4X_P2_SDVO_FAST }, .find_pll = intel_g4x_find_best_PLL, -}; - -static const intel_limit_t intel_limits_g4x_hdmi = { + }, + { /* INTEL_LIMIT_G4X_HDMI_DAC */ .dot = { .min = G4X_DOT_HDMI_DAC_MIN, .max = G4X_DOT_HDMI_DAC_MAX }, .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, .n = { .min = G4X_N_HDMI_DAC_MIN, .max = G4X_N_HDMI_DAC_MAX }, @@ -357,9 +342,8 @@ static const intel_limit_t intel_limits_g4x_hdmi = { .p2_fast = G4X_P2_HDMI_DAC_FAST }, .find_pll = intel_g4x_find_best_PLL, -}; - -static const intel_limit_t intel_limits_g4x_single_channel_lvds = { + }, + { /* INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS */ .dot = { .min = G4X_DOT_SINGLE_CHANNEL_LVDS_MIN, .max = G4X_DOT_SINGLE_CHANNEL_LVDS_MAX }, .vco = { .min = G4X_VCO_MIN, @@ -381,9 +365,8 @@ static const intel_limit_t intel_limits_g4x_single_channel_lvds = { .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST }, .find_pll = intel_g4x_find_best_PLL, -}; - -static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { + }, + { /* INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS */ .dot = { .min = G4X_DOT_DUAL_CHANNEL_LVDS_MIN, .max = G4X_DOT_DUAL_CHANNEL_LVDS_MAX }, .vco = { .min = G4X_VCO_MIN, @@ -405,32 +388,8 @@ static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST }, .find_pll = intel_g4x_find_best_PLL, -}; - -static const intel_limit_t intel_limits_g4x_display_port = { - .dot = { .min = G4X_DOT_DISPLAY_PORT_MIN, - .max = G4X_DOT_DISPLAY_PORT_MAX }, - .vco = { .min = G4X_VCO_MIN, - .max = G4X_VCO_MAX}, - .n = { .min = G4X_N_DISPLAY_PORT_MIN, - .max = G4X_N_DISPLAY_PORT_MAX }, - .m = { .min = G4X_M_DISPLAY_PORT_MIN, - .max = G4X_M_DISPLAY_PORT_MAX }, - .m1 = { .min = G4X_M1_DISPLAY_PORT_MIN, - .max = G4X_M1_DISPLAY_PORT_MAX }, - .m2 = { .min = G4X_M2_DISPLAY_PORT_MIN, - .max = G4X_M2_DISPLAY_PORT_MAX }, - .p = { .min = G4X_P_DISPLAY_PORT_MIN, - .max = G4X_P_DISPLAY_PORT_MAX }, - .p1 = { .min = G4X_P1_DISPLAY_PORT_MIN, - .max = G4X_P1_DISPLAY_PORT_MAX}, - .p2 = { .dot_limit = G4X_P2_DISPLAY_PORT_LIMIT, - .p2_slow = G4X_P2_DISPLAY_PORT_SLOW, - .p2_fast = G4X_P2_DISPLAY_PORT_FAST }, - .find_pll = intel_find_pll_g4x_dp, -}; - -static const intel_limit_t intel_limits_igd_sdvo = { + }, + { /* INTEL_LIMIT_IGD_SDVO */ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, @@ -442,9 +401,8 @@ static const intel_limit_t intel_limits_igd_sdvo = { .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, .find_pll = intel_find_best_PLL, -}; - -static const intel_limit_t intel_limits_igd_lvds = { + }, + { /* INTEL_LIMIT_IGD_LVDS */ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, @@ -457,9 +415,8 @@ static const intel_limit_t intel_limits_igd_lvds = { .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, .find_pll = intel_find_best_PLL, -}; - -static const intel_limit_t intel_limits_igdng_sdvo = { + }, + { /* INTEL_LIMIT_IGDNG_SDVO_DAC */ .dot = { .min = IGDNG_DOT_MIN, .max = IGDNG_DOT_MAX }, .vco = { .min = IGDNG_VCO_MIN, .max = IGDNG_VCO_MAX }, .n = { .min = IGDNG_N_MIN, .max = IGDNG_N_MAX }, @@ -472,9 +429,8 @@ static const intel_limit_t intel_limits_igdng_sdvo = { .p2_slow = IGDNG_P2_SDVO_DAC_SLOW, .p2_fast = IGDNG_P2_SDVO_DAC_FAST }, .find_pll = intel_igdng_find_best_PLL, -}; - -static const intel_limit_t intel_limits_igdng_lvds = { + }, + { /* INTEL_LIMIT_IGDNG_LVDS */ .dot = { .min = IGDNG_DOT_MIN, .max = IGDNG_DOT_MAX }, .vco = { .min = IGDNG_VCO_MIN, .max = IGDNG_VCO_MAX }, .n = { .min = IGDNG_N_MIN, .max = IGDNG_N_MAX }, @@ -487,15 +443,16 @@ static const intel_limit_t intel_limits_igdng_lvds = { .p2_slow = IGDNG_P2_LVDS_SLOW, .p2_fast = IGDNG_P2_LVDS_FAST }, .find_pll = intel_igdng_find_best_PLL, + }, }; static const intel_limit_t *intel_igdng_limit(struct drm_crtc *crtc) { const intel_limit_t *limit; if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) - limit = &intel_limits_igdng_lvds; + limit = &intel_limits[INTEL_LIMIT_IGDNG_LVDS]; else - limit = &intel_limits_igdng_sdvo; + limit = &intel_limits[INTEL_LIMIT_IGDNG_SDVO_DAC]; return limit; } @@ -510,19 +467,19 @@ static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc) if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) /* LVDS with dual channel */ - limit = &intel_limits_g4x_dual_channel_lvds; + limit = &intel_limits + [INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS]; else /* LVDS with dual channel */ - limit = &intel_limits_g4x_single_channel_lvds; + limit = &intel_limits + [INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS]; } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) || intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) { - limit = &intel_limits_g4x_hdmi; + limit = &intel_limits[INTEL_LIMIT_G4X_HDMI_DAC]; } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) { - limit = &intel_limits_g4x_sdvo; - } else if (intel_pipe_has_type (crtc, INTEL_OUTPUT_DISPLAYPORT)) { - limit = &intel_limits_g4x_display_port; + limit = &intel_limits[INTEL_LIMIT_G4X_SDVO]; } else /* The option is for other outputs */ - limit = &intel_limits_i9xx_sdvo; + limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; return limit; } @@ -538,19 +495,19 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc) limit = intel_g4x_limit(crtc); } else if (IS_I9XX(dev) && !IS_IGD(dev)) { if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) - limit = &intel_limits_i9xx_lvds; + limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS]; else - limit = &intel_limits_i9xx_sdvo; + limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; } else if (IS_IGD(dev)) { if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) - limit = &intel_limits_igd_lvds; + limit = &intel_limits[INTEL_LIMIT_IGD_LVDS]; else - limit = &intel_limits_igd_sdvo; + limit = &intel_limits[INTEL_LIMIT_IGD_SDVO_DAC]; } else { if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) - limit = &intel_limits_i8xx_lvds; + limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS]; else - limit = &intel_limits_i8xx_dvo; + limit = &intel_limits[INTEL_LIMIT_I8XX_DVO_DAC]; } return limit; } @@ -807,35 +764,6 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, return found; } -/* DisplayPort has only two frequencies, 162MHz and 270MHz */ -static bool -intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock) -{ - intel_clock_t clock; - if (target < 200000) { - clock.dot = 161670; - clock.p = 20; - clock.p1 = 2; - clock.p2 = 10; - clock.n = 0x01; - clock.m = 97; - clock.m1 = 0x10; - clock.m2 = 0x05; - } else { - clock.dot = 270000; - clock.p = 10; - clock.p1 = 1; - clock.p2 = 10; - clock.n = 0x02; - clock.m = 108; - clock.m1 = 0x12; - clock.m2 = 0x06; - } - memcpy(best_clock, &clock, sizeof(intel_clock_t)); - return true; -} - void intel_wait_for_vblank(struct drm_device *dev) { @@ -1613,7 +1541,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, intel_clock_t clock; u32 dpll = 0, fp = 0, dspcntr, pipeconf; bool ok, is_sdvo = false, is_dvo = false; - bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; + bool is_crt = false, is_lvds = false, is_tv = false; struct drm_mode_config *mode_config = &dev->mode_config; struct drm_connector *connector; const intel_limit_t *limit; @@ -1657,9 +1585,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, case INTEL_OUTPUT_ANALOG: is_crt = true; break; - case INTEL_OUTPUT_DISPLAYPORT: - is_dp = true; - break; } num_outputs++; @@ -1675,7 +1600,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, } else { refclk = 48000; } - /* * Returns a set of divisors for the desired target clock with the given @@ -1738,8 +1662,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, else if (IS_IGDNG(dev)) dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; } - if (is_dp) - dpll |= DPLL_DVO_HIGH_SPEED; /* compute bitmask from p1 value */ if (IS_IGD(dev)) @@ -1887,8 +1809,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, I915_WRITE(lvds_reg, lvds); I915_READ(lvds_reg); } - if (is_dp) - intel_dp_set_m_n(crtc, mode, adjusted_mode); I915_WRITE(fp_reg, fp); I915_WRITE(dpll_reg, dpll); @@ -2555,8 +2475,6 @@ static void intel_setup_outputs(struct drm_device *dev) found = intel_sdvo_init(dev, SDVOB); if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) intel_hdmi_init(dev, SDVOB); - if (!found && SUPPORTS_INTEGRATED_DP(dev)) - intel_dp_init(dev, DP_B); } /* Before G4X SDVOC doesn't have its own detect register */ @@ -2569,11 +2487,7 @@ static void intel_setup_outputs(struct drm_device *dev) found = intel_sdvo_init(dev, SDVOC); if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) intel_hdmi_init(dev, SDVOC); - if (!found && SUPPORTS_INTEGRATED_DP(dev)) - intel_dp_init(dev, DP_C); } - if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED)) - intel_dp_init(dev, DP_D); } else intel_dvo_init(dev); @@ -2616,11 +2530,6 @@ static void intel_setup_outputs(struct drm_device *dev) (1 << 1)); clone_mask = (1 << INTEL_OUTPUT_TVOUT); break; - case INTEL_OUTPUT_DISPLAYPORT: - crtc_mask = ((1 << 0) | - (1 << 1)); - clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT); - break; } encoder->possible_crtcs = crtc_mask; encoder->possible_clones = intel_connector_clones(dev, clone_mask); diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c deleted file mode 100644 index 8f8d37d5663a..000000000000 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ /dev/null @@ -1,1153 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Keith Packard - * - */ - -#include -#include "drmP.h" -#include "drm.h" -#include "drm_crtc.h" -#include "drm_crtc_helper.h" -#include "intel_drv.h" -#include "i915_drm.h" -#include "i915_drv.h" -#include "intel_dp.h" - -#define DP_LINK_STATUS_SIZE 6 -#define DP_LINK_CHECK_TIMEOUT (10 * 1000) - -#define DP_LINK_CONFIGURATION_SIZE 9 - -struct intel_dp_priv { - uint32_t output_reg; - uint32_t DP; - uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; - uint32_t save_DP; - uint8_t save_link_configuration[DP_LINK_CONFIGURATION_SIZE]; - bool has_audio; - int dpms_mode; - uint8_t link_bw; - uint8_t lane_count; - uint8_t dpcd[4]; - struct intel_output *intel_output; - struct i2c_adapter adapter; - struct i2c_algo_dp_aux_data algo; -}; - -static void -intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, - uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]); - -static void -intel_dp_link_down(struct intel_output *intel_output, uint32_t DP); - -static int -intel_dp_max_lane_count(struct intel_output *intel_output) -{ - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - int max_lane_count = 4; - - if (dp_priv->dpcd[0] >= 0x11) { - max_lane_count = dp_priv->dpcd[2] & 0x1f; - switch (max_lane_count) { - case 1: case 2: case 4: - break; - default: - max_lane_count = 4; - } - } - return max_lane_count; -} - -static int -intel_dp_max_link_bw(struct intel_output *intel_output) -{ - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - int max_link_bw = dp_priv->dpcd[1]; - - switch (max_link_bw) { - case DP_LINK_BW_1_62: - case DP_LINK_BW_2_7: - break; - default: - max_link_bw = DP_LINK_BW_1_62; - break; - } - return max_link_bw; -} - -static int -intel_dp_link_clock(uint8_t link_bw) -{ - if (link_bw == DP_LINK_BW_2_7) - return 270000; - else - return 162000; -} - -/* I think this is a fiction */ -static int -intel_dp_link_required(int pixel_clock) -{ - return pixel_clock * 3; -} - -static int -intel_dp_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct intel_output *intel_output = to_intel_output(connector); - int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output)); - int max_lanes = intel_dp_max_lane_count(intel_output); - - if (intel_dp_link_required(mode->clock) > max_link_clock * max_lanes) - return MODE_CLOCK_HIGH; - - if (mode->clock < 10000) - return MODE_CLOCK_LOW; - - return MODE_OK; -} - -static uint32_t -pack_aux(uint8_t *src, int src_bytes) -{ - int i; - uint32_t v = 0; - - if (src_bytes > 4) - src_bytes = 4; - for (i = 0; i < src_bytes; i++) - v |= ((uint32_t) src[i]) << ((3-i) * 8); - return v; -} - -static void -unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes) -{ - int i; - if (dst_bytes > 4) - dst_bytes = 4; - for (i = 0; i < dst_bytes; i++) - dst[i] = src >> ((3-i) * 8); -} - -/* hrawclock is 1/4 the FSB frequency */ -static int -intel_hrawclk(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t clkcfg; - - clkcfg = I915_READ(CLKCFG); - switch (clkcfg & CLKCFG_FSB_MASK) { - case CLKCFG_FSB_400: - return 100; - case CLKCFG_FSB_533: - return 133; - case CLKCFG_FSB_667: - return 166; - case CLKCFG_FSB_800: - return 200; - case CLKCFG_FSB_1067: - return 266; - case CLKCFG_FSB_1333: - return 333; - /* these two are just a guess; one of them might be right */ - case CLKCFG_FSB_1600: - case CLKCFG_FSB_1600_ALT: - return 400; - default: - return 133; - } -} - -static int -intel_dp_aux_ch(struct intel_output *intel_output, - uint8_t *send, int send_bytes, - uint8_t *recv, int recv_size) -{ - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - uint32_t output_reg = dp_priv->output_reg; - struct drm_device *dev = intel_output->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t ch_ctl = output_reg + 0x10; - uint32_t ch_data = ch_ctl + 4; - int i; - int recv_bytes; - uint32_t ctl; - uint32_t status; - uint32_t aux_clock_divider; - int try; - - /* The clock divider is based off the hrawclk, - * and would like to run at 2MHz. So, take the - * hrawclk value and divide by 2 and use that - */ - aux_clock_divider = intel_hrawclk(dev) / 2; - /* Must try at least 3 times according to DP spec */ - for (try = 0; try < 5; try++) { - /* Load the send data into the aux channel data registers */ - for (i = 0; i < send_bytes; i += 4) { - uint32_t d = pack_aux(send + i, send_bytes - i);; - - I915_WRITE(ch_data + i, d); - } - - ctl = (DP_AUX_CH_CTL_SEND_BUSY | - DP_AUX_CH_CTL_TIME_OUT_400us | - (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | - (5 << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | - (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | - DP_AUX_CH_CTL_DONE | - DP_AUX_CH_CTL_TIME_OUT_ERROR | - DP_AUX_CH_CTL_RECEIVE_ERROR); - - /* Send the command and wait for it to complete */ - I915_WRITE(ch_ctl, ctl); - (void) I915_READ(ch_ctl); - for (;;) { - udelay(100); - status = I915_READ(ch_ctl); - if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) - break; - } - - /* Clear done status and any errors */ - I915_WRITE(ch_ctl, (ctl | - DP_AUX_CH_CTL_DONE | - DP_AUX_CH_CTL_TIME_OUT_ERROR | - DP_AUX_CH_CTL_RECEIVE_ERROR)); - (void) I915_READ(ch_ctl); - if ((status & DP_AUX_CH_CTL_TIME_OUT_ERROR) == 0) - break; - } - - if ((status & DP_AUX_CH_CTL_DONE) == 0) { - printk(KERN_ERR "dp_aux_ch not done status 0x%08x\n", status); - return -EBUSY; - } - - /* Check for timeout or receive error. - * Timeouts occur when the sink is not connected - */ - if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) { - printk(KERN_ERR "dp_aux_ch receive error status 0x%08x\n", status); - return -EIO; - } - if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) { - printk(KERN_ERR "dp_aux_ch timeout status 0x%08x\n", status); - return -ETIMEDOUT; - } - - /* Unload any bytes sent back from the other side */ - recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >> - DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT); - - if (recv_bytes > recv_size) - recv_bytes = recv_size; - - for (i = 0; i < recv_bytes; i += 4) { - uint32_t d = I915_READ(ch_data + i); - - unpack_aux(d, recv + i, recv_bytes - i); - } - - return recv_bytes; -} - -/* Write data to the aux channel in native mode */ -static int -intel_dp_aux_native_write(struct intel_output *intel_output, - uint16_t address, uint8_t *send, int send_bytes) -{ - int ret; - uint8_t msg[20]; - int msg_bytes; - uint8_t ack; - - if (send_bytes > 16) - return -1; - msg[0] = AUX_NATIVE_WRITE << 4; - msg[1] = address >> 8; - msg[2] = address; - msg[3] = send_bytes - 1; - memcpy(&msg[4], send, send_bytes); - msg_bytes = send_bytes + 4; - for (;;) { - ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, &ack, 1); - if (ret < 0) - return ret; - if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) - break; - else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) - udelay(100); - else - return -EIO; - } - return send_bytes; -} - -/* Write a single byte to the aux channel in native mode */ -static int -intel_dp_aux_native_write_1(struct intel_output *intel_output, - uint16_t address, uint8_t byte) -{ - return intel_dp_aux_native_write(intel_output, address, &byte, 1); -} - -/* read bytes from a native aux channel */ -static int -intel_dp_aux_native_read(struct intel_output *intel_output, - uint16_t address, uint8_t *recv, int recv_bytes) -{ - uint8_t msg[4]; - int msg_bytes; - uint8_t reply[20]; - int reply_bytes; - uint8_t ack; - int ret; - - msg[0] = AUX_NATIVE_READ << 4; - msg[1] = address >> 8; - msg[2] = address & 0xff; - msg[3] = recv_bytes - 1; - - msg_bytes = 4; - reply_bytes = recv_bytes + 1; - - for (;;) { - ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, - reply, reply_bytes); - if (ret == 0) - return -EPROTO; - if (ret < 0) - return ret; - ack = reply[0]; - if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) { - memcpy(recv, reply + 1, ret - 1); - return ret - 1; - } - else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) - udelay(100); - else - return -EIO; - } -} - -static int -intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, - uint8_t *send, int send_bytes, - uint8_t *recv, int recv_bytes) -{ - struct intel_dp_priv *dp_priv = container_of(adapter, - struct intel_dp_priv, - adapter); - struct intel_output *intel_output = dp_priv->intel_output; - - return intel_dp_aux_ch(intel_output, - send, send_bytes, recv, recv_bytes); -} - -static int -intel_dp_i2c_init(struct intel_output *intel_output, const char *name) -{ - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - - DRM_ERROR("i2c_init %s\n", name); - dp_priv->algo.running = false; - dp_priv->algo.address = 0; - dp_priv->algo.aux_ch = intel_dp_i2c_aux_ch; - - memset(&dp_priv->adapter, '\0', sizeof (dp_priv->adapter)); - dp_priv->adapter.owner = THIS_MODULE; - dp_priv->adapter.class = I2C_CLASS_DDC; - strncpy (dp_priv->adapter.name, name, sizeof dp_priv->adapter.name - 1); - dp_priv->adapter.name[sizeof dp_priv->adapter.name - 1] = '\0'; - dp_priv->adapter.algo_data = &dp_priv->algo; - dp_priv->adapter.dev.parent = &intel_output->base.kdev; - - return i2c_dp_aux_add_bus(&dp_priv->adapter); -} - -static bool -intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - int lane_count, clock; - int max_lane_count = intel_dp_max_lane_count(intel_output); - int max_clock = intel_dp_max_link_bw(intel_output) == DP_LINK_BW_2_7 ? 1 : 0; - static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; - - for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { - for (clock = 0; clock <= max_clock; clock++) { - int link_avail = intel_dp_link_clock(bws[clock]) * lane_count; - - if (intel_dp_link_required(mode->clock) <= link_avail) { - dp_priv->link_bw = bws[clock]; - dp_priv->lane_count = lane_count; - adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); - printk(KERN_ERR "link bw %02x lane count %d clock %d\n", - dp_priv->link_bw, dp_priv->lane_count, - adjusted_mode->clock); - return true; - } - } - } - return false; -} - -struct intel_dp_m_n { - uint32_t tu; - uint32_t gmch_m; - uint32_t gmch_n; - uint32_t link_m; - uint32_t link_n; -}; - -static void -intel_reduce_ratio(uint32_t *num, uint32_t *den) -{ - while (*num > 0xffffff || *den > 0xffffff) { - *num >>= 1; - *den >>= 1; - } -} - -static void -intel_dp_compute_m_n(int bytes_per_pixel, - int nlanes, - int pixel_clock, - int link_clock, - struct intel_dp_m_n *m_n) -{ - m_n->tu = 64; - m_n->gmch_m = pixel_clock * bytes_per_pixel; - m_n->gmch_n = link_clock * nlanes; - intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); - m_n->link_m = pixel_clock; - m_n->link_n = link_clock; - intel_reduce_ratio(&m_n->link_m, &m_n->link_n); -} - -void -intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = crtc->dev; - struct drm_mode_config *mode_config = &dev->mode_config; - struct drm_connector *connector; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int lane_count = 4; - struct intel_dp_m_n m_n; - - /* - * Find the lane count in the intel_output private - */ - list_for_each_entry(connector, &mode_config->connector_list, head) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - - if (!connector->encoder || connector->encoder->crtc != crtc) - continue; - - if (intel_output->type == INTEL_OUTPUT_DISPLAYPORT) { - lane_count = dp_priv->lane_count; - break; - } - } - - /* - * Compute the GMCH and Link ratios. The '3' here is - * the number of bytes_per_pixel post-LUT, which we always - * set up for 8-bits of R/G/B, or 3 bytes total. - */ - intel_dp_compute_m_n(3, lane_count, - mode->clock, adjusted_mode->clock, &m_n); - - if (intel_crtc->pipe == 0) { - I915_WRITE(PIPEA_GMCH_DATA_M, - ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | - m_n.gmch_m); - I915_WRITE(PIPEA_GMCH_DATA_N, - m_n.gmch_n); - I915_WRITE(PIPEA_DP_LINK_M, m_n.link_m); - I915_WRITE(PIPEA_DP_LINK_N, m_n.link_n); - } else { - I915_WRITE(PIPEB_GMCH_DATA_M, - ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | - m_n.gmch_m); - I915_WRITE(PIPEB_GMCH_DATA_N, - m_n.gmch_n); - I915_WRITE(PIPEB_DP_LINK_M, m_n.link_m); - I915_WRITE(PIPEB_DP_LINK_N, m_n.link_n); - } -} - -static void -intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - struct drm_crtc *crtc = intel_output->enc.crtc; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - - dp_priv->DP = (DP_LINK_TRAIN_OFF | - DP_VOLTAGE_0_4 | - DP_PRE_EMPHASIS_0 | - DP_SYNC_VS_HIGH | - DP_SYNC_HS_HIGH); - - switch (dp_priv->lane_count) { - case 1: - dp_priv->DP |= DP_PORT_WIDTH_1; - break; - case 2: - dp_priv->DP |= DP_PORT_WIDTH_2; - break; - case 4: - dp_priv->DP |= DP_PORT_WIDTH_4; - break; - } - if (dp_priv->has_audio) - dp_priv->DP |= DP_AUDIO_OUTPUT_ENABLE; - - memset(dp_priv->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); - dp_priv->link_configuration[0] = dp_priv->link_bw; - dp_priv->link_configuration[1] = dp_priv->lane_count; - - /* - * Check for DPCD version > 1.1, - * enable enahanced frame stuff in that case - */ - if (dp_priv->dpcd[0] >= 0x11) { - dp_priv->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; - dp_priv->DP |= DP_ENHANCED_FRAMING; - } - - if (intel_crtc->pipe == 1) - dp_priv->DP |= DP_PIPEB_SELECT; -} - - -static void -intel_dp_dpms(struct drm_encoder *encoder, int mode) -{ - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - struct drm_device *dev = intel_output->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t dp_reg = I915_READ(dp_priv->output_reg); - - if (mode != DRM_MODE_DPMS_ON) { - if (dp_reg & DP_PORT_EN) - intel_dp_link_down(intel_output, dp_priv->DP); - } else { - if (!(dp_reg & DP_PORT_EN)) - intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); - } - dp_priv->dpms_mode = mode; -} - -/* - * Fetch AUX CH registers 0x202 - 0x207 which contain - * link status information - */ -static bool -intel_dp_get_link_status(struct intel_output *intel_output, - uint8_t link_status[DP_LINK_STATUS_SIZE]) -{ - int ret; - - ret = intel_dp_aux_native_read(intel_output, - DP_LANE0_1_STATUS, - link_status, DP_LINK_STATUS_SIZE); - if (ret != DP_LINK_STATUS_SIZE) - return false; - return true; -} - -static uint8_t -intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE], - int r) -{ - return link_status[r - DP_LANE0_1_STATUS]; -} - -static void -intel_dp_save(struct drm_connector *connector) -{ - struct intel_output *intel_output = to_intel_output(connector); - struct drm_device *dev = intel_output->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - - dp_priv->save_DP = I915_READ(dp_priv->output_reg); - intel_dp_aux_native_read(intel_output, DP_LINK_BW_SET, - dp_priv->save_link_configuration, - sizeof (dp_priv->save_link_configuration)); -} - -static uint8_t -intel_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE], - int lane) -{ - int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); - int s = ((lane & 1) ? - DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : - DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); - uint8_t l = intel_dp_link_status(link_status, i); - - return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT; -} - -static uint8_t -intel_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE], - int lane) -{ - int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); - int s = ((lane & 1) ? - DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT : - DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); - uint8_t l = intel_dp_link_status(link_status, i); - - return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; -} - - -#if 0 -static char *voltage_names[] = { - "0.4V", "0.6V", "0.8V", "1.2V" -}; -static char *pre_emph_names[] = { - "0dB", "3.5dB", "6dB", "9.5dB" -}; -static char *link_train_names[] = { - "pattern 1", "pattern 2", "idle", "off" -}; -#endif - -/* - * These are source-specific values; current Intel hardware supports - * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB - */ -#define I830_DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_800 - -static uint8_t -intel_dp_pre_emphasis_max(uint8_t voltage_swing) -{ - switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { - case DP_TRAIN_VOLTAGE_SWING_400: - return DP_TRAIN_PRE_EMPHASIS_6; - case DP_TRAIN_VOLTAGE_SWING_600: - return DP_TRAIN_PRE_EMPHASIS_6; - case DP_TRAIN_VOLTAGE_SWING_800: - return DP_TRAIN_PRE_EMPHASIS_3_5; - case DP_TRAIN_VOLTAGE_SWING_1200: - default: - return DP_TRAIN_PRE_EMPHASIS_0; - } -} - -static void -intel_get_adjust_train(struct intel_output *intel_output, - uint8_t link_status[DP_LINK_STATUS_SIZE], - int lane_count, - uint8_t train_set[4]) -{ - uint8_t v = 0; - uint8_t p = 0; - int lane; - - for (lane = 0; lane < lane_count; lane++) { - uint8_t this_v = intel_get_adjust_request_voltage(link_status, lane); - uint8_t this_p = intel_get_adjust_request_pre_emphasis(link_status, lane); - - if (this_v > v) - v = this_v; - if (this_p > p) - p = this_p; - } - - if (v >= I830_DP_VOLTAGE_MAX) - v = I830_DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED; - - if (p >= intel_dp_pre_emphasis_max(v)) - p = intel_dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; - - for (lane = 0; lane < 4; lane++) - train_set[lane] = v | p; -} - -static uint32_t -intel_dp_signal_levels(uint8_t train_set, int lane_count) -{ - uint32_t signal_levels = 0; - - switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { - case DP_TRAIN_VOLTAGE_SWING_400: - default: - signal_levels |= DP_VOLTAGE_0_4; - break; - case DP_TRAIN_VOLTAGE_SWING_600: - signal_levels |= DP_VOLTAGE_0_6; - break; - case DP_TRAIN_VOLTAGE_SWING_800: - signal_levels |= DP_VOLTAGE_0_8; - break; - case DP_TRAIN_VOLTAGE_SWING_1200: - signal_levels |= DP_VOLTAGE_1_2; - break; - } - switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) { - case DP_TRAIN_PRE_EMPHASIS_0: - default: - signal_levels |= DP_PRE_EMPHASIS_0; - break; - case DP_TRAIN_PRE_EMPHASIS_3_5: - signal_levels |= DP_PRE_EMPHASIS_3_5; - break; - case DP_TRAIN_PRE_EMPHASIS_6: - signal_levels |= DP_PRE_EMPHASIS_6; - break; - case DP_TRAIN_PRE_EMPHASIS_9_5: - signal_levels |= DP_PRE_EMPHASIS_9_5; - break; - } - return signal_levels; -} - -static uint8_t -intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE], - int lane) -{ - int i = DP_LANE0_1_STATUS + (lane >> 1); - int s = (lane & 1) * 4; - uint8_t l = intel_dp_link_status(link_status, i); - - return (l >> s) & 0xf; -} - -/* Check for clock recovery is done on all channels */ -static bool -intel_clock_recovery_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count) -{ - int lane; - uint8_t lane_status; - - for (lane = 0; lane < lane_count; lane++) { - lane_status = intel_get_lane_status(link_status, lane); - if ((lane_status & DP_LANE_CR_DONE) == 0) - return false; - } - return true; -} - -/* Check to see if channel eq is done on all channels */ -#define CHANNEL_EQ_BITS (DP_LANE_CR_DONE|\ - DP_LANE_CHANNEL_EQ_DONE|\ - DP_LANE_SYMBOL_LOCKED) -static bool -intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count) -{ - uint8_t lane_align; - uint8_t lane_status; - int lane; - - lane_align = intel_dp_link_status(link_status, - DP_LANE_ALIGN_STATUS_UPDATED); - if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) - return false; - for (lane = 0; lane < lane_count; lane++) { - lane_status = intel_get_lane_status(link_status, lane); - if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS) - return false; - } - return true; -} - -static bool -intel_dp_set_link_train(struct intel_output *intel_output, - uint32_t dp_reg_value, - uint8_t dp_train_pat, - uint8_t train_set[4], - bool first) -{ - struct drm_device *dev = intel_output->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - int ret; - - I915_WRITE(dp_priv->output_reg, dp_reg_value); - POSTING_READ(dp_priv->output_reg); - if (first) - intel_wait_for_vblank(dev); - - intel_dp_aux_native_write_1(intel_output, - DP_TRAINING_PATTERN_SET, - dp_train_pat); - - ret = intel_dp_aux_native_write(intel_output, - DP_TRAINING_LANE0_SET, train_set, 4); - if (ret != 4) - return false; - - return true; -} - -static void -intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, - uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]) -{ - struct drm_device *dev = intel_output->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - uint8_t train_set[4]; - uint8_t link_status[DP_LINK_STATUS_SIZE]; - int i; - uint8_t voltage; - bool clock_recovery = false; - bool channel_eq = false; - bool first = true; - int tries; - - /* Write the link configuration data */ - intel_dp_aux_native_write(intel_output, 0x100, - link_configuration, DP_LINK_CONFIGURATION_SIZE); - - DP |= DP_PORT_EN; - DP &= ~DP_LINK_TRAIN_MASK; - memset(train_set, 0, 4); - voltage = 0xff; - tries = 0; - clock_recovery = false; - for (;;) { - /* Use train_set[0] to set the voltage and pre emphasis values */ - uint32_t signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); - DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; - - if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_1, - DP_TRAINING_PATTERN_1, train_set, first)) - break; - first = false; - /* Set training pattern 1 */ - - udelay(100); - if (!intel_dp_get_link_status(intel_output, link_status)) - break; - - if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) { - clock_recovery = true; - break; - } - - /* Check to see if we've tried the max voltage */ - for (i = 0; i < dp_priv->lane_count; i++) - if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) - break; - if (i == dp_priv->lane_count) - break; - - /* Check to see if we've tried the same voltage 5 times */ - if ((train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { - ++tries; - if (tries == 5) - break; - } else - tries = 0; - voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; - - /* Compute new train_set as requested by target */ - intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set); - } - - /* channel equalization */ - tries = 0; - channel_eq = false; - for (;;) { - /* Use train_set[0] to set the voltage and pre emphasis values */ - uint32_t signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); - DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; - - /* channel eq pattern */ - if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_2, - DP_TRAINING_PATTERN_2, train_set, - false)) - break; - - udelay(400); - if (!intel_dp_get_link_status(intel_output, link_status)) - break; - - if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) { - channel_eq = true; - break; - } - - /* Try 5 times */ - if (tries > 5) - break; - - /* Compute new train_set as requested by target */ - intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set); - ++tries; - } - - I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_OFF); - POSTING_READ(dp_priv->output_reg); - intel_dp_aux_native_write_1(intel_output, - DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); -} - -static void -intel_dp_link_down(struct intel_output *intel_output, uint32_t DP) -{ - struct drm_device *dev = intel_output->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - - I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); - POSTING_READ(dp_priv->output_reg); -} - -static void -intel_dp_restore(struct drm_connector *connector) -{ - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - - if (dp_priv->save_DP & DP_PORT_EN) - intel_dp_link_train(intel_output, dp_priv->save_DP, dp_priv->save_link_configuration); - else - intel_dp_link_down(intel_output, dp_priv->save_DP); -} - -/* - * According to DP spec - * 5.1.2: - * 1. Read DPCD - * 2. Configure link according to Receiver Capabilities - * 3. Use Link Training from 2.5.3.3 and 3.5.1.3 - * 4. Check link status on receipt of hot-plug interrupt - */ - -static void -intel_dp_check_link_status(struct intel_output *intel_output) -{ - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - uint8_t link_status[DP_LINK_STATUS_SIZE]; - - if (!intel_output->enc.crtc) - return; - - if (!intel_dp_get_link_status(intel_output, link_status)) { - intel_dp_link_down(intel_output, dp_priv->DP); - return; - } - - if (!intel_channel_eq_ok(link_status, dp_priv->lane_count)) - intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); -} - -/** - * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection. - * - * \return true if DP port is connected. - * \return false if DP port is disconnected. - */ -static enum drm_connector_status -intel_dp_detect(struct drm_connector *connector) -{ - struct intel_output *intel_output = to_intel_output(connector); - struct drm_device *dev = intel_output->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - uint32_t temp, bit; - enum drm_connector_status status; - - dp_priv->has_audio = false; - - temp = I915_READ(PORT_HOTPLUG_EN); - - I915_WRITE(PORT_HOTPLUG_EN, - temp | - DPB_HOTPLUG_INT_EN | - DPC_HOTPLUG_INT_EN | - DPD_HOTPLUG_INT_EN); - - POSTING_READ(PORT_HOTPLUG_EN); - - switch (dp_priv->output_reg) { - case DP_B: - bit = DPB_HOTPLUG_INT_STATUS; - break; - case DP_C: - bit = DPC_HOTPLUG_INT_STATUS; - break; - case DP_D: - bit = DPD_HOTPLUG_INT_STATUS; - break; - default: - return connector_status_unknown; - } - - temp = I915_READ(PORT_HOTPLUG_STAT); - - if ((temp & bit) == 0) - return connector_status_disconnected; - - status = connector_status_disconnected; - if (intel_dp_aux_native_read(intel_output, - 0x000, dp_priv->dpcd, - sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) - { - if (dp_priv->dpcd[0] != 0) - status = connector_status_connected; - } - return status; -} - -static int intel_dp_get_modes(struct drm_connector *connector) -{ - struct intel_output *intel_output = to_intel_output(connector); - - /* We should parse the EDID data and find out if it has an audio sink - */ - - return intel_ddc_get_modes(intel_output); -} - -static void -intel_dp_destroy (struct drm_connector *connector) -{ - struct intel_output *intel_output = to_intel_output(connector); - - if (intel_output->i2c_bus) - intel_i2c_destroy(intel_output->i2c_bus); - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(intel_output); -} - -static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { - .dpms = intel_dp_dpms, - .mode_fixup = intel_dp_mode_fixup, - .prepare = intel_encoder_prepare, - .mode_set = intel_dp_mode_set, - .commit = intel_encoder_commit, -}; - -static const struct drm_connector_funcs intel_dp_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .save = intel_dp_save, - .restore = intel_dp_restore, - .detect = intel_dp_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = intel_dp_destroy, -}; - -static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = { - .get_modes = intel_dp_get_modes, - .mode_valid = intel_dp_mode_valid, - .best_encoder = intel_best_encoder, -}; - -static void intel_dp_enc_destroy(struct drm_encoder *encoder) -{ - drm_encoder_cleanup(encoder); -} - -static const struct drm_encoder_funcs intel_dp_enc_funcs = { - .destroy = intel_dp_enc_destroy, -}; - -void -intel_dp_hot_plug(struct intel_output *intel_output) -{ - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - - if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON) - intel_dp_check_link_status(intel_output); -} - -void -intel_dp_init(struct drm_device *dev, int output_reg) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_connector *connector; - struct intel_output *intel_output; - struct intel_dp_priv *dp_priv; - - intel_output = kcalloc(sizeof(struct intel_output) + - sizeof(struct intel_dp_priv), 1, GFP_KERNEL); - if (!intel_output) - return; - - dp_priv = (struct intel_dp_priv *)(intel_output + 1); - - connector = &intel_output->base; - drm_connector_init(dev, connector, &intel_dp_connector_funcs, - DRM_MODE_CONNECTOR_DisplayPort); - drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); - - intel_output->type = INTEL_OUTPUT_DISPLAYPORT; - - connector->interlace_allowed = true; - connector->doublescan_allowed = 0; - - dp_priv->intel_output = intel_output; - dp_priv->output_reg = output_reg; - dp_priv->has_audio = false; - dp_priv->dpms_mode = DRM_MODE_DPMS_ON; - intel_output->dev_priv = dp_priv; - - drm_encoder_init(dev, &intel_output->enc, &intel_dp_enc_funcs, - DRM_MODE_ENCODER_TMDS); - drm_encoder_helper_add(&intel_output->enc, &intel_dp_helper_funcs); - - drm_mode_connector_attach_encoder(&intel_output->base, - &intel_output->enc); - drm_sysfs_connector_add(connector); - - /* Set up the DDC bus. */ - intel_dp_i2c_init(intel_output, - (output_reg == DP_B) ? "DPDDC-B" : - (output_reg == DP_C) ? "DPDDC-C" : "DPDDC-D"); - intel_output->ddc_bus = &dp_priv->adapter; - intel_output->hot_plug = intel_dp_hot_plug; - - /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written - * 0xd. Failure to do so will result in spurious interrupts being - * generated on the port when a cable is not attached. - */ - if (IS_G4X(dev) && !IS_GM45(dev)) { - u32 temp = I915_READ(PEG_BAND_GAP_DATA); - I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd); - } -} diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.h b/trunk/drivers/gpu/drm/i915/intel_dp.h deleted file mode 100644 index 2b38054d3b6d..000000000000 --- a/trunk/drivers/gpu/drm/i915/intel_dp.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright © 2008 Keith Packard - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#ifndef _INTEL_DP_H_ -#define _INTEL_DP_H_ - -/* From the VESA DisplayPort spec */ - -#define AUX_NATIVE_WRITE 0x8 -#define AUX_NATIVE_READ 0x9 -#define AUX_I2C_WRITE 0x0 -#define AUX_I2C_READ 0x1 -#define AUX_I2C_STATUS 0x2 -#define AUX_I2C_MOT 0x4 - -#define AUX_NATIVE_REPLY_ACK (0x0 << 4) -#define AUX_NATIVE_REPLY_NACK (0x1 << 4) -#define AUX_NATIVE_REPLY_DEFER (0x2 << 4) -#define AUX_NATIVE_REPLY_MASK (0x3 << 4) - -#define AUX_I2C_REPLY_ACK (0x0 << 6) -#define AUX_I2C_REPLY_NACK (0x1 << 6) -#define AUX_I2C_REPLY_DEFER (0x2 << 6) -#define AUX_I2C_REPLY_MASK (0x3 << 6) - -/* AUX CH addresses */ -#define DP_LINK_BW_SET 0x100 -# define DP_LINK_BW_1_62 0x06 -# define DP_LINK_BW_2_7 0x0a - -#define DP_LANE_COUNT_SET 0x101 -# define DP_LANE_COUNT_MASK 0x0f -# define DP_LANE_COUNT_ENHANCED_FRAME_EN (1 << 7) - -#define DP_TRAINING_PATTERN_SET 0x102 - -# define DP_TRAINING_PATTERN_DISABLE 0 -# define DP_TRAINING_PATTERN_1 1 -# define DP_TRAINING_PATTERN_2 2 -# define DP_TRAINING_PATTERN_MASK 0x3 - -# define DP_LINK_QUAL_PATTERN_DISABLE (0 << 2) -# define DP_LINK_QUAL_PATTERN_D10_2 (1 << 2) -# define DP_LINK_QUAL_PATTERN_ERROR_RATE (2 << 2) -# define DP_LINK_QUAL_PATTERN_PRBS7 (3 << 2) -# define DP_LINK_QUAL_PATTERN_MASK (3 << 2) - -# define DP_RECOVERED_CLOCK_OUT_EN (1 << 4) -# define DP_LINK_SCRAMBLING_DISABLE (1 << 5) - -# define DP_SYMBOL_ERROR_COUNT_BOTH (0 << 6) -# define DP_SYMBOL_ERROR_COUNT_DISPARITY (1 << 6) -# define DP_SYMBOL_ERROR_COUNT_SYMBOL (2 << 6) -# define DP_SYMBOL_ERROR_COUNT_MASK (3 << 6) - -#define DP_TRAINING_LANE0_SET 0x103 -#define DP_TRAINING_LANE1_SET 0x104 -#define DP_TRAINING_LANE2_SET 0x105 -#define DP_TRAINING_LANE3_SET 0x106 - -# define DP_TRAIN_VOLTAGE_SWING_MASK 0x3 -# define DP_TRAIN_VOLTAGE_SWING_SHIFT 0 -# define DP_TRAIN_MAX_SWING_REACHED (1 << 2) -# define DP_TRAIN_VOLTAGE_SWING_400 (0 << 0) -# define DP_TRAIN_VOLTAGE_SWING_600 (1 << 0) -# define DP_TRAIN_VOLTAGE_SWING_800 (2 << 0) -# define DP_TRAIN_VOLTAGE_SWING_1200 (3 << 0) - -# define DP_TRAIN_PRE_EMPHASIS_MASK (3 << 3) -# define DP_TRAIN_PRE_EMPHASIS_0 (0 << 3) -# define DP_TRAIN_PRE_EMPHASIS_3_5 (1 << 3) -# define DP_TRAIN_PRE_EMPHASIS_6 (2 << 3) -# define DP_TRAIN_PRE_EMPHASIS_9_5 (3 << 3) - -# define DP_TRAIN_PRE_EMPHASIS_SHIFT 3 -# define DP_TRAIN_MAX_PRE_EMPHASIS_REACHED (1 << 5) - -#define DP_DOWNSPREAD_CTRL 0x107 -# define DP_SPREAD_AMP_0_5 (1 << 4) - -#define DP_MAIN_LINK_CHANNEL_CODING_SET 0x108 -# define DP_SET_ANSI_8B10B (1 << 0) - -#define DP_LANE0_1_STATUS 0x202 -#define DP_LANE2_3_STATUS 0x203 - -# define DP_LANE_CR_DONE (1 << 0) -# define DP_LANE_CHANNEL_EQ_DONE (1 << 1) -# define DP_LANE_SYMBOL_LOCKED (1 << 2) - -#define DP_LANE_ALIGN_STATUS_UPDATED 0x204 - -#define DP_INTERLANE_ALIGN_DONE (1 << 0) -#define DP_DOWNSTREAM_PORT_STATUS_CHANGED (1 << 6) -#define DP_LINK_STATUS_UPDATED (1 << 7) - -#define DP_SINK_STATUS 0x205 - -#define DP_RECEIVE_PORT_0_STATUS (1 << 0) -#define DP_RECEIVE_PORT_1_STATUS (1 << 1) - -#define DP_ADJUST_REQUEST_LANE0_1 0x206 -#define DP_ADJUST_REQUEST_LANE2_3 0x207 - -#define DP_ADJUST_VOLTAGE_SWING_LANE0_MASK 0x03 -#define DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT 0 -#define DP_ADJUST_PRE_EMPHASIS_LANE0_MASK 0x0c -#define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT 2 -#define DP_ADJUST_VOLTAGE_SWING_LANE1_MASK 0x30 -#define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT 4 -#define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK 0xc0 -#define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT 6 - -struct i2c_algo_dp_aux_data { - bool running; - u16 address; - int (*aux_ch) (struct i2c_adapter *adapter, - uint8_t *send, int send_bytes, - uint8_t *recv, int recv_bytes); -}; - -int -i2c_dp_aux_add_bus(struct i2c_adapter *adapter); - -#endif /* _INTEL_DP_H_ */ diff --git a/trunk/drivers/gpu/drm/i915/intel_dp_i2c.c b/trunk/drivers/gpu/drm/i915/intel_dp_i2c.c deleted file mode 100644 index 4e60f14b1a6d..000000000000 --- a/trunk/drivers/gpu/drm/i915/intel_dp_i2c.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright © 2009 Keith Packard - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "intel_dp.h" - -/* Run a single AUX_CH I2C transaction, writing/reading data as necessary */ - -#define MODE_I2C_START 1 -#define MODE_I2C_WRITE 2 -#define MODE_I2C_READ 4 -#define MODE_I2C_STOP 8 - -static int -i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode, - uint8_t write_byte, uint8_t *read_byte) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - uint16_t address = algo_data->address; - uint8_t msg[5]; - uint8_t reply[2]; - int msg_bytes; - int reply_bytes; - int ret; - - /* Set up the command byte */ - if (mode & MODE_I2C_READ) - msg[0] = AUX_I2C_READ << 4; - else - msg[0] = AUX_I2C_WRITE << 4; - - if (!(mode & MODE_I2C_STOP)) - msg[0] |= AUX_I2C_MOT << 4; - - msg[1] = address >> 8; - msg[2] = address; - - switch (mode) { - case MODE_I2C_WRITE: - msg[3] = 0; - msg[4] = write_byte; - msg_bytes = 5; - reply_bytes = 1; - break; - case MODE_I2C_READ: - msg[3] = 0; - msg_bytes = 4; - reply_bytes = 2; - break; - default: - msg_bytes = 3; - reply_bytes = 1; - break; - } - - for (;;) { - ret = (*algo_data->aux_ch)(adapter, - msg, msg_bytes, - reply, reply_bytes); - if (ret < 0) { - printk(KERN_ERR "aux_ch failed %d\n", ret); - return ret; - } - switch (reply[0] & AUX_I2C_REPLY_MASK) { - case AUX_I2C_REPLY_ACK: - if (mode == MODE_I2C_READ) { - *read_byte = reply[1]; - } - return reply_bytes - 1; - case AUX_I2C_REPLY_NACK: - printk(KERN_ERR "aux_ch nack\n"); - return -EREMOTEIO; - case AUX_I2C_REPLY_DEFER: - printk(KERN_ERR "aux_ch defer\n"); - udelay(100); - break; - default: - printk(KERN_ERR "aux_ch invalid reply 0x%02x\n", reply[0]); - return -EREMOTEIO; - } - } -} - -/* - * I2C over AUX CH - */ - -/* - * Send the address. If the I2C link is running, this 'restarts' - * the connection with the new address, this is used for doing - * a write followed by a read (as needed for DDC) - */ -static int -i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - int mode = MODE_I2C_START; - int ret; - - if (reading) - mode |= MODE_I2C_READ; - else - mode |= MODE_I2C_WRITE; - algo_data->address = address; - algo_data->running = true; - ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL); - return ret; -} - -/* - * Stop the I2C transaction. This closes out the link, sending - * a bare address packet with the MOT bit turned off - */ -static void -i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - int mode = MODE_I2C_STOP; - - if (reading) - mode |= MODE_I2C_READ; - else - mode |= MODE_I2C_WRITE; - if (algo_data->running) { - (void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL); - algo_data->running = false; - } -} - -/* - * Write a single byte to the current I2C address, the - * the I2C link must be running or this returns -EIO - */ -static int -i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - int ret; - - if (!algo_data->running) - return -EIO; - - ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL); - return ret; -} - -/* - * Read a single byte from the current I2C address, the - * I2C link must be running or this returns -EIO - */ -static int -i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - int ret; - - if (!algo_data->running) - return -EIO; - - ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret); - return ret; -} - -static int -i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter, - struct i2c_msg *msgs, - int num) -{ - int ret = 0; - bool reading = false; - int m; - int b; - - for (m = 0; m < num; m++) { - u16 len = msgs[m].len; - u8 *buf = msgs[m].buf; - reading = (msgs[m].flags & I2C_M_RD) != 0; - ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading); - if (ret < 0) - break; - if (reading) { - for (b = 0; b < len; b++) { - ret = i2c_algo_dp_aux_get_byte(adapter, &buf[b]); - if (ret < 0) - break; - } - } else { - for (b = 0; b < len; b++) { - ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]); - if (ret < 0) - break; - } - } - if (ret < 0) - break; - } - if (ret >= 0) - ret = num; - i2c_algo_dp_aux_stop(adapter, reading); - printk(KERN_ERR "dp_aux_xfer return %d\n", ret); - return ret; -} - -static u32 -i2c_algo_dp_aux_functionality(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | - I2C_FUNC_SMBUS_READ_BLOCK_DATA | - I2C_FUNC_SMBUS_BLOCK_PROC_CALL | - I2C_FUNC_10BIT_ADDR; -} - -static const struct i2c_algorithm i2c_dp_aux_algo = { - .master_xfer = i2c_algo_dp_aux_xfer, - .functionality = i2c_algo_dp_aux_functionality, -}; - -static void -i2c_dp_aux_reset_bus(struct i2c_adapter *adapter) -{ - (void) i2c_algo_dp_aux_address(adapter, 0, false); - (void) i2c_algo_dp_aux_stop(adapter, false); - -} - -static int -i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter) -{ - adapter->algo = &i2c_dp_aux_algo; - adapter->retries = 3; - i2c_dp_aux_reset_bus(adapter); - return 0; -} - -int -i2c_dp_aux_add_bus(struct i2c_adapter *adapter) -{ - int error; - - error = i2c_dp_aux_prepare_bus(adapter); - if (error) - return error; - error = i2c_add_adapter(adapter); - return error; -} -EXPORT_SYMBOL(i2c_dp_aux_add_bus); diff --git a/trunk/drivers/gpu/drm/i915/intel_drv.h b/trunk/drivers/gpu/drm/i915/intel_drv.h index 004541c935a8..cd4b9c5f715e 100644 --- a/trunk/drivers/gpu/drm/i915/intel_drv.h +++ b/trunk/drivers/gpu/drm/i915/intel_drv.h @@ -54,7 +54,6 @@ #define INTEL_OUTPUT_LVDS 4 #define INTEL_OUTPUT_TVOUT 5 #define INTEL_OUTPUT_HDMI 6 -#define INTEL_OUTPUT_DISPLAYPORT 7 #define INTEL_DVO_CHIP_NONE 0 #define INTEL_DVO_CHIP_LVDS 1 @@ -66,6 +65,7 @@ struct intel_i2c_chan { u32 reg; /* GPIO reg */ struct i2c_adapter adapter; struct i2c_algo_bit_data algo; + u8 slave_addr; }; struct intel_framebuffer { @@ -79,12 +79,11 @@ struct intel_output { struct drm_encoder enc; int type; - struct i2c_adapter *i2c_bus; - struct i2c_adapter *ddc_bus; + struct intel_i2c_chan *i2c_bus; /* for control functions */ + struct intel_i2c_chan *ddc_bus; /* for DDC only stuff */ bool load_detect_temp; bool needs_tv_clock; void *dev_priv; - void (*hot_plug)(struct intel_output *); }; struct intel_crtc { @@ -105,9 +104,9 @@ struct intel_crtc { #define enc_to_intel_output(x) container_of(x, struct intel_output, enc) #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) -struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, - const char *name); -void intel_i2c_destroy(struct i2c_adapter *adapter); +struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg, + const char *name); +void intel_i2c_destroy(struct intel_i2c_chan *chan); int intel_ddc_get_modes(struct intel_output *intel_output); extern bool intel_ddc_probe(struct intel_output *intel_output); void intel_i2c_quirk_set(struct drm_device *dev, bool enable); @@ -117,10 +116,6 @@ extern bool intel_sdvo_init(struct drm_device *dev, int output_device); extern void intel_dvo_init(struct drm_device *dev); extern void intel_tv_init(struct drm_device *dev); extern void intel_lvds_init(struct drm_device *dev); -extern void intel_dp_init(struct drm_device *dev, int dp_reg); -void -intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); extern void intel_crtc_load_lut(struct drm_crtc *crtc); extern void intel_encoder_prepare (struct drm_encoder *encoder); diff --git a/trunk/drivers/gpu/drm/i915/intel_dvo.c b/trunk/drivers/gpu/drm/i915/intel_dvo.c index 13bff20930e8..1ee3007d6ec0 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_dvo.c @@ -384,9 +384,10 @@ void intel_dvo_init(struct drm_device *dev) { struct intel_output *intel_output; struct intel_dvo_device *dvo; - struct i2c_adapter *i2cbus = NULL; + struct intel_i2c_chan *i2cbus = NULL; int ret = 0; int i; + int gpio_inited = 0; int encoder_type = DRM_MODE_ENCODER_NONE; intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL); if (!intel_output) @@ -419,11 +420,14 @@ void intel_dvo_init(struct drm_device *dev) * It appears that everything is on GPIOE except for panels * on i830 laptops, which are on GPIOB (DVOA). */ - if (i2cbus != NULL) - intel_i2c_destroy(i2cbus); - if (!(i2cbus = intel_i2c_create(dev, gpio, - gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E"))) { - continue; + if (gpio_inited != gpio) { + if (i2cbus != NULL) + intel_i2c_destroy(i2cbus); + if (!(i2cbus = intel_i2c_create(dev, gpio, + gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E"))) { + continue; + } + gpio_inited = gpio; } if (dvo->dev_ops!= NULL) diff --git a/trunk/drivers/gpu/drm/i915/intel_hdmi.c b/trunk/drivers/gpu/drm/i915/intel_hdmi.c index 9e30daae37dc..4ea2a651b92c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_hdmi.c +++ b/trunk/drivers/gpu/drm/i915/intel_hdmi.c @@ -31,7 +31,6 @@ #include "drmP.h" #include "drm.h" #include "drm_crtc.h" -#include "drm_edid.h" #include "intel_drv.h" #include "i915_drm.h" #include "i915_drv.h" @@ -57,7 +56,8 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE | SDVO_VSYNC_ACTIVE_HIGH | - SDVO_HSYNC_ACTIVE_HIGH; + SDVO_HSYNC_ACTIVE_HIGH | + SDVO_NULL_PACKETS_DURING_VSYNC; if (hdmi_priv->has_hdmi_sink) sdvox |= SDVO_AUDIO_ENABLE; @@ -129,26 +129,20 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, return true; } -static enum drm_connector_status -intel_hdmi_edid_detect(struct drm_connector *connector) +static void +intel_hdmi_sink_detect(struct drm_connector *connector) { struct intel_output *intel_output = to_intel_output(connector); struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; struct edid *edid = NULL; - enum drm_connector_status status = connector_status_disconnected; edid = drm_get_edid(&intel_output->base, - intel_output->ddc_bus); - hdmi_priv->has_hdmi_sink = false; - if (edid) { - if (edid->input & DRM_EDID_INPUT_DIGITAL) { - status = connector_status_connected; - hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); - } - intel_output->base.display_info.raw_edid = NULL; + &intel_output->ddc_bus->adapter); + if (edid != NULL) { + hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); kfree(edid); + intel_output->base.display_info.raw_edid = NULL; } - return status; } static enum drm_connector_status @@ -160,7 +154,11 @@ igdng_hdmi_detect(struct drm_connector *connector) /* FIXME hotplug detect */ hdmi_priv->has_hdmi_sink = false; - return intel_hdmi_edid_detect(connector); + intel_hdmi_sink_detect(connector); + if (hdmi_priv->has_hdmi_sink) + return connector_status_connected; + else + return connector_status_disconnected; } static enum drm_connector_status @@ -203,9 +201,10 @@ intel_hdmi_detect(struct drm_connector *connector) return connector_status_unknown; } - if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0) - return intel_hdmi_edid_detect(connector); - else + if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0) { + intel_hdmi_sink_detect(connector); + return connector_status_connected; + } else return connector_status_disconnected; } diff --git a/trunk/drivers/gpu/drm/i915/intel_i2c.c b/trunk/drivers/gpu/drm/i915/intel_i2c.c index 62b8bead7652..f7061f68d050 100644 --- a/trunk/drivers/gpu/drm/i915/intel_i2c.c +++ b/trunk/drivers/gpu/drm/i915/intel_i2c.c @@ -124,7 +124,6 @@ static void set_data(void *data, int state_high) * @output: driver specific output device * @reg: GPIO reg to use * @name: name for this bus - * @slave_addr: slave address (if fixed) * * Creates and registers a new i2c bus with the Linux i2c layer, for use * in output probing and control (e.g. DDC or SDVO control functions). @@ -140,8 +139,8 @@ static void set_data(void *data, int state_high) * %GPIOH * see PRM for details on how these different busses are used. */ -struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, - const char *name) +struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg, + const char *name) { struct intel_i2c_chan *chan; @@ -175,7 +174,7 @@ struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, intel_i2c_quirk_set(dev, false); udelay(20); - return &chan->adapter; + return chan; out_free: kfree(chan); @@ -188,16 +187,11 @@ struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, * * Unregister the adapter from the i2c layer, then free the structure. */ -void intel_i2c_destroy(struct i2c_adapter *adapter) +void intel_i2c_destroy(struct intel_i2c_chan *chan) { - struct intel_i2c_chan *chan; - - if (!adapter) + if (!chan) return; - chan = container_of(adapter, - struct intel_i2c_chan, - adapter); i2c_del_adapter(&chan->adapter); kfree(chan); } diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index 9564ca44a977..f073ed8432e8 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -39,21 +39,6 @@ #define I915_LVDS "i915_lvds" -/* - * the following four scaling options are defined. - * #define DRM_MODE_SCALE_NON_GPU 0 - * #define DRM_MODE_SCALE_FULLSCREEN 1 - * #define DRM_MODE_SCALE_NO_SCALE 2 - * #define DRM_MODE_SCALE_ASPECT 3 - */ - -/* Private structure for the integrated LVDS support */ -struct intel_lvds_priv { - int fitting_mode; - u32 pfit_control; - u32 pfit_pgm_ratios; -}; - /** * Sets the backlight level. * @@ -228,27 +213,10 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - /* - * float point operation is not supported . So the PANEL_RATIO_FACTOR - * is defined, which can avoid the float point computation when - * calculating the panel ratio. - */ -#define PANEL_RATIO_FACTOR 8192 struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct drm_encoder *tmp_encoder; - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; - u32 pfit_control = 0, pfit_pgm_ratios = 0; - int left_border = 0, right_border = 0, top_border = 0; - int bottom_border = 0; - bool border = 0; - int panel_ratio, desired_ratio, vert_scale, horiz_scale; - int horiz_ratio, vert_ratio; - u32 hsync_width, vsync_width; - u32 hblank_width, vblank_width; - u32 hsync_pos, vsync_pos; /* Should never happen!! */ if (!IS_I965G(dev) && intel_crtc->pipe == 0) { @@ -264,9 +232,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, return false; } } - /* If we don't have a panel mode, there is nothing we can do */ - if (dev_priv->panel_fixed_mode == NULL) - return true; + /* * If we have timings from the BIOS for the panel, put them in * to the adjusted mode. The CRTC will be set up for this mode, @@ -290,243 +256,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); } - /* Make sure pre-965s set dither correctly */ - if (!IS_I965G(dev)) { - if (dev_priv->panel_wants_dither || dev_priv->lvds_dither) - pfit_control |= PANEL_8TO6_DITHER_ENABLE; - } - - /* Native modes don't need fitting */ - if (adjusted_mode->hdisplay == mode->hdisplay && - adjusted_mode->vdisplay == mode->vdisplay) { - pfit_pgm_ratios = 0; - border = 0; - goto out; - } - - /* 965+ wants fuzzy fitting */ - if (IS_I965G(dev)) - pfit_control |= (intel_crtc->pipe << PFIT_PIPE_SHIFT) | - PFIT_FILTER_FUZZY; - - hsync_width = adjusted_mode->crtc_hsync_end - - adjusted_mode->crtc_hsync_start; - vsync_width = adjusted_mode->crtc_vsync_end - - adjusted_mode->crtc_vsync_start; - hblank_width = adjusted_mode->crtc_hblank_end - - adjusted_mode->crtc_hblank_start; - vblank_width = adjusted_mode->crtc_vblank_end - - adjusted_mode->crtc_vblank_start; - /* - * Deal with panel fitting options. Figure out how to stretch the - * image based on its aspect ratio & the current panel fitting mode. - */ - panel_ratio = adjusted_mode->hdisplay * PANEL_RATIO_FACTOR / - adjusted_mode->vdisplay; - desired_ratio = mode->hdisplay * PANEL_RATIO_FACTOR / - mode->vdisplay; - /* - * Enable automatic panel scaling for non-native modes so that they fill - * the screen. Should be enabled before the pipe is enabled, according - * to register description and PRM. - * Change the value here to see the borders for debugging - */ - I915_WRITE(BCLRPAT_A, 0); - I915_WRITE(BCLRPAT_B, 0); - - switch (lvds_priv->fitting_mode) { - case DRM_MODE_SCALE_NO_SCALE: - /* - * For centered modes, we have to calculate border widths & - * heights and modify the values programmed into the CRTC. - */ - left_border = (adjusted_mode->hdisplay - mode->hdisplay) / 2; - right_border = left_border; - if (mode->hdisplay & 1) - right_border++; - top_border = (adjusted_mode->vdisplay - mode->vdisplay) / 2; - bottom_border = top_border; - if (mode->vdisplay & 1) - bottom_border++; - /* Set active & border values */ - adjusted_mode->crtc_hdisplay = mode->hdisplay; - /* Keep the boder be even */ - if (right_border & 1) - right_border++; - /* use the border directly instead of border minuse one */ - adjusted_mode->crtc_hblank_start = mode->hdisplay + - right_border; - /* keep the blank width constant */ - adjusted_mode->crtc_hblank_end = - adjusted_mode->crtc_hblank_start + hblank_width; - /* get the hsync pos relative to hblank start */ - hsync_pos = (hblank_width - hsync_width) / 2; - /* keep the hsync pos be even */ - if (hsync_pos & 1) - hsync_pos++; - adjusted_mode->crtc_hsync_start = - adjusted_mode->crtc_hblank_start + hsync_pos; - /* keep the hsync width constant */ - adjusted_mode->crtc_hsync_end = - adjusted_mode->crtc_hsync_start + hsync_width; - adjusted_mode->crtc_vdisplay = mode->vdisplay; - /* use the border instead of border minus one */ - adjusted_mode->crtc_vblank_start = mode->vdisplay + - bottom_border; - /* keep the vblank width constant */ - adjusted_mode->crtc_vblank_end = - adjusted_mode->crtc_vblank_start + vblank_width; - /* get the vsync start postion relative to vblank start */ - vsync_pos = (vblank_width - vsync_width) / 2; - adjusted_mode->crtc_vsync_start = - adjusted_mode->crtc_vblank_start + vsync_pos; - /* keep the vsync width constant */ - adjusted_mode->crtc_vsync_end = - adjusted_mode->crtc_vblank_start + vsync_width; - border = 1; - break; - case DRM_MODE_SCALE_ASPECT: - /* Scale but preserve the spect ratio */ - pfit_control |= PFIT_ENABLE; - if (IS_I965G(dev)) { - /* 965+ is easy, it does everything in hw */ - if (panel_ratio > desired_ratio) - pfit_control |= PFIT_SCALING_PILLAR; - else if (panel_ratio < desired_ratio) - pfit_control |= PFIT_SCALING_LETTER; - else - pfit_control |= PFIT_SCALING_AUTO; - } else { - /* - * For earlier chips we have to calculate the scaling - * ratio by hand and program it into the - * PFIT_PGM_RATIO register - */ - u32 horiz_bits, vert_bits, bits = 12; - horiz_ratio = mode->hdisplay * PANEL_RATIO_FACTOR/ - adjusted_mode->hdisplay; - vert_ratio = mode->vdisplay * PANEL_RATIO_FACTOR/ - adjusted_mode->vdisplay; - horiz_scale = adjusted_mode->hdisplay * - PANEL_RATIO_FACTOR / mode->hdisplay; - vert_scale = adjusted_mode->vdisplay * - PANEL_RATIO_FACTOR / mode->vdisplay; - - /* retain aspect ratio */ - if (panel_ratio > desired_ratio) { /* Pillar */ - u32 scaled_width; - scaled_width = mode->hdisplay * vert_scale / - PANEL_RATIO_FACTOR; - horiz_ratio = vert_ratio; - pfit_control |= (VERT_AUTO_SCALE | - VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); - /* Pillar will have left/right borders */ - left_border = (adjusted_mode->hdisplay - - scaled_width) / 2; - right_border = left_border; - if (mode->hdisplay & 1) /* odd resolutions */ - right_border++; - /* keep the border be even */ - if (right_border & 1) - right_border++; - adjusted_mode->crtc_hdisplay = scaled_width; - /* use border instead of border minus one */ - adjusted_mode->crtc_hblank_start = - scaled_width + right_border; - /* keep the hblank width constant */ - adjusted_mode->crtc_hblank_end = - adjusted_mode->crtc_hblank_start + - hblank_width; - /* - * get the hsync start pos relative to - * hblank start - */ - hsync_pos = (hblank_width - hsync_width) / 2; - /* keep the hsync_pos be even */ - if (hsync_pos & 1) - hsync_pos++; - adjusted_mode->crtc_hsync_start = - adjusted_mode->crtc_hblank_start + - hsync_pos; - /* keept hsync width constant */ - adjusted_mode->crtc_hsync_end = - adjusted_mode->crtc_hsync_start + - hsync_width; - border = 1; - } else if (panel_ratio < desired_ratio) { /* letter */ - u32 scaled_height = mode->vdisplay * - horiz_scale / PANEL_RATIO_FACTOR; - vert_ratio = horiz_ratio; - pfit_control |= (HORIZ_AUTO_SCALE | - VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); - /* Letterbox will have top/bottom border */ - top_border = (adjusted_mode->vdisplay - - scaled_height) / 2; - bottom_border = top_border; - if (mode->vdisplay & 1) - bottom_border++; - adjusted_mode->crtc_vdisplay = scaled_height; - /* use border instead of border minus one */ - adjusted_mode->crtc_vblank_start = - scaled_height + bottom_border; - /* keep the vblank width constant */ - adjusted_mode->crtc_vblank_end = - adjusted_mode->crtc_vblank_start + - vblank_width; - /* - * get the vsync start pos relative to - * vblank start - */ - vsync_pos = (vblank_width - vsync_width) / 2; - adjusted_mode->crtc_vsync_start = - adjusted_mode->crtc_vblank_start + - vsync_pos; - /* keep the vsync width constant */ - adjusted_mode->crtc_vsync_end = - adjusted_mode->crtc_vsync_start + - vsync_width; - border = 1; - } else { - /* Aspects match, Let hw scale both directions */ - pfit_control |= (VERT_AUTO_SCALE | - HORIZ_AUTO_SCALE | - VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); - } - horiz_bits = (1 << bits) * horiz_ratio / - PANEL_RATIO_FACTOR; - vert_bits = (1 << bits) * vert_ratio / - PANEL_RATIO_FACTOR; - pfit_pgm_ratios = - ((vert_bits << PFIT_VERT_SCALE_SHIFT) & - PFIT_VERT_SCALE_MASK) | - ((horiz_bits << PFIT_HORIZ_SCALE_SHIFT) & - PFIT_HORIZ_SCALE_MASK); - } - break; - - case DRM_MODE_SCALE_FULLSCREEN: - /* - * Full scaling, even if it changes the aspect ratio. - * Fortunately this is all done for us in hw. - */ - pfit_control |= PFIT_ENABLE; - if (IS_I965G(dev)) - pfit_control |= PFIT_SCALING_AUTO; - else - pfit_control |= (VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | - VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); - break; - default: - break; - } - -out: - lvds_priv->pfit_control = pfit_control; - lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios; /* * XXX: It would be nice to support lower refresh rates on the * panels to reduce power consumption, and perhaps match the @@ -572,8 +301,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, { struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); + u32 pfit_control; /* * The LVDS pin pair will already have been turned on in the @@ -590,8 +319,22 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, * screen. Should be enabled before the pipe is enabled, according to * register description and PRM. */ - I915_WRITE(PFIT_PGM_RATIOS, lvds_priv->pfit_pgm_ratios); - I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control); + if (mode->hdisplay != adjusted_mode->hdisplay || + mode->vdisplay != adjusted_mode->vdisplay) + pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE | + HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR | + HORIZ_INTERP_BILINEAR); + else + pfit_control = 0; + + if (!IS_I965G(dev)) { + if (dev_priv->panel_wants_dither || dev_priv->lvds_dither) + pfit_control |= PANEL_8TO6_DITHER_ENABLE; + } + else + pfit_control |= intel_crtc->pipe << PFIT_PIPE_SHIFT; + + I915_WRITE(PFIT_CONTROL, pfit_control); } /** @@ -663,34 +406,6 @@ static int intel_lvds_set_property(struct drm_connector *connector, struct drm_property *property, uint64_t value) { - struct drm_device *dev = connector->dev; - struct intel_output *intel_output = - to_intel_output(connector); - - if (property == dev->mode_config.scaling_mode_property && - connector->encoder) { - struct drm_crtc *crtc = connector->encoder->crtc; - struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; - if (value == DRM_MODE_SCALE_NON_GPU) { - DRM_DEBUG_KMS(I915_LVDS, - "non_GPU property is unsupported\n"); - return 0; - } - if (lvds_priv->fitting_mode == value) { - /* the LVDS scaling property is not changed */ - return 0; - } - lvds_priv->fitting_mode = value; - if (crtc && crtc->enabled) { - /* - * If the CRTC is enabled, the display will be changed - * according to the new panel fitting mode. - */ - drm_crtc_helper_set_mode(crtc, &crtc->mode, - crtc->x, crtc->y, crtc->fb); - } - } - return 0; } @@ -741,7 +456,7 @@ static const struct dmi_system_id intel_no_lvds[] = { .callback = intel_no_lvds_dmi_callback, .ident = "Apple Mac Mini (Core series)", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple"), + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), }, }, @@ -749,7 +464,7 @@ static const struct dmi_system_id intel_no_lvds[] = { .callback = intel_no_lvds_dmi_callback, .ident = "Apple Mac Mini (Core 2 series)", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple"), + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"), }, }, @@ -803,7 +518,6 @@ void intel_lvds_init(struct drm_device *dev) struct drm_encoder *encoder; struct drm_display_mode *scan; /* *modes, *bios_mode; */ struct drm_crtc *crtc; - struct intel_lvds_priv *lvds_priv; u32 lvds; int pipe, gpio = GPIOC; @@ -817,8 +531,7 @@ void intel_lvds_init(struct drm_device *dev) gpio = PCH_GPIOC; } - intel_output = kzalloc(sizeof(struct intel_output) + - sizeof(struct intel_lvds_priv), GFP_KERNEL); + intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); if (!intel_output) { return; } @@ -840,18 +553,7 @@ void intel_lvds_init(struct drm_device *dev) connector->interlace_allowed = false; connector->doublescan_allowed = false; - lvds_priv = (struct intel_lvds_priv *)(intel_output + 1); - intel_output->dev_priv = lvds_priv; - /* create the scaling mode property */ - drm_mode_create_scaling_mode_property(dev); - /* - * the initial panel fitting mode will be FULL_SCREEN. - */ - drm_connector_attach_property(&intel_output->base, - dev->mode_config.scaling_mode_property, - DRM_MODE_SCALE_FULLSCREEN); - lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN; /* * LVDS discovery: * 1) check for EDID on DDC @@ -947,5 +649,5 @@ void intel_lvds_init(struct drm_device *dev) if (intel_output->ddc_bus) intel_i2c_destroy(intel_output->ddc_bus); drm_connector_cleanup(connector); - kfree(intel_output); + kfree(connector); } diff --git a/trunk/drivers/gpu/drm/i915/intel_modes.c b/trunk/drivers/gpu/drm/i915/intel_modes.c index 67e2f4632a24..e0910fefce87 100644 --- a/trunk/drivers/gpu/drm/i915/intel_modes.c +++ b/trunk/drivers/gpu/drm/i915/intel_modes.c @@ -53,9 +53,10 @@ bool intel_ddc_probe(struct intel_output *intel_output) } }; - intel_i2c_quirk_set(intel_output->base.dev, true); - ret = i2c_transfer(intel_output->ddc_bus, msgs, 2); - intel_i2c_quirk_set(intel_output->base.dev, false); + intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, true); + ret = i2c_transfer(&intel_output->ddc_bus->adapter, msgs, 2); + intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, false); + if (ret == 2) return true; @@ -73,9 +74,10 @@ int intel_ddc_get_modes(struct intel_output *intel_output) struct edid *edid; int ret = 0; - intel_i2c_quirk_set(intel_output->base.dev, true); - edid = drm_get_edid(&intel_output->base, intel_output->ddc_bus); - intel_i2c_quirk_set(intel_output->base.dev, false); + intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, true); + edid = drm_get_edid(&intel_output->base, + &intel_output->ddc_bus->adapter); + intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, false); if (edid) { drm_mode_connector_update_edid_property(&intel_output->base, edid); diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo.c b/trunk/drivers/gpu/drm/i915/intel_sdvo.c index f03473779feb..9a00adb3a508 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo.c @@ -38,7 +38,8 @@ #undef SDVO_DEBUG #define I915_SDVO "i915_sdvo" struct intel_sdvo_priv { - u8 slave_addr; + struct intel_i2c_chan *i2c_bus; + int slaveaddr; /* Register for the SDVO device: SDVOB or SDVOC */ int output_device; @@ -145,13 +146,13 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, struct i2c_msg msgs[] = { { - .addr = sdvo_priv->slave_addr >> 1, + .addr = sdvo_priv->i2c_bus->slave_addr, .flags = 0, .len = 1, .buf = out_buf, }, { - .addr = sdvo_priv->slave_addr >> 1, + .addr = sdvo_priv->i2c_bus->slave_addr, .flags = I2C_M_RD, .len = 1, .buf = buf, @@ -161,7 +162,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, out_buf[0] = addr; out_buf[1] = 0; - if ((ret = i2c_transfer(intel_output->i2c_bus, msgs, 2)) == 2) + if ((ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2)) == 2) { *ch = buf[0]; return true; @@ -174,11 +175,10 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, u8 ch) { - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; u8 out_buf[2]; struct i2c_msg msgs[] = { { - .addr = sdvo_priv->slave_addr >> 1, + .addr = intel_output->i2c_bus->slave_addr, .flags = 0, .len = 2, .buf = out_buf, @@ -188,7 +188,7 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, out_buf[0] = addr; out_buf[1] = ch; - if (i2c_transfer(intel_output->i2c_bus, msgs, 1) == 1) + if (i2c_transfer(&intel_output->i2c_bus->adapter, msgs, 1) == 1) { return true; } @@ -1369,8 +1369,9 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; struct edid *edid = NULL; + intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); edid = drm_get_edid(&intel_output->base, - intel_output->ddc_bus); + &intel_output->ddc_bus->adapter); if (edid != NULL) { sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); kfree(edid); @@ -1548,6 +1549,7 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) { struct intel_output *intel_output = to_intel_output(connector); + struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; struct drm_i915_private *dev_priv = connector->dev->dev_private; /* @@ -1555,6 +1557,8 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) * Assume that the preferred modes are * arranged in priority order. */ + /* set the bus switch and get the modes */ + intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); intel_ddc_get_modes(intel_output); if (list_empty(&connector->probed_modes) == false) return; @@ -1705,7 +1709,7 @@ intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan) list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (to_intel_output(connector)->ddc_bus == &chan->adapter) { + if (to_intel_output(connector)->ddc_bus == chan) { intel_output = to_intel_output(connector); break; } @@ -1719,7 +1723,7 @@ static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, struct intel_output *intel_output; struct intel_sdvo_priv *sdvo_priv; struct i2c_algo_bit_data *algo_data; - const struct i2c_algorithm *algo; + struct i2c_algorithm *algo; algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; intel_output = @@ -1729,7 +1733,7 @@ static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, return -EINVAL; sdvo_priv = intel_output->dev_priv; - algo = intel_output->i2c_bus->algo; + algo = (struct i2c_algorithm *)intel_output->i2c_bus->adapter.algo; intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); return algo->master_xfer(i2c_adap, msgs, num); @@ -1781,11 +1785,13 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) struct drm_connector *connector; struct intel_output *intel_output; struct intel_sdvo_priv *sdvo_priv; - + struct intel_i2c_chan *i2cbus = NULL; + struct intel_i2c_chan *ddcbus = NULL; int connector_type; u8 ch[0x40]; int i; - int encoder_type; + int encoder_type, output_id; + u8 slave_addr; intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); if (!intel_output) { @@ -1793,24 +1799,29 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) } sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1); - sdvo_priv->output_device = output_device; - - intel_output->dev_priv = sdvo_priv; intel_output->type = INTEL_OUTPUT_SDVO; /* setup the DDC bus. */ if (output_device == SDVOB) - intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); + i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); else - intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); + i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); - if (!intel_output->i2c_bus) + if (!i2cbus) goto err_inteloutput; - sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, output_device); + slave_addr = intel_sdvo_get_slave_addr(dev, output_device); + sdvo_priv->i2c_bus = i2cbus; - /* Save the bit-banging i2c functionality for use by the DDC wrapper */ - intel_sdvo_i2c_bit_algo.functionality = intel_output->i2c_bus->algo->functionality; + if (output_device == SDVOB) { + output_id = 1; + } else { + output_id = 2; + } + sdvo_priv->i2c_bus->slave_addr = slave_addr >> 1; + sdvo_priv->output_device = output_device; + intel_output->i2c_bus = i2cbus; + intel_output->dev_priv = sdvo_priv; /* Read the regs to test if we can talk to the device */ for (i = 0; i < 0x40; i++) { @@ -1824,15 +1835,17 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) /* setup the DDC bus. */ if (output_device == SDVOB) - intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); + ddcbus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); else - intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); + ddcbus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); - if (intel_output->ddc_bus == NULL) + if (ddcbus == NULL) goto err_i2c; - /* Wrap with our custom algo which switches to DDC mode */ - intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; + intel_sdvo_i2c_bit_algo.functionality = + intel_output->i2c_bus->adapter.algo->functionality; + ddcbus->adapter.algo = &intel_sdvo_i2c_bit_algo; + intel_output->ddc_bus = ddcbus; /* In defaut case sdvo lvds is false */ sdvo_priv->is_lvds = false; @@ -1952,10 +1965,9 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) return true; err_i2c: - if (intel_output->ddc_bus != NULL) + if (ddcbus != NULL) intel_i2c_destroy(intel_output->ddc_bus); - if (intel_output->i2c_bus != NULL) - intel_i2c_destroy(intel_output->i2c_bus); + intel_i2c_destroy(intel_output->i2c_bus); err_inteloutput: kfree(intel_output); diff --git a/trunk/drivers/gpu/drm/i915/intel_tv.c b/trunk/drivers/gpu/drm/i915/intel_tv.c index a43c98e3f077..ea68992e4416 100644 --- a/trunk/drivers/gpu/drm/i915/intel_tv.c +++ b/trunk/drivers/gpu/drm/i915/intel_tv.c @@ -1383,31 +1383,34 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output) /* * Detect TV by polling) */ - save_tv_dac = tv_dac; - tv_ctl = I915_READ(TV_CTL); - save_tv_ctl = tv_ctl; - tv_ctl &= ~TV_ENC_ENABLE; - tv_ctl &= ~TV_TEST_MODE_MASK; - tv_ctl |= TV_TEST_MODE_MONITOR_DETECT; - tv_dac &= ~TVDAC_SENSE_MASK; - tv_dac &= ~DAC_A_MASK; - tv_dac &= ~DAC_B_MASK; - tv_dac &= ~DAC_C_MASK; - tv_dac |= (TVDAC_STATE_CHG_EN | - TVDAC_A_SENSE_CTL | - TVDAC_B_SENSE_CTL | - TVDAC_C_SENSE_CTL | - DAC_CTL_OVERRIDE | - DAC_A_0_7_V | - DAC_B_0_7_V | - DAC_C_0_7_V); - I915_WRITE(TV_CTL, tv_ctl); - I915_WRITE(TV_DAC, tv_dac); - intel_wait_for_vblank(dev); - tv_dac = I915_READ(TV_DAC); - I915_WRITE(TV_DAC, save_tv_dac); - I915_WRITE(TV_CTL, save_tv_ctl); - intel_wait_for_vblank(dev); + if (intel_output->load_detect_temp) { + /* TV not currently running, prod it with destructive detect */ + save_tv_dac = tv_dac; + tv_ctl = I915_READ(TV_CTL); + save_tv_ctl = tv_ctl; + tv_ctl &= ~TV_ENC_ENABLE; + tv_ctl &= ~TV_TEST_MODE_MASK; + tv_ctl |= TV_TEST_MODE_MONITOR_DETECT; + tv_dac &= ~TVDAC_SENSE_MASK; + tv_dac &= ~DAC_A_MASK; + tv_dac &= ~DAC_B_MASK; + tv_dac &= ~DAC_C_MASK; + tv_dac |= (TVDAC_STATE_CHG_EN | + TVDAC_A_SENSE_CTL | + TVDAC_B_SENSE_CTL | + TVDAC_C_SENSE_CTL | + DAC_CTL_OVERRIDE | + DAC_A_0_7_V | + DAC_B_0_7_V | + DAC_C_0_7_V); + I915_WRITE(TV_CTL, tv_ctl); + I915_WRITE(TV_DAC, tv_dac); + intel_wait_for_vblank(dev); + tv_dac = I915_READ(TV_DAC); + I915_WRITE(TV_DAC, save_tv_dac); + I915_WRITE(TV_CTL, save_tv_ctl); + intel_wait_for_vblank(dev); + } /* * A B C * 0 1 1 Composite diff --git a/trunk/drivers/gpu/drm/radeon/radeon_device.c b/trunk/drivers/gpu/drm/radeon/radeon_device.c index f97563db4e59..f30aa7274a54 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_device.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_device.c @@ -34,23 +34,6 @@ #include "radeon_asic.h" #include "atom.h" -/* - * Clear GPU surface registers. - */ -static void radeon_surface_init(struct radeon_device *rdev) -{ - /* FIXME: check this out */ - if (rdev->family < CHIP_R600) { - int i; - - for (i = 0; i < 8; i++) { - WREG32(RADEON_SURFACE0_INFO + - i * (RADEON_SURFACE1_INFO - RADEON_SURFACE0_INFO), - 0); - } - } -} - /* * GPU scratch registers helpers function. */ @@ -513,8 +496,6 @@ int radeon_device_init(struct radeon_device *rdev, radeon_errata(rdev); /* Initialize scratch registers */ radeon_scratch_init(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); /* TODO: disable VGA need to use VGA request */ /* BIOS*/ @@ -623,6 +604,9 @@ int radeon_device_init(struct radeon_device *rdev, if (r) { return r; } + if (rdev->fbdev_rfb && rdev->fbdev_rfb->obj) { + rdev->fbdev_robj = rdev->fbdev_rfb->obj->driver_private; + } if (!ret) { DRM_INFO("radeon: kernel modesetting successfully initialized.\n"); } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_drv.c b/trunk/drivers/gpu/drm/radeon/radeon_drv.c index 84ba69f48784..09c9fb9f6210 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_drv.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_drv.c @@ -345,7 +345,7 @@ static void __exit radeon_exit(void) drm_exit(driver); } -module_init(radeon_init); +late_initcall(radeon_init); module_exit(radeon_exit); MODULE_AUTHOR(DRIVER_AUTHOR); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_fb.c b/trunk/drivers/gpu/drm/radeon/radeon_fb.c index 9e8f191eb64a..fa86d398945e 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_fb.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_fb.c @@ -478,16 +478,14 @@ int radeonfb_create(struct radeon_device *rdev, { struct fb_info *info; struct radeon_fb_device *rfbdev; - struct drm_framebuffer *fb = NULL; + struct drm_framebuffer *fb; struct radeon_framebuffer *rfb; struct drm_mode_fb_cmd mode_cmd; struct drm_gem_object *gobj = NULL; struct radeon_object *robj = NULL; struct device *device = &rdev->pdev->dev; int size, aligned_size, ret; - u64 fb_gpuaddr; void *fbptr = NULL; - unsigned long tmp; mode_cmd.width = surface_width; mode_cmd.height = surface_height; @@ -500,12 +498,11 @@ int radeonfb_create(struct radeon_device *rdev, aligned_size = ALIGN(size, PAGE_SIZE); ret = radeon_gem_object_create(rdev, aligned_size, 0, - RADEON_GEM_DOMAIN_VRAM, - false, ttm_bo_type_kernel, - false, &gobj); + RADEON_GEM_DOMAIN_VRAM, + false, ttm_bo_type_kernel, + false, &gobj); if (ret) { - printk(KERN_ERR "failed to allocate framebuffer (%d %d)\n", - surface_width, surface_height); + printk(KERN_ERR "failed to allocate framebuffer\n"); ret = -ENOMEM; goto out; } @@ -518,19 +515,12 @@ int radeonfb_create(struct radeon_device *rdev, ret = -ENOMEM; goto out_unref; } - ret = radeon_object_pin(robj, RADEON_GEM_DOMAIN_VRAM, &fb_gpuaddr); - if (ret) { - printk(KERN_ERR "failed to pin framebuffer\n"); - ret = -ENOMEM; - goto out_unref; - } list_add(&fb->filp_head, &rdev->ddev->mode_config.fb_kernel_list); rfb = to_radeon_framebuffer(fb); *rfb_p = rfb; rdev->fbdev_rfb = rfb; - rdev->fbdev_robj = robj; info = framebuffer_alloc(sizeof(struct radeon_fb_device), device); if (info == NULL) { @@ -551,13 +541,13 @@ int radeonfb_create(struct radeon_device *rdev, info->fix.xpanstep = 1; /* doing it in hw */ info->fix.ypanstep = 1; /* doing it in hw */ info->fix.ywrapstep = 0; - info->fix.accel = FB_ACCEL_NONE; + info->fix.accel = FB_ACCEL_I830; info->fix.type_aux = 0; info->flags = FBINFO_DEFAULT; info->fbops = &radeonfb_ops; info->fix.line_length = fb->pitch; - tmp = fb_gpuaddr - rdev->mc.vram_location; - info->fix.smem_start = rdev->mc.aper_base + tmp; + info->screen_base = fbptr; + info->fix.smem_start = (unsigned long)fbptr; info->fix.smem_len = size; info->screen_base = fbptr; info->screen_size = size; @@ -572,8 +562,8 @@ int radeonfb_create(struct radeon_device *rdev, info->var.width = -1; info->var.xres = fb_width; info->var.yres = fb_height; - info->fix.mmio_start = 0; - info->fix.mmio_len = 0; + info->fix.mmio_start = pci_resource_start(rdev->pdev, 2); + info->fix.mmio_len = pci_resource_len(rdev->pdev, 2); info->pixmap.size = 64*1024; info->pixmap.buf_align = 8; info->pixmap.access_align = 32; @@ -654,7 +644,7 @@ int radeonfb_create(struct radeon_device *rdev, if (robj) { radeon_object_kunmap(robj); } - if (fb && ret) { + if (ret) { list_del(&fb->filp_head); drm_gem_object_unreference(gobj); drm_framebuffer_cleanup(fb); @@ -823,7 +813,6 @@ int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) robj = rfb->obj->driver_private; unregister_framebuffer(info); radeon_object_kunmap(robj); - radeon_object_unpin(robj); framebuffer_release(info); } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_object.c b/trunk/drivers/gpu/drm/radeon/radeon_object.c index bac0d06c52ac..983e8df5e000 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_object.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_object.c @@ -223,6 +223,7 @@ int radeon_object_pin(struct radeon_object *robj, uint32_t domain, { uint32_t flags; uint32_t tmp; + void *fbptr; int r; flags = radeon_object_flags_from_domain(domain); @@ -241,6 +242,10 @@ int radeon_object_pin(struct radeon_object *robj, uint32_t domain, DRM_ERROR("radeon: failed to reserve object for pinning it.\n"); return r; } + if (robj->rdev->fbdev_robj == robj) { + mutex_lock(&robj->rdev->fbdev_info->lock); + radeon_object_kunmap(robj); + } tmp = robj->tobj.mem.placement; ttm_flag_masked(&tmp, flags, TTM_PL_MASK_MEM); robj->tobj.proposed_placement = tmp | TTM_PL_FLAG_NO_EVICT | TTM_PL_MASK_CACHING; @@ -256,12 +261,23 @@ int radeon_object_pin(struct radeon_object *robj, uint32_t domain, DRM_ERROR("radeon: failed to pin object.\n"); } radeon_object_unreserve(robj); + if (robj->rdev->fbdev_robj == robj) { + if (!r) { + r = radeon_object_kmap(robj, &fbptr); + } + if (!r) { + robj->rdev->fbdev_info->screen_base = fbptr; + robj->rdev->fbdev_info->fix.smem_start = (unsigned long)fbptr; + } + mutex_unlock(&robj->rdev->fbdev_info->lock); + } return r; } void radeon_object_unpin(struct radeon_object *robj) { uint32_t flags; + void *fbptr; int r; spin_lock(&robj->tobj.lock); @@ -281,6 +297,10 @@ void radeon_object_unpin(struct radeon_object *robj) DRM_ERROR("radeon: failed to reserve object for unpinning it.\n"); return; } + if (robj->rdev->fbdev_robj == robj) { + mutex_lock(&robj->rdev->fbdev_info->lock); + radeon_object_kunmap(robj); + } flags = robj->tobj.mem.placement; robj->tobj.proposed_placement = flags & ~TTM_PL_FLAG_NO_EVICT; r = ttm_buffer_object_validate(&robj->tobj, @@ -290,6 +310,16 @@ void radeon_object_unpin(struct radeon_object *robj) DRM_ERROR("radeon: failed to unpin buffer.\n"); } radeon_object_unreserve(robj); + if (robj->rdev->fbdev_robj == robj) { + if (!r) { + r = radeon_object_kmap(robj, &fbptr); + } + if (!r) { + robj->rdev->fbdev_info->screen_base = fbptr; + robj->rdev->fbdev_info->fix.smem_start = (unsigned long)fbptr; + } + mutex_unlock(&robj->rdev->fbdev_info->lock); + } } int radeon_object_wait(struct radeon_object *robj) diff --git a/trunk/drivers/gpu/drm/ttm/ttm_bo_util.c b/trunk/drivers/gpu/drm/ttm/ttm_bo_util.c index bdec583901eb..517c84559633 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -34,6 +34,7 @@ #include #include #include +#include #include void ttm_bo_free_old_node(struct ttm_buffer_object *bo) diff --git a/trunk/drivers/gpu/drm/ttm/ttm_bo_vm.c b/trunk/drivers/gpu/drm/ttm/ttm_bo_vm.c index 40b75032ea47..27b146c54fbc 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/gpu/drm/ttm/ttm_tt.c b/trunk/drivers/gpu/drm/ttm/ttm_tt.c index 75dc8bd24592..0331fa74cd3f 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_tt.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_tt.c @@ -28,6 +28,7 @@ * Authors: Thomas Hellstrom */ +#include #include #include #include diff --git a/trunk/drivers/i2c/busses/Kconfig b/trunk/drivers/i2c/busses/Kconfig index 8206442fbabd..aa87b6a3bbef 100644 --- a/trunk/drivers/i2c/busses/Kconfig +++ b/trunk/drivers/i2c/busses/Kconfig @@ -328,7 +328,6 @@ config I2C_DAVINCI config I2C_DESIGNWARE tristate "Synopsys DesignWare" - depends on HAVE_CLK help If you say yes to this option, support will be included for the Synopsys DesignWare I2C adapter. Only master mode is supported. diff --git a/trunk/drivers/ide/cs5520.c b/trunk/drivers/ide/cs5520.c index 09f98ed0731f..bd066bb9d611 100644 --- a/trunk/drivers/ide/cs5520.c +++ b/trunk/drivers/ide/cs5520.c @@ -135,7 +135,6 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic ide_pci_setup_ports(dev, d, &hw[0], &hws[0]); hw[0].irq = 14; - hw[1].irq = 15; return ide_host_add(d, hws, 2, NULL); } diff --git a/trunk/drivers/ide/ide-acpi.c b/trunk/drivers/ide/ide-acpi.c index c509c9916464..77f79d26b264 100644 --- a/trunk/drivers/ide/ide-acpi.c +++ b/trunk/drivers/ide/ide-acpi.c @@ -92,11 +92,6 @@ int ide_acpi_init(void) return 0; } -bool ide_port_acpi(ide_hwif_t *hwif) -{ - return ide_noacpi == 0 && hwif->acpidata; -} - /** * ide_get_dev_handle - finds acpi_handle and PCI device.function * @dev: device to locate @@ -357,6 +352,9 @@ int ide_acpi_exec_tfs(ide_drive_t *drive) unsigned long gtf_address; unsigned long obj_loc; + if (ide_noacpi) + return 0; + DEBPRINT("call get_GTF, drive=%s port=%d\n", drive->name, drive->dn); ret = do_drive_get_GTF(drive, >f_length, >f_address, &obj_loc); @@ -391,6 +389,16 @@ void ide_acpi_get_timing(ide_hwif_t *hwif) struct acpi_buffer output; union acpi_object *out_obj; + if (ide_noacpi) + return; + + DEBPRINT("ENTER:\n"); + + if (!hwif->acpidata) { + DEBPRINT("no ACPI data for %s\n", hwif->name); + return; + } + /* Setting up output buffer for _GTM */ output.length = ACPI_ALLOCATE_BUFFER; output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ @@ -471,6 +479,16 @@ void ide_acpi_push_timing(ide_hwif_t *hwif) struct ide_acpi_drive_link *master = &hwif->acpidata->master; struct ide_acpi_drive_link *slave = &hwif->acpidata->slave; + if (ide_noacpi) + return; + + DEBPRINT("ENTER:\n"); + + if (!hwif->acpidata) { + DEBPRINT("no ACPI data for %s\n", hwif->name); + return; + } + /* Give the GTM buffer + drive Identify data to the channel via the * _STM method: */ /* setup input parameters buffer for _STM */ @@ -509,11 +527,16 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on) ide_drive_t *drive; int i; - if (ide_noacpi_psx) + if (ide_noacpi || ide_noacpi_psx) return; DEBPRINT("ENTER:\n"); + if (!hwif->acpidata) { + DEBPRINT("no ACPI data for %s\n", hwif->name); + return; + } + /* channel first and then drives for power on and verse versa for power off */ if (on) acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D0); @@ -593,7 +616,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif) drive->name, err); } - if (ide_noacpi || ide_acpionboot == 0) { + if (!ide_acpionboot) { DEBPRINT("ACPI methods disabled on boot\n"); return; } diff --git a/trunk/drivers/ide/ide-cd.c b/trunk/drivers/ide/ide-cd.c index 6a9a769bffc1..4a19686fcfe9 100644 --- a/trunk/drivers/ide/ide-cd.c +++ b/trunk/drivers/ide/ide-cd.c @@ -592,19 +592,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) } } else if (!blk_pc_request(rq)) { ide_cd_request_sense_fixup(drive, cmd); - + /* complain if we still have data left to transfer */ uptodate = cmd->nleft ? 0 : 1; - - /* - * suck out the remaining bytes from the drive in an - * attempt to complete the data xfer. (see BZ#13399) - */ - if (!(stat & ATA_ERR) && !uptodate && thislen) { - ide_pio_bytes(drive, cmd, write, thislen); - uptodate = cmd->nleft ? 0 : 1; - } - - if (!uptodate) + if (uptodate == 0) rq->cmd_flags |= REQ_FAILED; } goto out_end; @@ -886,12 +876,9 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, return stat; /* - * Sanity check the given block size, in so far as making - * sure the sectors_per_frame we give to the caller won't - * end up being bogus. + * Sanity check the given block size */ blocklen = be32_to_cpu(capbuf.blocklen); - blocklen = (blocklen >> SECTOR_BITS) << SECTOR_BITS; switch (blocklen) { case 512: case 1024: @@ -899,9 +886,10 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, case 4096: break; default: - printk_once(KERN_ERR PFX "%s: weird block size %u; " - "setting default block size to 2048\n", + printk(KERN_ERR PFX "%s: weird block size %u\n", drive->name, blocklen); + printk(KERN_ERR PFX "%s: default to 2kb block size\n", + drive->name); blocklen = 2048; break; } diff --git a/trunk/drivers/ide/ide-devsets.c b/trunk/drivers/ide/ide-devsets.c index 1099bf7cf968..5bf958e5b1d5 100644 --- a/trunk/drivers/ide/ide-devsets.c +++ b/trunk/drivers/ide/ide-devsets.c @@ -183,6 +183,6 @@ ide_startstop_t ide_do_devset(ide_drive_t *drive, struct request *rq) err = setfunc(drive, *(int *)&rq->cmd[1]); if (err) rq->errors = err; - ide_complete_rq(drive, err, blk_rq_bytes(rq)); + ide_complete_rq(drive, err, ide_rq_bytes(rq)); return ide_stopped; } diff --git a/trunk/drivers/ide/ide-dma.c b/trunk/drivers/ide/ide-dma.c index ee58c88dee5a..219e6fb78dc6 100644 --- a/trunk/drivers/ide/ide-dma.c +++ b/trunk/drivers/ide/ide-dma.c @@ -361,6 +361,9 @@ static int ide_tune_dma(ide_drive_t *drive) if (__ide_dma_bad_drive(drive)) return 0; + if (ide_id_dma_bug(drive)) + return 0; + if (hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA) return config_drive_for_dma(drive); @@ -391,6 +394,24 @@ static int ide_dma_check(ide_drive_t *drive) return -1; } +int ide_id_dma_bug(ide_drive_t *drive) +{ + u16 *id = drive->id; + + if (id[ATA_ID_FIELD_VALID] & 4) { + if ((id[ATA_ID_UDMA_MODES] >> 8) && + (id[ATA_ID_MWDMA_MODES] >> 8)) + goto err_out; + } else if ((id[ATA_ID_MWDMA_MODES] >> 8) && + (id[ATA_ID_SWDMA_MODES] >> 8)) + goto err_out; + + return 0; +err_out: + printk(KERN_ERR "%s: bad DMA info in identify block\n", drive->name); + return 1; +} + int ide_set_dma(ide_drive_t *drive) { int rc; diff --git a/trunk/drivers/ide/ide-eh.c b/trunk/drivers/ide/ide-eh.c index e9abf2c3c335..2b9141979613 100644 --- a/trunk/drivers/ide/ide-eh.c +++ b/trunk/drivers/ide/ide-eh.c @@ -149,7 +149,7 @@ static inline void ide_complete_drive_reset(ide_drive_t *drive, int err) if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) { if (err <= 0 && rq->errors == 0) rq->errors = -EIO; - ide_complete_rq(drive, err ? err : 0, blk_rq_bytes(rq)); + ide_complete_rq(drive, err ? err : 0, ide_rq_bytes(rq)); } } diff --git a/trunk/drivers/ide/ide-floppy.c b/trunk/drivers/ide/ide-floppy.c index fefbdfc8db06..8b3f204f7d73 100644 --- a/trunk/drivers/ide/ide-floppy.c +++ b/trunk/drivers/ide/ide-floppy.c @@ -293,7 +293,7 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, drive->failed_pc = NULL; if (blk_fs_request(rq) == 0 && rq->errors == 0) rq->errors = -EIO; - ide_complete_rq(drive, -EIO, blk_rq_bytes(rq)); + ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); return ide_stopped; } diff --git a/trunk/drivers/ide/ide-io.c b/trunk/drivers/ide/ide-io.c index d5f3c77beadd..1059f809b809 100644 --- a/trunk/drivers/ide/ide-io.c +++ b/trunk/drivers/ide/ide-io.c @@ -112,6 +112,16 @@ void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err) } } +/* obsolete, blk_rq_bytes() should be used instead */ +unsigned int ide_rq_bytes(struct request *rq) +{ + if (blk_pc_request(rq)) + return blk_rq_bytes(rq); + else + return blk_rq_cur_sectors(rq) << 9; +} +EXPORT_SYMBOL_GPL(ide_rq_bytes); + int ide_complete_rq(ide_drive_t *drive, int error, unsigned int nr_bytes) { ide_hwif_t *hwif = drive->hwif; @@ -142,14 +152,14 @@ void ide_kill_rq(ide_drive_t *drive, struct request *rq) if ((media == ide_floppy || media == ide_tape) && drv_req) { rq->errors = 0; + ide_complete_rq(drive, 0, blk_rq_bytes(rq)); } else { if (media == ide_tape) rq->errors = IDE_DRV_ERROR_GENERAL; else if (blk_fs_request(rq) == 0 && rq->errors == 0) rq->errors = -EIO; + ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); } - - ide_complete_rq(drive, -EIO, blk_rq_bytes(rq)); } static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) @@ -466,14 +476,10 @@ void do_ide_request(struct request_queue *q) if (!ide_lock_port(hwif)) { ide_hwif_t *prev_port; + + WARN_ON_ONCE(hwif->rq); repeat: prev_port = hwif->host->cur_port; - - if (drive->dev_flags & IDE_DFLAG_BLOCKED) - rq = hwif->rq; - else - WARN_ON_ONCE(hwif->rq); - if (drive->dev_flags & IDE_DFLAG_SLEEPING && time_after(drive->sleep, jiffies)) { ide_unlock_port(hwif); @@ -500,29 +506,43 @@ void do_ide_request(struct request_queue *q) hwif->cur_dev = drive; drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); - if (rq == NULL) { - spin_unlock_irq(&hwif->lock); - spin_lock_irq(q->queue_lock); - /* - * we know that the queue isn't empty, but this can - * happen if ->prep_rq_fn() decides to kill a request - */ + spin_unlock_irq(&hwif->lock); + spin_lock_irq(q->queue_lock); + /* + * we know that the queue isn't empty, but this can happen + * if the q->prep_rq_fn() decides to kill a request + */ + if (!rq) rq = blk_fetch_request(drive->queue); - spin_unlock_irq(q->queue_lock); - spin_lock_irq(&hwif->lock); - if (rq == NULL) { - ide_unlock_port(hwif); - goto out; - } + spin_unlock_irq(q->queue_lock); + spin_lock_irq(&hwif->lock); + + if (!rq) { + ide_unlock_port(hwif); + goto out; } /* * Sanity: don't accept a request that isn't a PM request - * if we are currently power managed. + * if we are currently power managed. This is very important as + * blk_stop_queue() doesn't prevent the blk_fetch_request() + * above to return us whatever is in the queue. Since we call + * ide_do_request() ourselves, we end up taking requests while + * the queue is blocked... + * + * We let requests forced at head of queue with ide-preempt + * though. I hope that doesn't happen too much, hopefully not + * unless the subdriver triggers such a thing in its own PM + * state machine. */ - BUG_ON((drive->dev_flags & IDE_DFLAG_BLOCKED) && - blk_pm_request(rq) == 0); + if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && + blk_pm_request(rq) == 0 && + (rq->cmd_flags & REQ_PREEMPT) == 0) { + /* there should be no pending command at this point */ + ide_unlock_port(hwif); + goto plug_device; + } hwif->rq = rq; diff --git a/trunk/drivers/ide/ide-ioctls.c b/trunk/drivers/ide/ide-ioctls.c index e246d3d3fbcc..82f252c3ee6e 100644 --- a/trunk/drivers/ide/ide-ioctls.c +++ b/trunk/drivers/ide/ide-ioctls.c @@ -64,8 +64,7 @@ static int ide_get_identity_ioctl(ide_drive_t *drive, unsigned int cmd, goto out; } - /* ata_id_to_hd_driveid() relies on 'id' to be fully allocated. */ - id = kmalloc(ATA_ID_WORDS * 2, GFP_KERNEL); + id = kmalloc(size, GFP_KERNEL); if (id == NULL) { rc = -ENOMEM; goto out; diff --git a/trunk/drivers/ide/ide-iops.c b/trunk/drivers/ide/ide-iops.c index 2892b242bbe1..fa047150a1c6 100644 --- a/trunk/drivers/ide/ide-iops.c +++ b/trunk/drivers/ide/ide-iops.c @@ -210,7 +210,6 @@ EXPORT_SYMBOL_GPL(ide_in_drive_list); */ static const struct drive_list_entry ivb_list[] = { { "QUANTUM FIREBALLlct10 05" , "A03.0900" }, - { "QUANTUM FIREBALLlct20 30" , "APL.0900" }, { "TSSTcorp CDDVDW SH-S202J" , "SB00" }, { "TSSTcorp CDDVDW SH-S202J" , "SB01" }, { "TSSTcorp CDDVDW SH-S202N" , "SB00" }, @@ -330,6 +329,9 @@ int ide_driveid_update(ide_drive_t *drive) kfree(id); + if ((drive->dev_flags & IDE_DFLAG_USING_DMA) && ide_id_dma_bug(drive)) + ide_dma_off(drive); + return 1; out_err: if (rc == 2) diff --git a/trunk/drivers/ide/ide-pm.c b/trunk/drivers/ide/ide-pm.c index ad7be2669dcb..c14ca144cffe 100644 --- a/trunk/drivers/ide/ide-pm.c +++ b/trunk/drivers/ide/ide-pm.c @@ -10,11 +10,9 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg) struct request_pm_state rqpm; int ret; - if (ide_port_acpi(hwif)) { - /* call ACPI _GTM only once */ - if ((drive->dn & 1) == 0 || pair == NULL) - ide_acpi_get_timing(hwif); - } + /* call ACPI _GTM only once */ + if ((drive->dn & 1) == 0 || pair == NULL) + ide_acpi_get_timing(hwif); memset(&rqpm, 0, sizeof(rqpm)); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); @@ -28,11 +26,9 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg) ret = blk_execute_rq(drive->queue, NULL, rq, 0); blk_put_request(rq); - if (ret == 0 && ide_port_acpi(hwif)) { - /* call ACPI _PS3 only after both devices are suspended */ - if ((drive->dn & 1) || pair == NULL) - ide_acpi_set_state(hwif, 0); - } + /* call ACPI _PS3 only after both devices are suspended */ + if (ret == 0 && ((drive->dn & 1) || pair == NULL)) + ide_acpi_set_state(hwif, 0); return ret; } @@ -46,16 +42,14 @@ int generic_ide_resume(struct device *dev) struct request_pm_state rqpm; int err; - if (ide_port_acpi(hwif)) { - /* call ACPI _PS0 / _STM only once */ - if ((drive->dn & 1) == 0 || pair == NULL) { - ide_acpi_set_state(hwif, 1); - ide_acpi_push_timing(hwif); - } - - ide_acpi_exec_tfs(drive); + /* call ACPI _PS0 / _STM only once */ + if ((drive->dn & 1) == 0 || pair == NULL) { + ide_acpi_set_state(hwif, 1); + ide_acpi_push_timing(hwif); } + ide_acpi_exec_tfs(drive); + memset(&rqpm, 0, sizeof(rqpm)); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_PM_RESUME; diff --git a/trunk/drivers/ide/ide-probe.c b/trunk/drivers/ide/ide-probe.c index 1bb106f6221a..51af4eea0d36 100644 --- a/trunk/drivers/ide/ide-probe.c +++ b/trunk/drivers/ide/ide-probe.c @@ -818,24 +818,6 @@ static int ide_port_setup_devices(ide_hwif_t *hwif) return j; } -static void ide_host_enable_irqs(struct ide_host *host) -{ - ide_hwif_t *hwif; - int i; - - ide_host_for_each_port(i, hwif, host) { - if (hwif == NULL) - continue; - - /* clear any pending IRQs */ - hwif->tp_ops->read_status(hwif); - - /* unmask IRQs */ - if (hwif->io_ports.ctl_addr) - hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); - } -} - /* * This routine sets up the IRQ for an IDE interface. */ @@ -849,6 +831,9 @@ static int init_irq (ide_hwif_t *hwif) if (irq_handler == NULL) irq_handler = ide_intr; + if (io_ports->ctl_addr) + hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); + if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif)) goto out_up; @@ -1419,8 +1404,6 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, ide_port_tune_devices(hwif); } - ide_host_enable_irqs(host); - ide_host_for_each_port(i, hwif, host) { if (hwif == NULL) continue; diff --git a/trunk/drivers/leds/Kconfig b/trunk/drivers/leds/Kconfig index 7c8e7122aaa9..9b60b6b684d9 100644 --- a/trunk/drivers/leds/Kconfig +++ b/trunk/drivers/leds/Kconfig @@ -75,7 +75,6 @@ config LEDS_ALIX2 depends on LEDS_CLASS && X86 && EXPERIMENTAL help This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs. - You have to set leds-alix2.force=1 for boards with Award BIOS. config LEDS_H1940 tristate "LED Support for iPAQ H1940 device" @@ -146,16 +145,15 @@ config LEDS_GPIO_OF of_platform devices. For instance, LEDs which are listed in a "dts" file. -config LEDS_LP3944 - tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip" +config LEDS_LP5521 + tristate "LED Support for the LP5521 LEDs" depends on LEDS_CLASS && I2C help - This option enables support for LEDs connected to the National - Semiconductor LP3944 Lighting Management Unit (LMU) also known as - Fun Light Chip. + If you say 'Y' here you get support for the National Semiconductor + LP5521 LED driver used in n8x0 boards. - To compile this driver as a module, choose M here: the - module will be called leds-lp3944. + This driver can be built as a module by choosing 'M'. The module + will be called leds-lp5521. config LEDS_CLEVO_MAIL tristate "Mail LED on Clevo notebook" diff --git a/trunk/drivers/leds/Makefile b/trunk/drivers/leds/Makefile index e8cdcf77a4c3..2d41c4dcf92f 100644 --- a/trunk/drivers/leds/Makefile +++ b/trunk/drivers/leds/Makefile @@ -20,7 +20,6 @@ obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o obj-$(CONFIG_LEDS_PCA9532) += leds-pca9532.o obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o -obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o obj-$(CONFIG_LEDS_FSG) += leds-fsg.o diff --git a/trunk/drivers/leds/leds-alix2.c b/trunk/drivers/leds/leds-alix2.c index 731d4eef3425..ddbd7730dfc8 100644 --- a/trunk/drivers/leds/leds-alix2.c +++ b/trunk/drivers/leds/leds-alix2.c @@ -14,7 +14,7 @@ static int force = 0; module_param(force, bool, 0444); -MODULE_PARM_DESC(force, "Assume system has ALIX.2/ALIX.3 style LEDs"); +MODULE_PARM_DESC(force, "Assume system has ALIX.2 style LEDs"); struct alix_led { struct led_classdev cdev; @@ -155,11 +155,6 @@ static int __init alix_led_init(void) goto out; } - /* enable output on GPIO for LED 1,2,3 */ - outl(1 << 6, 0x6104); - outl(1 << 9, 0x6184); - outl(1 << 11, 0x6184); - pdev = platform_device_register_simple(KBUILD_MODNAME, -1, NULL, 0); if (!IS_ERR(pdev)) { ret = platform_driver_probe(&alix_led_driver, alix_led_probe); diff --git a/trunk/drivers/leds/leds-bd2802.c b/trunk/drivers/leds/leds-bd2802.c index 779d7f262c04..4149ecb3a9b2 100644 --- a/trunk/drivers/leds/leds-bd2802.c +++ b/trunk/drivers/leds/leds-bd2802.c @@ -97,10 +97,6 @@ struct bd2802_led { enum led_ids led_id; enum led_colors color; enum led_bits state; - - /* General attributes of RGB LEDs */ - int wave_pattern; - int rgb_current; }; @@ -258,7 +254,7 @@ static void bd2802_set_on(struct bd2802_led *led, enum led_ids id, bd2802_reset_cancel(led); reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP); - bd2802_write_byte(led->client, reg, led->rgb_current); + bd2802_write_byte(led->client, reg, BD2802_CURRENT_032); reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP); bd2802_write_byte(led->client, reg, BD2802_CURRENT_000); reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN); @@ -279,9 +275,9 @@ static void bd2802_set_blink(struct bd2802_led *led, enum led_ids id, reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP); bd2802_write_byte(led->client, reg, BD2802_CURRENT_000); reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP); - bd2802_write_byte(led->client, reg, led->rgb_current); + bd2802_write_byte(led->client, reg, BD2802_CURRENT_032); reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN); - bd2802_write_byte(led->client, reg, led->wave_pattern); + bd2802_write_byte(led->client, reg, BD2802_PATTERN_HALF); bd2802_enable(led, id); bd2802_update_state(led, id, color, BD2802_BLINK); @@ -410,7 +406,7 @@ static void bd2802_enable_adv_conf(struct bd2802_led *led) ret = device_create_file(&led->client->dev, bd2802_addr_attributes[i]); if (ret) { - dev_err(&led->client->dev, "failed: sysfs file %s\n", + dev_err(&led->client->dev, "failed to sysfs file %s\n", bd2802_addr_attributes[i]->attr.name); goto failed_remove_files; } @@ -487,52 +483,6 @@ static struct device_attribute bd2802_adv_conf_attr = { .store = bd2802_store_adv_conf, }; -#define BD2802_CONTROL_ATTR(attr_name, name_str) \ -static ssize_t bd2802_show_##attr_name(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));\ - ssize_t ret; \ - down_read(&led->rwsem); \ - ret = sprintf(buf, "0x%02x\n", led->attr_name); \ - up_read(&led->rwsem); \ - return ret; \ -} \ -static ssize_t bd2802_store_##attr_name(struct device *dev, \ - struct device_attribute *attr, const char *buf, size_t count) \ -{ \ - struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));\ - unsigned long val; \ - int ret; \ - if (!count) \ - return -EINVAL; \ - ret = strict_strtoul(buf, 16, &val); \ - if (ret) \ - return ret; \ - down_write(&led->rwsem); \ - led->attr_name = val; \ - up_write(&led->rwsem); \ - return count; \ -} \ -static struct device_attribute bd2802_##attr_name##_attr = { \ - .attr = { \ - .name = name_str, \ - .mode = 0644, \ - .owner = THIS_MODULE \ - }, \ - .show = bd2802_show_##attr_name, \ - .store = bd2802_store_##attr_name, \ -}; - -BD2802_CONTROL_ATTR(wave_pattern, "wave_pattern"); -BD2802_CONTROL_ATTR(rgb_current, "rgb_current"); - -static struct device_attribute *bd2802_attributes[] = { - &bd2802_adv_conf_attr, - &bd2802_wave_pattern_attr, - &bd2802_rgb_current_attr, -}; - static void bd2802_led_work(struct work_struct *work) { struct bd2802_led *led = container_of(work, struct bd2802_led, work); @@ -588,6 +538,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) led->cdev_led1r.brightness = LED_OFF; led->cdev_led1r.brightness_set = bd2802_set_led1r_brightness; led->cdev_led1r.blink_set = bd2802_set_led1r_blink; + led->cdev_led1r.flags |= LED_CORE_SUSPENDRESUME; ret = led_classdev_register(&led->client->dev, &led->cdev_led1r); if (ret < 0) { @@ -600,6 +551,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) led->cdev_led1g.brightness = LED_OFF; led->cdev_led1g.brightness_set = bd2802_set_led1g_brightness; led->cdev_led1g.blink_set = bd2802_set_led1g_blink; + led->cdev_led1g.flags |= LED_CORE_SUSPENDRESUME; ret = led_classdev_register(&led->client->dev, &led->cdev_led1g); if (ret < 0) { @@ -612,6 +564,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) led->cdev_led1b.brightness = LED_OFF; led->cdev_led1b.brightness_set = bd2802_set_led1b_brightness; led->cdev_led1b.blink_set = bd2802_set_led1b_blink; + led->cdev_led1b.flags |= LED_CORE_SUSPENDRESUME; ret = led_classdev_register(&led->client->dev, &led->cdev_led1b); if (ret < 0) { @@ -624,6 +577,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) led->cdev_led2r.brightness = LED_OFF; led->cdev_led2r.brightness_set = bd2802_set_led2r_brightness; led->cdev_led2r.blink_set = bd2802_set_led2r_blink; + led->cdev_led2r.flags |= LED_CORE_SUSPENDRESUME; ret = led_classdev_register(&led->client->dev, &led->cdev_led2r); if (ret < 0) { @@ -636,6 +590,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) led->cdev_led2g.brightness = LED_OFF; led->cdev_led2g.brightness_set = bd2802_set_led2g_brightness; led->cdev_led2g.blink_set = bd2802_set_led2g_blink; + led->cdev_led2g.flags |= LED_CORE_SUSPENDRESUME; ret = led_classdev_register(&led->client->dev, &led->cdev_led2g); if (ret < 0) { @@ -685,7 +640,7 @@ static int __devinit bd2802_probe(struct i2c_client *client, { struct bd2802_led *led; struct bd2802_led_platform_data *pdata; - int ret, i; + int ret; led = kzalloc(sizeof(struct bd2802_led), GFP_KERNEL); if (!led) { @@ -715,20 +670,13 @@ static int __devinit bd2802_probe(struct i2c_client *client, /* To save the power, reset BD2802 after detecting */ gpio_set_value(led->pdata->reset_gpio, 0); - /* Default attributes */ - led->wave_pattern = BD2802_PATTERN_HALF; - led->rgb_current = BD2802_CURRENT_032; - init_rwsem(&led->rwsem); - for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++) { - ret = device_create_file(&led->client->dev, - bd2802_attributes[i]); - if (ret) { - dev_err(&led->client->dev, "failed: sysfs file %s\n", - bd2802_attributes[i]->attr.name); - goto failed_unregister_dev_file; - } + ret = device_create_file(&client->dev, &bd2802_adv_conf_attr); + if (ret) { + dev_err(&client->dev, "failed to create sysfs file %s\n", + bd2802_adv_conf_attr.attr.name); + goto failed_free; } ret = bd2802_register_led_classdev(led); @@ -738,8 +686,7 @@ static int __devinit bd2802_probe(struct i2c_client *client, return 0; failed_unregister_dev_file: - for (i--; i >= 0; i--) - device_remove_file(&led->client->dev, bd2802_attributes[i]); + device_remove_file(&client->dev, &bd2802_adv_conf_attr); failed_free: i2c_set_clientdata(client, NULL); kfree(led); @@ -750,14 +697,12 @@ static int __devinit bd2802_probe(struct i2c_client *client, static int __exit bd2802_remove(struct i2c_client *client) { struct bd2802_led *led = i2c_get_clientdata(client); - int i; - gpio_set_value(led->pdata->reset_gpio, 0); bd2802_unregister_led_classdev(led); + gpio_set_value(led->pdata->reset_gpio, 0); if (led->adf_on) bd2802_disable_adv_conf(led); - for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++) - device_remove_file(&led->client->dev, bd2802_attributes[i]); + device_remove_file(&client->dev, &bd2802_adv_conf_attr); i2c_set_clientdata(client, NULL); kfree(led); @@ -778,7 +723,8 @@ static int bd2802_resume(struct i2c_client *client) struct bd2802_led *led = i2c_get_clientdata(client); if (!bd2802_is_all_off(led) || led->adf_on) { - bd2802_reset_cancel(led); + gpio_set_value(led->pdata->reset_gpio, 1); + udelay(100); bd2802_restore_state(led); } @@ -816,4 +762,4 @@ module_exit(bd2802_exit); MODULE_AUTHOR("Kim Kyuwon "); MODULE_DESCRIPTION("BD2802 LED driver"); -MODULE_LICENSE("GPL v2"); +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/leds/leds-gpio.c b/trunk/drivers/leds/leds-gpio.c index 6b06638eb5b4..d2109054de85 100644 --- a/trunk/drivers/leds/leds-gpio.c +++ b/trunk/drivers/leds/leds-gpio.c @@ -76,7 +76,7 @@ static int __devinit create_gpio_led(const struct gpio_led *template, struct gpio_led_data *led_dat, struct device *parent, int (*blink_set)(unsigned, unsigned long *, unsigned long *)) { - int ret, state; + int ret; /* skip leds that aren't available */ if (!gpio_is_valid(template->gpio)) { @@ -99,15 +99,11 @@ static int __devinit create_gpio_led(const struct gpio_led *template, led_dat->cdev.blink_set = gpio_blink_set; } led_dat->cdev.brightness_set = gpio_led_set; - if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP) - state = !!gpio_get_value(led_dat->gpio) ^ led_dat->active_low; - else - state = (template->default_state == LEDS_GPIO_DEFSTATE_ON); - led_dat->cdev.brightness = state ? LED_FULL : LED_OFF; + led_dat->cdev.brightness = LED_OFF; if (!template->retain_state_suspended) led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; - ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state); + ret = gpio_direction_output(led_dat->gpio, led_dat->active_low); if (ret < 0) goto err; @@ -133,7 +129,7 @@ static void delete_gpio_led(struct gpio_led_data *led) } #ifdef CONFIG_LEDS_GPIO_PLATFORM -static int __devinit gpio_led_probe(struct platform_device *pdev) +static int gpio_led_probe(struct platform_device *pdev) { struct gpio_led_platform_data *pdata = pdev->dev.platform_data; struct gpio_led_data *leds_data; @@ -227,22 +223,12 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev, memset(&led, 0, sizeof(led)); for_each_child_of_node(np, child) { enum of_gpio_flags flags; - const char *state; led.gpio = of_get_gpio_flags(child, 0, &flags); led.active_low = flags & OF_GPIO_ACTIVE_LOW; led.name = of_get_property(child, "label", NULL) ? : child->name; led.default_trigger = of_get_property(child, "linux,default-trigger", NULL); - state = of_get_property(child, "default-state", NULL); - if (state) { - if (!strcmp(state, "keep")) - led.default_state = LEDS_GPIO_DEFSTATE_KEEP; - else if(!strcmp(state, "on")) - led.default_state = LEDS_GPIO_DEFSTATE_ON; - else - led.default_state = LEDS_GPIO_DEFSTATE_OFF; - } ret = create_gpio_led(&led, &pdata->led_data[pdata->num_leds++], &ofdev->dev, NULL); diff --git a/trunk/drivers/leds/leds-lp3944.c b/trunk/drivers/leds/leds-lp3944.c deleted file mode 100644 index 5946208ba26e..000000000000 --- a/trunk/drivers/leds/leds-lp3944.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - * leds-lp3944.c - driver for National Semiconductor LP3944 Funlight Chip - * - * Copyright (C) 2009 Antonio Ospite - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -/* - * I2C driver for National Semiconductor LP3944 Funlight Chip - * http://www.national.com/pf/LP/LP3944.html - * - * This helper chip can drive up to 8 leds, with two programmable DIM modes; - * it could even be used as a gpio expander but this driver assumes it is used - * as a led controller. - * - * The DIM modes are used to set _blink_ patterns for leds, the pattern is - * specified supplying two parameters: - * - period: from 0s to 1.6s - * - duty cycle: percentage of the period the led is on, from 0 to 100 - * - * LP3944 can be found on Motorola A910 smartphone, where it drives the rgb - * leds, the camera flash light and the displays backlights. - */ - -#include -#include -#include -#include -#include -#include - -/* Read Only Registers */ -#define LP3944_REG_INPUT1 0x00 /* LEDs 0-7 InputRegister (Read Only) */ -#define LP3944_REG_REGISTER1 0x01 /* None (Read Only) */ - -#define LP3944_REG_PSC0 0x02 /* Frequency Prescaler 0 (R/W) */ -#define LP3944_REG_PWM0 0x03 /* PWM Register 0 (R/W) */ -#define LP3944_REG_PSC1 0x04 /* Frequency Prescaler 1 (R/W) */ -#define LP3944_REG_PWM1 0x05 /* PWM Register 1 (R/W) */ -#define LP3944_REG_LS0 0x06 /* LEDs 0-3 Selector (R/W) */ -#define LP3944_REG_LS1 0x07 /* LEDs 4-7 Selector (R/W) */ - -/* These registers are not used to control leds in LP3944, they can store - * arbitrary values which the chip will ignore. - */ -#define LP3944_REG_REGISTER8 0x08 -#define LP3944_REG_REGISTER9 0x09 - -#define LP3944_DIM0 0 -#define LP3944_DIM1 1 - -/* period in ms */ -#define LP3944_PERIOD_MIN 0 -#define LP3944_PERIOD_MAX 1600 - -/* duty cycle is a percentage */ -#define LP3944_DUTY_CYCLE_MIN 0 -#define LP3944_DUTY_CYCLE_MAX 100 - -#define ldev_to_led(c) container_of(c, struct lp3944_led_data, ldev) - -/* Saved data */ -struct lp3944_led_data { - u8 id; - enum lp3944_type type; - enum lp3944_status status; - struct led_classdev ldev; - struct i2c_client *client; - struct work_struct work; -}; - -struct lp3944_data { - struct mutex lock; - struct i2c_client *client; - struct lp3944_led_data leds[LP3944_LEDS_MAX]; -}; - -static int lp3944_reg_read(struct i2c_client *client, u8 reg, u8 *value) -{ - int tmp; - - tmp = i2c_smbus_read_byte_data(client, reg); - if (tmp < 0) - return -EINVAL; - - *value = tmp; - - return 0; -} - -static int lp3944_reg_write(struct i2c_client *client, u8 reg, u8 value) -{ - return i2c_smbus_write_byte_data(client, reg, value); -} - -/** - * Set the period for DIM status - * - * @client: the i2c client - * @dim: either LP3944_DIM0 or LP3944_DIM1 - * @period: period of a blink, that is a on/off cycle, expressed in ms. - */ -static int lp3944_dim_set_period(struct i2c_client *client, u8 dim, u16 period) -{ - u8 psc_reg; - u8 psc_value; - int err; - - if (dim == LP3944_DIM0) - psc_reg = LP3944_REG_PSC0; - else if (dim == LP3944_DIM1) - psc_reg = LP3944_REG_PSC1; - else - return -EINVAL; - - /* Convert period to Prescaler value */ - if (period > LP3944_PERIOD_MAX) - return -EINVAL; - - psc_value = (period * 255) / LP3944_PERIOD_MAX; - - err = lp3944_reg_write(client, psc_reg, psc_value); - - return err; -} - -/** - * Set the duty cycle for DIM status - * - * @client: the i2c client - * @dim: either LP3944_DIM0 or LP3944_DIM1 - * @duty_cycle: percentage of a period during which a led is ON - */ -static int lp3944_dim_set_dutycycle(struct i2c_client *client, u8 dim, - u8 duty_cycle) -{ - u8 pwm_reg; - u8 pwm_value; - int err; - - if (dim == LP3944_DIM0) - pwm_reg = LP3944_REG_PWM0; - else if (dim == LP3944_DIM1) - pwm_reg = LP3944_REG_PWM1; - else - return -EINVAL; - - /* Convert duty cycle to PWM value */ - if (duty_cycle > LP3944_DUTY_CYCLE_MAX) - return -EINVAL; - - pwm_value = (duty_cycle * 255) / LP3944_DUTY_CYCLE_MAX; - - err = lp3944_reg_write(client, pwm_reg, pwm_value); - - return err; -} - -/** - * Set the led status - * - * @led: a lp3944_led_data structure - * @status: one of LP3944_LED_STATUS_OFF - * LP3944_LED_STATUS_ON - * LP3944_LED_STATUS_DIM0 - * LP3944_LED_STATUS_DIM1 - */ -static int lp3944_led_set(struct lp3944_led_data *led, u8 status) -{ - struct lp3944_data *data = i2c_get_clientdata(led->client); - u8 id = led->id; - u8 reg; - u8 val = 0; - int err; - - dev_dbg(&led->client->dev, "%s: %s, status before normalization:%d\n", - __func__, led->ldev.name, status); - - switch (id) { - case LP3944_LED0: - case LP3944_LED1: - case LP3944_LED2: - case LP3944_LED3: - reg = LP3944_REG_LS0; - break; - case LP3944_LED4: - case LP3944_LED5: - case LP3944_LED6: - case LP3944_LED7: - id -= LP3944_LED4; - reg = LP3944_REG_LS1; - break; - default: - return -EINVAL; - } - - if (status > LP3944_LED_STATUS_DIM1) - return -EINVAL; - - /* invert only 0 and 1, leave unchanged the other values, - * remember we are abusing status to set blink patterns - */ - if (led->type == LP3944_LED_TYPE_LED_INVERTED && status < 2) - status = 1 - status; - - mutex_lock(&data->lock); - lp3944_reg_read(led->client, reg, &val); - - val &= ~(LP3944_LED_STATUS_MASK << (id << 1)); - val |= (status << (id << 1)); - - dev_dbg(&led->client->dev, "%s: %s, reg:%d id:%d status:%d val:%#x\n", - __func__, led->ldev.name, reg, id, status, val); - - /* set led status */ - err = lp3944_reg_write(led->client, reg, val); - mutex_unlock(&data->lock); - - return err; -} - -static int lp3944_led_set_blink(struct led_classdev *led_cdev, - unsigned long *delay_on, - unsigned long *delay_off) -{ - struct lp3944_led_data *led = ldev_to_led(led_cdev); - u16 period; - u8 duty_cycle; - int err; - - /* units are in ms */ - if (*delay_on + *delay_off > LP3944_PERIOD_MAX) - return -EINVAL; - - if (*delay_on == 0 && *delay_off == 0) { - /* Special case: the leds subsystem requires a default user - * friendly blink pattern for the LED. Let's blink the led - * slowly (1Hz). - */ - *delay_on = 500; - *delay_off = 500; - } - - period = (*delay_on) + (*delay_off); - - /* duty_cycle is the percentage of period during which the led is ON */ - duty_cycle = 100 * (*delay_on) / period; - - /* invert duty cycle for inverted leds, this has the same effect of - * swapping delay_on and delay_off - */ - if (led->type == LP3944_LED_TYPE_LED_INVERTED) - duty_cycle = 100 - duty_cycle; - - /* NOTE: using always the first DIM mode, this means that all leds - * will have the same blinking pattern. - * - * We could find a way later to have two leds blinking in hardware - * with different patterns at the same time, falling back to software - * control for the other ones. - */ - err = lp3944_dim_set_period(led->client, LP3944_DIM0, period); - if (err) - return err; - - err = lp3944_dim_set_dutycycle(led->client, LP3944_DIM0, duty_cycle); - if (err) - return err; - - dev_dbg(&led->client->dev, "%s: OK hardware accelerated blink!\n", - __func__); - - led->status = LP3944_LED_STATUS_DIM0; - schedule_work(&led->work); - - return 0; -} - -static void lp3944_led_set_brightness(struct led_classdev *led_cdev, - enum led_brightness brightness) -{ - struct lp3944_led_data *led = ldev_to_led(led_cdev); - - dev_dbg(&led->client->dev, "%s: %s, %d\n", - __func__, led_cdev->name, brightness); - - led->status = brightness; - schedule_work(&led->work); -} - -static void lp3944_led_work(struct work_struct *work) -{ - struct lp3944_led_data *led; - - led = container_of(work, struct lp3944_led_data, work); - lp3944_led_set(led, led->status); -} - -static int lp3944_configure(struct i2c_client *client, - struct lp3944_data *data, - struct lp3944_platform_data *pdata) -{ - int i, err = 0; - - for (i = 0; i < pdata->leds_size; i++) { - struct lp3944_led *pled = &pdata->leds[i]; - struct lp3944_led_data *led = &data->leds[i]; - led->client = client; - led->id = i; - - switch (pled->type) { - - case LP3944_LED_TYPE_LED: - case LP3944_LED_TYPE_LED_INVERTED: - led->type = pled->type; - led->status = pled->status; - led->ldev.name = pled->name; - led->ldev.max_brightness = 1; - led->ldev.brightness_set = lp3944_led_set_brightness; - led->ldev.blink_set = lp3944_led_set_blink; - led->ldev.flags = LED_CORE_SUSPENDRESUME; - - INIT_WORK(&led->work, lp3944_led_work); - err = led_classdev_register(&client->dev, &led->ldev); - if (err < 0) { - dev_err(&client->dev, - "couldn't register LED %s\n", - led->ldev.name); - goto exit; - } - - /* to expose the default value to userspace */ - led->ldev.brightness = led->status; - - /* Set the default led status */ - err = lp3944_led_set(led, led->status); - if (err < 0) { - dev_err(&client->dev, - "%s couldn't set STATUS %d\n", - led->ldev.name, led->status); - goto exit; - } - break; - - case LP3944_LED_TYPE_NONE: - default: - break; - - } - } - return 0; - -exit: - if (i > 0) - for (i = i - 1; i >= 0; i--) - switch (pdata->leds[i].type) { - - case LP3944_LED_TYPE_LED: - case LP3944_LED_TYPE_LED_INVERTED: - led_classdev_unregister(&data->leds[i].ldev); - cancel_work_sync(&data->leds[i].work); - break; - - case LP3944_LED_TYPE_NONE: - default: - break; - } - - return err; -} - -static int __devinit lp3944_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct lp3944_platform_data *lp3944_pdata = client->dev.platform_data; - struct lp3944_data *data; - - if (lp3944_pdata == NULL) { - dev_err(&client->dev, "no platform data\n"); - return -EINVAL; - } - - /* Let's see whether this adapter can support what we need. */ - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA)) { - dev_err(&client->dev, "insufficient functionality!\n"); - return -ENODEV; - } - - data = kzalloc(sizeof(struct lp3944_data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->client = client; - i2c_set_clientdata(client, data); - - mutex_init(&data->lock); - - dev_info(&client->dev, "lp3944 enabled\n"); - - lp3944_configure(client, data, lp3944_pdata); - return 0; -} - -static int __devexit lp3944_remove(struct i2c_client *client) -{ - struct lp3944_platform_data *pdata = client->dev.platform_data; - struct lp3944_data *data = i2c_get_clientdata(client); - int i; - - for (i = 0; i < pdata->leds_size; i++) - switch (data->leds[i].type) { - case LP3944_LED_TYPE_LED: - case LP3944_LED_TYPE_LED_INVERTED: - led_classdev_unregister(&data->leds[i].ldev); - cancel_work_sync(&data->leds[i].work); - break; - - case LP3944_LED_TYPE_NONE: - default: - break; - } - - kfree(data); - i2c_set_clientdata(client, NULL); - - return 0; -} - -/* lp3944 i2c driver struct */ -static const struct i2c_device_id lp3944_id[] = { - {"lp3944", 0}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, lp3944_id); - -static struct i2c_driver lp3944_driver = { - .driver = { - .name = "lp3944", - }, - .probe = lp3944_probe, - .remove = __devexit_p(lp3944_remove), - .id_table = lp3944_id, -}; - -static int __init lp3944_module_init(void) -{ - return i2c_add_driver(&lp3944_driver); -} - -static void __exit lp3944_module_exit(void) -{ - i2c_del_driver(&lp3944_driver); -} - -module_init(lp3944_module_init); -module_exit(lp3944_module_exit); - -MODULE_AUTHOR("Antonio Ospite "); -MODULE_DESCRIPTION("LP3944 Fun Light Chip"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/leds/leds-pca9532.c b/trunk/drivers/leds/leds-pca9532.c index dba8921240f2..3937244fdcab 100644 --- a/trunk/drivers/leds/leds-pca9532.c +++ b/trunk/drivers/leds/leds-pca9532.c @@ -35,7 +35,7 @@ struct pca9532_data { struct pca9532_led leds[16]; struct mutex update_lock; struct input_dev *idev; - struct work_struct work; + struct work_struct work; u8 pwm[2]; u8 psc[2]; }; @@ -87,14 +87,14 @@ static int pca9532_calcpwm(struct i2c_client *client, int pwm, int blink, if (b > 0xFF) return -EINVAL; data->pwm[pwm] = b; - data->psc[pwm] = blink; - return 0; + data->psc[pwm] = blink; + return 0; } static int pca9532_setpwm(struct i2c_client *client, int pwm) { - struct pca9532_data *data = i2c_get_clientdata(client); - mutex_lock(&data->update_lock); + struct pca9532_data *data = i2c_get_clientdata(client); + mutex_lock(&data->update_lock); i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(pwm), data->pwm[pwm]); i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(pwm), @@ -132,11 +132,11 @@ static void pca9532_set_brightness(struct led_classdev *led_cdev, led->state = PCA9532_ON; else { led->state = PCA9532_PWM0; /* Thecus: hardcode one pwm */ - err = pca9532_calcpwm(led->client, 0, 0, value); + err = pca9532_calcpwm(led->client, 0, 0, value); if (err) return; /* XXX: led api doesn't allow error code? */ } - schedule_work(&led->work); + schedule_work(&led->work); } static int pca9532_set_blink(struct led_classdev *led_cdev, @@ -145,7 +145,7 @@ static int pca9532_set_blink(struct led_classdev *led_cdev, struct pca9532_led *led = ldev_to_led(led_cdev); struct i2c_client *client = led->client; int psc; - int err = 0; + int err = 0; if (*delay_on == 0 && *delay_off == 0) { /* led subsystem ask us for a blink rate */ @@ -157,11 +157,11 @@ static int pca9532_set_blink(struct led_classdev *led_cdev, /* Thecus specific: only use PSC/PWM 0 */ psc = (*delay_on * 152-1)/1000; - err = pca9532_calcpwm(client, 0, psc, led_cdev->brightness); - if (err) - return err; - schedule_work(&led->work); - return 0; + err = pca9532_calcpwm(client, 0, psc, led_cdev->brightness); + if (err) + return err; + schedule_work(&led->work); + return 0; } static int pca9532_event(struct input_dev *dev, unsigned int type, @@ -178,15 +178,15 @@ static int pca9532_event(struct input_dev *dev, unsigned int type, else data->pwm[1] = 0; - schedule_work(&data->work); + schedule_work(&data->work); - return 0; + return 0; } static void pca9532_input_work(struct work_struct *work) { - struct pca9532_data *data; - data = container_of(work, struct pca9532_data, work); + struct pca9532_data *data; + data = container_of(work, struct pca9532_data, work); mutex_lock(&data->update_lock); i2c_smbus_write_byte_data(data->client, PCA9532_REG_PWM(1), data->pwm[1]); @@ -195,11 +195,11 @@ static void pca9532_input_work(struct work_struct *work) static void pca9532_led_work(struct work_struct *work) { - struct pca9532_led *led; - led = container_of(work, struct pca9532_led, work); - if (led->state == PCA9532_PWM0) - pca9532_setpwm(led->client, 0); - pca9532_setled(led); + struct pca9532_led *led; + led = container_of(work, struct pca9532_led, work); + if (led->state == PCA9532_PWM0) + pca9532_setpwm(led->client, 0); + pca9532_setled(led); } static int pca9532_configure(struct i2c_client *client, @@ -232,7 +232,7 @@ static int pca9532_configure(struct i2c_client *client, led->ldev.brightness = LED_OFF; led->ldev.brightness_set = pca9532_set_brightness; led->ldev.blink_set = pca9532_set_blink; - INIT_WORK(&led->work, pca9532_led_work); + INIT_WORK(&led->work, pca9532_led_work); err = led_classdev_register(&client->dev, &led->ldev); if (err < 0) { dev_err(&client->dev, @@ -262,11 +262,11 @@ static int pca9532_configure(struct i2c_client *client, BIT_MASK(SND_TONE); data->idev->event = pca9532_event; input_set_drvdata(data->idev, data); - INIT_WORK(&data->work, pca9532_input_work); + INIT_WORK(&data->work, pca9532_input_work); err = input_register_device(data->idev); if (err) { input_free_device(data->idev); - cancel_work_sync(&data->work); + cancel_work_sync(&data->work); data->idev = NULL; goto exit; } @@ -283,13 +283,13 @@ static int pca9532_configure(struct i2c_client *client, break; case PCA9532_TYPE_LED: led_classdev_unregister(&data->leds[i].ldev); - cancel_work_sync(&data->leds[i].work); + cancel_work_sync(&data->leds[i].work); break; case PCA9532_TYPE_N2100_BEEP: if (data->idev != NULL) { input_unregister_device(data->idev); input_free_device(data->idev); - cancel_work_sync(&data->work); + cancel_work_sync(&data->work); data->idev = NULL; } break; @@ -340,13 +340,13 @@ static int pca9532_remove(struct i2c_client *client) break; case PCA9532_TYPE_LED: led_classdev_unregister(&data->leds[i].ldev); - cancel_work_sync(&data->leds[i].work); + cancel_work_sync(&data->leds[i].work); break; case PCA9532_TYPE_N2100_BEEP: if (data->idev != NULL) { input_unregister_device(data->idev); input_free_device(data->idev); - cancel_work_sync(&data->work); + cancel_work_sync(&data->work); data->idev = NULL; } break; diff --git a/trunk/drivers/lguest/lg.h b/trunk/drivers/lguest/lg.h index 9c3138265f8e..d4e8979735cb 100644 --- a/trunk/drivers/lguest/lg.h +++ b/trunk/drivers/lguest/lg.h @@ -82,7 +82,7 @@ struct lg_cpu { struct lg_eventfd { unsigned long addr; - struct eventfd_ctx *event; + struct file *event; }; struct lg_eventfd_map { diff --git a/trunk/drivers/lguest/lguest_user.c b/trunk/drivers/lguest/lguest_user.c index 9f9a2953b383..32e297121058 100644 --- a/trunk/drivers/lguest/lguest_user.c +++ b/trunk/drivers/lguest/lguest_user.c @@ -50,7 +50,7 @@ static int add_eventfd(struct lguest *lg, unsigned long addr, int fd) /* Now append new entry. */ new->map[new->num].addr = addr; - new->map[new->num].event = eventfd_ctx_fdget(fd); + new->map[new->num].event = eventfd_fget(fd); if (IS_ERR(new->map[new->num].event)) { kfree(new); return PTR_ERR(new->map[new->num].event); @@ -357,7 +357,7 @@ static int close(struct inode *inode, struct file *file) /* Release any eventfds they registered. */ for (i = 0; i < lg->eventfds->num; i++) - eventfd_ctx_put(lg->eventfds->map[i].event); + fput(lg->eventfds->map[i].event); kfree(lg->eventfds); /* If lg->dead doesn't contain an error code it will be NULL or a diff --git a/trunk/drivers/macintosh/macio_asic.c b/trunk/drivers/macintosh/macio_asic.c index a0f68386c12f..6e149f4a1fff 100644 --- a/trunk/drivers/macintosh/macio_asic.c +++ b/trunk/drivers/macintosh/macio_asic.c @@ -378,17 +378,6 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, dev->ofdev.dev.bus = &macio_bus_type; dev->ofdev.dev.release = macio_release_dev; -#ifdef CONFIG_PCI - /* Set the DMA ops to the ones from the PCI device, this could be - * fishy if we didn't know that on PowerMac it's always direct ops - * or iommu ops that will work fine - */ - dev->ofdev.dev.archdata.dma_ops = - chip->lbus.pdev->dev.archdata.dma_ops; - dev->ofdev.dev.archdata.dma_data = - chip->lbus.pdev->dev.archdata.dma_data; -#endif /* CONFIG_PCI */ - #ifdef DEBUG printk("preparing mdev @%p, ofdev @%p, dev @%p, kobj @%p\n", dev, &dev->ofdev, &dev->ofdev.dev, &dev->ofdev.dev.kobj); diff --git a/trunk/drivers/md/dm-exception-store.c b/trunk/drivers/md/dm-exception-store.c index 3710ff88fc10..c3ae51584b12 100644 --- a/trunk/drivers/md/dm-exception-store.c +++ b/trunk/drivers/md/dm-exception-store.c @@ -195,7 +195,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, struct dm_exception_store **store) { int r = 0; - struct dm_exception_store_type *type = NULL; + struct dm_exception_store_type *type; struct dm_exception_store *tmp_store; char persistent; @@ -211,15 +211,12 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, } persistent = toupper(*argv[1]); - if (persistent == 'P') - type = get_type("P"); - else if (persistent == 'N') - type = get_type("N"); - else { + if (persistent != 'P' && persistent != 'N') { ti->error = "Persistent flag is not P or N"; return -EINVAL; } + type = get_type(&persistent); if (!type) { ti->error = "Exception store type not recognised"; r = -EINVAL; diff --git a/trunk/drivers/md/dm-table.c b/trunk/drivers/md/dm-table.c index 2cba557d9e61..4899ebe767c8 100644 --- a/trunk/drivers/md/dm-table.c +++ b/trunk/drivers/md/dm-table.c @@ -495,7 +495,7 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev, return 0; } - if (blk_stack_limits(limits, &q->limits, start << 9) < 0) + if (blk_stack_limits(limits, &q->limits, start) < 0) DMWARN("%s: target device %s is misaligned", dm_device_name(ti->table->md), bdevname(bdev, b)); diff --git a/trunk/drivers/md/dm.c b/trunk/drivers/md/dm.c index 9acd54a5cffb..3c6d4ee8921d 100644 --- a/trunk/drivers/md/dm.c +++ b/trunk/drivers/md/dm.c @@ -1017,7 +1017,7 @@ static struct bio *split_bvec(struct bio *bio, sector_t sector, clone->bi_flags |= 1 << BIO_CLONED; if (bio_integrity(bio)) { - bio_integrity_clone(clone, bio, GFP_NOIO, bs); + bio_integrity_clone(clone, bio, GFP_NOIO); bio_integrity_trim(clone, bio_sector_offset(bio, idx, offset), len); } @@ -1045,7 +1045,7 @@ static struct bio *clone_bio(struct bio *bio, sector_t sector, clone->bi_flags &= ~(1 << BIO_SEG_VALID); if (bio_integrity(bio)) { - bio_integrity_clone(clone, bio, GFP_NOIO, bs); + bio_integrity_clone(clone, bio, GFP_NOIO); if (idx != bio->bi_idx || clone->bi_size < bio->bi_size) bio_integrity_trim(clone, diff --git a/trunk/drivers/md/linear.c b/trunk/drivers/md/linear.c index 5810fa906af0..15c8b7b25a9b 100644 --- a/trunk/drivers/md/linear.c +++ b/trunk/drivers/md/linear.c @@ -166,8 +166,8 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) rdev->sectors = sectors * mddev->chunk_sectors; } - disk_stack_limits(mddev->gendisk, rdev->bdev, - rdev->data_offset << 9); + blk_queue_stack_limits(mddev->queue, + rdev->bdev->bd_disk->queue); /* as we don't honour merge_bvec_fn, we must never risk * violating it, so limit ->max_sector to one PAGE, as * a one page request is never in violation. diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 0f4a70c43ffc..09be637d52cb 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -3573,8 +3573,7 @@ suspend_lo_store(mddev_t *mddev, const char *buf, size_t len) char *e; unsigned long long new = simple_strtoull(buf, &e, 10); - if (mddev->pers == NULL || - mddev->pers->quiesce == NULL) + if (mddev->pers->quiesce == NULL) return -EINVAL; if (buf == e || (*e && *e != '\n')) return -EINVAL; @@ -3602,8 +3601,7 @@ suspend_hi_store(mddev_t *mddev, const char *buf, size_t len) char *e; unsigned long long new = simple_strtoull(buf, &e, 10); - if (mddev->pers == NULL || - mddev->pers->quiesce == NULL) + if (mddev->pers->quiesce == NULL) return -EINVAL; if (buf == e || (*e && *e != '\n')) return -EINVAL; @@ -3846,9 +3844,11 @@ static int md_alloc(dev_t dev, char *name) flush_scheduled_work(); mutex_lock(&disks_mutex); - error = -EEXIST; - if (mddev->gendisk) - goto abort; + if (mddev->gendisk) { + mutex_unlock(&disks_mutex); + mddev_put(mddev); + return -EEXIST; + } if (name) { /* Need to ensure that 'name' is not a duplicate. @@ -3860,15 +3860,17 @@ static int md_alloc(dev_t dev, char *name) if (mddev2->gendisk && strcmp(mddev2->gendisk->disk_name, name) == 0) { spin_unlock(&all_mddevs_lock); - goto abort; + return -EEXIST; } spin_unlock(&all_mddevs_lock); } - error = -ENOMEM; mddev->queue = blk_alloc_queue(GFP_KERNEL); - if (!mddev->queue) - goto abort; + if (!mddev->queue) { + mutex_unlock(&disks_mutex); + mddev_put(mddev); + return -ENOMEM; + } mddev->queue->queuedata = mddev; /* Can be unlocked because the queue is new: no concurrency */ @@ -3878,9 +3880,11 @@ static int md_alloc(dev_t dev, char *name) disk = alloc_disk(1 << shift); if (!disk) { + mutex_unlock(&disks_mutex); blk_cleanup_queue(mddev->queue); mddev->queue = NULL; - goto abort; + mddev_put(mddev); + return -ENOMEM; } disk->major = MAJOR(mddev->unit); disk->first_minor = unit << shift; @@ -3902,22 +3906,16 @@ static int md_alloc(dev_t dev, char *name) mddev->gendisk = disk; error = kobject_init_and_add(&mddev->kobj, &md_ktype, &disk_to_dev(disk)->kobj, "%s", "md"); - if (error) { - /* This isn't possible, but as kobject_init_and_add is marked - * __must_check, we must do something with the result - */ + mutex_unlock(&disks_mutex); + if (error) printk(KERN_WARNING "md: cannot register %s/md - name in use\n", disk->disk_name); - error = 0; - } - abort: - mutex_unlock(&disks_mutex); - if (!error) { + else { kobject_uevent(&mddev->kobj, KOBJ_ADD); mddev->sysfs_state = sysfs_get_dirent(mddev->kobj.sd, "array_state"); } mddev_put(mddev); - return error; + return 0; } static struct kobject *md_probe(dev_t dev, int *part, void *data) @@ -6336,16 +6334,10 @@ void md_do_sync(mddev_t *mddev) sysfs_notify(&mddev->kobj, NULL, "sync_completed"); } - while (j >= mddev->resync_max && !kthread_should_stop()) { - /* As this condition is controlled by user-space, - * we can block indefinitely, so use '_interruptible' - * to avoid triggering warnings. - */ - flush_signals(current); /* just in case */ - wait_event_interruptible(mddev->recovery_wait, - mddev->resync_max > j - || kthread_should_stop()); - } + if (j >= mddev->resync_max) + wait_event(mddev->recovery_wait, + mddev->resync_max > j + || kthread_should_stop()); if (kthread_should_stop()) goto interrupted; diff --git a/trunk/drivers/md/multipath.c b/trunk/drivers/md/multipath.c index 237fe3fd235c..cbe368fa6598 100644 --- a/trunk/drivers/md/multipath.c +++ b/trunk/drivers/md/multipath.c @@ -294,8 +294,7 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) for (path = first; path <= last; path++) if ((p=conf->multipaths+path)->rdev == NULL) { q = rdev->bdev->bd_disk->queue; - disk_stack_limits(mddev->gendisk, rdev->bdev, - rdev->data_offset << 9); + blk_queue_stack_limits(mddev->queue, q); /* as we don't honour merge_bvec_fn, we must never risk * violating it, so limit ->max_sector to one PAGE, as @@ -464,9 +463,9 @@ static int multipath_run (mddev_t *mddev) disk = conf->multipaths + disk_idx; disk->rdev = rdev; - disk_stack_limits(mddev->gendisk, rdev->bdev, - rdev->data_offset << 9); + blk_queue_stack_limits(mddev->queue, + rdev->bdev->bd_disk->queue); /* as we don't honour merge_bvec_fn, we must never risk * violating it, not that we ever expect a device with * a merge_bvec_fn to be involved in multipath */ diff --git a/trunk/drivers/md/raid0.c b/trunk/drivers/md/raid0.c index 335f490dcad6..ab4a489d8695 100644 --- a/trunk/drivers/md/raid0.c +++ b/trunk/drivers/md/raid0.c @@ -170,8 +170,8 @@ static int create_strip_zones(mddev_t *mddev) } dev[j] = rdev1; - disk_stack_limits(mddev->gendisk, rdev1->bdev, - rdev1->data_offset << 9); + blk_queue_stack_limits(mddev->queue, + rdev1->bdev->bd_disk->queue); /* as we don't honour merge_bvec_fn, we must never risk * violating it, so limit ->max_sector to one PAGE, as * a one page request is never in violation. @@ -250,11 +250,6 @@ static int create_strip_zones(mddev_t *mddev) mddev->chunk_sectors << 9); goto abort; } - - blk_queue_io_min(mddev->queue, mddev->chunk_sectors << 9); - blk_queue_io_opt(mddev->queue, - (mddev->chunk_sectors << 9) * mddev->raid_disks); - printk(KERN_INFO "raid0: done.\n"); mddev->private = conf; return 0; diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index 0569efba0c02..89939a7aef57 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -1123,8 +1123,8 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) for (mirror = first; mirror <= last; mirror++) if ( !(p=conf->mirrors+mirror)->rdev) { - disk_stack_limits(mddev->gendisk, rdev->bdev, - rdev->data_offset << 9); + blk_queue_stack_limits(mddev->queue, + rdev->bdev->bd_disk->queue); /* as we don't honour merge_bvec_fn, we must never risk * violating it, so limit ->max_sector to one PAGE, as * a one page request is never in violation. @@ -1988,8 +1988,9 @@ static int run(mddev_t *mddev) disk = conf->mirrors + disk_idx; disk->rdev = rdev; - disk_stack_limits(mddev->gendisk, rdev->bdev, - rdev->data_offset << 9); + + blk_queue_stack_limits(mddev->queue, + rdev->bdev->bd_disk->queue); /* as we don't honour merge_bvec_fn, we must never risk * violating it, so limit ->max_sector to one PAGE, as * a one page request is never in violation. diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index 7298a5e5a183..ae12ceafe10c 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -1151,8 +1151,8 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) for ( ; mirror <= last ; mirror++) if ( !(p=conf->mirrors+mirror)->rdev) { - disk_stack_limits(mddev->gendisk, rdev->bdev, - rdev->data_offset << 9); + blk_queue_stack_limits(mddev->queue, + rdev->bdev->bd_disk->queue); /* as we don't honour merge_bvec_fn, we must never risk * violating it, so limit ->max_sector to one PAGE, as * a one page request is never in violation. @@ -2044,7 +2044,7 @@ raid10_size(mddev_t *mddev, sector_t sectors, int raid_disks) static int run(mddev_t *mddev) { conf_t *conf; - int i, disk_idx, chunk_size; + int i, disk_idx; mirror_info_t *disk; mdk_rdev_t *rdev; int nc, fc, fo; @@ -2130,14 +2130,6 @@ static int run(mddev_t *mddev) spin_lock_init(&conf->device_lock); mddev->queue->queue_lock = &conf->device_lock; - chunk_size = mddev->chunk_sectors << 9; - blk_queue_io_min(mddev->queue, chunk_size); - if (conf->raid_disks % conf->near_copies) - blk_queue_io_opt(mddev->queue, chunk_size * conf->raid_disks); - else - blk_queue_io_opt(mddev->queue, chunk_size * - (conf->raid_disks / conf->near_copies)); - list_for_each_entry(rdev, &mddev->disks, same_set) { disk_idx = rdev->raid_disk; if (disk_idx >= mddev->raid_disks @@ -2146,8 +2138,9 @@ static int run(mddev_t *mddev) disk = conf->mirrors + disk_idx; disk->rdev = rdev; - disk_stack_limits(mddev->gendisk, rdev->bdev, - rdev->data_offset << 9); + + blk_queue_stack_limits(mddev->queue, + rdev->bdev->bd_disk->queue); /* as we don't honour merge_bvec_fn, we must never risk * violating it, so limit ->max_sector to one PAGE, as * a one page request is never in violation. diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index 37835538b58e..f9f991e6e138 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -3699,21 +3699,13 @@ static int make_request(struct request_queue *q, struct bio * bi) goto retry; } } - - if (bio_data_dir(bi) == WRITE && - logical_sector >= mddev->suspend_lo && + /* FIXME what if we get a false positive because these + * are being updated. + */ + if (logical_sector >= mddev->suspend_lo && logical_sector < mddev->suspend_hi) { release_stripe(sh); - /* As the suspend_* range is controlled by - * userspace, we want an interruptible - * wait. - */ - flush_signals(current); - prepare_to_wait(&conf->wait_for_overlap, - &w, TASK_INTERRUPTIBLE); - if (logical_sector >= mddev->suspend_lo && - logical_sector < mddev->suspend_hi) - schedule(); + schedule(); goto retry; } @@ -4460,7 +4452,7 @@ static raid5_conf_t *setup_conf(mddev_t *mddev) static int run(mddev_t *mddev) { raid5_conf_t *conf; - int working_disks = 0, chunk_size; + int working_disks = 0; mdk_rdev_t *rdev; if (mddev->recovery_cp != MaxSector) @@ -4615,14 +4607,6 @@ static int run(mddev_t *mddev) md_set_array_sectors(mddev, raid5_size(mddev, 0, 0)); blk_queue_merge_bvec(mddev->queue, raid5_mergeable_bvec); - chunk_size = mddev->chunk_sectors << 9; - blk_queue_io_min(mddev->queue, chunk_size); - blk_queue_io_opt(mddev->queue, chunk_size * - (conf->raid_disks - conf->max_degraded)); - - list_for_each_entry(rdev, &mddev->disks, same_set) - disk_stack_limits(mddev->gendisk, rdev->bdev, - rdev->data_offset << 9); return 0; abort: diff --git a/trunk/drivers/mmc/host/mmc_spi.c b/trunk/drivers/mmc/host/mmc_spi.c index a461017ce5ce..240608cc7ae9 100644 --- a/trunk/drivers/mmc/host/mmc_spi.c +++ b/trunk/drivers/mmc/host/mmc_spi.c @@ -1313,12 +1313,6 @@ static int mmc_spi_probe(struct spi_device *spi) struct mmc_spi_host *host; int status; - /* We rely on full duplex transfers, mostly to reduce - * per-transfer overheads (by making fewer transfers). - */ - if (spi->master->flags & SPI_MASTER_HALF_DUPLEX) - return -EINVAL; - /* MMC and SD specs only seem to care that sampling is on the * rising edge ... meaning SPI modes 0 or 3. So either SPI mode * should be legit. We'll use mode 0 since the steady state is 0, diff --git a/trunk/drivers/mtd/cmdlinepart.c b/trunk/drivers/mtd/cmdlinepart.c index 1479da6d3aa6..5011fa73f918 100644 --- a/trunk/drivers/mtd/cmdlinepart.c +++ b/trunk/drivers/mtd/cmdlinepart.c @@ -194,7 +194,7 @@ static struct mtd_partition * newpart(char *s, parts[this_part].name = extra_mem; extra_mem += name_len + 1; - dbg(("partition %d: name <%s>, offset %llx, size %llx, mask flags %x\n", + dbg(("partition %d: name <%s>, offset %x, size %x, mask flags %x\n", this_part, parts[this_part].name, parts[this_part].offset, diff --git a/trunk/drivers/mtd/devices/m25p80.c b/trunk/drivers/mtd/devices/m25p80.c index ae5fe91867e1..59c46126a5ce 100644 --- a/trunk/drivers/mtd/devices/m25p80.c +++ b/trunk/drivers/mtd/devices/m25p80.c @@ -54,7 +54,7 @@ #define SR_SRWD 0x80 /* SR write protect */ /* Define max times to check status register before we give up. */ -#define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */ +#define MAX_READY_WAIT_JIFFIES (10 * HZ) /* eg. M25P128 specs 6s max sector erase */ #define CMD_SIZE 4 #ifdef CONFIG_M25PXX_USE_FAST_READ diff --git a/trunk/drivers/mtd/inftlcore.c b/trunk/drivers/mtd/inftlcore.c index d8cf29c01cc4..73f05227dc8c 100644 --- a/trunk/drivers/mtd/inftlcore.c +++ b/trunk/drivers/mtd/inftlcore.c @@ -226,7 +226,7 @@ static u16 INFTL_findfreeblock(struct INFTLrecord *inftl, int desperate) if (!desperate && inftl->numfreeEUNs < 2) { DEBUG(MTD_DEBUG_LEVEL1, "INFTL: there are too few free " "EUNs (%d)\n", inftl->numfreeEUNs); - return BLOCK_NIL; + return 0xffff; } /* Scan for a free block */ @@ -281,8 +281,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned silly = MAX_LOOPS; while (thisEUN < inftl->nb_blocks) { for (block = 0; block < inftl->EraseSize/SECTORSIZE; block ++) { - if ((BlockMap[block] != BLOCK_NIL) || - BlockDeleted[block]) + if ((BlockMap[block] != 0xffff) || BlockDeleted[block]) continue; if (inftl_read_oob(mtd, (thisEUN * inftl->EraseSize) @@ -526,7 +525,7 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block) if (!silly--) { printk(KERN_WARNING "INFTL: infinite loop in " "Virtual Unit Chain 0x%x\n", thisVUC); - return BLOCK_NIL; + return 0xffff; } /* Skip to next block in chain */ @@ -550,7 +549,7 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block) * waiting to be picked up. We're going to have to fold * a chain to make room. */ - thisEUN = INFTL_makefreeblock(inftl, BLOCK_NIL); + thisEUN = INFTL_makefreeblock(inftl, 0xffff); /* * Hopefully we free something, lets try again. @@ -632,7 +631,7 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block) printk(KERN_WARNING "INFTL: error folding to make room for Virtual " "Unit Chain 0x%x\n", thisVUC); - return BLOCK_NIL; + return 0xffff; } /* diff --git a/trunk/drivers/mtd/maps/integrator-flash.c b/trunk/drivers/mtd/maps/integrator-flash.c index 2aac41bde8b3..b08a798ee254 100644 --- a/trunk/drivers/mtd/maps/integrator-flash.c +++ b/trunk/drivers/mtd/maps/integrator-flash.c @@ -42,8 +42,10 @@ #include #include +#define SUBDEV_NAME_SIZE (BUS_ID_SIZE + 2) + struct armflash_subdev_info { - char *name; + char name[SUBDEV_NAME_SIZE]; struct mtd_info *mtd; struct map_info map; struct flash_platform_data *plat; @@ -132,8 +134,6 @@ static void armflash_subdev_remove(struct armflash_subdev_info *subdev) map_destroy(subdev->mtd); if (subdev->map.virt) iounmap(subdev->map.virt); - kfree(subdev->name); - subdev->name = NULL; release_mem_region(subdev->map.phys, subdev->map.size); } @@ -177,22 +177,16 @@ static int armflash_probe(struct platform_device *dev) if (nr == 1) /* No MTD concatenation, just use the default name */ - subdev->name = kstrdup(dev_name(&dev->dev), GFP_KERNEL); + snprintf(subdev->name, SUBDEV_NAME_SIZE, "%s", + dev_name(&dev->dev)); else - subdev->name = kasprintf(GFP_KERNEL, "%s-%d", - dev_name(&dev->dev), i); - if (!subdev->name) { - err = -ENOMEM; - break; - } + snprintf(subdev->name, SUBDEV_NAME_SIZE, "%s-%d", + dev_name(&dev->dev), i); subdev->plat = plat; err = armflash_subdev_probe(subdev, res); - if (err) { - kfree(subdev->name); - subdev->name = NULL; + if (err) break; - } } info->nr_subdev = i; diff --git a/trunk/drivers/mtd/nand/atmel_nand.c b/trunk/drivers/mtd/nand/atmel_nand.c index 20c828ba9405..2802992b39da 100644 --- a/trunk/drivers/mtd/nand/atmel_nand.c +++ b/trunk/drivers/mtd/nand/atmel_nand.c @@ -534,7 +534,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev) &num_partitions); if ((!partitions) || (num_partitions == 0)) { - printk(KERN_ERR "atmel_nand: No partitions defined, or unsupported device.\n"); + printk(KERN_ERR "atmel_nand: No parititions defined, or unsupported device.\n"); res = ENXIO; goto err_no_partitions; } diff --git a/trunk/drivers/mtd/nand/omap2.c b/trunk/drivers/mtd/nand/omap2.c index ebd07e95b814..0cd76f89f4b0 100644 --- a/trunk/drivers/mtd/nand/omap2.c +++ b/trunk/drivers/mtd/nand/omap2.c @@ -11,8 +11,6 @@ #include #include #include -#include -#include #include #include #include @@ -543,7 +541,7 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip) struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); unsigned long timeo = jiffies; - int status = NAND_STATUS_FAIL, state = this->state; + int status, state = this->state; if (state == FL_ERASING) timeo += (HZ * 400) / 1000; @@ -558,9 +556,8 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip) while (time_before(jiffies, timeo)) { status = __raw_readb(this->IO_ADDR_R); - if (status & NAND_STATUS_READY) + if (!(status & 0x40)) break; - cond_resched(); } return status; } diff --git a/trunk/drivers/mtd/nftlcore.c b/trunk/drivers/mtd/nftlcore.c index fb86cacd5bdb..e3f8495a94c2 100644 --- a/trunk/drivers/mtd/nftlcore.c +++ b/trunk/drivers/mtd/nftlcore.c @@ -208,7 +208,7 @@ static u16 NFTL_findfreeblock(struct NFTLrecord *nftl, int desperate ) /* Normally, we force a fold to happen before we run out of free blocks completely */ if (!desperate && nftl->numfreeEUNs < 2) { DEBUG(MTD_DEBUG_LEVEL1, "NFTL_findfreeblock: there are too few free EUNs\n"); - return BLOCK_NIL; + return 0xffff; } /* Scan for a free block */ @@ -230,11 +230,11 @@ static u16 NFTL_findfreeblock(struct NFTLrecord *nftl, int desperate ) printk("Argh! No free blocks found! LastFreeEUN = %d, " "FirstEUN = %d\n", nftl->LastFreeEUN, le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN)); - return BLOCK_NIL; + return 0xffff; } } while (pot != nftl->LastFreeEUN); - return BLOCK_NIL; + return 0xffff; } static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned pendingblock ) @@ -431,7 +431,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p /* add the header so that it is now a valid chain */ oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum = cpu_to_le16(thisVUC); - oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = BLOCK_NIL; + oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff; nftl_write_oob(mtd, (nftl->EraseSize * targetEUN) + 8, 8, &retlen, (char *)&oob.u); @@ -515,7 +515,7 @@ static u16 NFTL_makefreeblock( struct NFTLrecord *nftl , unsigned pendingblock) if (ChainLength < 2) { printk(KERN_WARNING "No Virtual Unit Chains available for folding. " "Failing request\n"); - return BLOCK_NIL; + return 0xffff; } return NFTL_foldchain (nftl, LongestChain, pendingblock); @@ -578,7 +578,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block) printk(KERN_WARNING "Infinite loop in Virtual Unit Chain 0x%x\n", thisVUC); - return BLOCK_NIL; + return 0xffff; } /* Skip to next block in chain */ @@ -601,7 +601,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block) //u16 startEUN = nftl->EUNtable[thisVUC]; //printk("Write to VirtualUnitChain %d, calling makefreeblock()\n", thisVUC); - writeEUN = NFTL_makefreeblock(nftl, BLOCK_NIL); + writeEUN = NFTL_makefreeblock(nftl, 0xffff); if (writeEUN == BLOCK_NIL) { /* OK, we accept that the above comment is @@ -673,7 +673,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block) printk(KERN_WARNING "Error folding to make room for Virtual Unit Chain 0x%x\n", thisVUC); - return BLOCK_NIL; + return 0xffff; } static int nftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block, diff --git a/trunk/drivers/net/atl1c/atl1c_ethtool.c b/trunk/drivers/net/atl1c/atl1c_ethtool.c index 607007d75b6f..e4afbd628c23 100644 --- a/trunk/drivers/net/atl1c/atl1c_ethtool.c +++ b/trunk/drivers/net/atl1c/atl1c_ethtool.c @@ -281,8 +281,6 @@ static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) if (wol->wolopts & WAKE_PHY) adapter->wol |= AT_WUFC_LNKC; - device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); - return 0; } diff --git a/trunk/drivers/net/atl1e/atl1e_ethtool.c b/trunk/drivers/net/atl1e/atl1e_ethtool.c index 4003955d7a96..619c6583e1aa 100644 --- a/trunk/drivers/net/atl1e/atl1e_ethtool.c +++ b/trunk/drivers/net/atl1e/atl1e_ethtool.c @@ -365,8 +365,6 @@ static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) if (wol->wolopts & WAKE_PHY) adapter->wol |= AT_WUFC_LNKC; - device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); - return 0; } diff --git a/trunk/drivers/net/benet/be.h b/trunk/drivers/net/benet/be.h index 5b4bf3d2cdc2..f703758f0a6e 100644 --- a/trunk/drivers/net/benet/be.h +++ b/trunk/drivers/net/benet/be.h @@ -73,7 +73,7 @@ static inline char *nic_name(struct pci_dev *pdev) #define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST) #define BE_MAX_LRO_DESCRIPTORS 16 -#define BE_MAX_FRAGS_PER_FRAME (min((u32) 16, (u32) MAX_SKB_FRAGS)) +#define BE_MAX_FRAGS_PER_FRAME 16 struct be_dma_mem { void *va; diff --git a/trunk/drivers/net/benet/be_ethtool.c b/trunk/drivers/net/benet/be_ethtool.c index cccc5419ad72..9592f22e4c8c 100644 --- a/trunk/drivers/net/benet/be_ethtool.c +++ b/trunk/drivers/net/benet/be_ethtool.c @@ -162,8 +162,8 @@ be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) return -EINVAL; adapter->max_rx_coal = coalesce->rx_max_coalesced_frames; - if (adapter->max_rx_coal > BE_MAX_FRAGS_PER_FRAME) - adapter->max_rx_coal = BE_MAX_FRAGS_PER_FRAME; + if (adapter->max_rx_coal > MAX_SKB_FRAGS) + adapter->max_rx_coal = MAX_SKB_FRAGS - 1; /* if AIC is being turned on now, start with an EQD of 0 */ if (rx_eq->enable_aic == 0 && diff --git a/trunk/drivers/net/benet/be_main.c b/trunk/drivers/net/benet/be_main.c index 308eb09ca56b..66c10c87f517 100644 --- a/trunk/drivers/net/benet/be_main.c +++ b/trunk/drivers/net/benet/be_main.c @@ -666,7 +666,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, { struct be_queue_info *rxq = &adapter->rx_obj.q; struct be_rx_page_info *page_info; - u16 rxq_idx, i, num_rcvd, j; + u16 rxq_idx, i, num_rcvd; u32 pktsize, hdr_len, curr_frag_len; u8 *start; @@ -709,33 +709,22 @@ static void skb_fill_rx_data(struct be_adapter *adapter, /* More frags present for this completion */ pktsize -= curr_frag_len; /* account for above copied frag */ - for (i = 1, j = 0; i < num_rcvd; i++) { + for (i = 1; i < num_rcvd; i++) { index_inc(&rxq_idx, rxq->len); page_info = get_rx_page_info(adapter, rxq_idx); curr_frag_len = min(pktsize, rx_frag_size); - /* Coalesce all frags from the same physical page in one slot */ - if (page_info->page_offset == 0) { - /* Fresh page */ - j++; - skb_shinfo(skb)->frags[j].page = page_info->page; - skb_shinfo(skb)->frags[j].page_offset = - page_info->page_offset; - skb_shinfo(skb)->frags[j].size = 0; - skb_shinfo(skb)->nr_frags++; - } else { - put_page(page_info->page); - } - - skb_shinfo(skb)->frags[j].size += curr_frag_len; + skb_shinfo(skb)->frags[i].page = page_info->page; + skb_shinfo(skb)->frags[i].page_offset = page_info->page_offset; + skb_shinfo(skb)->frags[i].size = curr_frag_len; skb->len += curr_frag_len; skb->data_len += curr_frag_len; + skb_shinfo(skb)->nr_frags++; pktsize -= curr_frag_len; memset(page_info, 0, sizeof(*page_info)); } - BUG_ON(j > MAX_SKB_FRAGS); done: be_rx_stats_update(adapter, pktsize, num_rcvd); @@ -797,7 +786,7 @@ static void be_rx_compl_process_lro(struct be_adapter *adapter, struct skb_frag_struct rx_frags[BE_MAX_FRAGS_PER_FRAME]; struct be_queue_info *rxq = &adapter->rx_obj.q; u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; - u16 i, rxq_idx = 0, vid, j; + u16 i, rxq_idx = 0, vid; num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); @@ -805,28 +794,20 @@ static void be_rx_compl_process_lro(struct be_adapter *adapter, rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); remaining = pkt_size; - for (i = 0, j = -1; i < num_rcvd; i++) { + for (i = 0; i < num_rcvd; i++) { page_info = get_rx_page_info(adapter, rxq_idx); curr_frag_len = min(remaining, rx_frag_size); - /* Coalesce all frags from the same physical page in one slot */ - if (i == 0 || page_info->page_offset == 0) { - /* First frag or Fresh page */ - j++; - rx_frags[j].page = page_info->page; - rx_frags[j].page_offset = page_info->page_offset; - rx_frags[j].size = 0; - } else { - put_page(page_info->page); - } - rx_frags[j].size += curr_frag_len; - + rx_frags[i].page = page_info->page; + rx_frags[i].page_offset = page_info->page_offset; + rx_frags[i].size = curr_frag_len; remaining -= curr_frag_len; + index_inc(&rxq_idx, rxq->len); + memset(page_info, 0, sizeof(*page_info)); } - BUG_ON(j > MAX_SKB_FRAGS); if (likely(!vlanf)) { lro_receive_frags(&adapter->rx_obj.lro_mgr, rx_frags, pkt_size, diff --git a/trunk/drivers/net/bnx2x_main.c b/trunk/drivers/net/bnx2x_main.c index 951714a7f90a..fbf1352e9c1c 100644 --- a/trunk/drivers/net/bnx2x_main.c +++ b/trunk/drivers/net/bnx2x_main.c @@ -8637,14 +8637,6 @@ static int bnx2x_nway_reset(struct net_device *dev) return 0; } -static u32 -bnx2x_get_link(struct net_device *dev) -{ - struct bnx2x *bp = netdev_priv(dev); - - return bp->link_vars.link_up; -} - static int bnx2x_get_eeprom_len(struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); @@ -10042,7 +10034,7 @@ static struct ethtool_ops bnx2x_ethtool_ops = { .get_msglevel = bnx2x_get_msglevel, .set_msglevel = bnx2x_set_msglevel, .nway_reset = bnx2x_nway_reset, - .get_link = bnx2x_get_link, + .get_link = ethtool_op_get_link, .get_eeprom_len = bnx2x_get_eeprom_len, .get_eeprom = bnx2x_get_eeprom, .set_eeprom = bnx2x_set_eeprom, diff --git a/trunk/drivers/net/cpmac.c b/trunk/drivers/net/cpmac.c index fd5e32cbcb87..58afafbd3b9c 100644 --- a/trunk/drivers/net/cpmac.c +++ b/trunk/drivers/net/cpmac.c @@ -1097,7 +1097,7 @@ static const struct net_device_ops cpmac_netdev_ops = { .ndo_start_xmit = cpmac_start_xmit, .ndo_tx_timeout = cpmac_tx_timeout, .ndo_set_multicast_list = cpmac_set_multicast_list, - .ndo_do_ioctl = cpmac_ioctl, + .ndo_so_ioctl = cpmac_ioctl, .ndo_set_config = cpmac_config, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index 5b8cbdb4b520..5e3356f8eb5a 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -2185,16 +2185,12 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter, /* Free all the Rx ring sk_buffs */ for (i = 0; i < rx_ring->count; i++) { buffer_info = &rx_ring->buffer_info[i]; - if (buffer_info->dma) { + if (buffer_info->skb) { pci_unmap_single(pdev, buffer_info->dma, buffer_info->length, PCI_DMA_FROMDEVICE); - } - - buffer_info->dma = 0; - if (buffer_info->skb) { dev_kfree_skb(buffer_info->skb); buffer_info->skb = NULL; } @@ -4037,7 +4033,6 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, buffer_info->dma, buffer_info->length, PCI_DMA_FROMDEVICE); - buffer_info->dma = 0; length = le16_to_cpu(rx_desc->length); /* !EOP means multiple descriptors were used to store a single @@ -4227,7 +4222,6 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, pci_unmap_single(pdev, buffer_info->dma, adapter->rx_buffer_len, PCI_DMA_FROMDEVICE); - buffer_info->dma = 0; break; /* while !buffer_info->skb */ } @@ -4823,9 +4817,6 @@ static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, netif_device_detach(netdev); - if (state == pci_channel_io_perm_failure) - return PCI_ERS_RESULT_DISCONNECT; - if (netif_running(netdev)) e1000_down(adapter); pci_disable_device(pdev); diff --git a/trunk/drivers/net/e1000e/netdev.c b/trunk/drivers/net/e1000e/netdev.c index 63415bb6f48f..679885a122b4 100644 --- a/trunk/drivers/net/e1000e/netdev.c +++ b/trunk/drivers/net/e1000e/netdev.c @@ -4785,9 +4785,6 @@ static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, netif_device_detach(netdev); - if (state == pci_channel_io_perm_failure) - return PCI_ERS_RESULT_DISCONNECT; - if (netif_running(netdev)) e1000e_down(adapter); pci_disable_device(pdev); diff --git a/trunk/drivers/net/fsl_pq_mdio.c b/trunk/drivers/net/fsl_pq_mdio.c index d167090248e2..3af581303ca2 100644 --- a/trunk/drivers/net/fsl_pq_mdio.c +++ b/trunk/drivers/net/fsl_pq_mdio.c @@ -188,7 +188,7 @@ static int fsl_pq_mdio_find_free(struct mii_bus *new_bus) } -#if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) +#ifdef CONFIG_GIANFAR static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs) { struct gfar __iomem *enet_regs; @@ -206,7 +206,7 @@ static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs) #endif -#if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) +#ifdef CONFIG_UCC_GETH static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id) { struct device_node *np = NULL; @@ -291,7 +291,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, if (of_device_is_compatible(np, "fsl,gianfar-mdio") || of_device_is_compatible(np, "fsl,gianfar-tbi") || of_device_is_compatible(np, "gianfar")) { -#if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) +#ifdef CONFIG_GIANFAR tbipa = get_gfar_tbipa(regs); #else err = -ENODEV; @@ -299,7 +299,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, #endif } else if (of_device_is_compatible(np, "fsl,ucc-mdio") || of_device_is_compatible(np, "ucc_geth_phy")) { -#if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) +#ifdef CONFIG_UCC_GETH u32 id; static u32 mii_mng_master; diff --git a/trunk/drivers/net/igb/igb_main.c b/trunk/drivers/net/igb/igb_main.c index be480292aba1..ea17319624aa 100644 --- a/trunk/drivers/net/igb/igb_main.c +++ b/trunk/drivers/net/igb/igb_main.c @@ -4549,12 +4549,11 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring, cleaned = true; cleaned_count++; - /* this is the fast path for the non-packet split case */ if (!adapter->rx_ps_hdr_size) { pci_unmap_single(pdev, buffer_info->dma, - adapter->rx_buffer_len, + adapter->rx_buffer_len + + NET_IP_ALIGN, PCI_DMA_FROMDEVICE); - buffer_info->dma = 0; skb_put(skb, length); goto send_up; } @@ -4571,9 +4570,8 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring, if (!skb_shinfo(skb)->nr_frags) { pci_unmap_single(pdev, buffer_info->dma, - adapter->rx_ps_hdr_size, + adapter->rx_ps_hdr_size + NET_IP_ALIGN, PCI_DMA_FROMDEVICE); - buffer_info->dma = 0; skb_put(skb, hlen); } @@ -4715,6 +4713,7 @@ static void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, bufsz = adapter->rx_ps_hdr_size; else bufsz = adapter->rx_buffer_len; + bufsz += NET_IP_ALIGN; while (cleaned_count--) { rx_desc = E1000_RX_DESC_ADV(*rx_ring, i); @@ -4738,7 +4737,7 @@ static void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, } if (!buffer_info->skb) { - skb = netdev_alloc_skb(netdev, bufsz + NET_IP_ALIGN); + skb = netdev_alloc_skb(netdev, bufsz); if (!skb) { adapter->alloc_rx_buff_failed++; goto no_buffers; @@ -5339,9 +5338,6 @@ static pci_ers_result_t igb_io_error_detected(struct pci_dev *pdev, netif_device_detach(netdev); - if (state == pci_channel_io_perm_failure) - return PCI_ERS_RESULT_DISCONNECT; - if (netif_running(netdev)) igb_down(adapter); pci_disable_device(pdev); diff --git a/trunk/drivers/net/irda/bfin_sir.c b/trunk/drivers/net/irda/bfin_sir.c index 911c082cee5a..f3eed6a8fba5 100644 --- a/trunk/drivers/net/irda/bfin_sir.c +++ b/trunk/drivers/net/irda/bfin_sir.c @@ -677,14 +677,6 @@ static int bfin_sir_init_iobuf(iobuff_t *io, int size) return 0; } -static const struct net_device_ops bfin_sir_ndo = { - .ndo_open = bfin_sir_open, - .ndo_stop = bfin_sir_stop, - .ndo_start_xmit = bfin_sir_hard_xmit, - .ndo_do_ioctl = bfin_sir_ioctl, - .ndo_get_stats = bfin_sir_stats, -}; - static int __devinit bfin_sir_probe(struct platform_device *pdev) { struct net_device *dev; @@ -726,8 +718,12 @@ static int __devinit bfin_sir_probe(struct platform_device *pdev) if (err) goto err_mem_3; - dev->netdev_ops = &bfin_sir_ndo; - dev->irq = sir_port->irq; + dev->hard_start_xmit = bfin_sir_hard_xmit; + dev->open = bfin_sir_open; + dev->stop = bfin_sir_stop; + dev->do_ioctl = bfin_sir_ioctl; + dev->get_stats = bfin_sir_stats; + dev->irq = sir_port->irq; irda_init_max_qos_capabilies(&self->qos); diff --git a/trunk/drivers/net/ixgbe/ixgbe_ethtool.c b/trunk/drivers/net/ixgbe/ixgbe_ethtool.c index 0f7b6a3a2e68..86f4f3e36f27 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/trunk/drivers/net/ixgbe/ixgbe_ethtool.c @@ -139,7 +139,7 @@ static int ixgbe_get_settings(struct net_device *netdev, ecmd->autoneg = AUTONEG_ENABLE; ecmd->transceiver = XCVR_EXTERNAL; if ((hw->phy.media_type == ixgbe_media_type_copper) || - (hw->phy.multispeed_fiber)) { + (hw->mac.type == ixgbe_mac_82599EB)) { ecmd->supported |= (SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg); @@ -217,7 +217,7 @@ static int ixgbe_set_settings(struct net_device *netdev, s32 err = 0; if ((hw->phy.media_type == ixgbe_media_type_copper) || - (hw->phy.multispeed_fiber)) { + (hw->mac.type == ixgbe_mac_82599EB)) { /* 10000/copper and 1000/copper must autoneg * this function does not support any duplex forcing, but can * limit the advertising of the adapter to only 10000 or 1000 */ @@ -245,7 +245,6 @@ static int ixgbe_set_settings(struct net_device *netdev, } else { /* in this case we currently only support 10Gb/FULL */ if ((ecmd->autoneg == AUTONEG_ENABLE) || - (ecmd->advertising != ADVERTISED_10000baseT_Full) || (ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)) return -EINVAL; } diff --git a/trunk/drivers/net/ixgbe/ixgbe_main.c b/trunk/drivers/net/ixgbe/ixgbe_main.c index 5588ef493a3d..e756e220db32 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ixgbe/ixgbe_main.c @@ -563,6 +563,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, union ixgbe_adv_rx_desc *rx_desc; struct ixgbe_rx_buffer *bi; unsigned int i; + unsigned int bufsz = rx_ring->rx_buf_len + NET_IP_ALIGN; i = rx_ring->next_to_use; bi = &rx_ring->rx_buffer_info[i]; @@ -592,9 +593,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, if (!bi->skb) { struct sk_buff *skb; - skb = netdev_alloc_skb(adapter->netdev, - (rx_ring->rx_buf_len + - NET_IP_ALIGN)); + skb = netdev_alloc_skb(adapter->netdev, bufsz); if (!skb) { adapter->alloc_rx_buff_failed++; @@ -609,8 +608,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, skb_reserve(skb, NET_IP_ALIGN); bi->skb = skb; - bi->dma = pci_map_single(pdev, skb->data, - rx_ring->rx_buf_len, + bi->dma = pci_map_single(pdev, skb->data, bufsz, PCI_DMA_FROMDEVICE); } /* Refresh the desc even if buffer_addrs didn't change because @@ -734,7 +732,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, pci_unmap_single(pdev, rx_buffer_info->dma, rx_ring->rx_buf_len, PCI_DMA_FROMDEVICE); - rx_buffer_info->dma = 0; skb_put(skb, len); } @@ -2704,10 +2701,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) */ err = hw->phy.ops.identify(hw); if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { - dev_err(&adapter->pdev->dev, "failed to initialize because " - "an unsupported SFP+ module type was detected.\n" - "Reload the driver after installing a supported " - "module.\n"); + DPRINTK(PROBE, ERR, "PHY not supported on this NIC %d\n", err); ixgbe_down(adapter); return err; } @@ -2818,11 +2812,9 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, } if (!rx_buffer_info->page) continue; - if (rx_buffer_info->page_dma) { - pci_unmap_page(pdev, rx_buffer_info->page_dma, - PAGE_SIZE / 2, PCI_DMA_FROMDEVICE); - rx_buffer_info->page_dma = 0; - } + pci_unmap_page(pdev, rx_buffer_info->page_dma, PAGE_SIZE / 2, + PCI_DMA_FROMDEVICE); + rx_buffer_info->page_dma = 0; put_page(rx_buffer_info->page); rx_buffer_info->page = NULL; rx_buffer_info->page_offset = 0; @@ -3728,11 +3720,10 @@ static void ixgbe_sfp_task(struct work_struct *work) goto reschedule; ret = hw->phy.ops.reset(hw); if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) { - dev_err(&adapter->pdev->dev, "failed to initialize " - "because an unsupported SFP+ module type " - "was detected.\n" - "Reload the driver after installing a " - "supported module.\n"); + DPRINTK(PROBE, ERR, "failed to initialize because an " + "unsupported SFP+ module type was detected.\n" + "Reload the driver after installing a " + "supported module.\n"); unregister_netdev(adapter->netdev); } else { DPRINTK(PROBE, INFO, "detected SFP+: %d\n", @@ -4511,8 +4502,7 @@ static void ixgbe_multispeed_fiber_task(struct work_struct *work) u32 autoneg; adapter->flags |= IXGBE_FLAG_IN_SFP_LINK_TASK; - autoneg = hw->phy.autoneg_advertised; - if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) + if (hw->mac.ops.get_link_capabilities) hw->mac.ops.get_link_capabilities(hw, &autoneg, &hw->mac.autoneg); if (hw->mac.ops.setup_link_speed) @@ -4536,10 +4526,7 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work) adapter->flags |= IXGBE_FLAG_IN_SFP_MOD_TASK; err = hw->phy.ops.identify_sfp(hw); if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { - dev_err(&adapter->pdev->dev, "failed to initialize because " - "an unsupported SFP+ module type was detected.\n" - "Reload the driver after installing a supported " - "module.\n"); + DPRINTK(PROBE, ERR, "PHY not supported on this NIC %d\n", err); ixgbe_down(adapter); return; } @@ -5526,10 +5513,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, round_jiffies(jiffies + (2 * HZ))); err = 0; } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { - dev_err(&adapter->pdev->dev, "failed to initialize because " - "an unsupported SFP+ module type was detected.\n" - "Reload the driver after installing a supported " - "module.\n"); + dev_err(&adapter->pdev->dev, "failed to load because an " + "unsupported SFP+ module type was detected.\n"); goto err_sw_init; } else if (err) { dev_err(&adapter->pdev->dev, "HW Init failed: %d\n", err); diff --git a/trunk/drivers/net/mdio.c b/trunk/drivers/net/mdio.c index 6851bdb2ce29..dc45e9856c35 100644 --- a/trunk/drivers/net/mdio.c +++ b/trunk/drivers/net/mdio.c @@ -14,10 +14,6 @@ #include #include -MODULE_DESCRIPTION("Generic support for MDIO-compatible transceivers"); -MODULE_AUTHOR("Copyright 2006-2009 Solarflare Communications Inc."); -MODULE_LICENSE("GPL"); - /** * mdio45_probe - probe for an MDIO (clause 45) device * @mdio: MDIO interface diff --git a/trunk/drivers/net/sh_eth.c b/trunk/drivers/net/sh_eth.c index a2d82ddb3b4d..341882f959f3 100644 --- a/trunk/drivers/net/sh_eth.c +++ b/trunk/drivers/net/sh_eth.c @@ -865,7 +865,8 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) struct sh_eth_private *mdp = netdev_priv(ndev); struct sh_eth_cpu_data *cd = mdp->cd; irqreturn_t ret = IRQ_NONE; - u32 ioaddr, intr_status = 0; + u32 ioaddr, boguscnt = RX_RING_SIZE; + u32 intr_status = 0; ioaddr = ndev->base_addr; spin_lock(&mdp->lock); @@ -900,6 +901,12 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) if (intr_status & cd->eesr_err_check) sh_eth_error(ndev, intr_status); + if (--boguscnt < 0) { + printk(KERN_WARNING + "%s: Too much work at interrupt, status=0x%4.4x.\n", + ndev->name, intr_status); + } + other_irq: spin_unlock(&mdp->lock); diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index daf961ab68bc..7681d28c53d7 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -2495,7 +2495,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) if (likely(status >> 16 == (status & 0xffff))) { skb = sky2->rx_ring[sky2->rx_next].skb; skb->ip_summed = CHECKSUM_COMPLETE; - skb->csum = le16_to_cpu(status); + skb->csum = status & 0xffff; } else { printk(KERN_NOTICE PFX "%s: hardware receive " "checksum problem (status = %#x)\n", diff --git a/trunk/drivers/net/usb/cdc_eem.c b/trunk/drivers/net/usb/cdc_eem.c index cd35d50e46d4..80e01778dd3b 100644 --- a/trunk/drivers/net/usb/cdc_eem.c +++ b/trunk/drivers/net/usb/cdc_eem.c @@ -319,7 +319,7 @@ static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb) return crc == crc2; if (unlikely(crc != crc2)) { - dev->net->stats.rx_errors++; + dev->stats.rx_errors++; dev_kfree_skb_any(skb2); } else usbnet_skb_return(dev, skb2); diff --git a/trunk/drivers/net/usb/dm9601.c b/trunk/drivers/net/usb/dm9601.c index 1d3730d6690f..7ae82446b93a 100644 --- a/trunk/drivers/net/usb/dm9601.c +++ b/trunk/drivers/net/usb/dm9601.c @@ -513,11 +513,11 @@ static int dm9601_rx_fixup(struct usbnet *dev, struct sk_buff *skb) len = (skb->data[1] | (skb->data[2] << 8)) - 4; if (unlikely(status & 0xbf)) { - if (status & 0x01) dev->net->stats.rx_fifo_errors++; - if (status & 0x02) dev->net->stats.rx_crc_errors++; - if (status & 0x04) dev->net->stats.rx_frame_errors++; - if (status & 0x20) dev->net->stats.rx_missed_errors++; - if (status & 0x90) dev->net->stats.rx_length_errors++; + if (status & 0x01) dev->stats.rx_fifo_errors++; + if (status & 0x02) dev->stats.rx_crc_errors++; + if (status & 0x04) dev->stats.rx_frame_errors++; + if (status & 0x20) dev->stats.rx_missed_errors++; + if (status & 0x90) dev->stats.rx_length_errors++; return 0; } diff --git a/trunk/drivers/net/usb/net1080.c b/trunk/drivers/net/usb/net1080.c index aeb1ab03a9ee..034e8a73ca6b 100644 --- a/trunk/drivers/net/usb/net1080.c +++ b/trunk/drivers/net/usb/net1080.c @@ -433,7 +433,7 @@ static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) dbg("rx framesize %d range %d..%d mtu %d", skb->len, net->hard_header_len, dev->hard_mtu, net->mtu); #endif - dev->net->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; nc_ensure_sync(dev); return 0; } @@ -442,12 +442,12 @@ static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) hdr_len = le16_to_cpup(&header->hdr_len); packet_len = le16_to_cpup(&header->packet_len); if (FRAMED_SIZE(packet_len) > NC_MAX_PACKET) { - dev->net->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; dbg("packet too big, %d", packet_len); nc_ensure_sync(dev); return 0; } else if (hdr_len < MIN_HEADER) { - dev->net->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; dbg("header too short, %d", hdr_len); nc_ensure_sync(dev); return 0; @@ -465,21 +465,21 @@ static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) if ((packet_len & 0x01) == 0) { if (skb->data [packet_len] != PAD_BYTE) { - dev->net->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; dbg("bad pad"); return 0; } skb_trim(skb, skb->len - 1); } if (skb->len != packet_len) { - dev->net->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; dbg("bad packet len %d (expected %d)", skb->len, packet_len); nc_ensure_sync(dev); return 0; } if (header->packet_id != get_unaligned(&trailer->packet_id)) { - dev->net->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; dbg("(2+ dropped) rx packet_id mismatch 0x%x 0x%x", le16_to_cpu(header->packet_id), le16_to_cpu(trailer->packet_id)); diff --git a/trunk/drivers/net/usb/rndis_host.c b/trunk/drivers/net/usb/rndis_host.c index 2232232b7989..1bf243ef950e 100644 --- a/trunk/drivers/net/usb/rndis_host.c +++ b/trunk/drivers/net/usb/rndis_host.c @@ -487,7 +487,7 @@ int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb) if (unlikely(hdr->msg_type != RNDIS_MSG_PACKET || skb->len < msg_len || (data_offset + data_len + 8) > msg_len)) { - dev->net->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; devdbg(dev, "bad rndis message %d/%d/%d/%d, len %d", le32_to_cpu(hdr->msg_type), msg_len, data_offset, data_len, skb->len); diff --git a/trunk/drivers/net/usb/smsc95xx.c b/trunk/drivers/net/usb/smsc95xx.c index fe045896406b..89a91f8c22de 100644 --- a/trunk/drivers/net/usb/smsc95xx.c +++ b/trunk/drivers/net/usb/smsc95xx.c @@ -1108,18 +1108,18 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) if (unlikely(header & RX_STS_ES_)) { if (netif_msg_rx_err(dev)) devdbg(dev, "Error header=0x%08x", header); - dev->net->stats.rx_errors++; - dev->net->stats.rx_dropped++; + dev->stats.rx_errors++; + dev->stats.rx_dropped++; if (header & RX_STS_CRC_) { - dev->net->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; } else { if (header & (RX_STS_TL_ | RX_STS_RF_)) - dev->net->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if ((header & RX_STS_LE_) && (!(header & RX_STS_FT_))) - dev->net->stats.rx_length_errors++; + dev->stats.rx_length_errors++; } } else { /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */ diff --git a/trunk/drivers/net/usb/usbnet.c b/trunk/drivers/net/usb/usbnet.c index edfd9e10ceba..22c0585a0319 100644 --- a/trunk/drivers/net/usb/usbnet.c +++ b/trunk/drivers/net/usb/usbnet.c @@ -234,8 +234,8 @@ void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb) int status; skb->protocol = eth_type_trans (skb, dev->net); - dev->net->stats.rx_packets++; - dev->net->stats.rx_bytes += skb->len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += skb->len; if (netif_msg_rx_status (dev)) devdbg (dev, "< rx, len %zu, type 0x%x", @@ -397,7 +397,7 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) if (netif_msg_rx_err (dev)) devdbg (dev, "drop"); error: - dev->net->stats.rx_errors++; + dev->stats.rx_errors++; skb_queue_tail (&dev->done, skb); } } @@ -420,8 +420,8 @@ static void rx_complete (struct urb *urb) case 0: if (skb->len < dev->net->hard_header_len) { entry->state = rx_cleanup; - dev->net->stats.rx_errors++; - dev->net->stats.rx_length_errors++; + dev->stats.rx_errors++; + dev->stats.rx_length_errors++; if (netif_msg_rx_err (dev)) devdbg (dev, "rx length %d", skb->len); } @@ -433,7 +433,7 @@ static void rx_complete (struct urb *urb) * storm, recovering as needed. */ case -EPIPE: - dev->net->stats.rx_errors++; + dev->stats.rx_errors++; usbnet_defer_kevent (dev, EVENT_RX_HALT); // FALLTHROUGH @@ -451,7 +451,7 @@ static void rx_complete (struct urb *urb) case -EPROTO: case -ETIME: case -EILSEQ: - dev->net->stats.rx_errors++; + dev->stats.rx_errors++; if (!timer_pending (&dev->delay)) { mod_timer (&dev->delay, jiffies + THROTTLE_JIFFIES); if (netif_msg_link (dev)) @@ -465,12 +465,12 @@ static void rx_complete (struct urb *urb) /* data overrun ... flush fifo? */ case -EOVERFLOW: - dev->net->stats.rx_over_errors++; + dev->stats.rx_over_errors++; // FALLTHROUGH default: entry->state = rx_cleanup; - dev->net->stats.rx_errors++; + dev->stats.rx_errors++; if (netif_msg_rx_err (dev)) devdbg (dev, "rx status %d", urb_status); break; @@ -583,8 +583,8 @@ int usbnet_stop (struct net_device *net) if (netif_msg_ifdown (dev)) devinfo (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld", - net->stats.rx_packets, net->stats.tx_packets, - net->stats.rx_errors, net->stats.tx_errors + dev->stats.rx_packets, dev->stats.tx_packets, + dev->stats.rx_errors, dev->stats.tx_errors ); // ensure there are no more active urbs @@ -891,10 +891,10 @@ static void tx_complete (struct urb *urb) struct usbnet *dev = entry->dev; if (urb->status == 0) { - dev->net->stats.tx_packets++; - dev->net->stats.tx_bytes += entry->length; + dev->stats.tx_packets++; + dev->stats.tx_bytes += entry->length; } else { - dev->net->stats.tx_errors++; + dev->stats.tx_errors++; switch (urb->status) { case -EPIPE: @@ -1020,7 +1020,7 @@ int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net) devdbg (dev, "drop, code %d", retval); drop: retval = NET_XMIT_SUCCESS; - dev->net->stats.tx_dropped++; + dev->stats.tx_dropped++; if (skb) dev_kfree_skb_any (skb); usb_free_urb (urb); diff --git a/trunk/drivers/net/veth.c b/trunk/drivers/net/veth.c index 1097c72e44d5..87197dd9c788 100644 --- a/trunk/drivers/net/veth.c +++ b/trunk/drivers/net/veth.c @@ -208,14 +208,11 @@ static int veth_xmit(struct sk_buff *skb, struct net_device *dev) static struct net_device_stats *veth_get_stats(struct net_device *dev) { - struct veth_priv *priv; - struct net_device_stats *dev_stats; - int cpu; + struct veth_priv *priv = netdev_priv(dev); + struct net_device_stats *dev_stats = &dev->stats; + unsigned int cpu; struct veth_net_stats *stats; - priv = netdev_priv(dev); - dev_stats = &dev->stats; - dev_stats->rx_packets = 0; dev_stats->tx_packets = 0; dev_stats->rx_bytes = 0; @@ -223,16 +220,17 @@ static struct net_device_stats *veth_get_stats(struct net_device *dev) dev_stats->tx_dropped = 0; dev_stats->rx_dropped = 0; - for_each_online_cpu(cpu) { - stats = per_cpu_ptr(priv->stats, cpu); + if (priv->stats) + for_each_online_cpu(cpu) { + stats = per_cpu_ptr(priv->stats, cpu); - dev_stats->rx_packets += stats->rx_packets; - dev_stats->tx_packets += stats->tx_packets; - dev_stats->rx_bytes += stats->rx_bytes; - dev_stats->tx_bytes += stats->tx_bytes; - dev_stats->tx_dropped += stats->tx_dropped; - dev_stats->rx_dropped += stats->rx_dropped; - } + dev_stats->rx_packets += stats->rx_packets; + dev_stats->tx_packets += stats->tx_packets; + dev_stats->rx_bytes += stats->rx_bytes; + dev_stats->tx_bytes += stats->tx_bytes; + dev_stats->tx_dropped += stats->tx_dropped; + dev_stats->rx_dropped += stats->rx_dropped; + } return dev_stats; } @@ -259,6 +257,8 @@ static int veth_close(struct net_device *dev) netif_carrier_off(dev); netif_carrier_off(priv->peer); + free_percpu(priv->stats); + priv->stats = NULL; return 0; } @@ -289,15 +289,6 @@ static int veth_dev_init(struct net_device *dev) return 0; } -static void veth_dev_free(struct net_device *dev) -{ - struct veth_priv *priv; - - priv = netdev_priv(dev); - free_percpu(priv->stats); - free_netdev(dev); -} - static const struct net_device_ops veth_netdev_ops = { .ndo_init = veth_dev_init, .ndo_open = veth_open, @@ -315,7 +306,7 @@ static void veth_setup(struct net_device *dev) dev->netdev_ops = &veth_netdev_ops; dev->ethtool_ops = &veth_ethtool_ops; dev->features |= NETIF_F_LLTX; - dev->destructor = veth_dev_free; + dev->destructor = free_netdev; } /* diff --git a/trunk/drivers/parport/parport_pc.c b/trunk/drivers/parport/parport_pc.c index 2597145a066e..1032d5fdbd42 100644 --- a/trunk/drivers/parport/parport_pc.c +++ b/trunk/drivers/parport/parport_pc.c @@ -2907,7 +2907,6 @@ enum parport_pc_pci_cards { netmos_9755, netmos_9805, netmos_9815, - netmos_9901, quatech_sppxp100, }; @@ -2988,7 +2987,7 @@ static struct parport_pc_pci { /* netmos_9755 */ { 2, { { 0, 1 }, { 2, 3 },} }, /* netmos_9805 */ { 1, { { 0, -1 }, } }, /* netmos_9815 */ { 2, { { 0, -1 }, { 2, -1 }, } }, - /* netmos_9901 */ { 1, { { 0, -1 }, } }, + /* quatech_sppxp100 */ { 1, { { 0, 1 }, } }, }; @@ -3090,8 +3089,6 @@ static const struct pci_device_id parport_pc_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9805 }, { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9815, PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 }, - { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901, - 0xA000, 0x2000, 0, 0, netmos_9901 }, /* Quatech SPPXP-100 Parallel port PCI ExpressCard */ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 }, diff --git a/trunk/drivers/pci/intel-iommu.c b/trunk/drivers/pci/intel-iommu.c index 53075424a434..e53eacd75c8d 100644 --- a/trunk/drivers/pci/intel-iommu.c +++ b/trunk/drivers/pci/intel-iommu.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "pci.h" #define ROOT_SIZE VTD_PAGE_SIZE @@ -56,32 +57,14 @@ #define MAX_AGAW_WIDTH 64 #define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1) -#define DOMAIN_MAX_PFN(gaw) ((((u64)1) << (gaw-VTD_PAGE_SHIFT)) - 1) #define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT) #define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32)) #define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64)) - -/* VT-d pages must always be _smaller_ than MM pages. Otherwise things - are never going to work. */ -static inline unsigned long dma_to_mm_pfn(unsigned long dma_pfn) -{ - return dma_pfn >> (PAGE_SHIFT - VTD_PAGE_SHIFT); -} - -static inline unsigned long mm_to_dma_pfn(unsigned long mm_pfn) -{ - return mm_pfn << (PAGE_SHIFT - VTD_PAGE_SHIFT); -} -static inline unsigned long page_to_dma_pfn(struct page *pg) -{ - return mm_to_dma_pfn(page_to_pfn(pg)); -} -static inline unsigned long virt_to_dma_pfn(void *p) -{ - return page_to_dma_pfn(virt_to_page(p)); -} +#ifndef PHYSICAL_PAGE_MASK +#define PHYSICAL_PAGE_MASK PAGE_MASK +#endif /* global iommu list, set NULL for ignored DMAR units */ static struct intel_iommu **g_iommus; @@ -222,17 +205,12 @@ static inline void dma_set_pte_prot(struct dma_pte *pte, unsigned long prot) static inline u64 dma_pte_addr(struct dma_pte *pte) { -#ifdef CONFIG_64BIT - return pte->val & VTD_PAGE_MASK; -#else - /* Must have a full atomic 64-bit read */ - return __cmpxchg64(pte, 0ULL, 0ULL) & VTD_PAGE_MASK; -#endif + return (pte->val & VTD_PAGE_MASK); } -static inline void dma_set_pte_pfn(struct dma_pte *pte, unsigned long pfn) +static inline void dma_set_pte_addr(struct dma_pte *pte, u64 addr) { - pte->val |= (uint64_t)pfn << VTD_PAGE_SHIFT; + pte->val |= (addr & VTD_PAGE_MASK); } static inline bool dma_pte_present(struct dma_pte *pte) @@ -240,11 +218,6 @@ static inline bool dma_pte_present(struct dma_pte *pte) return (pte->val & 3) != 0; } -static inline int first_pte_in_page(struct dma_pte *pte) -{ - return !((unsigned long)pte & ~VTD_PAGE_MASK); -} - /* * This domain is a statically identity mapping domain. * 1. This domain creats a static 1:1 mapping to all usable memory. @@ -272,6 +245,7 @@ struct dmar_domain { struct iova_domain iovad; /* iova's that belong to this domain */ struct dma_pte *pgd; /* virtual address */ + spinlock_t mapping_lock; /* page table lock */ int gaw; /* max guest address width */ /* adjusted guest address width, 0 is level 2 30-bit */ @@ -675,78 +649,80 @@ static inline int width_to_agaw(int width) static inline unsigned int level_to_offset_bits(int level) { - return (level - 1) * LEVEL_STRIDE; + return (12 + (level - 1) * LEVEL_STRIDE); } -static inline int pfn_level_offset(unsigned long pfn, int level) +static inline int address_level_offset(u64 addr, int level) { - return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK; + return ((addr >> level_to_offset_bits(level)) & LEVEL_MASK); } -static inline unsigned long level_mask(int level) +static inline u64 level_mask(int level) { - return -1UL << level_to_offset_bits(level); + return ((u64)-1 << level_to_offset_bits(level)); } -static inline unsigned long level_size(int level) +static inline u64 level_size(int level) { - return 1UL << level_to_offset_bits(level); + return ((u64)1 << level_to_offset_bits(level)); } -static inline unsigned long align_to_level(unsigned long pfn, int level) +static inline u64 align_to_level(u64 addr, int level) { - return (pfn + level_size(level) - 1) & level_mask(level); + return ((addr + level_size(level) - 1) & level_mask(level)); } -static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, - unsigned long pfn) +static struct dma_pte * addr_to_dma_pte(struct dmar_domain *domain, u64 addr) { - int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; + int addr_width = agaw_to_width(domain->agaw); struct dma_pte *parent, *pte = NULL; int level = agaw_to_level(domain->agaw); int offset; + unsigned long flags; BUG_ON(!domain->pgd); - BUG_ON(addr_width < BITS_PER_LONG && pfn >> addr_width); + + addr &= (((u64)1) << addr_width) - 1; parent = domain->pgd; + spin_lock_irqsave(&domain->mapping_lock, flags); while (level > 0) { void *tmp_page; - offset = pfn_level_offset(pfn, level); + offset = address_level_offset(addr, level); pte = &parent[offset]; if (level == 1) break; if (!dma_pte_present(pte)) { - uint64_t pteval; - tmp_page = alloc_pgtable_page(); - if (!tmp_page) + if (!tmp_page) { + spin_unlock_irqrestore(&domain->mapping_lock, + flags); return NULL; - - domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE); - pteval = (virt_to_dma_pfn(tmp_page) << VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE; - if (cmpxchg64(&pte->val, 0ULL, pteval)) { - /* Someone else set it while we were thinking; use theirs. */ - free_pgtable_page(tmp_page); - } else { - dma_pte_addr(pte); - domain_flush_cache(domain, pte, sizeof(*pte)); } + domain_flush_cache(domain, tmp_page, PAGE_SIZE); + dma_set_pte_addr(pte, virt_to_phys(tmp_page)); + /* + * high level table always sets r/w, last level page + * table control read/write + */ + dma_set_pte_readable(pte); + dma_set_pte_writable(pte); + domain_flush_cache(domain, pte, sizeof(*pte)); } parent = phys_to_virt(dma_pte_addr(pte)); level--; } + spin_unlock_irqrestore(&domain->mapping_lock, flags); return pte; } /* return address's pte at specific level */ -static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain, - unsigned long pfn, - int level) +static struct dma_pte *dma_addr_level_pte(struct dmar_domain *domain, u64 addr, + int level) { struct dma_pte *parent, *pte = NULL; int total = agaw_to_level(domain->agaw); @@ -754,7 +730,7 @@ static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain, parent = domain->pgd; while (level <= total) { - offset = pfn_level_offset(pfn, total); + offset = address_level_offset(addr, total); pte = &parent[offset]; if (level == total) return pte; @@ -767,82 +743,74 @@ static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain, return NULL; } -/* clear last level pte, a tlb flush should be followed */ -static void dma_pte_clear_range(struct dmar_domain *domain, - unsigned long start_pfn, - unsigned long last_pfn) +/* clear one page's page table */ +static void dma_pte_clear_one(struct dmar_domain *domain, u64 addr) { - int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; - struct dma_pte *first_pte, *pte; + struct dma_pte *pte = NULL; - BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width); - BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width); + /* get last level pte */ + pte = dma_addr_level_pte(domain, addr, 1); - /* we don't need lock here; nobody else touches the iova range */ - while (start_pfn <= last_pfn) { - first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1); - if (!pte) { - start_pfn = align_to_level(start_pfn + 1, 2); - continue; - } - do { - dma_clear_pte(pte); - start_pfn++; - pte++; - } while (start_pfn <= last_pfn && !first_pte_in_page(pte)); + if (pte) { + dma_clear_pte(pte); + domain_flush_cache(domain, pte, sizeof(*pte)); + } +} + +/* clear last level pte, a tlb flush should be followed */ +static void dma_pte_clear_range(struct dmar_domain *domain, u64 start, u64 end) +{ + int addr_width = agaw_to_width(domain->agaw); + int npages; + + start &= (((u64)1) << addr_width) - 1; + end &= (((u64)1) << addr_width) - 1; + /* in case it's partial page */ + start &= PAGE_MASK; + end = PAGE_ALIGN(end); + npages = (end - start) / VTD_PAGE_SIZE; - domain_flush_cache(domain, first_pte, - (void *)pte - (void *)first_pte); + /* we don't need lock here, nobody else touches the iova range */ + while (npages--) { + dma_pte_clear_one(domain, start); + start += VTD_PAGE_SIZE; } } /* free page table pages. last level pte should already be cleared */ static void dma_pte_free_pagetable(struct dmar_domain *domain, - unsigned long start_pfn, - unsigned long last_pfn) + u64 start, u64 end) { - int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; - struct dma_pte *first_pte, *pte; + int addr_width = agaw_to_width(domain->agaw); + struct dma_pte *pte; int total = agaw_to_level(domain->agaw); int level; - unsigned long tmp; + u64 tmp; - BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width); - BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width); + start &= (((u64)1) << addr_width) - 1; + end &= (((u64)1) << addr_width) - 1; - /* We don't need lock here; nobody else touches the iova range */ + /* we don't need lock here, nobody else touches the iova range */ level = 2; while (level <= total) { - tmp = align_to_level(start_pfn, level); - - /* If we can't even clear one PTE at this level, we're done */ - if (tmp + level_size(level) - 1 > last_pfn) + tmp = align_to_level(start, level); + if (tmp >= end || (tmp + level_size(level) > end)) return; - while (tmp + level_size(level) - 1 <= last_pfn) { - first_pte = pte = dma_pfn_level_pte(domain, tmp, level); - if (!pte) { - tmp = align_to_level(tmp + 1, level + 1); - continue; + while (tmp < end) { + pte = dma_addr_level_pte(domain, tmp, level); + if (pte) { + free_pgtable_page( + phys_to_virt(dma_pte_addr(pte))); + dma_clear_pte(pte); + domain_flush_cache(domain, pte, sizeof(*pte)); } - do { - if (dma_pte_present(pte)) { - free_pgtable_page(phys_to_virt(dma_pte_addr(pte))); - dma_clear_pte(pte); - } - pte++; - tmp += level_size(level); - } while (!first_pte_in_page(pte) && - tmp + level_size(level) - 1 <= last_pfn); - - domain_flush_cache(domain, first_pte, - (void *)pte - (void *)first_pte); - + tmp += level_size(level); } level++; } /* free pgd */ - if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) { + if (start == 0 && end >= ((((u64)1) << addr_width) - 1)) { free_pgtable_page(domain->pgd); domain->pgd = NULL; } @@ -1068,11 +1036,11 @@ static void iommu_flush_dev_iotlb(struct dmar_domain *domain, } static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did, - unsigned long pfn, unsigned int pages) + u64 addr, unsigned int pages) { unsigned int mask = ilog2(__roundup_pow_of_two(pages)); - uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT; + BUG_ON(addr & (~VTD_PAGE_MASK)); BUG_ON(pages == 0); /* @@ -1087,12 +1055,7 @@ static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did, else iommu->flush.flush_iotlb(iommu, did, addr, mask, DMA_TLB_PSI_FLUSH); - - /* - * In caching mode, domain ID 0 is reserved for non-present to present - * mapping flush. Device IOTLB doesn't need to be flushed in this case. - */ - if (!cap_caching_mode(iommu->cap) || did) + if (did) iommu_flush_dev_iotlb(iommu->domains[did], addr, mask); } @@ -1317,6 +1280,7 @@ static void dmar_init_reserved_ranges(void) struct pci_dev *pdev = NULL; struct iova *iova; int i; + u64 addr, size; init_iova_domain(&reserved_iova_list, DMA_32BIT_PFN); @@ -1339,9 +1303,12 @@ static void dmar_init_reserved_ranges(void) r = &pdev->resource[i]; if (!r->flags || !(r->flags & IORESOURCE_MEM)) continue; - iova = reserve_iova(&reserved_iova_list, - IOVA_PFN(r->start), - IOVA_PFN(r->end)); + addr = r->start; + addr &= PHYSICAL_PAGE_MASK; + size = r->end - addr; + size = PAGE_ALIGN(size); + iova = reserve_iova(&reserved_iova_list, IOVA_PFN(addr), + IOVA_PFN(size + addr) - 1); if (!iova) printk(KERN_ERR "Reserve iova failed\n"); } @@ -1375,6 +1342,7 @@ static int domain_init(struct dmar_domain *domain, int guest_width) unsigned long sagaw; init_iova_domain(&domain->iovad, DMA_32BIT_PFN); + spin_lock_init(&domain->mapping_lock); spin_lock_init(&domain->iommu_lock); domain_reserve_special_ranges(domain); @@ -1421,6 +1389,7 @@ static void domain_exit(struct dmar_domain *domain) { struct dmar_drhd_unit *drhd; struct intel_iommu *iommu; + u64 end; /* Domain 0 is reserved, so dont process it */ if (!domain) @@ -1429,12 +1398,14 @@ static void domain_exit(struct dmar_domain *domain) domain_remove_dev_info(domain); /* destroy iovas */ put_iova_domain(&domain->iovad); + end = DOMAIN_MAX_ADDR(domain->gaw); + end = end & (~PAGE_MASK); /* clear ptes */ - dma_pte_clear_range(domain, 0, DOMAIN_MAX_PFN(domain->gaw)); + dma_pte_clear_range(domain, 0, end); /* free page tables */ - dma_pte_free_pagetable(domain, 0, DOMAIN_MAX_PFN(domain->gaw)); + dma_pte_free_pagetable(domain, 0, end); for_each_active_iommu(iommu, drhd) if (test_bit(iommu->seq_id, &domain->iommu_bmp)) @@ -1648,86 +1619,42 @@ static int domain_context_mapped(struct pci_dev *pdev) tmp->devfn); } -static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, - struct scatterlist *sg, unsigned long phys_pfn, - unsigned long nr_pages, int prot) +static int +domain_page_mapping(struct dmar_domain *domain, dma_addr_t iova, + u64 hpa, size_t size, int prot) { - struct dma_pte *first_pte = NULL, *pte = NULL; - phys_addr_t uninitialized_var(pteval); - int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; - unsigned long sg_res; + u64 start_pfn, end_pfn; + struct dma_pte *pte; + int index; + int addr_width = agaw_to_width(domain->agaw); - BUG_ON(addr_width < BITS_PER_LONG && (iov_pfn + nr_pages - 1) >> addr_width); + hpa &= (((u64)1) << addr_width) - 1; if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0) return -EINVAL; - - prot &= DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP; - - if (sg) - sg_res = 0; - else { - sg_res = nr_pages + 1; - pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot; - } - - while (nr_pages--) { - uint64_t tmp; - - if (!sg_res) { - sg_res = (sg->offset + sg->length + VTD_PAGE_SIZE - 1) >> VTD_PAGE_SHIFT; - sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset; - sg->dma_length = sg->length; - pteval = page_to_phys(sg_page(sg)) | prot; - } - if (!pte) { - first_pte = pte = pfn_to_dma_pte(domain, iov_pfn); - if (!pte) - return -ENOMEM; - } + iova &= PAGE_MASK; + start_pfn = ((u64)hpa) >> VTD_PAGE_SHIFT; + end_pfn = (VTD_PAGE_ALIGN(((u64)hpa) + size)) >> VTD_PAGE_SHIFT; + index = 0; + while (start_pfn < end_pfn) { + pte = addr_to_dma_pte(domain, iova + VTD_PAGE_SIZE * index); + if (!pte) + return -ENOMEM; /* We don't need lock here, nobody else * touches the iova range */ - tmp = cmpxchg64_local(&pte->val, 0ULL, pteval); - if (tmp) { - static int dumps = 5; - printk(KERN_CRIT "ERROR: DMA PTE for vPFN 0x%lx already set (to %llx not %llx)\n", - iov_pfn, tmp, (unsigned long long)pteval); - if (dumps) { - dumps--; - debug_dma_dump_mappings(NULL); - } - WARN_ON(1); - } - pte++; - if (!nr_pages || first_pte_in_page(pte)) { - domain_flush_cache(domain, first_pte, - (void *)pte - (void *)first_pte); - pte = NULL; - } - iov_pfn++; - pteval += VTD_PAGE_SIZE; - sg_res--; - if (!sg_res) - sg = sg_next(sg); + BUG_ON(dma_pte_addr(pte)); + dma_set_pte_addr(pte, start_pfn << VTD_PAGE_SHIFT); + dma_set_pte_prot(pte, prot); + if (prot & DMA_PTE_SNP) + dma_set_pte_snp(pte); + domain_flush_cache(domain, pte, sizeof(*pte)); + start_pfn++; + index++; } return 0; } -static inline int domain_sg_mapping(struct dmar_domain *domain, unsigned long iov_pfn, - struct scatterlist *sg, unsigned long nr_pages, - int prot) -{ - return __domain_mapping(domain, iov_pfn, sg, 0, nr_pages, prot); -} - -static inline int domain_pfn_mapping(struct dmar_domain *domain, unsigned long iov_pfn, - unsigned long phys_pfn, unsigned long nr_pages, - int prot) -{ - return __domain_mapping(domain, iov_pfn, NULL, phys_pfn, nr_pages, prot); -} - static void iommu_detach_dev(struct intel_iommu *iommu, u8 bus, u8 devfn) { if (!iommu) @@ -1918,61 +1845,58 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) static int iommu_identity_mapping; -static int iommu_domain_identity_map(struct dmar_domain *domain, - unsigned long long start, - unsigned long long end) -{ - unsigned long first_vpfn = start >> VTD_PAGE_SHIFT; - unsigned long last_vpfn = end >> VTD_PAGE_SHIFT; - - if (!reserve_iova(&domain->iovad, dma_to_mm_pfn(first_vpfn), - dma_to_mm_pfn(last_vpfn))) { - printk(KERN_ERR "IOMMU: reserve iova failed\n"); - return -ENOMEM; - } - - pr_debug("Mapping reserved region %llx-%llx for domain %d\n", - start, end, domain->id); - /* - * RMRR range might have overlap with physical memory range, - * clear it first - */ - dma_pte_clear_range(domain, first_vpfn, last_vpfn); - - return domain_pfn_mapping(domain, first_vpfn, first_vpfn, - last_vpfn - first_vpfn + 1, - DMA_PTE_READ|DMA_PTE_WRITE); -} - static int iommu_prepare_identity_map(struct pci_dev *pdev, unsigned long long start, unsigned long long end) { struct dmar_domain *domain; + unsigned long size; + unsigned long long base; int ret; printk(KERN_INFO - "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n", - pci_name(pdev), start, end); - - domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH); + "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n", + pci_name(pdev), start, end); + if (iommu_identity_mapping) + domain = si_domain; + else + /* page table init */ + domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH); if (!domain) return -ENOMEM; - ret = iommu_domain_identity_map(domain, start, end); - if (ret) + /* The address might not be aligned */ + base = start & PAGE_MASK; + size = end - base; + size = PAGE_ALIGN(size); + if (!reserve_iova(&domain->iovad, IOVA_PFN(base), + IOVA_PFN(base + size) - 1)) { + printk(KERN_ERR "IOMMU: reserve iova failed\n"); + ret = -ENOMEM; goto error; + } - /* context entry init */ - ret = domain_context_mapping(domain, pdev, CONTEXT_TT_MULTI_LEVEL); + pr_debug("Mapping reserved region %lx@%llx for %s\n", + size, base, pci_name(pdev)); + /* + * RMRR range might have overlap with physical memory range, + * clear it first + */ + dma_pte_clear_range(domain, base, base + size); + + ret = domain_page_mapping(domain, base, base, size, + DMA_PTE_READ|DMA_PTE_WRITE); if (ret) goto error; - return 0; - - error: + /* context entry init */ + ret = domain_context_mapping(domain, pdev, CONTEXT_TT_MULTI_LEVEL); + if (!ret) + return 0; +error: domain_exit(domain); return ret; + } static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr, @@ -1984,6 +1908,64 @@ static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr, rmrr->end_address + 1); } +#ifdef CONFIG_DMAR_GFX_WA +struct iommu_prepare_data { + struct pci_dev *pdev; + int ret; +}; + +static int __init iommu_prepare_work_fn(unsigned long start_pfn, + unsigned long end_pfn, void *datax) +{ + struct iommu_prepare_data *data; + + data = (struct iommu_prepare_data *)datax; + + data->ret = iommu_prepare_identity_map(data->pdev, + start_pfn<ret; + +} + +static int __init iommu_prepare_with_active_regions(struct pci_dev *pdev) +{ + int nid; + struct iommu_prepare_data data; + + data.pdev = pdev; + data.ret = 0; + + for_each_online_node(nid) { + work_with_active_regions(nid, iommu_prepare_work_fn, &data); + if (data.ret) + return data.ret; + } + return data.ret; +} + +static void __init iommu_prepare_gfx_mapping(void) +{ + struct pci_dev *pdev = NULL; + int ret; + + for_each_pci_dev(pdev) { + if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO || + !IS_GFX_DEVICE(pdev)) + continue; + printk(KERN_INFO "IOMMU: gfx device %s 1-1 mapping\n", + pci_name(pdev)); + ret = iommu_prepare_with_active_regions(pdev); + if (ret) + printk(KERN_ERR "IOMMU: mapping reserved region failed\n"); + } +} +#else /* !CONFIG_DMAR_GFX_WA */ +static inline void iommu_prepare_gfx_mapping(void) +{ + return; +} +#endif + #ifdef CONFIG_DMAR_FLOPPY_WA static inline void iommu_prepare_isa(void) { @@ -1994,12 +1976,12 @@ static inline void iommu_prepare_isa(void) if (!pdev) return; - printk(KERN_INFO "IOMMU: Prepare 0-16MiB unity mapping for LPC\n"); + printk(KERN_INFO "IOMMU: Prepare 0-16M unity mapping for LPC\n"); ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024); if (ret) - printk(KERN_ERR "IOMMU: Failed to create 0-16MiB identity map; " - "floppy might not work\n"); + printk(KERN_ERR "IOMMU: Failed to create 0-64M identity map, " + "floppy might not work\n"); } #else @@ -2027,30 +2009,16 @@ static int __init init_context_pass_through(void) } static int md_domain_init(struct dmar_domain *domain, int guest_width); - -static int __init si_domain_work_fn(unsigned long start_pfn, - unsigned long end_pfn, void *datax) -{ - int *ret = datax; - - *ret = iommu_domain_identity_map(si_domain, - (uint64_t)start_pfn << PAGE_SHIFT, - (uint64_t)end_pfn << PAGE_SHIFT); - return *ret; - -} - static int si_domain_init(void) { struct dmar_drhd_unit *drhd; struct intel_iommu *iommu; - int nid, ret = 0; + int ret = 0; si_domain = alloc_domain(); if (!si_domain) return -EFAULT; - pr_debug("Identity mapping domain is domain %d\n", si_domain->id); for_each_active_iommu(iommu, drhd) { ret = iommu_attach_domain(si_domain, iommu); @@ -2067,12 +2035,6 @@ static int si_domain_init(void) si_domain->flags = DOMAIN_FLAG_STATIC_IDENTITY; - for_each_online_node(nid) { - work_with_active_regions(nid, si_domain_work_fn, &ret); - if (ret) - return ret; - } - return 0; } @@ -2119,6 +2081,7 @@ static int domain_add_dev_info(struct dmar_domain *domain, static int iommu_prepare_static_identity_mapping(void) { + int i; struct pci_dev *pdev = NULL; int ret; @@ -2126,14 +2089,20 @@ static int iommu_prepare_static_identity_mapping(void) if (ret) return -EFAULT; + printk(KERN_INFO "IOMMU: Setting identity map:\n"); for_each_pci_dev(pdev) { - printk(KERN_INFO "IOMMU: identity mapping for device %s\n", - pci_name(pdev)); - - ret = domain_context_mapping(si_domain, pdev, - CONTEXT_TT_MULTI_LEVEL); - if (ret) - return ret; + for (i = 0; i < e820.nr_map; i++) { + struct e820entry *ei = &e820.map[i]; + + if (ei->type == E820_RAM) { + ret = iommu_prepare_identity_map(pdev, + ei->addr, ei->addr + ei->size); + if (ret) { + printk(KERN_INFO "1:1 mapping to one domain failed.\n"); + return -EFAULT; + } + } + } ret = domain_add_dev_info(si_domain, pdev); if (ret) return ret; @@ -2324,6 +2293,8 @@ int __init init_dmars(void) } } + iommu_prepare_gfx_mapping(); + iommu_prepare_isa(); } @@ -2368,40 +2339,50 @@ int __init init_dmars(void) return ret; } -static inline unsigned long aligned_nrpages(unsigned long host_addr, - size_t size) +static inline u64 aligned_size(u64 host_addr, size_t size) +{ + u64 addr; + addr = (host_addr & (~PAGE_MASK)) + size; + return PAGE_ALIGN(addr); +} + +struct iova * +iommu_alloc_iova(struct dmar_domain *domain, size_t size, u64 end) { - host_addr &= ~PAGE_MASK; - host_addr += size + PAGE_SIZE - 1; + struct iova *piova; - return host_addr >> VTD_PAGE_SHIFT; + /* Make sure it's in range */ + end = min_t(u64, DOMAIN_MAX_ADDR(domain->gaw), end); + if (!size || (IOVA_START_ADDR + size > end)) + return NULL; + + piova = alloc_iova(&domain->iovad, + size >> PAGE_SHIFT, IOVA_PFN(end), 1); + return piova; } -static struct iova *intel_alloc_iova(struct device *dev, - struct dmar_domain *domain, - unsigned long nrpages, uint64_t dma_mask) +static struct iova * +__intel_alloc_iova(struct device *dev, struct dmar_domain *domain, + size_t size, u64 dma_mask) { struct pci_dev *pdev = to_pci_dev(dev); struct iova *iova = NULL; - /* Restrict dma_mask to the width that the iommu can handle */ - dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw), dma_mask); - - if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) { + if (dma_mask <= DMA_BIT_MASK(32) || dmar_forcedac) + iova = iommu_alloc_iova(domain, size, dma_mask); + else { /* * First try to allocate an io virtual address in * DMA_BIT_MASK(32) and if that fails then try allocating * from higher range */ - iova = alloc_iova(&domain->iovad, nrpages, - IOVA_PFN(DMA_BIT_MASK(32)), 1); - if (iova) - return iova; - } - iova = alloc_iova(&domain->iovad, nrpages, IOVA_PFN(dma_mask), 1); - if (unlikely(!iova)) { - printk(KERN_ERR "Allocating %ld-page iova for %s failed", - nrpages, pci_name(pdev)); + iova = iommu_alloc_iova(domain, size, DMA_BIT_MASK(32)); + if (!iova) + iova = iommu_alloc_iova(domain, size, dma_mask); + } + + if (!iova) { + printk(KERN_ERR"Allocating iova for %s failed", pci_name(pdev)); return NULL; } @@ -2504,12 +2485,14 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, return 0; iommu = domain_get_iommu(domain); - size = aligned_nrpages(paddr, size); + size = aligned_size((u64)paddr, size); - iova = intel_alloc_iova(hwdev, domain, size, pdev->dma_mask); + iova = __intel_alloc_iova(hwdev, domain, size, pdev->dma_mask); if (!iova) goto error; + start_paddr = (phys_addr_t)iova->pfn_lo << PAGE_SHIFT; + /* * Check if DMAR supports zero-length reads on write only * mappings.. @@ -2525,20 +2508,20 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, * might have two guest_addr mapping to the same host paddr, but this * is not a big problem */ - ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova->pfn_lo), - paddr >> VTD_PAGE_SHIFT, size, prot); + ret = domain_page_mapping(domain, start_paddr, + ((u64)paddr) & PHYSICAL_PAGE_MASK, + size, prot); if (ret) goto error; /* it's a non-present to present mapping. Only flush if caching mode */ if (cap_caching_mode(iommu->cap)) - iommu_flush_iotlb_psi(iommu, 0, mm_to_dma_pfn(iova->pfn_lo), size); + iommu_flush_iotlb_psi(iommu, 0, start_paddr, + size >> VTD_PAGE_SHIFT); else iommu_flush_write_buffer(iommu); - start_paddr = (phys_addr_t)iova->pfn_lo << PAGE_SHIFT; - start_paddr += paddr & ~PAGE_MASK; - return start_paddr; + return start_paddr + ((u64)paddr & (~PAGE_MASK)); error: if (iova) @@ -2631,7 +2614,7 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr, { struct pci_dev *pdev = to_pci_dev(dev); struct dmar_domain *domain; - unsigned long start_pfn, last_pfn; + unsigned long start_addr; struct iova *iova; struct intel_iommu *iommu; @@ -2644,25 +2627,22 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr, iommu = domain_get_iommu(domain); iova = find_iova(&domain->iovad, IOVA_PFN(dev_addr)); - if (WARN_ONCE(!iova, "Driver unmaps unmatched page at PFN %llx\n", - (unsigned long long)dev_addr)) + if (!iova) return; - start_pfn = mm_to_dma_pfn(iova->pfn_lo); - last_pfn = mm_to_dma_pfn(iova->pfn_hi + 1) - 1; + start_addr = iova->pfn_lo << PAGE_SHIFT; + size = aligned_size((u64)dev_addr, size); - pr_debug("Device %s unmapping: pfn %lx-%lx\n", - pci_name(pdev), start_pfn, last_pfn); + pr_debug("Device %s unmapping: %zx@%llx\n", + pci_name(pdev), size, (unsigned long long)start_addr); /* clear the whole page */ - dma_pte_clear_range(domain, start_pfn, last_pfn); - + dma_pte_clear_range(domain, start_addr, start_addr + size); /* free page tables */ - dma_pte_free_pagetable(domain, start_pfn, last_pfn); - + dma_pte_free_pagetable(domain, start_addr, start_addr + size); if (intel_iommu_strict) { - iommu_flush_iotlb_psi(iommu, domain->id, start_pfn, - last_pfn - start_pfn + 1); + iommu_flush_iotlb_psi(iommu, domain->id, start_addr, + size >> VTD_PAGE_SHIFT); /* free iova */ __free_iova(&domain->iovad, iova); } else { @@ -2720,10 +2700,14 @@ static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist, int nelems, enum dma_data_direction dir, struct dma_attrs *attrs) { + int i; struct pci_dev *pdev = to_pci_dev(hwdev); struct dmar_domain *domain; - unsigned long start_pfn, last_pfn; + unsigned long start_addr; struct iova *iova; + size_t size = 0; + phys_addr_t addr; + struct scatterlist *sg; struct intel_iommu *iommu; if (iommu_no_mapping(pdev)) @@ -2735,21 +2719,22 @@ static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist, iommu = domain_get_iommu(domain); iova = find_iova(&domain->iovad, IOVA_PFN(sglist[0].dma_address)); - if (WARN_ONCE(!iova, "Driver unmaps unmatched sglist at PFN %llx\n", - (unsigned long long)sglist[0].dma_address)) + if (!iova) return; + for_each_sg(sglist, sg, nelems, i) { + addr = page_to_phys(sg_page(sg)) + sg->offset; + size += aligned_size((u64)addr, sg->length); + } - start_pfn = mm_to_dma_pfn(iova->pfn_lo); - last_pfn = mm_to_dma_pfn(iova->pfn_hi + 1) - 1; + start_addr = iova->pfn_lo << PAGE_SHIFT; /* clear the whole page */ - dma_pte_clear_range(domain, start_pfn, last_pfn); - + dma_pte_clear_range(domain, start_addr, start_addr + size); /* free page tables */ - dma_pte_free_pagetable(domain, start_pfn, last_pfn); + dma_pte_free_pagetable(domain, start_addr, start_addr + size); - iommu_flush_iotlb_psi(iommu, domain->id, start_pfn, - (last_pfn - start_pfn + 1)); + iommu_flush_iotlb_psi(iommu, domain->id, start_addr, + size >> VTD_PAGE_SHIFT); /* free iova */ __free_iova(&domain->iovad, iova); @@ -2772,16 +2757,17 @@ static int intel_nontranslate_map_sg(struct device *hddev, static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems, enum dma_data_direction dir, struct dma_attrs *attrs) { + phys_addr_t addr; int i; struct pci_dev *pdev = to_pci_dev(hwdev); struct dmar_domain *domain; size_t size = 0; int prot = 0; - size_t offset_pfn = 0; + size_t offset = 0; struct iova *iova = NULL; int ret; struct scatterlist *sg; - unsigned long start_vpfn; + unsigned long start_addr; struct intel_iommu *iommu; BUG_ON(dir == DMA_NONE); @@ -2794,10 +2780,12 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne iommu = domain_get_iommu(domain); - for_each_sg(sglist, sg, nelems, i) - size += aligned_nrpages(sg->offset, sg->length); + for_each_sg(sglist, sg, nelems, i) { + addr = page_to_phys(sg_page(sg)) + sg->offset; + size += aligned_size((u64)addr, sg->length); + } - iova = intel_alloc_iova(hwdev, domain, size, pdev->dma_mask); + iova = __intel_alloc_iova(hwdev, domain, size, pdev->dma_mask); if (!iova) { sglist->dma_length = 0; return 0; @@ -2813,24 +2801,35 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) prot |= DMA_PTE_WRITE; - start_vpfn = mm_to_dma_pfn(iova->pfn_lo); - - ret = domain_sg_mapping(domain, start_vpfn, sglist, mm_to_dma_pfn(size), prot); - if (unlikely(ret)) { - /* clear the page */ - dma_pte_clear_range(domain, start_vpfn, - start_vpfn + size - 1); - /* free page tables */ - dma_pte_free_pagetable(domain, start_vpfn, - start_vpfn + size - 1); - /* free iova */ - __free_iova(&domain->iovad, iova); - return 0; + start_addr = iova->pfn_lo << PAGE_SHIFT; + offset = 0; + for_each_sg(sglist, sg, nelems, i) { + addr = page_to_phys(sg_page(sg)) + sg->offset; + size = aligned_size((u64)addr, sg->length); + ret = domain_page_mapping(domain, start_addr + offset, + ((u64)addr) & PHYSICAL_PAGE_MASK, + size, prot); + if (ret) { + /* clear the page */ + dma_pte_clear_range(domain, start_addr, + start_addr + offset); + /* free page tables */ + dma_pte_free_pagetable(domain, start_addr, + start_addr + offset); + /* free iova */ + __free_iova(&domain->iovad, iova); + return 0; + } + sg->dma_address = start_addr + offset + + ((u64)addr & (~PAGE_MASK)); + sg->dma_length = sg->length; + offset += size; } /* it's a non-present to present mapping. Only flush if caching mode */ if (cap_caching_mode(iommu->cap)) - iommu_flush_iotlb_psi(iommu, 0, start_vpfn, offset_pfn); + iommu_flush_iotlb_psi(iommu, 0, start_addr, + offset >> VTD_PAGE_SHIFT); else iommu_flush_write_buffer(iommu); @@ -3335,6 +3334,7 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width) int adjust_width; init_iova_domain(&domain->iovad, DMA_32BIT_PFN); + spin_lock_init(&domain->mapping_lock); spin_lock_init(&domain->iommu_lock); domain_reserve_special_ranges(domain); @@ -3388,6 +3388,8 @@ static void iommu_free_vm_domain(struct dmar_domain *domain) static void vm_domain_exit(struct dmar_domain *domain) { + u64 end; + /* Domain 0 is reserved, so dont process it */ if (!domain) return; @@ -3395,12 +3397,14 @@ static void vm_domain_exit(struct dmar_domain *domain) vm_domain_remove_all_dev_info(domain); /* destroy iovas */ put_iova_domain(&domain->iovad); + end = DOMAIN_MAX_ADDR(domain->gaw); + end = end & (~VTD_PAGE_MASK); /* clear ptes */ - dma_pte_clear_range(domain, 0, DOMAIN_MAX_PFN(domain->gaw)); + dma_pte_clear_range(domain, 0, end); /* free page tables */ - dma_pte_free_pagetable(domain, 0, DOMAIN_MAX_PFN(domain->gaw)); + dma_pte_free_pagetable(domain, 0, end); iommu_free_vm_domain(domain); free_domain_mem(domain); @@ -3509,7 +3513,7 @@ static int intel_iommu_map_range(struct iommu_domain *domain, if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping) prot |= DMA_PTE_SNP; - max_addr = iova + size; + max_addr = (iova & VTD_PAGE_MASK) + VTD_PAGE_ALIGN(size); if (dmar_domain->max_addr < max_addr) { int min_agaw; u64 end; @@ -3527,11 +3531,8 @@ static int intel_iommu_map_range(struct iommu_domain *domain, } dmar_domain->max_addr = max_addr; } - /* Round up size to next multiple of PAGE_SIZE, if it and - the low bits of hpa would take us onto the next page */ - size = aligned_nrpages(hpa, size); - ret = domain_pfn_mapping(dmar_domain, iova >> VTD_PAGE_SHIFT, - hpa >> VTD_PAGE_SHIFT, size, prot); + + ret = domain_page_mapping(dmar_domain, iova, hpa, size, prot); return ret; } @@ -3539,12 +3540,15 @@ static void intel_iommu_unmap_range(struct iommu_domain *domain, unsigned long iova, size_t size) { struct dmar_domain *dmar_domain = domain->priv; + dma_addr_t base; - dma_pte_clear_range(dmar_domain, iova >> VTD_PAGE_SHIFT, - (iova + size - 1) >> VTD_PAGE_SHIFT); + /* The address might not be aligned */ + base = iova & VTD_PAGE_MASK; + size = VTD_PAGE_ALIGN(size); + dma_pte_clear_range(dmar_domain, base, base + size); - if (dmar_domain->max_addr == iova + size) - dmar_domain->max_addr = iova; + if (dmar_domain->max_addr == base + size) + dmar_domain->max_addr = base; } static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, @@ -3554,7 +3558,7 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, struct dma_pte *pte; u64 phys = 0; - pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT); + pte = addr_to_dma_pte(dmar_domain, iova); if (pte) phys = dma_pte_addr(pte); diff --git a/trunk/drivers/pci/iova.c b/trunk/drivers/pci/iova.c index 46dd440e2315..2287116e9822 100644 --- a/trunk/drivers/pci/iova.c +++ b/trunk/drivers/pci/iova.c @@ -1,19 +1,9 @@ /* - * Copyright © 2006-2009, Intel Corporation. + * Copyright (c) 2006, Intel Corporation. * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. + * This file is released under the GPLv2. * + * Copyright (C) 2006-2008 Intel Corporation * Author: Anil S Keshavamurthy */ @@ -133,15 +123,7 @@ static int __alloc_and_insert_iova_range(struct iova_domain *iovad, /* Insert the new_iova into domain rbtree by holding writer lock */ /* Add new node and rebalance tree. */ { - struct rb_node **entry, *parent = NULL; - - /* If we have 'prev', it's a valid place to start the - insertion. Otherwise, start from the root. */ - if (prev) - entry = &prev; - else - entry = &iovad->rbroot.rb_node; - + struct rb_node **entry = &((prev)), *parent = NULL; /* Figure out where to put new node */ while (*entry) { struct iova *this = container_of(*entry, diff --git a/trunk/drivers/platform/x86/Kconfig b/trunk/drivers/platform/x86/Kconfig index 46dad12f952f..7232fe7104aa 100644 --- a/trunk/drivers/platform/x86/Kconfig +++ b/trunk/drivers/platform/x86/Kconfig @@ -355,7 +355,6 @@ config EEEPC_LAPTOP depends on INPUT depends on EXPERIMENTAL depends on RFKILL || RFKILL = n - depends on HOTPLUG_PCI select BACKLIGHT_CLASS_DEVICE select HWMON ---help--- diff --git a/trunk/drivers/platform/x86/eeepc-laptop.c b/trunk/drivers/platform/x86/eeepc-laptop.c index ec560f16d720..4207b26ff990 100644 --- a/trunk/drivers/platform/x86/eeepc-laptop.c +++ b/trunk/drivers/platform/x86/eeepc-laptop.c @@ -16,8 +16,6 @@ * GNU General Public License for more details. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -33,7 +31,6 @@ #include #include #include -#include #define EEEPC_LAPTOP_VERSION "0.1" @@ -43,6 +40,11 @@ #define EEEPC_HOTK_DEVICE_NAME "Hotkey" #define EEEPC_HOTK_HID "ASUS010" +#define EEEPC_LOG EEEPC_HOTK_FILE ": " +#define EEEPC_ERR KERN_ERR EEEPC_LOG +#define EEEPC_WARNING KERN_WARNING EEEPC_LOG +#define EEEPC_NOTICE KERN_NOTICE EEEPC_LOG +#define EEEPC_INFO KERN_INFO EEEPC_LOG /* * Definitions for Asus EeePC @@ -139,10 +141,8 @@ struct eeepc_hotk { u16 event_count[128]; /* count for each event */ struct input_dev *inputdev; u16 *keycode_map; - struct rfkill *wlan_rfkill; - struct rfkill *bluetooth_rfkill; - struct rfkill *wwan3g_rfkill; - struct hotplug_slot *hotplug_slot; + struct rfkill *eeepc_wlan_rfkill; + struct rfkill *eeepc_bluetooth_rfkill; }; /* The actual device the driver binds to */ @@ -213,15 +213,6 @@ static struct acpi_driver eeepc_hotk_driver = { }, }; -/* PCI hotplug ops */ -static int eeepc_get_adapter_status(struct hotplug_slot *slot, u8 *value); - -static struct hotplug_slot_ops eeepc_hotplug_slot_ops = { - .owner = THIS_MODULE, - .get_adapter_status = eeepc_get_adapter_status, - .get_power_status = eeepc_get_adapter_status, -}; - /* The backlight device /sys/class/backlight */ static struct backlight_device *eeepc_backlight_device; @@ -283,20 +274,20 @@ static int set_acpi(int cm, int value) if (method == NULL) return -ENODEV; if (write_acpi_int(ehotk->handle, method, value, NULL)) - pr_warning("Error writing %s\n", method); + printk(EEEPC_WARNING "Error writing %s\n", method); } return 0; } static int get_acpi(int cm) { - int value = -ENODEV; + int value = -1; if ((ehotk->cm_supported & (0x1 << cm))) { const char *method = cm_getv[cm]; if (method == NULL) return -ENODEV; if (read_acpi_int(ehotk->handle, method, &value)) - pr_warning("Error reading %s\n", method); + printk(EEEPC_WARNING "Error reading %s\n", method); } return value; } @@ -368,19 +359,13 @@ static ssize_t store_sys_acpi(int cm, const char *buf, size_t count) rv = parse_arg(buf, count, &value); if (rv > 0) - value = set_acpi(cm, value); - if (value < 0) - return value; + set_acpi(cm, value); return rv; } static ssize_t show_sys_acpi(int cm, char *buf) { - int value = get_acpi(cm); - - if (value < 0) - return value; - return sprintf(buf, "%d\n", value); + return sprintf(buf, "%d\n", get_acpi(cm)); } #define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \ @@ -554,28 +539,6 @@ static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode) return -EINVAL; } -static void cmsg_quirk(int cm, const char *name) -{ - int dummy; - - /* Some BIOSes do not report cm although it is avaliable. - Check if cm_getv[cm] works and, if yes, assume cm should be set. */ - if (!(ehotk->cm_supported & (1 << cm)) - && !read_acpi_int(ehotk->handle, cm_getv[cm], &dummy)) { - pr_info("%s (%x) not reported by BIOS," - " enabling anyway\n", name, 1 << cm); - ehotk->cm_supported |= 1 << cm; - } -} - -static void cmsg_quirks(void) -{ - cmsg_quirk(CM_ASL_LID, "LID"); - cmsg_quirk(CM_ASL_TYPE, "TYPE"); - cmsg_quirk(CM_ASL_PANELPOWER, "PANELPOWER"); - cmsg_quirk(CM_ASL_TPD, "TPD"); -} - static int eeepc_hotk_check(void) { const struct key_entry *key; @@ -588,24 +551,26 @@ static int eeepc_hotk_check(void) if (ehotk->device->status.present) { if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag, &buffer)) { - pr_err("Hotkey initialization failed\n"); + printk(EEEPC_ERR "Hotkey initialization failed\n"); return -ENODEV; } else { - pr_notice("Hotkey init flags 0x%x\n", ehotk->init_flag); + printk(EEEPC_NOTICE "Hotkey init flags 0x%x\n", + ehotk->init_flag); } /* get control methods supported */ if (read_acpi_int(ehotk->handle, "CMSG" , &ehotk->cm_supported)) { - pr_err("Get control methods supported failed\n"); + printk(EEEPC_ERR + "Get control methods supported failed\n"); return -ENODEV; } else { - cmsg_quirks(); - pr_info("Get control methods supported: 0x%x\n", - ehotk->cm_supported); + printk(EEEPC_INFO + "Get control methods supported: 0x%x\n", + ehotk->cm_supported); } ehotk->inputdev = input_allocate_device(); if (!ehotk->inputdev) { - pr_info("Unable to allocate input device\n"); + printk(EEEPC_INFO "Unable to allocate input device\n"); return 0; } ehotk->inputdev->name = "Asus EeePC extra buttons"; @@ -624,12 +589,12 @@ static int eeepc_hotk_check(void) } result = input_register_device(ehotk->inputdev); if (result) { - pr_info("Unable to register input device\n"); + printk(EEEPC_INFO "Unable to register input device\n"); input_free_device(ehotk->inputdev); return 0; } } else { - pr_err("Hotkey device not present, aborting\n"); + printk(EEEPC_ERR "Hotkey device not present, aborting\n"); return -EINVAL; } return 0; @@ -647,19 +612,6 @@ static int notify_brn(void) return -1; } -static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot, - u8 *value) -{ - int val = get_acpi(CM_ASL_WLAN); - - if (val == 1 || val == 0) - *value = val; - else - return -EINVAL; - - return 0; -} - static void eeepc_rfkill_hotplug(void) { struct pci_dev *dev; @@ -667,7 +619,7 @@ static void eeepc_rfkill_hotplug(void) bool blocked; if (!bus) { - pr_warning("Unable to find PCI bus 1?\n"); + printk(EEEPC_WARNING "Unable to find PCI bus 1?\n"); return; } @@ -683,7 +635,7 @@ static void eeepc_rfkill_hotplug(void) if (dev) { pci_bus_assign_resources(bus); if (pci_bus_add_device(dev)) - pr_err("Unable to hotplug wifi\n"); + printk(EEEPC_ERR "Unable to hotplug wifi\n"); } } else { dev = pci_get_slot(bus, 0); @@ -693,7 +645,7 @@ static void eeepc_rfkill_hotplug(void) } } - rfkill_set_sw_state(ehotk->wlan_rfkill, blocked); + rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, blocked); } static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) @@ -766,7 +718,8 @@ static int eeepc_register_rfkill_notifier(char *node) eeepc_rfkill_notify, NULL); if (ACPI_FAILURE(status)) - pr_warning("Failed to register notify on %s\n", node); + printk(EEEPC_WARNING + "Failed to register notify on %s\n", node); } else return -ENODEV; @@ -785,66 +738,19 @@ static void eeepc_unregister_rfkill_notifier(char *node) ACPI_SYSTEM_NOTIFY, eeepc_rfkill_notify); if (ACPI_FAILURE(status)) - pr_err("Error removing rfkill notify handler %s\n", + printk(EEEPC_ERR + "Error removing rfkill notify handler %s\n", node); } } -static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot) -{ - kfree(hotplug_slot->info); - kfree(hotplug_slot); -} - -static int eeepc_setup_pci_hotplug(void) -{ - int ret = -ENOMEM; - struct pci_bus *bus = pci_find_bus(0, 1); - - if (!bus) { - pr_err("Unable to find wifi PCI bus\n"); - return -ENODEV; - } - - ehotk->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); - if (!ehotk->hotplug_slot) - goto error_slot; - - ehotk->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info), - GFP_KERNEL); - if (!ehotk->hotplug_slot->info) - goto error_info; - - ehotk->hotplug_slot->private = ehotk; - ehotk->hotplug_slot->release = &eeepc_cleanup_pci_hotplug; - ehotk->hotplug_slot->ops = &eeepc_hotplug_slot_ops; - eeepc_get_adapter_status(ehotk->hotplug_slot, - &ehotk->hotplug_slot->info->adapter_status); - - ret = pci_hp_register(ehotk->hotplug_slot, bus, 0, "eeepc-wifi"); - if (ret) { - pr_err("Unable to register hotplug slot - %d\n", ret); - goto error_register; - } - - return 0; - -error_register: - kfree(ehotk->hotplug_slot->info); -error_info: - kfree(ehotk->hotplug_slot); - ehotk->hotplug_slot = NULL; -error_slot: - return ret; -} - static int eeepc_hotk_add(struct acpi_device *device) { int result; if (!device) return -EINVAL; - pr_notice(EEEPC_HOTK_NAME "\n"); + printk(EEEPC_NOTICE EEEPC_HOTK_NAME "\n"); ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL); if (!ehotk) return -ENOMEM; @@ -858,8 +764,53 @@ static int eeepc_hotk_add(struct acpi_device *device) if (result) goto ehotk_fail; + eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); + eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); + + if (get_acpi(CM_ASL_WLAN) != -1) { + ehotk->eeepc_wlan_rfkill = rfkill_alloc("eeepc-wlan", + &device->dev, + RFKILL_TYPE_WLAN, + &eeepc_rfkill_ops, + (void *)CM_ASL_WLAN); + + if (!ehotk->eeepc_wlan_rfkill) + goto wlan_fail; + + rfkill_init_sw_state(ehotk->eeepc_wlan_rfkill, + get_acpi(CM_ASL_WLAN) != 1); + result = rfkill_register(ehotk->eeepc_wlan_rfkill); + if (result) + goto wlan_fail; + } + + if (get_acpi(CM_ASL_BLUETOOTH) != -1) { + ehotk->eeepc_bluetooth_rfkill = + rfkill_alloc("eeepc-bluetooth", + &device->dev, + RFKILL_TYPE_BLUETOOTH, + &eeepc_rfkill_ops, + (void *)CM_ASL_BLUETOOTH); + + if (!ehotk->eeepc_bluetooth_rfkill) + goto bluetooth_fail; + + rfkill_init_sw_state(ehotk->eeepc_bluetooth_rfkill, + get_acpi(CM_ASL_BLUETOOTH) != 1); + result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); + if (result) + goto bluetooth_fail; + } + return 0; + bluetooth_fail: + rfkill_destroy(ehotk->eeepc_bluetooth_rfkill); + rfkill_unregister(ehotk->eeepc_wlan_rfkill); + wlan_fail: + rfkill_destroy(ehotk->eeepc_wlan_rfkill); + eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); + eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); ehotk_fail: kfree(ehotk); ehotk = NULL; @@ -872,13 +823,16 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type) if (!device || !acpi_driver_data(device)) return -EINVAL; + eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); + eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); + kfree(ehotk); return 0; } static int eeepc_hotk_resume(struct acpi_device *device) { - if (ehotk->wlan_rfkill) { + if (ehotk->eeepc_wlan_rfkill) { bool wlan; /* Workaround - it seems that _PTS disables the wireless @@ -890,13 +844,14 @@ static int eeepc_hotk_resume(struct acpi_device *device) wlan = get_acpi(CM_ASL_WLAN); set_acpi(CM_ASL_WLAN, wlan); - rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1); + rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, + wlan != 1); eeepc_rfkill_hotplug(); } - if (ehotk->bluetooth_rfkill) - rfkill_set_sw_state(ehotk->bluetooth_rfkill, + if (ehotk->eeepc_bluetooth_rfkill) + rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill, get_acpi(CM_ASL_BLUETOOTH) != 1); return 0; @@ -1018,16 +973,10 @@ static void eeepc_backlight_exit(void) static void eeepc_rfkill_exit(void) { - eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); - eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); - if (ehotk->wlan_rfkill) - rfkill_unregister(ehotk->wlan_rfkill); - if (ehotk->bluetooth_rfkill) - rfkill_unregister(ehotk->bluetooth_rfkill); - if (ehotk->wwan3g_rfkill) - rfkill_unregister(ehotk->wwan3g_rfkill); - if (ehotk->hotplug_slot) - pci_hp_deregister(ehotk->hotplug_slot); + if (ehotk->eeepc_wlan_rfkill) + rfkill_unregister(ehotk->eeepc_wlan_rfkill); + if (ehotk->eeepc_bluetooth_rfkill) + rfkill_unregister(ehotk->eeepc_bluetooth_rfkill); } static void eeepc_input_exit(void) @@ -1062,75 +1011,6 @@ static void __exit eeepc_laptop_exit(void) platform_driver_unregister(&platform_driver); } -static int eeepc_new_rfkill(struct rfkill **rfkill, - const char *name, struct device *dev, - enum rfkill_type type, int cm) -{ - int result; - - result = get_acpi(cm); - if (result < 0) - return result; - - *rfkill = rfkill_alloc(name, dev, type, - &eeepc_rfkill_ops, (void *)(unsigned long)cm); - - if (!*rfkill) - return -EINVAL; - - rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1); - result = rfkill_register(*rfkill); - if (result) { - rfkill_destroy(*rfkill); - *rfkill = NULL; - return result; - } - return 0; -} - - -static int eeepc_rfkill_init(struct device *dev) -{ - int result = 0; - - eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); - eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); - - result = eeepc_new_rfkill(&ehotk->wlan_rfkill, - "eeepc-wlan", dev, - RFKILL_TYPE_WLAN, CM_ASL_WLAN); - - if (result && result != -ENODEV) - goto exit; - - result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill, - "eeepc-bluetooth", dev, - RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH); - - if (result && result != -ENODEV) - goto exit; - - result = eeepc_new_rfkill(&ehotk->wwan3g_rfkill, - "eeepc-wwan3g", dev, - RFKILL_TYPE_WWAN, CM_ASL_3G); - - if (result && result != -ENODEV) - goto exit; - - result = eeepc_setup_pci_hotplug(); - /* - * If we get -EBUSY then something else is handling the PCI hotplug - - * don't fail in this case - */ - if (result == -EBUSY) - result = 0; - -exit: - if (result && result != -ENODEV) - eeepc_rfkill_exit(); - return result; -} - static int eeepc_backlight_init(struct device *dev) { struct backlight_device *bd; @@ -1138,7 +1018,8 @@ static int eeepc_backlight_init(struct device *dev) bd = backlight_device_register(EEEPC_HOTK_FILE, dev, NULL, &eeepcbl_ops); if (IS_ERR(bd)) { - pr_err("Could not register eeepc backlight device\n"); + printk(EEEPC_ERR + "Could not register eeepc backlight device\n"); eeepc_backlight_device = NULL; return PTR_ERR(bd); } @@ -1157,7 +1038,8 @@ static int eeepc_hwmon_init(struct device *dev) hwmon = hwmon_device_register(dev); if (IS_ERR(hwmon)) { - pr_err("Could not register eeepc hwmon device\n"); + printk(EEEPC_ERR + "Could not register eeepc hwmon device\n"); eeepc_hwmon_device = NULL; return PTR_ERR(hwmon); } @@ -1183,6 +1065,19 @@ static int __init eeepc_laptop_init(void) acpi_bus_unregister_driver(&eeepc_hotk_driver); return -ENODEV; } + dev = acpi_get_physical_device(ehotk->device->handle); + + if (!acpi_video_backlight_support()) { + result = eeepc_backlight_init(dev); + if (result) + goto fail_backlight; + } else + printk(EEEPC_INFO "Backlight controlled by ACPI video " + "driver\n"); + + result = eeepc_hwmon_init(dev); + if (result) + goto fail_hwmon; eeepc_enable_camera(); @@ -1202,33 +1097,7 @@ static int __init eeepc_laptop_init(void) &platform_attribute_group); if (result) goto fail_sysfs; - - dev = &platform_device->dev; - - if (!acpi_video_backlight_support()) { - result = eeepc_backlight_init(dev); - if (result) - goto fail_backlight; - } else - pr_info("Backlight controlled by ACPI video " - "driver\n"); - - result = eeepc_hwmon_init(dev); - if (result) - goto fail_hwmon; - - result = eeepc_rfkill_init(dev); - if (result) - goto fail_rfkill; - return 0; -fail_rfkill: - eeepc_hwmon_exit(); -fail_hwmon: - eeepc_backlight_exit(); -fail_backlight: - sysfs_remove_group(&platform_device->dev.kobj, - &platform_attribute_group); fail_sysfs: platform_device_del(platform_device); fail_platform_device2: @@ -1236,7 +1105,12 @@ static int __init eeepc_laptop_init(void) fail_platform_device1: platform_driver_unregister(&platform_driver); fail_platform_driver: + eeepc_hwmon_exit(); +fail_hwmon: + eeepc_backlight_exit(); +fail_backlight: eeepc_input_exit(); + eeepc_rfkill_exit(); return result; } diff --git a/trunk/drivers/rtc/rtc-bfin.c b/trunk/drivers/rtc/rtc-bfin.c index a118eb0f1e67..aafd3e6ebb0d 100644 --- a/trunk/drivers/rtc/rtc-bfin.c +++ b/trunk/drivers/rtc/rtc-bfin.c @@ -1,8 +1,8 @@ /* * Blackfin On-Chip Real Time Clock Driver - * Supports BF51x/BF52x/BF53[123]/BF53[467]/BF54x + * Supports BF52[257]/BF53[123]/BF53[467]/BF54[24789] * - * Copyright 2004-2009 Analog Devices Inc. + * Copyright 2004-2008 Analog Devices Inc. * * Enter bugs at http://blackfin.uclinux.org/ * @@ -363,7 +363,7 @@ static int __devinit bfin_rtc_probe(struct platform_device *pdev) struct bfin_rtc *rtc; struct device *dev = &pdev->dev; int ret = 0; - unsigned long timeout = jiffies + HZ; + unsigned long timeout; dev_dbg_stamp(dev); @@ -374,32 +374,32 @@ static int __devinit bfin_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rtc); device_init_wakeup(dev, 1); - /* Register our RTC with the RTC framework */ - rtc->rtc_dev = rtc_device_register(pdev->name, dev, &bfin_rtc_ops, - THIS_MODULE); - if (unlikely(IS_ERR(rtc->rtc_dev))) { - ret = PTR_ERR(rtc->rtc_dev); - goto err; - } - /* Grab the IRQ and init the hardware */ ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, IRQF_SHARED, pdev->name, dev); if (unlikely(ret)) - goto err_reg; + goto err; /* sometimes the bootloader touched things, but the write complete was not * enabled, so let's just do a quick timeout here since the IRQ will not fire ... */ + timeout = jiffies + HZ; while (bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING) if (time_after(jiffies, timeout)) break; bfin_rtc_reset(dev, RTC_ISTAT_WRITE_COMPLETE); bfin_write_RTC_SWCNT(0); + /* Register our RTC with the RTC framework */ + rtc->rtc_dev = rtc_device_register(pdev->name, dev, &bfin_rtc_ops, THIS_MODULE); + if (unlikely(IS_ERR(rtc->rtc_dev))) { + ret = PTR_ERR(rtc->rtc_dev); + goto err_irq; + } + return 0; -err_reg: - rtc_device_unregister(rtc->rtc_dev); -err: + err_irq: + free_irq(IRQ_RTC, dev); + err: kfree(rtc); return ret; } diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c index 869a11bdccbd..9928704e235f 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -1095,9 +1095,14 @@ static void adapter_info_rsp(struct srp_event_struct *evt_struct) MAX_INDIRECT_BUFS); hostdata->host->sg_tablesize = MAX_INDIRECT_BUFS; } + + if (hostdata->madapter_info.os_type == 3) { + enable_fast_fail(hostdata); + return; + } } - enable_fast_fail(hostdata); + send_srp_login(hostdata); } /** diff --git a/trunk/drivers/scsi/sg.c b/trunk/drivers/scsi/sg.c index ef142fd47a83..8201387b4daa 100644 --- a/trunk/drivers/scsi/sg.c +++ b/trunk/drivers/scsi/sg.c @@ -210,11 +210,13 @@ static void sg_put_dev(Sg_device *sdp); static int sg_allow_access(struct file *filp, unsigned char *cmd) { struct sg_fd *sfp = (struct sg_fd *)filp->private_data; + struct request_queue *q = sfp->parentdp->device->request_queue; if (sfp->parentdp->device->type == TYPE_SCANNER) return 0; - return blk_verify_command(cmd, filp->f_mode & FMODE_WRITE); + return blk_verify_command(&q->cmd_filter, + cmd, filp->f_mode & FMODE_WRITE); } static int diff --git a/trunk/drivers/serial/8250_pci.c b/trunk/drivers/serial/8250_pci.c index 6160e03f410c..a07015d646dd 100644 --- a/trunk/drivers/serial/8250_pci.c +++ b/trunk/drivers/serial/8250_pci.c @@ -759,8 +759,6 @@ static int pci_netmos_init(struct pci_dev *dev) /* subdevice 0x00PS means

parallel, serial */ unsigned int num_serial = dev->subsystem_device & 0xf; - if (dev->device == PCI_DEVICE_ID_NETMOS_9901) - return 0; if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM && dev->subsystem_device == 0x0299) return 0; @@ -3559,10 +3557,6 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_VENDOR_ID_IBM, 0x0299, 0, 0, pbn_b0_bt_2_115200 }, - { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901, - 0xA000, 0x1000, - 0, 0, pbn_b0_1_115200 }, - /* * These entries match devices with class COMMUNICATION_SERIAL, * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL diff --git a/trunk/drivers/spi/omap_uwire.c b/trunk/drivers/spi/omap_uwire.c index 8980a5640bd9..aa90ddb37066 100644 --- a/trunk/drivers/spi/omap_uwire.c +++ b/trunk/drivers/spi/omap_uwire.c @@ -514,8 +514,6 @@ static int __init uwire_probe(struct platform_device *pdev) /* the spi->mode bits understood by this driver: */ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; - master->flags = SPI_MASTER_HALF_DUPLEX; - master->bus_num = 2; /* "official" */ master->num_chipselect = 4; master->setup = uwire_setup; diff --git a/trunk/drivers/spi/spi_bitbang.c b/trunk/drivers/spi/spi_bitbang.c index f1db395dd889..2a5abc08e857 100644 --- a/trunk/drivers/spi/spi_bitbang.c +++ b/trunk/drivers/spi/spi_bitbang.c @@ -258,11 +258,6 @@ static void bitbang_work(struct work_struct *work) struct spi_bitbang *bitbang = container_of(work, struct spi_bitbang, work); unsigned long flags; - int do_setup = -1; - int (*setup_transfer)(struct spi_device *, - struct spi_transfer *); - - setup_transfer = bitbang->setup_transfer; spin_lock_irqsave(&bitbang->lock, flags); bitbang->busy = 1; @@ -274,6 +269,8 @@ static void bitbang_work(struct work_struct *work) unsigned tmp; unsigned cs_change; int status; + int (*setup_transfer)(struct spi_device *, + struct spi_transfer *); m = container_of(bitbang->queue.next, struct spi_message, queue); @@ -290,19 +287,19 @@ static void bitbang_work(struct work_struct *work) tmp = 0; cs_change = 1; status = 0; + setup_transfer = NULL; list_for_each_entry (t, &m->transfers, transfer_list) { - /* override speed or wordsize? */ - if (t->speed_hz || t->bits_per_word) - do_setup = 1; - - /* init (-1) or override (1) transfer params */ - if (do_setup != 0) { + /* override or restore speed and wordsize */ + if (t->speed_hz || t->bits_per_word) { + setup_transfer = bitbang->setup_transfer; if (!setup_transfer) { status = -ENOPROTOOPT; break; } + } + if (setup_transfer) { status = setup_transfer(spi, t); if (status < 0) break; @@ -366,10 +363,9 @@ static void bitbang_work(struct work_struct *work) m->status = status; m->complete(m->context); - /* restore speed and wordsize if it was overridden */ - if (do_setup == 1) + /* restore speed and wordsize */ + if (setup_transfer) setup_transfer(spi, NULL); - do_setup = 0; /* normally deactivate chipselect ... unless no error and * cs_change has hinted that the next message will probably diff --git a/trunk/drivers/spi/spidev.c b/trunk/drivers/spi/spidev.c index 606e7a40a8da..5d869c4d3eb2 100644 --- a/trunk/drivers/spi/spidev.c +++ b/trunk/drivers/spi/spidev.c @@ -58,20 +58,15 @@ static unsigned long minors[N_SPI_MINORS / BITS_PER_LONG]; /* Bit masks for spi_device.mode management. Note that incorrect - * settings for some settings can cause *lots* of trouble for other - * devices on a shared bus: + * settings for CS_HIGH and 3WIRE can cause *lots* of trouble for other + * devices on a shared bus: CS_HIGH, because this device will be + * active when it shouldn't be; 3WIRE, because when active it won't + * behave as it should. * - * - CS_HIGH ... this device will be active when it shouldn't be - * - 3WIRE ... when active, it won't behave as it should - * - NO_CS ... there will be no explicit message boundaries; this - * is completely incompatible with the shared bus model - * - READY ... transfers may proceed when they shouldn't. - * - * REVISIT should changing those flags be privileged? + * REVISIT should changing those two modes be privileged? */ #define SPI_MODE_MASK (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH \ - | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP \ - | SPI_NO_CS | SPI_READY) + | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP) struct spidev_data { dev_t devt; diff --git a/trunk/drivers/usb/class/cdc-acm.c b/trunk/drivers/usb/class/cdc-acm.c index 3f1045993474..38bfdb0f6660 100644 --- a/trunk/drivers/usb/class/cdc-acm.c +++ b/trunk/drivers/usb/class/cdc-acm.c @@ -550,7 +550,7 @@ static void acm_waker(struct work_struct *waker) static int acm_tty_open(struct tty_struct *tty, struct file *filp) { struct acm *acm; - int rv = -ENODEV; + int rv = -EINVAL; int i; dbg("Entering acm_tty_open."); @@ -677,7 +677,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) /* Perform the closing process and see if we need to do the hardware shutdown */ - if (!acm || tty_port_close_start(&acm->port, tty, filp) == 0) + if (tty_port_close_start(&acm->port, tty, filp) == 0) return; acm_port_down(acm, 0); tty_port_close_end(&acm->port, tty); diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index a84216464ca0..d595aa5586a7 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -333,9 +333,6 @@ static void serial_close(struct tty_struct *tty, struct file *filp) { struct usb_serial_port *port = tty->driver_data; - if (!port) - return; - dbg("%s - port %d", __func__, port->number); diff --git a/trunk/drivers/video/atafb.c b/trunk/drivers/video/atafb.c index 497ff8af03ed..018850c116c6 100644 --- a/trunk/drivers/video/atafb.c +++ b/trunk/drivers/video/atafb.c @@ -2414,10 +2414,7 @@ static int atafb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) if (err) return err; memset(fix, 0, sizeof(struct fb_fix_screeninfo)); - mutex_lock(&info->mm_lock); - err = fbhw->encode_fix(fix, &par); - mutex_unlock(&info->mm_lock); - return err; + return fbhw->encode_fix(fix, &par); } static int atafb_get_var(struct fb_var_screeninfo *var, struct fb_info *info) @@ -2746,9 +2743,7 @@ static int atafb_set_par(struct fb_info *info) /* Decode wanted screen parameters */ fbhw->decode_var(&info->var, par); - mutex_lock(&info->mm_lock); fbhw->encode_fix(&info->fix, par); - mutex_unlock(&info->mm_lock); /* Set new videomode */ ata_set_par(par); diff --git a/trunk/drivers/video/atmel_lcdfb.c b/trunk/drivers/video/atmel_lcdfb.c index cb88394ba995..5afd64482f55 100644 --- a/trunk/drivers/video/atmel_lcdfb.c +++ b/trunk/drivers/video/atmel_lcdfb.c @@ -270,9 +270,7 @@ static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo) smem_len = (var->xres_virtual * var->yres_virtual * ((var->bits_per_pixel + 7) / 8)); - mutex_lock(&info->mm_lock); info->fix.smem_len = max(smem_len, sinfo->smem_len); - mutex_unlock(&info->mm_lock); info->screen_base = dma_alloc_writecombine(info->device, info->fix.smem_len, (dma_addr_t *)&info->fix.smem_start, GFP_KERNEL); diff --git a/trunk/drivers/video/aty/atyfb.h b/trunk/drivers/video/aty/atyfb.h index 1f39a62f899b..7691e73823d3 100644 --- a/trunk/drivers/video/aty/atyfb.h +++ b/trunk/drivers/video/aty/atyfb.h @@ -187,8 +187,6 @@ struct atyfb_par { int mtrr_reg; #endif u32 mem_cntl; - struct crtc saved_crtc; - union aty_pll saved_pll; }; /* @@ -219,7 +217,6 @@ struct atyfb_par { #define M64F_XL_DLL 0x00080000 #define M64F_MFB_FORCE_4 0x00100000 #define M64F_HW_TRIPLE 0x00200000 -#define M64F_XL_MEM 0x00400000 /* * Register access */ diff --git a/trunk/drivers/video/aty/atyfb_base.c b/trunk/drivers/video/aty/atyfb_base.c index 63d3739d43a8..1207c208a30b 100644 --- a/trunk/drivers/video/aty/atyfb_base.c +++ b/trunk/drivers/video/aty/atyfb_base.c @@ -66,8 +66,6 @@ #include #include #include -#include -#include #include #include @@ -251,6 +249,8 @@ static int aty_init(struct fb_info *info); static int store_video_par(char *videopar, unsigned char m64_num); #endif +static struct crtc saved_crtc; +static union aty_pll saved_pll; static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc); static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc); @@ -261,8 +261,6 @@ static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info); static int read_aty_sense(const struct atyfb_par *par); #endif -static DEFINE_MUTEX(reboot_lock); -static struct fb_info *reboot_info; /* * Interface used by the world @@ -363,8 +361,8 @@ static unsigned long phys_guiregbase[FB_MAX] __devinitdata = { 0, }; #define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D) #define ATI_CHIP_264LTPRO (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D) -#define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM) -#define ATI_CHIP_MOBILITY (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM | M64F_MOBIL_BUS) +#define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4) +#define ATI_CHIP_MOBILITY (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_MOBIL_BUS) static struct { u16 pci_id; @@ -541,7 +539,6 @@ static char ram_edo[] __devinitdata = "EDO"; static char ram_sdram[] __devinitdata = "SDRAM (1:1)"; static char ram_sgram[] __devinitdata = "SGRAM (1:1)"; static char ram_sdram32[] __devinitdata = "SDRAM (2:1) (32-bit)"; -static char ram_wram[] __devinitdata = "WRAM"; static char ram_off[] __devinitdata = "OFF"; #endif /* CONFIG_FB_ATY_CT */ @@ -555,10 +552,6 @@ static char *aty_gx_ram[8] __devinitdata = { #ifdef CONFIG_FB_ATY_CT static char *aty_ct_ram[8] __devinitdata = { - ram_off, ram_dram, ram_edo, ram_edo, - ram_sdram, ram_sgram, ram_wram, ram_resv -}; -static char *aty_xl_ram[8] __devinitdata = { ram_off, ram_dram, ram_edo, ram_edo, ram_sdram, ram_sgram, ram_sdram32, ram_resv }; @@ -767,17 +760,6 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc) #endif /* CONFIG_FB_ATY_GENERIC_LCD */ } -static u32 calc_line_length(struct atyfb_par *par, u32 vxres, u32 bpp) -{ - u32 line_length = vxres * bpp / 8; - - if (par->ram_type == SGRAM || - (!M64_HAS(XL_MEM) && par->ram_type == WRAM)) - line_length = (line_length + 63) & ~63; - - return line_length; -} - static int aty_var_to_crtc(const struct fb_info *info, const struct fb_var_screeninfo *var, struct crtc *crtc) { @@ -787,14 +769,13 @@ static int aty_var_to_crtc(const struct fb_info *info, u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol; u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync; u32 pix_width, dp_pix_width, dp_chain_mask; - u32 line_length; /* input */ - xres = (var->xres + 7) & ~7; + xres = var->xres; yres = var->yres; - vxres = (var->xres_virtual + 7) & ~7; + vxres = var->xres_virtual; vyres = var->yres_virtual; - xoffset = (var->xoffset + 7) & ~7; + xoffset = var->xoffset; yoffset = var->yoffset; bpp = var->bits_per_pixel; if (bpp == 16) @@ -846,9 +827,7 @@ static int aty_var_to_crtc(const struct fb_info *info, } else FAIL("invalid bpp"); - line_length = calc_line_length(par, vxres, bpp); - - if (vyres * line_length > info->fix.smem_len) + if (vxres * vyres * bpp / 8 > info->fix.smem_len) FAIL("not enough video RAM"); h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; @@ -990,9 +969,7 @@ static int aty_var_to_crtc(const struct fb_info *info, crtc->xoffset = xoffset; crtc->yoffset = yoffset; crtc->bpp = bpp; - crtc->off_pitch = - ((yoffset * line_length + xoffset * bpp / 8) / 8) | - ((line_length / bpp) << 22); + crtc->off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19); crtc->vline_crnt_vline = 0; crtc->h_tot_disp = h_total | (h_disp<<16); @@ -1417,9 +1394,7 @@ static int atyfb_set_par(struct fb_info *info) } aty_st_8(DAC_MASK, 0xff, par); - info->fix.line_length = calc_line_length(par, var->xres_virtual, - var->bits_per_pixel); - + info->fix.line_length = var->xres_virtual * var->bits_per_pixel/8; info->fix.visual = var->bits_per_pixel <= 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; @@ -1530,12 +1505,10 @@ static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info) { u32 xoffset = info->var.xoffset; u32 yoffset = info->var.yoffset; - u32 line_length = info->fix.line_length; + u32 vxres = par->crtc.vxres; u32 bpp = info->var.bits_per_pixel; - par->crtc.off_pitch = - ((yoffset * line_length + xoffset * bpp / 8) / 8) | - ((line_length / bpp) << 22); + par->crtc.off_pitch = ((yoffset * vxres + xoffset) * bpp / 64) | (vxres << 19); } @@ -2228,7 +2201,7 @@ static void __devinit aty_calc_mem_refresh(struct atyfb_par *par, int xclk) const int *refresh_tbl; int i, size; - if (M64_HAS(XL_MEM)) { + if (IS_XL(par->pci_id) || IS_MOBILITY(par->pci_id)) { refresh_tbl = ragexl_tbl; size = ARRAY_SIZE(ragexl_tbl); } else { @@ -2362,10 +2335,7 @@ static int __devinit aty_init(struct fb_info *info) par->pll_ops = &aty_pll_ct; par->bus_type = PCI; par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07); - if (M64_HAS(XL_MEM)) - ramname = aty_xl_ram[par->ram_type]; - else - ramname = aty_ct_ram[par->ram_type]; + ramname = aty_ct_ram[par->ram_type]; /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM) par->pll_limits.mclk = 63; @@ -2420,9 +2390,9 @@ static int __devinit aty_init(struct fb_info *info) #endif /* CONFIG_FB_ATY_CT */ /* save previous video mode */ - aty_get_crtc(par, &par->saved_crtc); + aty_get_crtc(par, &saved_crtc); if(par->pll_ops->get_pll) - par->pll_ops->get_pll(info, &par->saved_pll); + par->pll_ops->get_pll(info, &saved_pll); par->mem_cntl = aty_ld_le32(MEM_CNTL, par); gtb_memsize = M64_HAS(GTB_DSP); @@ -2697,8 +2667,8 @@ static int __devinit aty_init(struct fb_info *info) aty_init_exit: /* restore video mode */ - aty_set_crtc(par, &par->saved_crtc); - par->pll_ops->set_pll(info, &par->saved_pll); + aty_set_crtc(par, &saved_crtc); + par->pll_ops->set_pll(info, &saved_pll); #ifdef CONFIG_MTRR if (par->mtrr_reg >= 0) { @@ -3532,11 +3502,6 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi par->mmap_map[1].prot_flag = _PAGE_E; #endif /* __sparc__ */ - mutex_lock(&reboot_lock); - if (!reboot_info) - reboot_info = info; - mutex_unlock(&reboot_lock); - return 0; err_release_io: @@ -3649,8 +3614,8 @@ static void __devexit atyfb_remove(struct fb_info *info) struct atyfb_par *par = (struct atyfb_par *) info->par; /* restore video mode */ - aty_set_crtc(par, &par->saved_crtc); - par->pll_ops->set_pll(info, &par->saved_pll); + aty_set_crtc(par, &saved_crtc); + par->pll_ops->set_pll(info, &saved_pll); unregister_framebuffer(info); @@ -3696,11 +3661,6 @@ static void __devexit atyfb_pci_remove(struct pci_dev *pdev) { struct fb_info *info = pci_get_drvdata(pdev); - mutex_lock(&reboot_lock); - if (reboot_info == info) - reboot_info = NULL; - mutex_unlock(&reboot_lock); - atyfb_remove(info); } @@ -3848,56 +3808,6 @@ static int __init atyfb_setup(char *options) } #endif /* MODULE */ -static int atyfb_reboot_notify(struct notifier_block *nb, - unsigned long code, void *unused) -{ - struct atyfb_par *par; - - if (code != SYS_RESTART) - return NOTIFY_DONE; - - mutex_lock(&reboot_lock); - - if (!reboot_info) - goto out; - - if (!lock_fb_info(reboot_info)) - goto out; - - par = reboot_info->par; - - /* - * HP OmniBook 500's BIOS doesn't like the state of the - * hardware after atyfb has been used. Restore the hardware - * to the original state to allow successful reboots. - */ - aty_set_crtc(par, &par->saved_crtc); - par->pll_ops->set_pll(reboot_info, &par->saved_pll); - - unlock_fb_info(reboot_info); - out: - mutex_unlock(&reboot_lock); - - return NOTIFY_DONE; -} - -static struct notifier_block atyfb_reboot_notifier = { - .notifier_call = atyfb_reboot_notify, -}; - -static const struct dmi_system_id atyfb_reboot_ids[] = { - { - .ident = "HP OmniBook 500", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"), - DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook 500 FA"), - }, - }, - - { } -}; - static int __init atyfb_init(void) { int err1 = 1, err2 = 1; @@ -3916,20 +3826,11 @@ static int __init atyfb_init(void) err2 = atyfb_atari_probe(); #endif - if (err1 && err2) - return -ENODEV; - - if (dmi_check_system(atyfb_reboot_ids)) - register_reboot_notifier(&atyfb_reboot_notifier); - - return 0; + return (err1 && err2) ? -ENODEV : 0; } static void __exit atyfb_exit(void) { - if (dmi_check_system(atyfb_reboot_ids)) - unregister_reboot_notifier(&atyfb_reboot_notifier); - #ifdef CONFIG_PCI pci_unregister_driver(&atyfb_driver); #endif diff --git a/trunk/drivers/video/aty/mach64_accel.c b/trunk/drivers/video/aty/mach64_accel.c index 51fcc0a2c94a..0cc9724e61a2 100644 --- a/trunk/drivers/video/aty/mach64_accel.c +++ b/trunk/drivers/video/aty/mach64_accel.c @@ -63,17 +63,14 @@ static void reset_GTC_3D_engine(const struct atyfb_par *par) void aty_init_engine(struct atyfb_par *par, struct fb_info *info) { u32 pitch_value; - u32 vxres; /* determine modal information from global mode structure */ - pitch_value = info->fix.line_length / (info->var.bits_per_pixel / 8); - vxres = info->var.xres_virtual; + pitch_value = info->var.xres_virtual; if (info->var.bits_per_pixel == 24) { /* In 24 bpp, the engine is in 8 bpp - this requires that all */ /* horizontal coordinates and widths must be adjusted */ pitch_value *= 3; - vxres *= 3; } /* On GTC (RagePro), we need to reset the 3D engine before */ @@ -136,7 +133,7 @@ void aty_init_engine(struct atyfb_par *par, struct fb_info *info) aty_st_le32(SC_LEFT, 0, par); aty_st_le32(SC_TOP, 0, par); aty_st_le32(SC_BOTTOM, par->crtc.vyres - 1, par); - aty_st_le32(SC_RIGHT, vxres - 1, par); + aty_st_le32(SC_RIGHT, pitch_value - 1, par); /* set background color to minimum value (usually BLACK) */ aty_st_le32(DP_BKGD_CLR, 0, par); diff --git a/trunk/drivers/video/backlight/tdo24m.c b/trunk/drivers/video/backlight/tdo24m.c index 51422fc4f606..1dae7f8f3c6b 100644 --- a/trunk/drivers/video/backlight/tdo24m.c +++ b/trunk/drivers/video/backlight/tdo24m.c @@ -356,7 +356,7 @@ static int __devinit tdo24m_probe(struct spi_device *spi) lcd->power = FB_BLANK_POWERDOWN; lcd->mode = MODE_VGA; /* default to VGA */ - lcd->buf = kmalloc(TDO24M_SPI_BUFF_SIZE, GFP_KERNEL); + lcd->buf = kmalloc(TDO24M_SPI_BUFF_SIZE, sizeof(GFP_KERNEL)); if (lcd->buf == NULL) { kfree(lcd); return -ENOMEM; diff --git a/trunk/drivers/video/fbmem.c b/trunk/drivers/video/fbmem.c index 53ea05645ff8..f8a09bf8d0cd 100644 --- a/trunk/drivers/video/fbmem.c +++ b/trunk/drivers/video/fbmem.c @@ -1310,6 +1310,8 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd, static int fb_mmap(struct file *file, struct vm_area_struct * vma) +__acquires(&info->lock) +__releases(&info->lock) { int fbidx = iminor(file->f_path.dentry->d_inode); struct fb_info *info = registered_fb[fbidx]; @@ -1323,14 +1325,16 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) off = vma->vm_pgoff << PAGE_SHIFT; if (!fb) return -ENODEV; - mutex_lock(&info->mm_lock); if (fb->fb_mmap) { int res; + mutex_lock(&info->lock); res = fb->fb_mmap(info, vma); - mutex_unlock(&info->mm_lock); + mutex_unlock(&info->lock); return res; } + mutex_lock(&info->lock); + /* frame buffer memory */ start = info->fix.smem_start; len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); @@ -1338,13 +1342,13 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) /* memory mapped io */ off -= len; if (info->var.accel_flags) { - mutex_unlock(&info->mm_lock); + mutex_unlock(&info->lock); return -EINVAL; } start = info->fix.mmio_start; len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); } - mutex_unlock(&info->mm_lock); + mutex_unlock(&info->lock); start &= PAGE_MASK; if ((vma->vm_end - vma->vm_start + off) > len) return -EINVAL; @@ -1514,7 +1518,6 @@ register_framebuffer(struct fb_info *fb_info) break; fb_info->node = i; mutex_init(&fb_info->lock); - mutex_init(&fb_info->mm_lock); fb_info->dev = device_create(fb_class, fb_info->device, MKDEV(FB_MAJOR, i), NULL, "fb%d", i); diff --git a/trunk/drivers/video/fsl-diu-fb.c b/trunk/drivers/video/fsl-diu-fb.c index 0bf2190928d0..f153c581cbd7 100644 --- a/trunk/drivers/video/fsl-diu-fb.c +++ b/trunk/drivers/video/fsl-diu-fb.c @@ -750,26 +750,24 @@ static void update_lcdc(struct fb_info *info) static int map_video_memory(struct fb_info *info) { phys_addr_t phys; - u32 smem_len = info->fix.line_length * info->var.yres_virtual; pr_debug("info->var.xres_virtual = %d\n", info->var.xres_virtual); pr_debug("info->var.yres_virtual = %d\n", info->var.yres_virtual); pr_debug("info->fix.line_length = %d\n", info->fix.line_length); - pr_debug("MAP_VIDEO_MEMORY: smem_len = %u\n", smem_len); - info->screen_base = fsl_diu_alloc(smem_len, &phys); + info->fix.smem_len = info->fix.line_length * info->var.yres_virtual; + pr_debug("MAP_VIDEO_MEMORY: smem_len = %d\n", info->fix.smem_len); + info->screen_base = fsl_diu_alloc(info->fix.smem_len, &phys); if (info->screen_base == NULL) { printk(KERN_ERR "Unable to allocate fb memory\n"); return -ENOMEM; } - mutex_lock(&info->mm_lock); info->fix.smem_start = (unsigned long) phys; - info->fix.smem_len = smem_len; - mutex_unlock(&info->mm_lock); info->screen_size = info->fix.smem_len; pr_debug("Allocated fb @ paddr=0x%08lx, size=%d.\n", - info->fix.smem_start, info->fix.smem_len); + info->fix.smem_start, + info->fix.smem_len); pr_debug("screen base %p\n", info->screen_base); return 0; @@ -778,11 +776,9 @@ static int map_video_memory(struct fb_info *info) static void unmap_video_memory(struct fb_info *info) { fsl_diu_free(info->screen_base, info->fix.smem_len); - mutex_lock(&info->mm_lock); info->screen_base = NULL; info->fix.smem_start = 0; info->fix.smem_len = 0; - mutex_unlock(&info->mm_lock); } /* diff --git a/trunk/drivers/video/i810/i810_main.c b/trunk/drivers/video/i810/i810_main.c index 71960672d721..2e940199fc89 100644 --- a/trunk/drivers/video/i810/i810_main.c +++ b/trunk/drivers/video/i810/i810_main.c @@ -1090,10 +1090,8 @@ static int encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) memset(fix, 0, sizeof(struct fb_fix_screeninfo)); strcpy(fix->id, "I810"); - mutex_lock(&info->mm_lock); fix->smem_start = par->fb.physical; fix->smem_len = par->fb.size; - mutex_unlock(&info->mm_lock); fix->type = FB_TYPE_PACKED_PIXELS; fix->type_aux = 0; fix->xpanstep = 8; diff --git a/trunk/drivers/video/matrox/matroxfb_base.c b/trunk/drivers/video/matrox/matroxfb_base.c index 59c3a2e14913..8e7a275df50c 100644 --- a/trunk/drivers/video/matrox/matroxfb_base.c +++ b/trunk/drivers/video/matrox/matroxfb_base.c @@ -724,10 +724,8 @@ static void matroxfb_update_fix(WPMINFO2) struct fb_fix_screeninfo *fix = &ACCESS_FBINFO(fbcon).fix; DBG(__func__) - mutex_lock(&ACCESS_FBINFO(fbcon).mm_lock); fix->smem_start = ACCESS_FBINFO(video.base) + ACCESS_FBINFO(curr.ydstorg.bytes); fix->smem_len = ACCESS_FBINFO(video.len_usable) - ACCESS_FBINFO(curr.ydstorg.bytes); - mutex_unlock(&ACCESS_FBINFO(fbcon).mm_lock); } static int matroxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) @@ -2083,7 +2081,6 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm spin_lock_init(&ACCESS_FBINFO(lock.accel)); init_rwsem(&ACCESS_FBINFO(crtc2.lock)); init_rwsem(&ACCESS_FBINFO(altout.lock)); - mutex_init(&ACCESS_FBINFO(fbcon).mm_lock); ACCESS_FBINFO(irq_flags) = 0; init_waitqueue_head(&ACCESS_FBINFO(crtc1.vsync.wait)); init_waitqueue_head(&ACCESS_FBINFO(crtc2.vsync.wait)); diff --git a/trunk/drivers/video/matrox/matroxfb_crtc2.c b/trunk/drivers/video/matrox/matroxfb_crtc2.c index 909e10a11898..7ac4c5f6145d 100644 --- a/trunk/drivers/video/matrox/matroxfb_crtc2.c +++ b/trunk/drivers/video/matrox/matroxfb_crtc2.c @@ -289,16 +289,13 @@ static int matroxfb_dh_release(struct fb_info* info, int user) { #undef m2info } -static void matroxfb_dh_init_fix(struct matroxfb_dh_fb_info *m2info) -{ +static void matroxfb_dh_init_fix(struct matroxfb_dh_fb_info *m2info) { struct fb_fix_screeninfo *fix = &m2info->fbcon.fix; strcpy(fix->id, "MATROX DH"); - mutex_lock(&m2info->fbcon.mm_lock); fix->smem_start = m2info->video.base; fix->smem_len = m2info->video.len_usable; - mutex_unlock(&m2info->fbcon.mm_lock); fix->ypanstep = 1; fix->ywrapstep = 0; fix->xpanstep = 8; /* TBD */ diff --git a/trunk/drivers/video/mx3fb.c b/trunk/drivers/video/mx3fb.c index 567fb944bd2a..b7af5256e887 100644 --- a/trunk/drivers/video/mx3fb.c +++ b/trunk/drivers/video/mx3fb.c @@ -669,7 +669,7 @@ static uint32_t bpp_to_pixfmt(int bpp) } static int mx3fb_blank(int blank, struct fb_info *fbi); -static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len); +static int mx3fb_map_video_memory(struct fb_info *fbi); static int mx3fb_unmap_video_memory(struct fb_info *fbi); /** @@ -742,7 +742,8 @@ static int mx3fb_set_par(struct fb_info *fbi) if (fbi->fix.smem_start) mx3fb_unmap_video_memory(fbi); - if (mx3fb_map_video_memory(fbi, mem_len) < 0) { + fbi->fix.smem_len = mem_len; + if (mx3fb_map_video_memory(fbi) < 0) { mutex_unlock(&mx3_fbi->mutex); return -ENOMEM; } @@ -1197,7 +1198,6 @@ static int mx3fb_resume(struct platform_device *pdev) /** * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer. * @fbi: framebuffer information pointer - * @mem_len: length of mapped memory * @return: Error code indicating success or failure * * This buffer is remapped into a non-cached, non-buffered, memory region to @@ -1205,26 +1205,23 @@ static int mx3fb_resume(struct platform_device *pdev) * area is remapped, all virtual memory access to the video memory should occur * at the new region. */ -static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len) +static int mx3fb_map_video_memory(struct fb_info *fbi) { int retval = 0; dma_addr_t addr; fbi->screen_base = dma_alloc_writecombine(fbi->device, - mem_len, + fbi->fix.smem_len, &addr, GFP_DMA); if (!fbi->screen_base) { dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n", - mem_len); + fbi->fix.smem_len); retval = -EBUSY; goto err0; } - mutex_lock(&fbi->mm_lock); fbi->fix.smem_start = addr; - fbi->fix.smem_len = mem_len; - mutex_unlock(&fbi->mm_lock); dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n", (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len); @@ -1254,10 +1251,8 @@ static int mx3fb_unmap_video_memory(struct fb_info *fbi) fbi->screen_base, fbi->fix.smem_start); fbi->screen_base = 0; - mutex_lock(&fbi->mm_lock); fbi->fix.smem_start = 0; fbi->fix.smem_len = 0; - mutex_unlock(&fbi->mm_lock); return 0; } diff --git a/trunk/drivers/video/omap/omapfb_main.c b/trunk/drivers/video/omap/omapfb_main.c index 4ea99bfc37b4..060d72fe57cb 100644 --- a/trunk/drivers/video/omap/omapfb_main.c +++ b/trunk/drivers/video/omap/omapfb_main.c @@ -393,10 +393,8 @@ static void set_fb_fix(struct fb_info *fbi) rg = &plane->fbdev->mem_desc.region[plane->idx]; fbi->screen_base = rg->vaddr; - mutex_lock(&fbi->mm_lock); fix->smem_start = rg->paddr; fix->smem_len = rg->size; - mutex_unlock(&fbi->mm_lock); fix->type = FB_TYPE_PACKED_PIXELS; bpp = var->bits_per_pixel; @@ -888,10 +886,8 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi) * plane memory is dealloce'd, the other * screen parameters in var / fix are invalid. */ - mutex_lock(&fbi->mm_lock); fbi->fix.smem_start = 0; fbi->fix.smem_len = 0; - mutex_unlock(&fbi->mm_lock); } } } diff --git a/trunk/drivers/video/platinumfb.c b/trunk/drivers/video/platinumfb.c index bacfabd9ce16..03b3670130a0 100644 --- a/trunk/drivers/video/platinumfb.c +++ b/trunk/drivers/video/platinumfb.c @@ -141,9 +141,7 @@ static int platinumfb_set_par (struct fb_info *info) offset = 0x10; info->screen_base = pinfo->frame_buffer + init->fb_offset + offset; - mutex_lock(&info->mm_lock); info->fix.smem_start = (pinfo->frame_buffer_phys) + init->fb_offset + offset; - mutex_unlock(&info->mm_lock); info->fix.visual = (pinfo->cmode == CMODE_8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; info->fix.line_length = vmode_attrs[pinfo->vmode-1].hres * (1<cmode) diff --git a/trunk/drivers/video/pxafb.c b/trunk/drivers/video/pxafb.c index 6506117c134b..0889d50c3288 100644 --- a/trunk/drivers/video/pxafb.c +++ b/trunk/drivers/video/pxafb.c @@ -815,10 +815,8 @@ static int overlayfb_map_video_memory(struct pxafb_layer *ofb) ofb->video_mem_phys = virt_to_phys(ofb->video_mem); ofb->video_mem_size = size; - mutex_lock(&ofb->fb.mm_lock); ofb->fb.fix.smem_start = ofb->video_mem_phys; ofb->fb.fix.smem_len = ofb->fb.fix.line_length * var->yres_virtual; - mutex_unlock(&ofb->fb.mm_lock); ofb->fb.screen_base = ofb->video_mem; return 0; } diff --git a/trunk/drivers/video/sh7760fb.c b/trunk/drivers/video/sh7760fb.c index 9f6d6e61f0cc..653bdfee3057 100644 --- a/trunk/drivers/video/sh7760fb.c +++ b/trunk/drivers/video/sh7760fb.c @@ -120,6 +120,18 @@ static int sh7760_setcolreg (u_int regno, return 0; } +static void encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info, + unsigned long stride) +{ + memset(fix, 0, sizeof(struct fb_fix_screeninfo)); + strcpy(fix->id, "sh7760-lcdc"); + + fix->smem_start = (unsigned long)info->screen_base; + fix->smem_len = info->screen_size; + + fix->line_length = stride; +} + static int sh7760fb_get_color_info(struct device *dev, u16 lddfr, int *bpp, int *gray) { @@ -322,8 +334,7 @@ static int sh7760fb_set_par(struct fb_info *info) iowrite32(ldsarl, par->base + LDSARL); /* mem for lower half of DSTN */ - info->fix.line_length = stride; - + encode_fix(&info->fix, info, stride); sh7760fb_check_var(&info->var, info); sh7760fb_blank(FB_BLANK_UNBLANK, info); /* panel on! */ @@ -424,8 +435,6 @@ static int sh7760fb_alloc_mem(struct fb_info *info) info->screen_base = fbmem; info->screen_size = vram; - info->fix.smem_start = (unsigned long)info->screen_base; - info->fix.smem_len = info->screen_size; return 0; } @@ -511,8 +520,6 @@ static int __devinit sh7760fb_probe(struct platform_device *pdev) info->var.transp.length = 0; info->var.transp.msb_right = 0; - strcpy(info->fix.id, "sh7760-lcdc"); - /* set the DON2 bit now, before cmap allocation, as it will randomize * palette memory. */ diff --git a/trunk/drivers/video/sh_mobile_lcdcfb.c b/trunk/drivers/video/sh_mobile_lcdcfb.c index da983b720f08..f10d2fbeda06 100644 --- a/trunk/drivers/video/sh_mobile_lcdcfb.c +++ b/trunk/drivers/video/sh_mobile_lcdcfb.c @@ -17,7 +17,6 @@ #include #include #include -#include #include