diff --git a/[refs] b/[refs] index 79667f5e3943..56be2a2ec845 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 259cdbee2094d28b72f0f3d77bc9203d682994ff +refs/heads/master: 2066306099d35430d01ed1b3d81c0536d77bf390 diff --git a/trunk/CREDITS b/trunk/CREDITS index 2346b09ca8bb..d8fe12a9421f 100644 --- a/trunk/CREDITS +++ b/trunk/CREDITS @@ -1823,11 +1823,6 @@ S: Kattreinstr 38 S: D-64295 S: Germany -N: Avi Kivity -E: avi.kivity@gmail.com -D: Kernel-based Virtual Machine (KVM) -S: Ra'annana, Israel - N: Andi Kleen E: andi@firstfloor.org U: http://www.halobates.de diff --git a/trunk/Documentation/00-INDEX b/trunk/Documentation/00-INDEX index ceb1ff735469..f54273e2ac97 100644 --- a/trunk/Documentation/00-INDEX +++ b/trunk/Documentation/00-INDEX @@ -210,8 +210,6 @@ local_ops.txt - semantics and behavior of local atomic operations. lockdep-design.txt - documentation on the runtime locking correctness validator. -lockup-watchdogs.txt - - info on soft and hard lockup detectors (aka nmi_watchdog). logo.gif - full colour GIF image of Linux logo (penguin - Tux). logo.txt @@ -242,6 +240,8 @@ netlabel/ - directory with information on the NetLabel subsystem. networking/ - directory with info on various aspects of networking with Linux. +nmi_watchdog.txt + - info on NMI watchdog for SMP systems. nommu-mmap.txt - documentation about no-mmu memory mapping support. numastat.txt diff --git a/trunk/Documentation/IRQ-domain.txt b/trunk/Documentation/IRQ-domain.txt index 9bc95942ec22..1401cece745a 100644 --- a/trunk/Documentation/IRQ-domain.txt +++ b/trunk/Documentation/IRQ-domain.txt @@ -7,21 +7,6 @@ systems with multiple interrupt controllers the kernel must ensure that each one gets assigned non-overlapping allocations of Linux IRQ numbers. -The number of interrupt controllers registered as unique irqchips -show a rising tendency: for example subdrivers of different kinds -such as GPIO controllers avoid reimplementing identical callback -mechanisms as the IRQ core system by modelling their interrupt -handlers as irqchips, i.e. in effect cascading interrupt controllers. - -Here the interrupt number loose all kind of correspondence to -hardware interrupt numbers: whereas in the past, IRQ numbers could -be chosen so they matched the hardware IRQ line into the root -interrupt controller (i.e. the component actually fireing the -interrupt line to the CPU) nowadays this number is just a number. - -For this reason we need a mechanism to separate controller-local -interrupt numbers, called hardware irq's, from Linux IRQ numbers. - The irq_alloc_desc*() and irq_free_desc*() APIs provide allocation of irq numbers, but they don't provide any support for reverse mapping of the controller-local IRQ (hwirq) number into the Linux IRQ number @@ -55,10 +40,6 @@ required hardware setup. When an interrupt is received, irq_find_mapping() function should be used to find the Linux IRQ number from the hwirq number. -The irq_create_mapping() function must be called *atleast once* -before any call to irq_find_mapping(), lest the descriptor will not -be allocated. - If the driver has the Linux IRQ number or the irq_data pointer, and needs to know the associated hwirq number (such as in the irq_chip callbacks) then it can be directly obtained from irq_data->hwirq. @@ -138,17 +119,4 @@ numbers. Most users of legacy mappings should use irq_domain_add_simple() which will use a legacy domain only if an IRQ range is supplied by the -system and will otherwise use a linear domain mapping. The semantics -of this call are such that if an IRQ range is specified then -descriptors will be allocated on-the-fly for it, and if no range is -specified it will fall through to irq_domain_add_linear() which meand -*no* irq descriptors will be allocated. - -A typical use case for simple domains is where an irqchip provider -is supporting both dynamic and static IRQ assignments. - -In order to avoid ending up in a situation where a linear domain is -used and no descriptor gets allocated it is very important to make sure -that the driver using the simple domain call irq_create_mapping() -before any irq_find_mapping() since the latter will actually work -for the static IRQ assignment case. +system and will otherwise use a linear domain mapping. diff --git a/trunk/Documentation/arm64/memory.txt b/trunk/Documentation/arm64/memory.txt index 4110cca96bd6..dbbdcbba75a3 100644 --- a/trunk/Documentation/arm64/memory.txt +++ b/trunk/Documentation/arm64/memory.txt @@ -27,17 +27,17 @@ Start End Size Use ----------------------------------------------------------------------- 0000000000000000 0000007fffffffff 512GB user -ffffff8000000000 ffffffbbfffeffff ~240GB vmalloc +ffffff8000000000 ffffffbbfffcffff ~240GB vmalloc -ffffffbbffff0000 ffffffbbffffffff 64KB [guard page] +ffffffbbfffd0000 ffffffbcfffdffff 64KB [guard page] -ffffffbc00000000 ffffffbdffffffff 8GB vmemmap +ffffffbbfffe0000 ffffffbcfffeffff 64KB PCI I/O space -ffffffbe00000000 ffffffbffbbfffff ~8GB [guard, future vmmemap] +ffffffbbffff0000 ffffffbcffffffff 64KB [guard page] -ffffffbffbe00000 ffffffbffbe0ffff 64KB PCI I/O space +ffffffbc00000000 ffffffbdffffffff 8GB vmemmap -ffffffbbffff0000 ffffffbcffffffff ~2MB [guard] +ffffffbe00000000 ffffffbffbffffff ~8GB [guard, future vmmemap] ffffffbffc000000 ffffffbfffffffff 64MB modules diff --git a/trunk/Documentation/cgroups/memory.txt b/trunk/Documentation/cgroups/memory.txt index 71c4da413444..c07f7b4fb88d 100644 --- a/trunk/Documentation/cgroups/memory.txt +++ b/trunk/Documentation/cgroups/memory.txt @@ -466,10 +466,6 @@ Note: 5.3 swappiness Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only. -Please note that unlike the global swappiness, memcg knob set to 0 -really prevents from any swapping even if there is a swap storage -available. This might lead to memcg OOM killer if there are no file -pages to reclaim. Following cgroups' swappiness can't be changed. - root cgroup (uses /proc/sys/vm/swappiness). diff --git a/trunk/Documentation/devicetree/bindings/arm/atmel-at91.txt b/trunk/Documentation/devicetree/bindings/arm/atmel-at91.txt index 1196290082d1..ecc81e368715 100644 --- a/trunk/Documentation/devicetree/bindings/arm/atmel-at91.txt +++ b/trunk/Documentation/devicetree/bindings/arm/atmel-at91.txt @@ -7,14 +7,8 @@ PIT Timer required properties: - interrupts: Should contain interrupt for the PIT which is the IRQ line shared across all System Controller members. -System Timer (ST) required properties: -- compatible: Should be "atmel,at91rm9200-st" -- reg: Should contain registers location and length -- interrupts: Should contain interrupt for the ST which is the IRQ line - shared across all System Controller members. - TC/TCLIB Timer required properties: -- compatible: Should be "atmel,-tcb". +- compatible: Should be "atmel,-pit". can be "at91rm9200" or "at91sam9x5" - reg: Should contain registers location and length - interrupts: Should contain all interrupts for the TC block diff --git a/trunk/Documentation/devicetree/bindings/arm/l2cc.txt b/trunk/Documentation/devicetree/bindings/arm/l2cc.txt index 7ca52161e7ab..7c3ee3aeb7b7 100644 --- a/trunk/Documentation/devicetree/bindings/arm/l2cc.txt +++ b/trunk/Documentation/devicetree/bindings/arm/l2cc.txt @@ -37,7 +37,7 @@ L2: cache-controller { reg = <0xfff12000 0x1000>; arm,data-latency = <1 1 1>; arm,tag-latency = <2 2 2>; - arm,filter-latency = <0x80000000 0x8000000>; + arm,filter-ranges = <0x80000000 0x8000000>; cache-unified; cache-level = <2>; interrupts = <45>; diff --git a/trunk/Documentation/devicetree/bindings/clock/imx23-clock.txt b/trunk/Documentation/devicetree/bindings/clock/imx23-clock.txt index baadbb11fe98..a0b867ef8d96 100644 --- a/trunk/Documentation/devicetree/bindings/clock/imx23-clock.txt +++ b/trunk/Documentation/devicetree/bindings/clock/imx23-clock.txt @@ -52,7 +52,7 @@ clocks and IDs. lcdif 38 etm 39 usb 40 - usb_phy 41 + usb_pwr 41 Examples: diff --git a/trunk/Documentation/devicetree/bindings/clock/imx28-clock.txt b/trunk/Documentation/devicetree/bindings/clock/imx28-clock.txt index 52a49a4a50b3..aa2af2866fe8 100644 --- a/trunk/Documentation/devicetree/bindings/clock/imx28-clock.txt +++ b/trunk/Documentation/devicetree/bindings/clock/imx28-clock.txt @@ -73,8 +73,8 @@ clocks and IDs. can1 59 usb0 60 usb1 61 - usb0_phy 62 - usb1_phy 63 + usb0_pwr 62 + usb1_pwr 63 enet_out 64 Examples: diff --git a/trunk/Documentation/devicetree/bindings/gpio/gpio.txt b/trunk/Documentation/devicetree/bindings/gpio/gpio.txt index a33628759d36..4e16ba4feab0 100644 --- a/trunk/Documentation/devicetree/bindings/gpio/gpio.txt +++ b/trunk/Documentation/devicetree/bindings/gpio/gpio.txt @@ -75,40 +75,4 @@ Example of two SOC GPIO banks defined as gpio-controller nodes: gpio-controller; }; -2.1) gpio-controller and pinctrl subsystem ------------------------------------------- -gpio-controller on a SOC might be tightly coupled with the pinctrl -subsystem, in the sense that the pins can be used by other functions -together with optional gpio feature. - -While the pin allocation is totally managed by the pin ctrl subsystem, -gpio (under gpiolib) is still maintained by gpio drivers. It may happen -that different pin ranges in a SoC is managed by different gpio drivers. - -This makes it logical to let gpio drivers announce their pin ranges to -the pin ctrl subsystem and call 'pinctrl_request_gpio' in order to -request the corresponding pin before any gpio usage. - -For this, the gpio controller can use a pinctrl phandle and pins to -announce the pinrange to the pin ctrl subsystem. For example, - - qe_pio_e: gpio-controller@1460 { - #gpio-cells = <2>; - compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank"; - reg = <0x1460 0x18>; - gpio-controller; - gpio-ranges = <&pinctrl1 20 10>, <&pinctrl2 50 20>; - - } - -where, - &pinctrl1 and &pinctrl2 is the phandle to the pinctrl DT node. - - Next values specify the base pin and number of pins for the range - handled by 'qe_pio_e' gpio. In the given example from base pin 20 to - pin 29 under pinctrl1 and pin 50 to pin 69 under pinctrl2 is handled - by this gpio controller. - -The pinctrl node must have "#gpio-range-cells" property to show number of -arguments to pass with phandle from gpio controllers node. diff --git a/trunk/Documentation/devicetree/bindings/gpio/gpio_atmel.txt b/trunk/Documentation/devicetree/bindings/gpio/gpio_atmel.txt index 85f8c0d084fa..66efc804806a 100644 --- a/trunk/Documentation/devicetree/bindings/gpio/gpio_atmel.txt +++ b/trunk/Documentation/devicetree/bindings/gpio/gpio_atmel.txt @@ -9,10 +9,6 @@ Required properties: unused). - gpio-controller: Marks the device node as a GPIO controller. -optional properties: -- #gpio-lines: Number of gpio if absent 32. - - Example: pioA: gpio@fffff200 { compatible = "atmel,at91rm9200-gpio"; @@ -20,6 +16,5 @@ Example: interrupts = <2 4>; #gpio-cells = <2>; gpio-controller; - #gpio-lines = <19>; }; diff --git a/trunk/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt b/trunk/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt deleted file mode 100644 index df70318a617f..000000000000 --- a/trunk/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt +++ /dev/null @@ -1,19 +0,0 @@ -* EETI eGalax Multiple Touch Controller - -Required properties: -- compatible: must be "eeti,egalax_ts" -- reg: i2c slave address -- interrupt-parent: the phandle for the interrupt controller -- interrupts: touch controller interrupt -- wakeup-gpios: the gpio pin to be used for waking up the controller - as well as uased as irq pin - -Example: - - egalax_ts@04 { - compatible = "eeti,egalax_ts"; - reg = <0x04>; - interrupt-parent = <&gpio1>; - interrupts = <9 2>; - wakeup-gpios = <&gpio1 9 0>; - }; diff --git a/trunk/Documentation/devicetree/bindings/mmc/mmc.txt b/trunk/Documentation/devicetree/bindings/mmc/mmc.txt index a591c6741d75..8e2e0ba2f486 100644 --- a/trunk/Documentation/devicetree/bindings/mmc/mmc.txt +++ b/trunk/Documentation/devicetree/bindings/mmc/mmc.txt @@ -21,12 +21,6 @@ Optional properties: - cd-inverted: when present, polarity on the cd gpio line is inverted - wp-inverted: when present, polarity on the wp gpio line is inverted - max-frequency: maximum operating clock frequency -- no-1-8-v: when present, denotes that 1.8v card voltage is not supported on - this system, even if the controller claims it is. - -Optional SDIO properties: -- keep-power-in-suspend: Preserves card power during a suspend/resume cycle -- enable-sdio-wakeup: Enables wake up of host system on SDIO IRQ assertion Example: @@ -39,6 +33,4 @@ sdhci@ab000000 { cd-inverted; wp-gpios = <&gpio 70 0>; max-frequency = <50000000>; - keep-power-in-suspend; - enable-sdio-wakeup; } diff --git a/trunk/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt b/trunk/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt index 97e9e315400d..630a7d7f4718 100644 --- a/trunk/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt +++ b/trunk/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt @@ -12,6 +12,10 @@ is used. The Samsung's SDHCI controller bindings extends this as listed below. [A] The property "samsung,cd-pinmux-gpio" can be used as stated in the "Optional Board Specific Properties" section below. +[B] If core card-detect bindings and "samsung,cd-pinmux-gpio" property + is not specified, it is assumed that there is no card detection + mechanism used. + Required SoC Specific Properties: - compatible: should be one of the following - "samsung,s3c6410-sdhci": For controllers compatible with s3c6410 sdhci @@ -20,18 +24,14 @@ Required SoC Specific Properties: controller. Required Board Specific Properties: -- Samsung GPIO variant (will be completely replaced by pinctrl): - - gpios: Should specify the gpios used for clock, command and data lines. The - gpio specifier format depends on the gpio controller. -- Pinctrl variant (preferred if available): - - pinctrl-0: Should specify pin control groups used for this controller. - - pinctrl-names: Should contain only one value - "default". +- gpios: Should specify the gpios used for clock, command and data lines. The + gpio specifier format depends on the gpio controller. Optional Board Specific Properties: - samsung,cd-pinmux-gpio: Specifies the card detect line that is routed through a pinmux to the card-detect pin of the card slot. This property should be used only if none of the mmc core card-detect properties are - used. Only for Samsung GPIO variant. + used. Example: sdhci@12530000 { @@ -40,18 +40,12 @@ Example: interrupts = <0 75 0>; bus-width = <4>; cd-gpios = <&gpk2 2 2 3 3>; - - /* Samsung GPIO variant */ gpios = <&gpk2 0 2 0 3>, /* clock line */ <&gpk2 1 2 0 3>, /* command line */ <&gpk2 3 2 3 3>, /* data line 0 */ <&gpk2 4 2 3 3>, /* data line 1 */ <&gpk2 5 2 3 3>, /* data line 2 */ <&gpk2 6 2 3 3>; /* data line 3 */ - - /* Pinctrl variant */ - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4>; - pinctrl-names = "default"; }; Note: This example shows both SoC specific and board specific properties diff --git a/trunk/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt b/trunk/Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt similarity index 100% rename from trunk/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt rename to trunk/Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt diff --git a/trunk/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/trunk/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt index ed271fc255b2..be76a23b34c4 100644 --- a/trunk/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt +++ b/trunk/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt @@ -19,7 +19,6 @@ ti,dual-volt: boolean, supports dual voltage cards "supply-name" examples are "vmmc", "vmmc_aux" etc ti,non-removable: non-removable slot (like eMMC) ti,needs-special-reset: Requires a special softreset sequence -ti,needs-special-hs-handling: HSMMC IP needs special setting for handling High Speed Example: mmc1: mmc@0x4809c000 { diff --git a/trunk/Documentation/devicetree/bindings/mmc/vt8500-sdmmc.txt b/trunk/Documentation/devicetree/bindings/mmc/vt8500-sdmmc.txt deleted file mode 100644 index d7fb6abb3eb8..000000000000 --- a/trunk/Documentation/devicetree/bindings/mmc/vt8500-sdmmc.txt +++ /dev/null @@ -1,23 +0,0 @@ -* Wondermedia WM8505/WM8650 SD/MMC Host Controller - -This file documents differences between the core properties described -by mmc.txt and the properties used by the wmt-sdmmc driver. - -Required properties: -- compatible: Should be "wm,wm8505-sdhc". -- interrupts: Two interrupts are required - regular irq and dma irq. - -Optional properties: -- sdon-inverted: SD_ON bit is inverted on the controller - -Examples: - -sdhc@d800a000 { - compatible = "wm,wm8505-sdhc"; - reg = <0xd800a000 0x1000>; - interrupts = <20 21>; - clocks = <&sdhc>; - bus-width = <4>; - sdon-inverted; -}; - diff --git a/trunk/Documentation/devicetree/bindings/net/mdio-gpio.txt b/trunk/Documentation/devicetree/bindings/net/mdio-gpio.txt index c79bab025369..bc9549529014 100644 --- a/trunk/Documentation/devicetree/bindings/net/mdio-gpio.txt +++ b/trunk/Documentation/devicetree/bindings/net/mdio-gpio.txt @@ -8,16 +8,9 @@ gpios property as described in section VIII.1 in the following order: MDC, MDIO. -Note: Each gpio-mdio bus should have an alias correctly numbered in "aliases" -node. - Example: -aliases { - mdio-gpio0 = <&mdio0>; -}; - -mdio0: mdio { +mdio { compatible = "virtual,mdio-gpio"; #address-cells = <1>; #size-cells = <0>; diff --git a/trunk/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt b/trunk/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt deleted file mode 100644 index 3a268127b054..000000000000 --- a/trunk/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt +++ /dev/null @@ -1,141 +0,0 @@ -* Atmel AT91 Pinmux Controller - -The AT91 Pinmux Controler, enables the IC -to share one PAD to several functional blocks. The sharing is done by -multiplexing the PAD input/output signals. For each PAD there are up to -8 muxing options (called periph modes). Since different modules require -different PAD settings (like pull up, keeper, etc) the contoller controls -also the PAD settings parameters. - -Please refer to pinctrl-bindings.txt in this directory for details of the -common pinctrl bindings used by client devices, including the meaning of the -phrase "pin configuration node". - -Atmel AT91 pin configuration node is a node of a group of pins which can be -used for a specific device or function. This node represents both mux and config -of the pins in that group. The 'pins' selects the function mode(also named pin -mode) this pin can work on and the 'config' configures various pad settings -such as pull-up, multi drive, etc. - -Required properties for iomux controller: -- compatible: "atmel,at91rm9200-pinctrl" -- atmel,mux-mask: array of mask (periph per bank) to describe if a pin can be - configured in this periph mode. All the periph and bank need to be describe. - -How to create such array: - -Each column will represent the possible peripheral of the pinctrl -Each line will represent a pio bank - -Take an example on the 9260 -Peripheral: 2 ( A and B) -Bank: 3 (A, B and C) -=> - - /* A B */ - 0xffffffff 0xffc00c3b /* pioA */ - 0xffffffff 0x7fff3ccf /* pioB */ - 0xffffffff 0x007fffff /* pioC */ - -For each peripheral/bank we will descibe in a u32 if a pin can can be -configured in it by putting 1 to the pin bit (1 << pin) - -Let's take the pioA on peripheral B -From the datasheet Table 10-2. -Peripheral B -PA0 MCDB0 -PA1 MCCDB -PA2 -PA3 MCDB3 -PA4 MCDB2 -PA5 MCDB1 -PA6 -PA7 -PA8 -PA9 -PA10 ETX2 -PA11 ETX3 -PA12 -PA13 -PA14 -PA15 -PA16 -PA17 -PA18 -PA19 -PA20 -PA21 -PA22 ETXER -PA23 ETX2 -PA24 ETX3 -PA25 ERX2 -PA26 ERX3 -PA27 ERXCK -PA28 ECRS -PA29 ECOL -PA30 RXD4 -PA31 TXD4 - -=> 0xffc00c3b - -Required properties for pin configuration node: -- atmel,pins: 4 integers array, represents a group of pins mux and config - setting. The format is atmel,pins = . - The PERIPH 0 means gpio. - -Bits used for CONFIG: -PULL_UP (1 << 0): indicate this pin need a pull up. -MULTIDRIVE (1 << 1): indicate this pin need to be configured as multidrive. -DEGLITCH (1 << 2): indicate this pin need deglitch. -PULL_DOWN (1 << 3): indicate this pin need a pull down. -DIS_SCHMIT (1 << 4): indicate this pin need to disable schmit trigger. -DEBOUNCE (1 << 16): indicate this pin need debounce. -DEBOUNCE_VAL (0x3fff << 17): debounce val. - -NOTE: -Some requirements for using atmel,at91rm9200-pinctrl binding: -1. We have pin function node defined under at91 controller node to represent - what pinmux functions this SoC supports. -2. The driver can use the function node's name and pin configuration node's - name describe the pin function and group hierarchy. - For example, Linux at91 pinctrl driver takes the function node's name - as the function name and pin configuration node's name as group name to - create the map table. -3. Each pin configuration node should have a phandle, devices can set pins - configurations by referring to the phandle of that pin configuration node. -4. The gpio controller must be describe in the pinctrl simple-bus. - -Examples: - -pinctrl@fffff400 { - #address-cells = <1>; - #size-cells = <1>; - ranges; - compatible = "atmel,at91rm9200-pinctrl", "simple-bus"; - reg = <0xfffff400 0x600>; - - atmel,mux-mask = < - /* A B */ - 0xffffffff 0xffc00c3b /* pioA */ - 0xffffffff 0x7fff3ccf /* pioB */ - 0xffffffff 0x007fffff /* pioC */ - >; - - /* shared pinctrl settings */ - dbgu { - pinctrl_dbgu: dbgu-0 { - atmel,pins = - <1 14 0x1 0x0 /* PB14 periph A */ - 1 15 0x1 0x1>; /* PB15 periph with pullup */ - }; - }; -}; - -dbgu: serial@fffff200 { - compatible = "atmel,at91sam9260-usart"; - reg = <0xfffff200 0x200>; - interrupts = <1 4 7>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_dbgu>; - status = "disabled"; -}; diff --git a/trunk/Documentation/devicetree/bindings/pinctrl/nvidia,tegra20-pinmux.txt b/trunk/Documentation/devicetree/bindings/pinctrl/nvidia,tegra20-pinmux.txt index 683fde93c4fb..c8e578263ce2 100644 --- a/trunk/Documentation/devicetree/bindings/pinctrl/nvidia,tegra20-pinmux.txt +++ b/trunk/Documentation/devicetree/bindings/pinctrl/nvidia,tegra20-pinmux.txt @@ -93,7 +93,7 @@ Valid values for pin and group names are: With some exceptions, these support nvidia,high-speed-mode, nvidia,schmitt, nvidia,low-power-mode, nvidia,pull-down-strength, - nvidia,pull-up-strength, nvidia,slew-rate-rising, nvidia,slew-rate-falling. + nvidia,pull-up-strength, nvidia,slew_rate-rising, nvidia,slew_rate-falling. drive_ao1, drive_ao2, drive_at1, drive_at2, drive_cdev1, drive_cdev2, drive_csus, drive_dap1, drive_dap2, drive_dap3, drive_dap4, drive_dbg, diff --git a/trunk/Documentation/devicetree/bindings/pinctrl/nvidia,tegra30-pinmux.txt b/trunk/Documentation/devicetree/bindings/pinctrl/nvidia,tegra30-pinmux.txt index 6f426ed7009e..c275b70349c1 100644 --- a/trunk/Documentation/devicetree/bindings/pinctrl/nvidia,tegra30-pinmux.txt +++ b/trunk/Documentation/devicetree/bindings/pinctrl/nvidia,tegra30-pinmux.txt @@ -83,7 +83,7 @@ Valid values for pin and group names are: drive groups: These all support nvidia,pull-down-strength, nvidia,pull-up-strength, - nvidia,slew-rate-rising, nvidia,slew-rate-falling. Most but not all + nvidia,slew_rate-rising, nvidia,slew_rate-falling. Most but not all support nvidia,high-speed-mode, nvidia,schmitt, nvidia,low-power-mode. ao1, ao2, at1, at2, at3, at4, at5, cdev1, cdev2, cec, crt, csus, dap1, diff --git a/trunk/Documentation/filesystems/proc.txt b/trunk/Documentation/filesystems/proc.txt index 3844d21d6ca3..a1793d670cd0 100644 --- a/trunk/Documentation/filesystems/proc.txt +++ b/trunk/Documentation/filesystems/proc.txt @@ -33,7 +33,7 @@ Table of Contents 2 Modifying System Parameters 3 Per-Process Parameters - 3.1 /proc//oom_adj & /proc//oom_score_adj - Adjust the oom-killer + 3.1 /proc//oom_score_adj - Adjust the oom-killer score 3.2 /proc//oom_score - Display current oom-killer score 3.3 /proc//io - Display the IO accounting fields @@ -1320,10 +1320,10 @@ of the kernel. CHAPTER 3: PER-PROCESS PARAMETERS ------------------------------------------------------------------------------ -3.1 /proc//oom_adj & /proc//oom_score_adj- Adjust the oom-killer score +3.1 /proc//oom_score_adj- Adjust the oom-killer score -------------------------------------------------------------------------------- -These file can be used to adjust the badness heuristic used to select which +This file can be used to adjust the badness heuristic used to select which process gets killed in out of memory conditions. The badness heuristic assigns a value to each candidate task ranging from 0 @@ -1361,12 +1361,6 @@ same system, cpuset, mempolicy, or memory controller resources to use at least equivalent to discounting 50% of the task's allowed memory from being considered as scoring against the task. -For backwards compatibility with previous kernels, /proc//oom_adj may also -be used to tune the badness score. Its acceptable values range from -16 -(OOM_ADJUST_MIN) to +15 (OOM_ADJUST_MAX) and a special value of -17 -(OOM_DISABLE) to disable oom killing entirely for that task. Its value is -scaled linearly with /proc//oom_score_adj. - The value of /proc//oom_score_adj may be reduced no lower than the last value set by a CAP_SYS_RESOURCE process. To reduce the value any lower requires CAP_SYS_RESOURCE. @@ -1381,9 +1375,7 @@ minimal amount of work. ------------------------------------------------------------- This file can be used to check the current score used by the oom-killer is for -any given . Use it together with /proc//oom_score_adj to tune which -process should be killed in an out-of-memory situation. - +any given . 3.3 /proc//io - Display the IO accounting fields ------------------------------------------------------- diff --git a/trunk/Documentation/firmware_class/README b/trunk/Documentation/firmware_class/README index 815b711bcd85..7eceaff63f5f 100644 --- a/trunk/Documentation/firmware_class/README +++ b/trunk/Documentation/firmware_class/README @@ -18,40 +18,32 @@ High level behavior (mixed): ============================ - 1), kernel(driver): - - calls request_firmware(&fw_entry, $FIRMWARE, device) - - kernel searchs the fimware image with name $FIRMWARE directly - in the below search path of root filesystem: - "/lib/firmware/updates/" UTS_RELEASE, - "/lib/firmware/updates", - "/lib/firmware/" UTS_RELEASE, - "/lib/firmware" - - If found, goto 7), else goto 2) - - 2), userspace: + kernel(driver): calls request_firmware(&fw_entry, $FIRMWARE, device) + + userspace: - /sys/class/firmware/xxx/{loading,data} appear. - hotplug gets called with a firmware identifier in $FIRMWARE and the usual hotplug environment. - hotplug: echo 1 > /sys/class/firmware/xxx/loading - 3), kernel: Discard any previous partial load. + kernel: Discard any previous partial load. - 4), userspace: + userspace: - hotplug: cat appropriate_firmware_image > \ /sys/class/firmware/xxx/data - 5), kernel: grows a buffer in PAGE_SIZE increments to hold the image as it + kernel: grows a buffer in PAGE_SIZE increments to hold the image as it comes in. - 6), userspace: + userspace: - hotplug: echo 0 > /sys/class/firmware/xxx/loading - 7), kernel: request_firmware() returns and the driver has the firmware + kernel: request_firmware() returns and the driver has the firmware image in fw_entry->{data,size}. If something went wrong request_firmware() returns non-zero and fw_entry is set to NULL. - 8), kernel(driver): Driver code calls release_firmware(fw_entry) releasing + kernel(driver): Driver code calls release_firmware(fw_entry) releasing the firmware image and any related resource. High level behavior (driver code): diff --git a/trunk/Documentation/gpio.txt b/trunk/Documentation/gpio.txt index 77a1d11af723..e08a883de36e 100644 --- a/trunk/Documentation/gpio.txt +++ b/trunk/Documentation/gpio.txt @@ -439,48 +439,6 @@ slower clock delays the rising edge of SCK, and the I2C master adjusts its signaling rate accordingly. -GPIO controllers and the pinctrl subsystem ------------------------------------------- - -A GPIO controller on a SOC might be tightly coupled with the pinctrl -subsystem, in the sense that the pins can be used by other functions -together with an optional gpio feature. We have already covered the -case where e.g. a GPIO controller need to reserve a pin or set the -direction of a pin by calling any of: - -pinctrl_request_gpio() -pinctrl_free_gpio() -pinctrl_gpio_direction_input() -pinctrl_gpio_direction_output() - -But how does the pin control subsystem cross-correlate the GPIO -numbers (which are a global business) to a certain pin on a certain -pin controller? - -This is done by registering "ranges" of pins, which are essentially -cross-reference tables. These are described in -Documentation/pinctrl.txt - -While the pin allocation is totally managed by the pinctrl subsystem, -gpio (under gpiolib) is still maintained by gpio drivers. It may happen -that different pin ranges in a SoC is managed by different gpio drivers. - -This makes it logical to let gpio drivers announce their pin ranges to -the pin ctrl subsystem before it will call 'pinctrl_request_gpio' in order -to request the corresponding pin to be prepared by the pinctrl subsystem -before any gpio usage. - -For this, the gpio controller can register its pin range with pinctrl -subsystem. There are two ways of doing it currently: with or without DT. - -For with DT support refer to Documentation/devicetree/bindings/gpio/gpio.txt. - -For non-DT support, user can call gpiochip_add_pin_range() with appropriate -parameters to register a range of gpio pins with a pinctrl driver. For this -exact name string of pinctrl device has to be passed as one of the -argument to this routine. - - What do these conventions omit? =============================== One of the biggest things these conventions omit is pin multiplexing, since diff --git a/trunk/Documentation/hwmon/ads7828 b/trunk/Documentation/hwmon/ads7828 index f6e263e0f607..2bbebe6f771f 100644 --- a/trunk/Documentation/hwmon/ads7828 +++ b/trunk/Documentation/hwmon/ads7828 @@ -4,47 +4,29 @@ Kernel driver ads7828 Supported chips: * Texas Instruments/Burr-Brown ADS7828 Prefix: 'ads7828' - Datasheet: Publicly available at the Texas Instruments website: + Addresses scanned: I2C 0x48, 0x49, 0x4a, 0x4b + Datasheet: Publicly available at the Texas Instruments website : http://focus.ti.com/lit/ds/symlink/ads7828.pdf - * Texas Instruments ADS7830 - Prefix: 'ads7830' - Datasheet: Publicly available at the Texas Instruments website: - http://focus.ti.com/lit/ds/symlink/ads7830.pdf - Authors: Steve Hardy - Vivien Didelot - Guillaume Roguez - -Platform data -------------- - -The ads7828 driver accepts an optional ads7828_platform_data structure (defined -in include/linux/platform_data/ads7828.h). The structure fields are: -* diff_input: (bool) Differential operation - set to true for differential mode, false for default single ended mode. +Module Parameters +----------------- -* ext_vref: (bool) External reference - set to true if it operates with an external reference, false for default - internal reference. - -* vref_mv: (unsigned int) Voltage reference - if using an external reference, set this to the reference voltage in mV, - otherwise it will default to the internal value (2500mV). This value will be - bounded with limits accepted by the chip, described in the datasheet. - - If no structure is provided, the configuration defaults to single ended - operation and internal voltage reference (2.5V). +* se_input: bool (default Y) + Single ended operation - set to N for differential mode +* int_vref: bool (default Y) + Operate with the internal 2.5V reference - set to N for external reference +* vref_mv: int (default 2500) + If using an external reference, set this to the reference voltage in mV Description ----------- -This driver implements support for the Texas Instruments ADS7828 and ADS7830. +This driver implements support for the Texas Instruments ADS7828. -The ADS7828 device is a 12-bit 8-channel A/D converter, while the ADS7830 does -8-bit sampling. +This device is a 12-bit 8-channel A-D converter. It can operate in single ended mode (8 +ve inputs) or in differential mode, where 4 differential pairs can be measured. @@ -52,7 +34,3 @@ where 4 differential pairs can be measured. The chip also has the facility to use an external voltage reference. This may be required if your hardware supplies the ADS7828 from a 5V supply, see the datasheet for more details. - -There is no reliable way to identify this chip, so the driver will not scan -some addresses to try to auto-detect it. That means that you will have to -statically declare the device in the platform support code. diff --git a/trunk/Documentation/hwmon/coretemp b/trunk/Documentation/hwmon/coretemp index 3374c085678d..f17256f069ba 100644 --- a/trunk/Documentation/hwmon/coretemp +++ b/trunk/Documentation/hwmon/coretemp @@ -98,10 +98,8 @@ Process Processor TjMax(C) 45nm Atom Processors D525/510/425/410 100 - Z670/650 90 Z560/550/540/530P/530/520PT/520/515/510PT/510P 90 Z510/500 90 - N570/550 100 N475/470/455/450 100 N280/270 90 330/230 125 diff --git a/trunk/Documentation/hwmon/da9055 b/trunk/Documentation/hwmon/da9055 deleted file mode 100644 index 855c3f536e00..000000000000 --- a/trunk/Documentation/hwmon/da9055 +++ /dev/null @@ -1,47 +0,0 @@ -Supported chips: - * Dialog Semiconductors DA9055 PMIC - Prefix: 'da9055' - Datasheet: Datasheet is not publicly available. - -Authors: David Dajun Chen - -Description ------------ - -The DA9055 provides an Analogue to Digital Converter (ADC) with 10 bits -resolution and track and hold circuitry combined with an analogue input -multiplexer. The analogue input multiplexer will allow conversion of up to 5 -different inputs. The track and hold circuit ensures stable input voltages at -the input of the ADC during the conversion. - -The ADC is used to measure the following inputs: -Channel 0: VDDOUT - measurement of the system voltage -Channel 1: ADC_IN1 - high impedance input (0 - 2.5V) -Channel 2: ADC_IN2 - high impedance input (0 - 2.5V) -Channel 3: ADC_IN3 - high impedance input (0 - 2.5V) -Channel 4: Internal Tjunc. - sense (internal temp. sensor) - -By using sysfs attributes we can measure the system voltage VDDOUT, -chip junction temperature and auxiliary channels voltages. - -Voltage Monitoring ------------------- - -Voltages are sampled in a AUTO mode it can be manually sampled too and results -are stored in a 10 bit ADC. - -The system voltage is calculated as: - Milli volt = ((ADC value * 1000) / 85) + 2500 - -The voltages on ADC channels 1, 2 and 3 are calculated as: - Milli volt = (ADC value * 1000) / 102 - -Temperature Monitoring ----------------------- - -Temperatures are sampled by a 10 bit ADC. Junction temperatures -are monitored by the ADC channels. - -The junction temperature is calculated: - Degrees celsius = -0.4084 * (ADC_RES - T_OFFSET) + 307.6332 -The junction temperature attribute is supported by the driver. diff --git a/trunk/Documentation/hwmon/fam15h_power b/trunk/Documentation/hwmon/fam15h_power index 80654813d04a..a92918e0bd69 100644 --- a/trunk/Documentation/hwmon/fam15h_power +++ b/trunk/Documentation/hwmon/fam15h_power @@ -10,7 +10,7 @@ Supported chips: BIOS and Kernel Developer's Guide (BKDG) For AMD Family 15h Processors (not yet published) -Author: Andreas Herrmann +Author: Andreas Herrmann Description ----------- diff --git a/trunk/Documentation/mmc/mmc-dev-attrs.txt b/trunk/Documentation/mmc/mmc-dev-attrs.txt index 0d98fac8893b..22ae8441489f 100644 --- a/trunk/Documentation/mmc/mmc-dev-attrs.txt +++ b/trunk/Documentation/mmc/mmc-dev-attrs.txt @@ -25,8 +25,6 @@ All attributes are read-only. serial Product Serial Number (from CID Register) erase_size Erase group size preferred_erase_size Preferred erase size - raw_rpmb_size_mult RPMB partition size - rel_sectors Reliable write sector count Note on Erase Size and Preferred Erase Size: @@ -67,11 +65,6 @@ Note on Erase Size and Preferred Erase Size: "preferred_erase_size" is in bytes. -Note on raw_rpmb_size_mult: - "raw_rpmb_size_mult" is a mutliple of 128kB block. - RPMB size in byte is calculated by using the following equation: - RPMB partition size = 128kB x raw_rpmb_size_mult - SD/MMC/SDIO Clock Gating Attribute ================================== diff --git a/trunk/Documentation/networking/netdev-features.txt b/trunk/Documentation/networking/netdev-features.txt index f310edec8a77..4164f5c02e4b 100644 --- a/trunk/Documentation/networking/netdev-features.txt +++ b/trunk/Documentation/networking/netdev-features.txt @@ -164,4 +164,4 @@ read the CRC recorded by the NIC on receipt of the packet. This requests that the NIC receive all possible frames, including errored frames (such as bad FCS, etc). This can be helpful when sniffing a link with bad packets on it. Some NICs may receive more packets if also put into normal -PROMISC mode. +PROMISC mdoe. diff --git a/trunk/Documentation/networking/vxlan.txt b/trunk/Documentation/networking/vxlan.txt index 6d993510f091..5b34b762d7d5 100644 --- a/trunk/Documentation/networking/vxlan.txt +++ b/trunk/Documentation/networking/vxlan.txt @@ -32,7 +32,7 @@ no entry is in the forwarding table. # ip link delete vxlan0 3. Show vxlan info - # ip -d link show vxlan0 + # ip -d show vxlan0 It is possible to create, destroy and display the vxlan forwarding table using the new bridge command. @@ -41,7 +41,7 @@ forwarding table using the new bridge command. # bridge fdb add to 00:17:42:8a:b4:05 dst 192.19.0.2 dev vxlan0 2. Delete forwarding table entry - # bridge fdb delete 00:17:42:8a:b4:05 dev vxlan0 + # bridge fdb delete 00:17:42:8a:b4:05 3. Show forwarding table # bridge fdb show dev vxlan0 diff --git a/trunk/Documentation/pinctrl.txt b/trunk/Documentation/pinctrl.txt index da40efbef6ec..3b4ee5328868 100644 --- a/trunk/Documentation/pinctrl.txt +++ b/trunk/Documentation/pinctrl.txt @@ -364,9 +364,6 @@ will get an pin number into its handled number range. Further it is also passed the range ID value, so that the pin controller knows which range it should deal with. -Calling pinctrl_add_gpio_range from pinctrl driver is DEPRECATED. Please see -section 2.1 of Documentation/devicetree/bindings/gpio/gpio.txt on how to bind -pinctrl and gpio drivers. PINMUX interfaces ================= @@ -1196,6 +1193,4 @@ foo_switch() ... } -The above has to be done from process context. The reservation of the pins -will be done when the state is activated, so in effect one specific pin -can be used by different functions at different times on a running system. +The above has to be done from process context. diff --git a/trunk/Documentation/zh_CN/IRQ.txt b/trunk/Documentation/zh_CN/IRQ.txt deleted file mode 100644 index 956026d5cf82..000000000000 --- a/trunk/Documentation/zh_CN/IRQ.txt +++ /dev/null @@ -1,39 +0,0 @@ -Chinese translated version of Documentation/IRQ.txt - -If you have any comment or update to the content, please contact the -original document maintainer directly. However, if you have a problem -communicating in English you can also ask the Chinese maintainer for -help. Contact the Chinese maintainer if this translation is outdated -or if there is a problem with the translation. - -Maintainer: Eric W. Biederman -Chinese maintainer: Fu Wei ---------------------------------------------------------------------- -Documentation/IRQ.txt 的中文翻译 - -如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文 -交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻 -译存在问题,请联系中文版维护者。 -英文版维护者: Eric W. Biederman -中文版维护者: 傅炜 Fu Wei -中文版翻译者: 傅炜 Fu Wei -中文版校译者: 傅炜 Fu Wei - - -以下为正文 ---------------------------------------------------------------------- -何为 IRQ? - -一个 IRQ 是来自某个设备的一个中断请求。目前,它们可以来自一个硬件引脚, -或来自一个数据包。多个设备可能连接到同个硬件引脚,从而共享一个 IRQ。 - -一个 IRQ 编号是用于告知硬件中断源的内核标识。通常情况下,这是一个 -全局 irq_desc 数组的索引,但是除了在 linux/interrupt.h 中的实现, -具体的细节是体系结构特定的。 - -一个 IRQ 编号是设备上某个可能的中断源的枚举。通常情况下,枚举的编号是 -该引脚在系统内中断控制器的所有输入引脚中的编号。对于 ISA 总线中的情况, -枚举的是在两个 i8259 中断控制器中 16 个输入引脚。 - -架构可以对 IRQ 编号指定额外的含义,在硬件涉及任何手工配置的情况下, -是被提倡的。ISA 的 IRQ 是一个分配这类额外含义的典型例子。 diff --git a/trunk/Documentation/zh_CN/arm64/booting.txt b/trunk/Documentation/zh_CN/arm64/booting.txt deleted file mode 100644 index 28fa325b7461..000000000000 --- a/trunk/Documentation/zh_CN/arm64/booting.txt +++ /dev/null @@ -1,156 +0,0 @@ -Chinese translated version of Documentation/arm64/booting.txt - -If you have any comment or update to the content, please contact the -original document maintainer directly. However, if you have a problem -communicating in English you can also ask the Chinese maintainer for -help. Contact the Chinese maintainer if this translation is outdated -or if there is a problem with the translation. - -Maintainer: Will Deacon -Chinese maintainer: Fu Wei ---------------------------------------------------------------------- -Documentation/arm64/booting.txt 的中文翻译 - -如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文 -交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻 -译存在问题,请联系中文版维护者。 - -英文版维护者: Will Deacon -中文版维护者: 傅炜 Fu Wei -中文版翻译者: 傅炜 Fu Wei -中文版校译者: 傅炜 Fu Wei - -以下为正文 ---------------------------------------------------------------------- - 启动 AArch64 Linux - ================== - -作者: Will Deacon -日期: 2012 年 09 月 07 日 - -本文档基于 Russell King 的 ARM 启动文档,且适用于所有公开发布的 -AArch64 Linux 内核代码。 - -AArch64 异常模型由多个异常级别(EL0 - EL3)组成,对于 EL0 和 EL1 -异常级有对应的安全和非安全模式。EL2 是系统管理级,且仅存在于 -非安全模式下。EL3 是最高特权级,且仅存在于安全模式下。 - -基于本文档的目的,我们将简单地使用‘引导装载程序’(‘boot loader’) -这个术语来定义在将控制权交给 Linux 内核前 CPU 上执行的所有软件。 -这可能包含安全监控和系统管理代码,或者它可能只是一些用于准备最小启动 -环境的指令。 - -基本上,引导装载程序(至少)应实现以下操作: - -1、设置和初始化 RAM -2、设置设备树数据 -3、解压内核映像 -4、调用内核映像 - - -1、设置和初始化 RAM ------------------ - -必要性: 强制 - -引导装载程序应该找到并初始化系统中所有内核用于保持系统变量数据的 RAM。 -这个操作的执行是设备依赖的。(它可能使用内部算法来自动定位和计算所有 -RAM,或可能使用对这个设备已知的 RAM 信息,还可能使用任何引导装载程序 -设计者想到的匹配方法。) - - -2、设置设备树数据 ---------------- - -必要性: 强制 - -设备树数据块(dtb)大小必须不大于 2 MB,且位于从内核映像起始算起第一个 -512MB 内的 2MB 边界上。这使得内核可以通过初始页表中的单个节描述符来 -映射此数据块。 - - -3、解压内核映像 -------------- - -必要性: 可选 - -AArch64 内核当前没有提供自解压代码,因此如果使用了压缩内核映像文件 -(比如 Image.gz),则需要通过引导装载程序(使用 gzip 等)来进行解压。 -若引导装载程序没有实现这个需求,就要使用非压缩内核映像文件。 - - -4、调用内核映像 -------------- - -必要性: 强制 - -已解压的内核映像包含一个 32 字节的头,内容如下: - - u32 magic = 0x14000008; /* 跳转到 stext, 小端 */ - u32 res0 = 0; /* 保留 */ - u64 text_offset; /* 映像装载偏移 */ - u64 res1 = 0; /* 保留 */ - u64 res2 = 0; /* 保留 */ - -映像必须位于系统 RAM 起始处的特定偏移(当前是 0x80000)。系统 RAM -的起始地址必须是以 2MB 对齐的。 - -在跳转入内核前,必须符合以下状态: - -- 停止所有 DMA 设备,这样内存数据就不会因为虚假网络包或磁盘数据而 - 被破坏。这可能可以节省你许多的调试时间。 - -- 主 CPU 通用寄存器设置 - x0 = 系统 RAM 中设备树数据块(dtb)的物理地址。 - x1 = 0 (保留,将来可能使用) - x2 = 0 (保留,将来可能使用) - x3 = 0 (保留,将来可能使用) - -- CPU 模式 - 所有形式的中断必须在 PSTATE.DAIF 中被屏蔽(Debug、SError、IRQ - 和 FIQ)。 - CPU 必须处于 EL2(推荐,可访问虚拟化扩展)或非安全 EL1 模式下。 - -- 高速缓存、MMU - MMU 必须关闭。 - 指令缓存开启或关闭都可以。 - 数据缓存必须关闭且无效。 - 外部高速缓存(如果存在)必须配置并禁用。 - -- 架构计时器 - CNTFRQ 必须设定为计时器的频率。 - 如果在 EL1 模式下进入内核,则 CNTHCTL_EL2 中的 EL1PCTEN (bit 0) - 必须置位。 - -- 一致性 - 通过内核启动的所有 CPU 在内核入口地址上必须处于相同的一致性域中。 - 这可能要根据具体实现来定义初始化过程,以使能每个CPU上对维护操作的 - 接收。 - -- 系统寄存器 - 在进入内核映像的异常级中,所有构架中可写的系统寄存器必须通过软件 - 在一个更高的异常级别下初始化,以防止在 未知 状态下运行。 - -引导装载程序必须在每个 CPU 处于以下状态时跳入内核入口: - -- 主 CPU 必须直接跳入内核映像的第一条指令。通过此 CPU 传递的设备树 - 数据块必须在每个 CPU 节点中包含以下内容: - - 1、‘enable-method’属性。目前,此字段支持的值仅为字符串“spin-table”。 - - 2、‘cpu-release-addr’标识一个 64-bit、初始化为零的内存位置。 - - 引导装载程序必须生成这些设备树属性,并在跳入内核入口之前将其插入 - 数据块。 - -- 任何辅助 CPU 必须在内存保留区(通过设备树中的 /memreserve/ 域传递 - 给内核)中自旋于内核之外,轮询它们的 cpu-release-addr 位置(必须 - 包含在保留区中)。可通过插入 wfe 指令来降低忙循环开销,而主 CPU 将 - 发出 sev 指令。当对 cpu-release-addr 所指位置的读取操作返回非零值 - 时,CPU 必须直接跳入此值所指向的地址。 - -- 辅助 CPU 通用寄存器设置 - x0 = 0 (保留,将来可能使用) - x1 = 0 (保留,将来可能使用) - x2 = 0 (保留,将来可能使用) - x3 = 0 (保留,将来可能使用) diff --git a/trunk/Documentation/zh_CN/arm64/memory.txt b/trunk/Documentation/zh_CN/arm64/memory.txt deleted file mode 100644 index 83b519314706..000000000000 --- a/trunk/Documentation/zh_CN/arm64/memory.txt +++ /dev/null @@ -1,93 +0,0 @@ -Chinese translated version of Documentation/arm64/memory.txt - -If you have any comment or update to the content, please contact the -original document maintainer directly. However, if you have a problem -communicating in English you can also ask the Chinese maintainer for -help. Contact the Chinese maintainer if this translation is outdated -or if there is a problem with the translation. - -Maintainer: Catalin Marinas -Chinese maintainer: Fu Wei ---------------------------------------------------------------------- -Documentation/arm64/memory.txt 的中文翻译 - -如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文 -交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻 -译存在问题,请联系中文版维护者。 - -英文版维护者: Catalin Marinas -中文版维护者: 傅炜 Fu Wei -中文版翻译者: 傅炜 Fu Wei -中文版校译者: 傅炜 Fu Wei - -以下为正文 ---------------------------------------------------------------------- - Linux 在 AArch64 中的内存布局 - =========================== - -作者: Catalin Marinas -日期: 2012 年 02 月 20 日 - -本文档描述 AArch64 Linux 内核所使用的虚拟内存布局。此构架可以实现 -页大小为 4KB 的 4 级转换表和页大小为 64KB 的 3 级转换表。 - -AArch64 Linux 使用页大小为 4KB 的 3 级转换表配置,对于用户和内核 -都有 39-bit (512GB) 的虚拟地址空间。对于页大小为 64KB的配置,仅 -使用 2 级转换表,但内存布局相同。 - -用户地址空间的 63:39 位为 0,而内核地址空间的相应位为 1。TTBRx 的 -选择由虚拟地址的 63 位给出。swapper_pg_dir 仅包含内核(全局)映射, -而用户 pgd 仅包含用户(非全局)映射。swapper_pgd_dir 地址被写入 -TTBR1 中,且从不写入 TTBR0。 - - -AArch64 Linux 内存布局: - -起始地址 结束地址 大小 用途 ------------------------------------------------------------------------ -0000000000000000 0000007fffffffff 512GB 用户空间 - -ffffff8000000000 ffffffbbfffcffff ~240GB vmalloc - -ffffffbbfffd0000 ffffffbcfffdffff 64KB [防护页] - -ffffffbbfffe0000 ffffffbcfffeffff 64KB PCI I/O 空间 - -ffffffbbffff0000 ffffffbcffffffff 64KB [防护页] - -ffffffbc00000000 ffffffbdffffffff 8GB vmemmap - -ffffffbe00000000 ffffffbffbffffff ~8GB [防护页,未来用于 vmmemap] - -ffffffbffc000000 ffffffbfffffffff 64MB 模块 - -ffffffc000000000 ffffffffffffffff 256GB 内存空间 - - -4KB 页大小的转换表查找: - -+--------+--------+--------+--------+--------+--------+--------+--------+ -|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0| -+--------+--------+--------+--------+--------+--------+--------+--------+ - | | | | | | - | | | | | v - | | | | | [11:0] 页内偏移 - | | | | +-> [20:12] L3 索引 - | | | +-----------> [29:21] L2 索引 - | | +---------------------> [38:30] L1 索引 - | +-------------------------------> [47:39] L0 索引 (未使用) - +-------------------------------------------------> [63] TTBR0/1 - - -64KB 页大小的转换表查找: - -+--------+--------+--------+--------+--------+--------+--------+--------+ -|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0| -+--------+--------+--------+--------+--------+--------+--------+--------+ - | | | | | - | | | | v - | | | | [15:0] 页内偏移 - | | | +----------> [28:16] L3 索引 - | | +--------------------------> [41:29] L2 索引 (仅使用 38:29 ) - | +-------------------------------> [47:42] L1 索引 (未使用) - +-------------------------------------------------> [63] TTBR0/1 diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index cf7ff78f019b..027ec2bfa135 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -503,7 +503,7 @@ F: include/linux/altera_uart.h F: include/linux/altera_jtaguart.h AMD FAM15H PROCESSOR POWER MONITORING DRIVER -M: Andreas Herrmann +M: Andreas Herrmann L: lm-sensors@lm-sensors.org S: Maintained F: Documentation/hwmon/fam15h_power @@ -526,17 +526,17 @@ F: drivers/video/geode/ F: arch/x86/include/asm/geode.h AMD IOMMU (AMD-VI) -M: Joerg Roedel +M: Joerg Roedel L: iommu@lists.linux-foundation.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git -S: Maintained +S: Supported F: drivers/iommu/amd_iommu*.[ch] F: include/linux/amd-iommu.h AMD MICROCODE UPDATE SUPPORT -M: Andreas Herrmann +M: Andreas Herrmann L: amd64-microcode@amd64.org -S: Maintained +S: Supported F: arch/x86/kernel/microcode_amd.c AMS (Apple Motion Sensor) DRIVER @@ -637,13 +637,6 @@ W: http://www.arm.linux.org.uk/ S: Maintained F: arch/arm/ -ARM SUB-ARCHITECTURES -L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -S: MAINTAINED -F: arch/arm/mach-*/ -F: arch/arm/plat-*/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git - ARM PRIMECELL AACI PL041 DRIVER M: Russell King S: Maintained @@ -841,14 +834,6 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git F: arch/arm/mach-sa1100/jornada720.c F: arch/arm/mach-sa1100/include/mach/jornada720.h -ARM/IGEP MACHINE SUPPORT -M: Enric Balletbo i Serra -M: Javier Martinez Canillas -L: linux-omap@vger.kernel.org -L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -S: Maintained -F: arch/arm/mach-omap2/board-igep0020.c - ARM/INCOME PXA270 SUPPORT M: Marek Vasut L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -1237,7 +1222,6 @@ F: drivers/video/wm8505fb* F: drivers/video/wmt_ge_rops.* F: drivers/tty/serial/vt8500_serial.c F: drivers/rtc/rtc-vt8500-c -F: drivers/mmc/host/wmt-sdmmc.c ARM/ZIPIT Z2 SUPPORT M: Marek Vasut @@ -1369,6 +1353,14 @@ S: Maintained F: drivers/atm/ F: include/linux/atm* +ATMEL AT91 MCI DRIVER +M: Ludovic Desroches +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +W: http://www.atmel.com/products/AT91/ +W: http://www.at91.com/ +S: Maintained +F: drivers/mmc/host/at91_mci.c + ATMEL AT91 / AT32 MCI DRIVER M: Ludovic Desroches S: Maintained @@ -1987,6 +1979,7 @@ F: fs/coda/ F: include/linux/coda*.h COMMON CLK FRAMEWORK +M: Mike Turquette M: Mike Turquette L: linux-arm-kernel@lists.infradead.org (same as CLK API & CLKDEV) T: git git://git.linaro.org/people/mturquette/linux.git @@ -2507,7 +2500,6 @@ M: Joonyoung Shim M: Seung-Woo Kim M: Kyungmin Park L: dri-devel@lists.freedesktop.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git S: Supported F: drivers/gpu/drm/exynos F: include/drm/exynos* @@ -2708,10 +2700,10 @@ F: include/linux/edac.h EDAC-AMD64 M: Doug Thompson -M: Borislav Petkov +M: Borislav Petkov L: linux-edac@vger.kernel.org W: bluesmoke.sourceforge.net -S: Maintained +S: Supported F: drivers/edac/amd64_edac* EDAC-E752X @@ -2810,7 +2802,6 @@ F: sound/usb/misc/ua101.c EXTENSIBLE FIRMWARE INTERFACE (EFI) M: Matt Fleming L: linux-efi@vger.kernel.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git S: Maintained F: Documentation/x86/efi-stub.txt F: arch/ia64/kernel/efi.c @@ -3598,49 +3589,6 @@ F: drivers/hid/hid-hyperv.c F: drivers/net/hyperv/ F: drivers/staging/hv/ -I2C OVER PARALLEL PORT -M: Jean Delvare -L: linux-i2c@vger.kernel.org -S: Maintained -F: Documentation/i2c/busses/i2c-parport -F: Documentation/i2c/busses/i2c-parport-light -F: drivers/i2c/busses/i2c-parport.c -F: drivers/i2c/busses/i2c-parport-light.c - -I2C/SMBUS CONTROLLER DRIVERS FOR PC -M: Jean Delvare -L: linux-i2c@vger.kernel.org -S: Maintained -F: Documentation/i2c/busses/i2c-ali1535 -F: Documentation/i2c/busses/i2c-ali1563 -F: Documentation/i2c/busses/i2c-ali15x3 -F: Documentation/i2c/busses/i2c-amd756 -F: Documentation/i2c/busses/i2c-amd8111 -F: Documentation/i2c/busses/i2c-i801 -F: Documentation/i2c/busses/i2c-nforce2 -F: Documentation/i2c/busses/i2c-piix4 -F: Documentation/i2c/busses/i2c-sis5595 -F: Documentation/i2c/busses/i2c-sis630 -F: Documentation/i2c/busses/i2c-sis96x -F: Documentation/i2c/busses/i2c-via -F: Documentation/i2c/busses/i2c-viapro -F: drivers/i2c/busses/i2c-ali1535.c -F: drivers/i2c/busses/i2c-ali1563.c -F: drivers/i2c/busses/i2c-ali15x3.c -F: drivers/i2c/busses/i2c-amd756.c -F: drivers/i2c/busses/i2c-amd756-s4882.c -F: drivers/i2c/busses/i2c-amd8111.c -F: drivers/i2c/busses/i2c-i801.c -F: drivers/i2c/busses/i2c-isch.c -F: drivers/i2c/busses/i2c-nforce2.c -F: drivers/i2c/busses/i2c-nforce2-s4985.c -F: drivers/i2c/busses/i2c-piix4.c -F: drivers/i2c/busses/i2c-sis5595.c -F: drivers/i2c/busses/i2c-sis630.c -F: drivers/i2c/busses/i2c-sis96x.c -F: drivers/i2c/busses/i2c-via.c -F: drivers/i2c/busses/i2c-viapro.c - I2C/SMBUS STUB DRIVER M: "Mark M. Hoffman" L: linux-i2c@vger.kernel.org @@ -3648,8 +3596,9 @@ S: Maintained F: drivers/i2c/busses/i2c-stub.c I2C SUBSYSTEM -M: Wolfram Sang +M: "Jean Delvare (PC drivers, core)" M: "Ben Dooks (embedded platforms)" +M: "Wolfram Sang (embedded platforms)" L: linux-i2c@vger.kernel.org W: http://i2c.wiki.kernel.org/ T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/ @@ -3660,13 +3609,6 @@ F: drivers/i2c/ F: include/linux/i2c.h F: include/linux/i2c-*.h -I2C-TAOS-EVM DRIVER -M: Jean Delvare -L: linux-i2c@vger.kernel.org -S: Maintained -F: Documentation/i2c/busses/i2c-taos-evm -F: drivers/i2c/busses/i2c-taos-evm.c - I2C-TINY-USB DRIVER M: Till Harbaum L: linux-i2c@vger.kernel.org @@ -3753,7 +3695,7 @@ S: Maintained F: drivers/platform/x86/ideapad-laptop.c IDE/ATAPI DRIVERS -M: Borislav Petkov +M: Borislav Petkov L: linux-ide@vger.kernel.org S: Maintained F: Documentation/cdrom/ide-cd @@ -4280,8 +4222,8 @@ F: include/linux/lockd/ F: include/linux/sunrpc/ KERNEL VIRTUAL MACHINE (KVM) +M: Avi Kivity M: Marcelo Tosatti -M: Gleb Natapov L: kvm@vger.kernel.org W: http://kvm.qumranet.com S: Supported @@ -5119,13 +5061,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git S: Odd Fixes F: drivers/net/ F: include/linux/if_* -F: include/linux/netdevice.h -F: include/linux/arcdevice.h -F: include/linux/etherdevice.h -F: include/linux/fcdevice.h -F: include/linux/fddidevice.h -F: include/linux/hippidevice.h -F: include/linux/inetdevice.h +F: include/linux/*device.h NETXEN (1/10) GbE SUPPORT M: Sony Chacko @@ -5413,7 +5349,7 @@ S: Maintained F: sound/drivers/opl4/ OPROFILE -M: Robert Richter +M: Robert Richter L: oprofile-list@lists.sf.net S: Maintained F: arch/*/include/asm/oprofile*.h @@ -5688,12 +5624,6 @@ S: Maintained F: drivers/pinctrl/ F: include/linux/pinctrl/ -PIN CONTROLLER - ATMEL AT91 -M: Jean-Christophe Plagniol-Villard -L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -S: Maintained -F: drivers/pinctrl/pinctrl-at91.c - PIN CONTROLLER - ST SPEAR M: Viresh Kumar L: spear-devel@list.st.com @@ -5703,7 +5633,7 @@ S: Maintained F: drivers/pinctrl/spear/ PKTCDVD DRIVER -M: Jiri Kosina +M: Peter Osterlund S: Maintained F: drivers/block/pktcdvd.c F: include/linux/pktcdvd.h @@ -7265,14 +7195,6 @@ L: linux-xtensa@linux-xtensa.org S: Maintained F: arch/xtensa/ -THERMAL -M: Zhang Rui -L: linux-pm@vger.kernel.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git -S: Supported -F: drivers/thermal/ -F: include/linux/thermal.h - THINKPAD ACPI EXTRAS DRIVER M: Henrique de Moraes Holschuh L: ibm-acpi-devel@lists.sourceforge.net @@ -7950,6 +7872,13 @@ M: Roger Luethi S: Maintained F: drivers/net/ethernet/via/via-rhine.c +VIAPRO SMBUS DRIVER +M: Jean Delvare +L: linux-i2c@vger.kernel.org +S: Maintained +F: Documentation/i2c/busses/i2c-viapro +F: drivers/i2c/busses/i2c-viapro.c + VIA SD/MMC CARD CONTROLLER DRIVER M: Bruce Chang M: Harald Welte @@ -8204,7 +8133,7 @@ F: drivers/platform/x86 X86 MCE INFRASTRUCTURE M: Tony Luck -M: Borislav Petkov +M: Borislav Petkov L: linux-edac@vger.kernel.org S: Maintained F: arch/x86/kernel/cpu/mcheck/* diff --git a/trunk/Makefile b/trunk/Makefile index 540f7b240c77..14c93b39b929 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 7 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = -rc2 NAME = Terrified Chipmunk # *DOCUMENTATION* @@ -1321,12 +1321,10 @@ kernelversion: # Clear a bunch of variables before executing the submake tools/: FORCE - $(Q)mkdir -p $(objtree)/tools - $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= O=$(objtree) subdir=tools -C $(src)/tools/ + $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= -C $(src)/tools/ tools/%: FORCE - $(Q)mkdir -p $(objtree)/tools - $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= O=$(objtree) subdir=tools -C $(src)/tools/ $* + $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= -C $(src)/tools/ $* # Single targets # --------------------------------------------------------------------------- diff --git a/trunk/arch/alpha/include/asm/thread_info.h b/trunk/arch/alpha/include/asm/thread_info.h index 1f8c72959fb6..4554ecbff7c6 100644 --- a/trunk/arch/alpha/include/asm/thread_info.h +++ b/trunk/arch/alpha/include/asm/thread_info.h @@ -7,7 +7,6 @@ #include #include #include -#include #endif #ifndef __ASSEMBLY__ @@ -22,7 +21,6 @@ struct thread_info { mm_segment_t addr_limit; /* thread address space */ unsigned cpu; /* current CPU */ int preempt_count; /* 0 => preemptable, <0 => BUG */ - unsigned int status; /* thread-synchronous flags */ int bpt_nsaved; unsigned long bpt_addr[2]; /* breakpoint handling */ @@ -65,6 +63,8 @@ register struct thread_info *__current_thread_info __asm__("$8"); * - these are process state flags and used from assembly * - pending work-to-be-done flags come first and must be assigned to be * within bits 0 to 7 to fit in and immediate operand. + * - ALPHA_UAC_SHIFT below must be kept consistent with the unaligned + * control flags. * * TIF_SYSCALL_TRACE is known to be 0 via blbs. */ @@ -72,12 +72,18 @@ register struct thread_info *__current_thread_info __asm__("$8"); #define TIF_NOTIFY_RESUME 1 /* callback before returning to user */ #define TIF_SIGPENDING 2 /* signal pending */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ +#define TIF_POLLING_NRFLAG 8 /* poll_idle is polling NEED_RESCHED */ #define TIF_DIE_IF_KERNEL 9 /* dik recursion lock */ +#define TIF_UAC_NOPRINT 10 /* ! Preserve sequence of following */ +#define TIF_UAC_NOFIX 11 /* ! flags as they match */ +#define TIF_UAC_SIGBUS 12 /* ! userspace part of 'osf_sysinfo' */ #define TIF_MEMDIE 13 /* is terminating due to OOM killer */ +#define TIF_RESTORE_SIGMASK 14 /* restore signal mask in do_signal */ #define _TIF_SYSCALL_TRACE (1<status & TS_POLLING) - -#ifndef __ASSEMBLY__ -#define HAVE_SET_RESTORE_SIGMASK 1 -static inline void set_restore_sigmask(void) -{ - struct thread_info *ti = current_thread_info(); - ti->status |= TS_RESTORE_SIGMASK; - WARN_ON(!test_bit(TIF_SIGPENDING, (unsigned long *)&ti->flags)); -} -static inline void clear_restore_sigmask(void) -{ - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; -} -static inline bool test_restore_sigmask(void) -{ - return current_thread_info()->status & TS_RESTORE_SIGMASK; -} -static inline bool test_and_clear_restore_sigmask(void) -{ - struct thread_info *ti = current_thread_info(); - if (!(ti->status & TS_RESTORE_SIGMASK)) - return false; - ti->status &= ~TS_RESTORE_SIGMASK; - return true; -} -#endif - -#define SET_UNALIGN_CTL(task,value) ({ \ - __u32 status = task_thread_info(task)->status & ~UAC_BITMASK; \ - if (value & PR_UNALIGN_NOPRINT) \ - status |= TS_UAC_NOPRINT; \ - if (value & PR_UNALIGN_SIGBUS) \ - status |= TS_UAC_SIGBUS; \ - if (value & 4) /* alpha-specific */ \ - status |= TS_UAC_NOFIX; \ - task_thread_info(task)->status = status; \ +#define SET_UNALIGN_CTL(task,value) ({ \ + task_thread_info(task)->flags = ((task_thread_info(task)->flags & \ + ~ALPHA_UAC_MASK) \ + | (((value) << ALPHA_UAC_SHIFT) & (1<status & ~UAC_BITMASK; \ - __u32 res = 0; \ - if (status & TS_UAC_NOPRINT) \ - res |= PR_UNALIGN_NOPRINT; \ - if (status & TS_UAC_SIGBUS) \ - res |= PR_UNALIGN_SIGBUS; \ - if (status & TS_UAC_NOFIX) \ - res |= 4; \ - put_user(res, (int __user *)(value)); \ + put_user((task_thread_info(task)->flags & (1 << TIF_UAC_NOPRINT))\ + >> ALPHA_UAC_SHIFT \ + | (task_thread_info(task)->flags & (1 << TIF_UAC_SIGBUS))\ + >> (ALPHA_UAC_SHIFT + 1) \ + | (task_thread_info(task)->flags & (1 << TIF_UAC_NOFIX))\ + >> (ALPHA_UAC_SHIFT - 1), \ + (int __user *)(value)); \ }) +#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) + #endif /* __KERNEL__ */ #endif /* _ALPHA_THREAD_INFO_H */ diff --git a/trunk/arch/alpha/kernel/osf_sys.c b/trunk/arch/alpha/kernel/osf_sys.c index 14db93e4c8a8..9eb090582cf1 100644 --- a/trunk/arch/alpha/kernel/osf_sys.c +++ b/trunk/arch/alpha/kernel/osf_sys.c @@ -445,7 +445,7 @@ struct procfs_args { * unhappy with OSF UFS. [CHECKME] */ static int -osf_ufs_mount(const char *dirname, struct ufs_args __user *args, int flags) +osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags) { int retval; struct cdfs_args tmp; @@ -465,7 +465,7 @@ osf_ufs_mount(const char *dirname, struct ufs_args __user *args, int flags) } static int -osf_cdfs_mount(const char *dirname, struct cdfs_args __user *args, int flags) +osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags) { int retval; struct cdfs_args tmp; @@ -485,7 +485,7 @@ osf_cdfs_mount(const char *dirname, struct cdfs_args __user *args, int flags) } static int -osf_procfs_mount(const char *dirname, struct procfs_args __user *args, int flags) +osf_procfs_mount(char *dirname, struct procfs_args __user *args, int flags) { struct procfs_args tmp; @@ -793,7 +793,8 @@ SYSCALL_DEFINE5(osf_getsysinfo, unsigned long, op, void __user *, buffer, case GSI_UACPROC: if (nbytes < sizeof(unsigned int)) return -EINVAL; - w = current_thread_info()->status & UAC_BITMASK; + w = (current_thread_info()->flags >> ALPHA_UAC_SHIFT) & + UAC_BITMASK; if (put_user(w, (unsigned int __user *)buffer)) return -EFAULT; return 1; @@ -903,20 +904,24 @@ SYSCALL_DEFINE5(osf_setsysinfo, unsigned long, op, void __user *, buffer, break; case SSI_NVPAIRS: { - unsigned __user *p = buffer; - unsigned i; + unsigned long v, w, i; + unsigned int old, new; - for (i = 0, p = buffer; i < nbytes; ++i, p += 2) { - unsigned v, w, status; + for (i = 0; i < nbytes; ++i) { - if (get_user(v, p) || get_user(w, p + 1)) + if (get_user(v, 2*i + (unsigned int __user *)buffer)) + return -EFAULT; + if (get_user(w, 2*i + 1 + (unsigned int __user *)buffer)) return -EFAULT; switch (v) { case SSIN_UACPROC: - w &= UAC_BITMASK; - status = current_thread_info()->status; - status = (status & ~UAC_BITMASK) | w; - current_thread_info()->status = status; + again: + old = current_thread_info()->flags; + new = old & ~(UAC_BITMASK << ALPHA_UAC_SHIFT); + new = new | (w & UAC_BITMASK) << ALPHA_UAC_SHIFT; + if (cmpxchg(¤t_thread_info()->flags, + old, new) != old) + goto again; break; default: diff --git a/trunk/arch/alpha/kernel/process.c b/trunk/arch/alpha/kernel/process.c index 51987dcf79b8..4054e0ffe2b2 100644 --- a/trunk/arch/alpha/kernel/process.c +++ b/trunk/arch/alpha/kernel/process.c @@ -49,7 +49,7 @@ EXPORT_SYMBOL(pm_power_off); void cpu_idle(void) { - current_thread_info()->status |= TS_POLLING; + set_thread_flag(TIF_POLLING_NRFLAG); while (1) { /* FIXME -- EV6 and LCA45 know how to power down diff --git a/trunk/arch/alpha/kernel/traps.c b/trunk/arch/alpha/kernel/traps.c index 272666d006df..80d987c0e9aa 100644 --- a/trunk/arch/alpha/kernel/traps.c +++ b/trunk/arch/alpha/kernel/traps.c @@ -780,17 +780,17 @@ do_entUnaUser(void __user * va, unsigned long opcode, /* Check the UAC bits to decide what the user wants us to do with the unaliged access. */ - if (!(current_thread_info()->status & TS_UAC_NOPRINT)) { + if (!test_thread_flag (TIF_UAC_NOPRINT)) { if (__ratelimit(&ratelimit)) { printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n", current->comm, task_pid_nr(current), regs->pc - 4, va, opcode, reg); } } - if ((current_thread_info()->status & TS_UAC_SIGBUS)) + if (test_thread_flag (TIF_UAC_SIGBUS)) goto give_sigbus; /* Not sure why you'd want to use this, but... */ - if ((current_thread_info()->status & TS_UAC_NOFIX)) + if (test_thread_flag (TIF_UAC_NOFIX)) return; /* Don't bother reading ds in the access check since we already diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 67f1fdbad7f9..73067efd4845 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -330,8 +330,6 @@ config ARCH_AT91 select IRQ_DOMAIN select NEED_MACH_GPIO_H select NEED_MACH_IO_H if PCCARD - select PINCTRL - select PINCTRL_AT91 if USE_OF help This enables support for systems based on Atmel AT91RM9200 and AT91SAM9* processors. @@ -549,7 +547,6 @@ config ARCH_KIRKWOOD select CPU_FEROCEON select GENERIC_CLOCKEVENTS select PCI - select PCI_QUIRKS select PLAT_ORION_LEGACY help Support for the following Marvell Kirkwood series SoCs: @@ -589,7 +586,6 @@ config ARCH_MMP select GPIO_PXA select IRQ_DOMAIN select NEED_MACH_GPIO_H - select PINCTRL select PLAT_PXA select SPARSE_IRQ help @@ -1607,8 +1603,8 @@ config NR_CPUS default "4" config HOTPLUG_CPU - bool "Support for hot-pluggable CPUs" - depends on SMP && HOTPLUG + bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" + depends on SMP && HOTPLUG && EXPERIMENTAL help Say Y here to experiment with turning CPUs off and on. CPUs can be controlled through /sys/devices/system/cpu. @@ -1649,8 +1645,8 @@ config HZ default 100 config THUMB2_KERNEL - bool "Compile the kernel in Thumb-2 mode" - depends on CPU_V7 && !CPU_V6 && !CPU_V6K + bool "Compile the kernel in Thumb-2 mode (EXPERIMENTAL)" + depends on CPU_V7 && !CPU_V6 && !CPU_V6K && EXPERIMENTAL select AEABI select ARM_ASM_UNIFIED select ARM_UNWIND @@ -1854,7 +1850,6 @@ config XEN_DOM0 config XEN bool "Xen guest support on ARM (EXPERIMENTAL)" depends on EXPERIMENTAL && ARM && OF - depends on CPU_V7 && !CPU_V6 help Say Y if you want to run Linux in a Virtual Machine on Xen on ARM. diff --git a/trunk/arch/arm/Makefile b/trunk/arch/arm/Makefile index 5f914fca911b..f023e3acdfbd 100644 --- a/trunk/arch/arm/Makefile +++ b/trunk/arch/arm/Makefile @@ -21,6 +21,8 @@ endif OBJCOPYFLAGS :=-O binary -R .comment -S GZFLAGS :=-9 #KBUILD_CFLAGS +=-pipe +# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb: +KBUILD_CFLAGS +=$(call cc-option,-marm,) # Never generate .eh_frame KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm) @@ -103,20 +105,17 @@ endif ifeq ($(CONFIG_THUMB2_KERNEL),y) AFLAGS_AUTOIT :=$(call as-option,-Wa$(comma)-mimplicit-it=always,-Wa$(comma)-mauto-it) AFLAGS_NOWARN :=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W) -CFLAGS_ISA :=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN) -AFLAGS_ISA :=$(CFLAGS_ISA) -Wa$(comma)-mthumb +CFLAGS_THUMB2 :=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN) +AFLAGS_THUMB2 :=$(CFLAGS_THUMB2) -Wa$(comma)-mthumb # Work around buggy relocation from gas if requested: ifeq ($(CONFIG_THUMB2_AVOID_R_ARM_THM_JUMP11),y) CFLAGS_MODULE +=-fno-optimize-sibling-calls endif -else -CFLAGS_ISA :=$(call cc-option,-marm,) -AFLAGS_ISA :=$(CFLAGS_ISA) endif # Need -Uarm for gcc < 3.x -KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm -KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float +KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_THUMB2) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm +KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_THUMB2) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float CHECKFLAGS += -D__arm__ diff --git a/trunk/arch/arm/boot/Makefile b/trunk/arch/arm/boot/Makefile index 9137df539b61..3fdab016aa5c 100644 --- a/trunk/arch/arm/boot/Makefile +++ b/trunk/arch/arm/boot/Makefile @@ -33,7 +33,7 @@ ifeq ($(CONFIG_XIP_KERNEL),y) $(obj)/xipImage: vmlinux FORCE $(call if_changed,objcopy) - @$(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))' + @echo ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))' $(obj)/Image $(obj)/zImage: FORCE @echo 'Kernel configured for XIP (CONFIG_XIP_KERNEL=y)' @@ -48,14 +48,14 @@ $(obj)/xipImage: FORCE $(obj)/Image: vmlinux FORCE $(call if_changed,objcopy) - @$(kecho) ' Kernel: $@ is ready' + @echo ' Kernel: $@ is ready' $(obj)/compressed/vmlinux: $(obj)/Image FORCE $(Q)$(MAKE) $(build)=$(obj)/compressed $@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE $(call if_changed,objcopy) - @$(kecho) ' Kernel: $@ is ready' + @echo ' Kernel: $@ is ready' endif @@ -90,7 +90,7 @@ fi $(obj)/uImage: $(obj)/zImage FORCE @$(check_for_multiple_loadaddr) $(call if_changed,uimage) - @$(kecho) ' Image $@ is ready' + @echo ' Image $@ is ready' $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE $(Q)$(MAKE) $(build)=$(obj)/bootp $@ @@ -98,7 +98,7 @@ $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE $(obj)/bootpImage: $(obj)/bootp/bootp FORCE $(call if_changed,objcopy) - @$(kecho) ' Kernel: $@ is ready' + @echo ' Kernel: $@ is ready' PHONY += initrd FORCE initrd: diff --git a/trunk/arch/arm/boot/compressed/head.S b/trunk/arch/arm/boot/compressed/head.S index 49ca86e37b8d..90275f036cd1 100644 --- a/trunk/arch/arm/boot/compressed/head.S +++ b/trunk/arch/arm/boot/compressed/head.S @@ -652,15 +652,6 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size mov pc, lr ENDPROC(__setup_mmu) -@ Enable unaligned access on v6, to allow better code generation -@ for the decompressor C code: -__armv6_mmu_cache_on: - mrc p15, 0, r0, c1, c0, 0 @ read SCTLR - bic r0, r0, #2 @ A (no unaligned access fault) - orr r0, r0, #1 << 22 @ U (v6 unaligned access model) - mcr p15, 0, r0, c1, c0, 0 @ write SCTLR - b __armv4_mmu_cache_on - __arm926ejs_mmu_cache_on: #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mov r0, #4 @ put dcache in WT mode @@ -703,9 +694,6 @@ __armv7_mmu_cache_on: bic r0, r0, #1 << 28 @ clear SCTLR.TRE orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement orr r0, r0, #0x003c @ write buffer - bic r0, r0, #2 @ A (no unaligned access fault) - orr r0, r0, #1 << 22 @ U (v6 unaligned access model) - @ (needed for ARM1176) #ifdef CONFIG_MMU #ifdef CONFIG_CPU_ENDIAN_BE8 orr r0, r0, #1 << 25 @ big-endian page tables @@ -926,7 +914,7 @@ proc_types: .word 0x0007b000 @ ARMv6 .word 0x000ff000 - W(b) __armv6_mmu_cache_on + W(b) __armv4_mmu_cache_on W(b) __armv4_mmu_cache_off W(b) __armv6_mmu_cache_flush diff --git a/trunk/arch/arm/boot/dts/Makefile b/trunk/arch/arm/boot/dts/Makefile index fb5b07737ca7..f37cf9fa5fa0 100644 --- a/trunk/arch/arm/boot/dts/Makefile +++ b/trunk/arch/arm/boot/dts/Makefile @@ -1,37 +1,21 @@ ifeq ($(CONFIG_OF),y) -# Keep at91 dtb files sorted alphabetically for each SoC -# rm9200 -dtb-$(CONFIG_ARCH_AT91) += at91rm9200ek.dtb -# sam9260 -dtb-$(CONFIG_ARCH_AT91) += animeo_ip.dtb -dtb-$(CONFIG_ARCH_AT91) += aks-cdu.dtb -dtb-$(CONFIG_ARCH_AT91) += ethernut5.dtb -dtb-$(CONFIG_ARCH_AT91) += evk-pro3.dtb -dtb-$(CONFIG_ARCH_AT91) += tny_a9260.dtb -dtb-$(CONFIG_ARCH_AT91) += usb_a9260.dtb -# sam9263 -dtb-$(CONFIG_ARCH_AT91) += at91sam9263ek.dtb -dtb-$(CONFIG_ARCH_AT91) += tny_a9263.dtb -dtb-$(CONFIG_ARCH_AT91) += usb_a9263.dtb -# sam9g20 -dtb-$(CONFIG_ARCH_AT91) += at91sam9g20ek.dtb -dtb-$(CONFIG_ARCH_AT91) += at91sam9g20ek_2mmc.dtb -dtb-$(CONFIG_ARCH_AT91) += kizbox.dtb -dtb-$(CONFIG_ARCH_AT91) += tny_a9g20.dtb -dtb-$(CONFIG_ARCH_AT91) += usb_a9g20.dtb -# sam9g45 -dtb-$(CONFIG_ARCH_AT91) += at91sam9m10g45ek.dtb -dtb-$(CONFIG_ARCH_AT91) += pm9g45.dtb -# sam9n12 -dtb-$(CONFIG_ARCH_AT91) += at91sam9n12ek.dtb -# sam9x5 -dtb-$(CONFIG_ARCH_AT91) += at91sam9g15ek.dtb -dtb-$(CONFIG_ARCH_AT91) += at91sam9g25ek.dtb -dtb-$(CONFIG_ARCH_AT91) += at91sam9g35ek.dtb -dtb-$(CONFIG_ARCH_AT91) += at91sam9x25ek.dtb -dtb-$(CONFIG_ARCH_AT91) += at91sam9x35ek.dtb - +dtb-$(CONFIG_ARCH_AT91) += aks-cdu.dtb \ + at91sam9263ek.dtb \ + at91sam9g20ek_2mmc.dtb \ + at91sam9g20ek.dtb \ + at91sam9g25ek.dtb \ + at91sam9m10g45ek.dtb \ + at91sam9n12ek.dtb \ + ethernut5.dtb \ + evk-pro3.dtb \ + kizbox.dtb \ + tny_a9260.dtb \ + tny_a9263.dtb \ + tny_a9g20.dtb \ + usb_a9260.dtb \ + usb_a9263.dtb \ + usb_a9g20.dtb dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb dtb-$(CONFIG_ARCH_DOVE) += dove-cm-a510.dtb \ dove-cubox.dtb \ diff --git a/trunk/arch/arm/boot/dts/animeo_ip.dts b/trunk/arch/arm/boot/dts/animeo_ip.dts deleted file mode 100644 index 74d92cd29d87..000000000000 --- a/trunk/arch/arm/boot/dts/animeo_ip.dts +++ /dev/null @@ -1,178 +0,0 @@ -/* - * animeo_ip.dts - Device Tree file for Somfy Animeo IP Boards - * - * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD - * - * Licensed under GPLv2 only. - */ - -/dts-v1/; -/include/ "at91sam9260.dtsi" - -/ { - model = "Somfy Animeo IP"; - compatible = "somfy,animeo-ip", "atmel,at91sam9260", "atmel,at91sam9"; - - aliases { - serial0 = &usart1; - serial1 = &usart2; - serial2 = &usart0; - serial3 = &dbgu; - serial4 = &usart3; - serial5 = &uart0; - serial6 = &uart1; - }; - - chosen { - linux,stdout-path = &usart2; - }; - - memory { - reg = <0x20000000 0x4000000>; - }; - - clocks { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - main_clock: clock@0 { - compatible = "atmel,osc", "fixed-clock"; - clock-frequency = <18432000>; - }; - }; - - ahb { - apb { - usart0: serial@fffb0000 { - pinctrl-0 = <&pinctrl_usart0 &pinctrl_usart0_rts>; - linux,rs485-enabled-at-boot-time; - status = "okay"; - }; - - usart1: serial@fffb4000 { - pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts>; - linux,rs485-enabled-at-boot-time; - status = "okay"; - }; - - usart2: serial@fffb8000 { - pinctrl-0 = <&pinctrl_usart2>; - status = "okay"; - }; - - macb0: ethernet@fffc4000 { - pinctrl-0 = <&pinctrl_macb_rmii &pinctrl_macb_rmii_mii>; - phy-mode = "mii"; - status = "okay"; - }; - - mmc0: mmc@fffa8000 { - pinctrl-0 = <&pinctrl_mmc0_clk - &pinctrl_mmc0_slot1_cmd_dat0 - &pinctrl_mmc0_slot1_dat1_3>; - status = "okay"; - - slot@1 { - reg = <1>; - bus-width = <4>; - }; - }; - }; - - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "soft"; - nand-on-flash-bbt; - status = "okay"; - - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x8000>; - }; - - barebox@8000 { - label = "barebox"; - reg = <0x8000 0x40000>; - }; - - bareboxenv@48000 { - label = "bareboxenv"; - reg = <0x48000 0x8000>; - }; - - user_block@0x50000 { - label = "user_block"; - reg = <0x50000 0xb0000>; - }; - - kernel@100000 { - label = "kernel"; - reg = <0x100000 0x1b0000>; - }; - - root@2b0000 { - label = "root"; - reg = <0x2b0000 0x1D50000>; - }; - }; - - usb0: ohci@00500000 { - num-ports = <2>; - atmel,vbus-gpio = <&pioB 15 1>; - status = "okay"; - }; - }; - - leds { - compatible = "gpio-leds"; - - power_green { - label = "power_green"; - gpios = <&pioC 17 0>; - linux,default-trigger = "heartbeat"; - }; - - power_red { - label = "power_red"; - gpios = <&pioA 2 0>; - }; - - tx_green { - label = "tx_green"; - gpios = <&pioC 19 0>; - }; - - tx_red { - label = "tx_red"; - gpios = <&pioC 18 0>; - }; - }; - - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - - keyswitch_in { - label = "keyswitch_in"; - gpios = <&pioB 1 0>; - linux,code = <28>; - gpio-key,wakeup; - }; - - error_in { - label = "error_in"; - gpios = <&pioB 2 0>; - linux,code = <29>; - gpio-key,wakeup; - }; - - btn { - label = "btn"; - gpios = <&pioC 23 0>; - linux,code = <31>; - gpio-key,wakeup; - }; - }; -}; diff --git a/trunk/arch/arm/boot/dts/at91rm9200.dtsi b/trunk/arch/arm/boot/dts/at91rm9200.dtsi deleted file mode 100644 index e154f242c680..000000000000 --- a/trunk/arch/arm/boot/dts/at91rm9200.dtsi +++ /dev/null @@ -1,349 +0,0 @@ -/* - * at91rm9200.dtsi - Device Tree Include file for AT91RM9200 family SoC - * - * Copyright (C) 2011 Atmel, - * 2011 Nicolas Ferre , - * 2012 Joachim Eastwood - * - * Based on at91sam9260.dtsi - * - * Licensed under GPLv2 or later. - */ - -/include/ "skeleton.dtsi" - -/ { - model = "Atmel AT91RM9200 family SoC"; - compatible = "atmel,at91rm9200"; - interrupt-parent = <&aic>; - - aliases { - serial0 = &dbgu; - serial1 = &usart0; - serial2 = &usart1; - serial3 = &usart2; - serial4 = &usart3; - gpio0 = &pioA; - gpio1 = &pioB; - gpio2 = &pioC; - gpio3 = &pioD; - tcb0 = &tcb0; - tcb1 = &tcb1; - }; - cpus { - cpu@0 { - compatible = "arm,arm920t"; - }; - }; - - memory { - reg = <0x20000000 0x04000000>; - }; - - ahb { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - apb { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - aic: interrupt-controller@fffff000 { - #interrupt-cells = <3>; - compatible = "atmel,at91rm9200-aic"; - interrupt-controller; - reg = <0xfffff000 0x200>; - atmel,external-irqs = <25 26 27 28 29 30 31>; - }; - - ramc0: ramc@ffffff00 { - compatible = "atmel,at91rm9200-sdramc"; - reg = <0xffffff00 0x100>; - }; - - pmc: pmc@fffffc00 { - compatible = "atmel,at91rm9200-pmc"; - reg = <0xfffffc00 0x100>; - }; - - st: timer@fffffd00 { - compatible = "atmel,at91rm9200-st"; - reg = <0xfffffd00 0x100>; - interrupts = <1 4 7>; - }; - - tcb0: timer@fffa0000 { - compatible = "atmel,at91rm9200-tcb"; - reg = <0xfffa0000 0x100>; - interrupts = <17 4 0 18 4 0 19 4 0>; - }; - - tcb1: timer@fffa4000 { - compatible = "atmel,at91rm9200-tcb"; - reg = <0xfffa4000 0x100>; - interrupts = <20 4 0 21 4 0 22 4 0>; - }; - - pinctrl@fffff400 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "atmel,at91rm9200-pinctrl", "simple-bus"; - ranges = <0xfffff400 0xfffff400 0x800>; - - atmel,mux-mask = < - /* A B */ - 0xffffffff 0xffffffff /* pioA */ - 0xffffffff 0x083fffff /* pioB */ - 0xffff3fff 0x00000000 /* pioC */ - 0x03ff87ff 0x0fffff80 /* pioD */ - >; - - /* shared pinctrl settings */ - dbgu { - pinctrl_dbgu: dbgu-0 { - atmel,pins = - <0 30 0x1 0x0 /* PA30 periph A */ - 0 31 0x1 0x1>; /* PA31 periph with pullup */ - }; - }; - - uart0 { - pinctrl_uart0: uart0-0 { - atmel,pins = - <0 17 0x1 0x0 /* PA17 periph A */ - 0 18 0x1 0x0>; /* PA18 periph A */ - }; - - pinctrl_uart0_rts: uart0_rts-0 { - atmel,pins = - <0 20 0x1 0x0>; /* PA20 periph A */ - }; - - pinctrl_uart0_cts: uart0_cts-0 { - atmel,pins = - <0 21 0x1 0x0>; /* PA21 periph A */ - }; - }; - - uart1 { - pinctrl_uart1: uart1-0 { - atmel,pins = - <1 20 0x1 0x1 /* PB20 periph A with pullup */ - 1 21 0x1 0x0>; /* PB21 periph A */ - }; - - pinctrl_uart1_rts: uart1_rts-0 { - atmel,pins = - <1 24 0x1 0x0>; /* PB24 periph A */ - }; - - pinctrl_uart1_cts: uart1_cts-0 { - atmel,pins = - <1 26 0x1 0x0>; /* PB26 periph A */ - }; - - pinctrl_uart1_dtr_dsr: uart1_dtr_dsr-0 { - atmel,pins = - <1 19 0x1 0x0 /* PB19 periph A */ - 1 25 0x1 0x0>; /* PB25 periph A */ - }; - - pinctrl_uart1_dcd: uart1_dcd-0 { - atmel,pins = - <1 23 0x1 0x0>; /* PB23 periph A */ - }; - - pinctrl_uart1_ri: uart1_ri-0 { - atmel,pins = - <1 18 0x1 0x0>; /* PB18 periph A */ - }; - }; - - uart2 { - pinctrl_uart2: uart2-0 { - atmel,pins = - <0 22 0x1 0x0 /* PA22 periph A */ - 0 23 0x1 0x1>; /* PA23 periph A with pullup */ - }; - - pinctrl_uart2_rts: uart2_rts-0 { - atmel,pins = - <0 30 0x2 0x0>; /* PA30 periph B */ - }; - - pinctrl_uart2_cts: uart2_cts-0 { - atmel,pins = - <0 31 0x2 0x0>; /* PA31 periph B */ - }; - }; - - uart3 { - pinctrl_uart3: uart3-0 { - atmel,pins = - <0 5 0x2 0x1 /* PA5 periph B with pullup */ - 0 6 0x2 0x0>; /* PA6 periph B */ - }; - - pinctrl_uart3_rts: uart3_rts-0 { - atmel,pins = - <1 0 0x2 0x0>; /* PB0 periph B */ - }; - - pinctrl_uart3_cts: uart3_cts-0 { - atmel,pins = - <1 1 0x2 0x0>; /* PB1 periph B */ - }; - }; - - nand { - pinctrl_nand: nand-0 { - atmel,pins = - <2 2 0x0 0x1 /* PC2 gpio RDY pin pull_up */ - 1 1 0x0 0x1>; /* PB1 gpio CD pin pull_up */ - }; - }; - - pioA: gpio@fffff400 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff400 0x200>; - interrupts = <2 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; - - pioB: gpio@fffff600 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff600 0x200>; - interrupts = <3 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; - - pioC: gpio@fffff800 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff800 0x200>; - interrupts = <4 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; - - pioD: gpio@fffffa00 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffffa00 0x200>; - interrupts = <5 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; - }; - - dbgu: serial@fffff200 { - compatible = "atmel,at91rm9200-usart"; - reg = <0xfffff200 0x200>; - interrupts = <1 4 7>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_dbgu>; - status = "disabled"; - }; - - usart0: serial@fffc0000 { - compatible = "atmel,at91rm9200-usart"; - reg = <0xfffc0000 0x200>; - interrupts = <6 4 5>; - atmel,use-dma-rx; - atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart0>; - status = "disabled"; - }; - - usart1: serial@fffc4000 { - compatible = "atmel,at91rm9200-usart"; - reg = <0xfffc4000 0x200>; - interrupts = <7 4 5>; - atmel,use-dma-rx; - atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart1>; - status = "disabled"; - }; - - usart2: serial@fffc8000 { - compatible = "atmel,at91rm9200-usart"; - reg = <0xfffc8000 0x200>; - interrupts = <8 4 5>; - atmel,use-dma-rx; - atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart2>; - status = "disabled"; - }; - - usart3: serial@fffcc000 { - compatible = "atmel,at91rm9200-usart"; - reg = <0xfffcc000 0x200>; - interrupts = <23 4 5>; - atmel,use-dma-rx; - atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart3>; - status = "disabled"; - }; - - usb1: gadget@fffb0000 { - compatible = "atmel,at91rm9200-udc"; - reg = <0xfffb0000 0x4000>; - interrupts = <11 4 2>; - status = "disabled"; - }; - }; - - nand0: nand@40000000 { - compatible = "atmel,at91rm9200-nand"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0x40000000 0x10000000>; - atmel,nand-addr-offset = <21>; - atmel,nand-cmd-offset = <22>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_nand>; - nand-ecc-mode = "soft"; - gpios = <&pioC 2 0 - 0 - &pioB 1 0 - >; - status = "disabled"; - }; - - usb0: ohci@00300000 { - compatible = "atmel,at91rm9200-ohci", "usb-ohci"; - reg = <0x00300000 0x100000>; - interrupts = <23 4 2>; - status = "disabled"; - }; - }; - - i2c@0 { - compatible = "i2c-gpio"; - gpios = <&pioA 23 0 /* sda */ - &pioA 24 0 /* scl */ - >; - i2c-gpio,sda-open-drain; - i2c-gpio,scl-open-drain; - i2c-gpio,delay-us = <2>; /* ~100 kHz */ - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; -}; diff --git a/trunk/arch/arm/boot/dts/at91rm9200ek.dts b/trunk/arch/arm/boot/dts/at91rm9200ek.dts deleted file mode 100644 index 8aa48931e0a2..000000000000 --- a/trunk/arch/arm/boot/dts/at91rm9200ek.dts +++ /dev/null @@ -1,79 +0,0 @@ -/* - * at91rm9200ek.dts - Device Tree file for Atmel AT91RM9200 evaluation kit - * - * Copyright (C) 2012 Joachim Eastwood - * - * Licensed under GPLv2 only - */ -/dts-v1/; -/include/ "at91rm9200.dtsi" - -/ { - model = "Atmel AT91RM9200 evaluation kit"; - compatible = "atmel,at91rm9200ek", "atmel,at91rm9200"; - - memory { - reg = <0x20000000 0x4000000>; - }; - - clocks { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - main_clock: clock@0 { - compatible = "atmel,osc", "fixed-clock"; - clock-frequency = <18432000>; - }; - }; - - ahb { - apb { - dbgu: serial@fffff200 { - status = "okay"; - }; - - usart1: serial@fffc4000 { - pinctrl-0 = - <&pinctrl_uart1 - &pinctrl_uart1_rts - &pinctrl_uart1_cts - &pinctrl_uart1_dtr_dsr - &pinctrl_uart1_dcd - &pinctrl_uart1_ri>; - status = "okay"; - }; - - usb1: gadget@fffb0000 { - atmel,vbus-gpio = <&pioD 4 0>; - status = "okay"; - }; - }; - - usb0: ohci@00300000 { - num-ports = <2>; - status = "okay"; - }; - }; - - leds { - compatible = "gpio-leds"; - - ds2 { - label = "green"; - gpios = <&pioB 0 0x1>; - linux,default-trigger = "mmc0"; - }; - - ds4 { - label = "yellow"; - gpios = <&pioB 1 0x1>; - linux,default-trigger = "heartbeat"; - }; - - ds6 { - label = "red"; - gpios = <&pioB 2 0x1>; - }; - }; -}; diff --git a/trunk/arch/arm/boot/dts/at91sam9260.dtsi b/trunk/arch/arm/boot/dts/at91sam9260.dtsi index b1d3fab60e0a..d410581a5a85 100644 --- a/trunk/arch/arm/boot/dts/at91sam9260.dtsi +++ b/trunk/arch/arm/boot/dts/at91sam9260.dtsi @@ -21,8 +21,8 @@ serial2 = &usart1; serial3 = &usart2; serial4 = &usart3; - serial5 = &uart0; - serial6 = &uart1; + serial5 = &usart4; + serial6 = &usart5; gpio0 = &pioA; gpio1 = &pioB; gpio2 = &pioC; @@ -98,250 +98,40 @@ interrupts = <26 4 0 27 4 0 28 4 0>; }; - pinctrl@fffff400 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "atmel,at91rm9200-pinctrl", "simple-bus"; - ranges = <0xfffff400 0xfffff400 0x600>; - - atmel,mux-mask = < - /* A B */ - 0xffffffff 0xffc00c3b /* pioA */ - 0xffffffff 0x7fff3ccf /* pioB */ - 0xffffffff 0x007fffff /* pioC */ - >; - - /* shared pinctrl settings */ - dbgu { - pinctrl_dbgu: dbgu-0 { - atmel,pins = - <1 14 0x1 0x0 /* PB14 periph A */ - 1 15 0x1 0x1>; /* PB15 periph with pullup */ - }; - }; - - usart0 { - pinctrl_usart0: usart0-0 { - atmel,pins = - <1 4 0x1 0x0 /* PB4 periph A */ - 1 5 0x1 0x0>; /* PB5 periph A */ - }; - - pinctrl_usart0_rts: usart0_rts-0 { - atmel,pins = - <1 26 0x1 0x0>; /* PB26 periph A */ - }; - - pinctrl_usart0_cts: usart0_cts-0 { - atmel,pins = - <1 27 0x1 0x0>; /* PB27 periph A */ - }; - - pinctrl_usart0_dtr_dsr: usart0_dtr_dsr-0 { - atmel,pins = - <1 24 0x1 0x0 /* PB24 periph A */ - 1 22 0x1 0x0>; /* PB22 periph A */ - }; - - pinctrl_usart0_dcd: usart0_dcd-0 { - atmel,pins = - <1 23 0x1 0x0>; /* PB23 periph A */ - }; - - pinctrl_usart0_ri: usart0_ri-0 { - atmel,pins = - <1 25 0x1 0x0>; /* PB25 periph A */ - }; - }; - - usart1 { - pinctrl_usart1: usart1-0 { - atmel,pins = - <2 6 0x1 0x1 /* PB6 periph A with pullup */ - 2 7 0x1 0x0>; /* PB7 periph A */ - }; - - pinctrl_usart1_rts: usart1_rts-0 { - atmel,pins = - <1 28 0x1 0x0>; /* PB28 periph A */ - }; - - pinctrl_usart1_cts: usart1_cts-0 { - atmel,pins = - <1 29 0x1 0x0>; /* PB29 periph A */ - }; - }; - - usart2 { - pinctrl_usart2: usart2-0 { - atmel,pins = - <1 8 0x1 0x1 /* PB8 periph A with pullup */ - 1 9 0x1 0x0>; /* PB9 periph A */ - }; - - pinctrl_usart2_rts: usart2_rts-0 { - atmel,pins = - <0 4 0x1 0x0>; /* PA4 periph A */ - }; - - pinctrl_usart2_cts: usart2_cts-0 { - atmel,pins = - <0 5 0x1 0x0>; /* PA5 periph A */ - }; - }; - - usart3 { - pinctrl_usart3: usart3-0 { - atmel,pins = - <2 10 0x1 0x1 /* PB10 periph A with pullup */ - 2 11 0x1 0x0>; /* PB11 periph A */ - }; - - pinctrl_usart3_rts: usart3_rts-0 { - atmel,pins = - <3 8 0x2 0x0>; /* PB8 periph B */ - }; - - pinctrl_usart3_cts: usart3_cts-0 { - atmel,pins = - <3 10 0x2 0x0>; /* PB10 periph B */ - }; - }; - - uart0 { - pinctrl_uart0: uart0-0 { - atmel,pins = - <0 31 0x2 0x1 /* PA31 periph B with pullup */ - 0 30 0x2 0x0>; /* PA30 periph B */ - }; - }; - - uart1 { - pinctrl_uart1: uart1-0 { - atmel,pins = - <2 12 0x1 0x1 /* PB12 periph A with pullup */ - 2 13 0x1 0x0>; /* PB13 periph A */ - }; - }; - - nand { - pinctrl_nand: nand-0 { - atmel,pins = - <2 13 0x0 0x1 /* PC13 gpio RDY pin pull_up */ - 2 14 0x0 0x1>; /* PC14 gpio enable pin pull_up */ - }; - }; - - macb { - pinctrl_macb_rmii: macb_rmii-0 { - atmel,pins = - <0 12 0x1 0x0 /* PA12 periph A */ - 0 13 0x1 0x0 /* PA13 periph A */ - 0 14 0x1 0x0 /* PA14 periph A */ - 0 15 0x1 0x0 /* PA15 periph A */ - 0 16 0x1 0x0 /* PA16 periph A */ - 0 17 0x1 0x0 /* PA17 periph A */ - 0 18 0x1 0x0 /* PA18 periph A */ - 0 19 0x1 0x0 /* PA19 periph A */ - 0 20 0x1 0x0 /* PA20 periph A */ - 0 21 0x1 0x0>; /* PA21 periph A */ - }; - - pinctrl_macb_rmii_mii: macb_rmii_mii-0 { - atmel,pins = - <0 22 0x2 0x0 /* PA22 periph B */ - 0 23 0x2 0x0 /* PA23 periph B */ - 0 24 0x2 0x0 /* PA24 periph B */ - 0 25 0x2 0x0 /* PA25 periph B */ - 0 26 0x2 0x0 /* PA26 periph B */ - 0 27 0x2 0x0 /* PA27 periph B */ - 0 28 0x2 0x0 /* PA28 periph B */ - 0 29 0x2 0x0>; /* PA29 periph B */ - }; - - pinctrl_macb_rmii_mii_alt: macb_rmii_mii-1 { - atmel,pins = - <0 10 0x2 0x0 /* PA10 periph B */ - 0 11 0x2 0x0 /* PA11 periph B */ - 0 24 0x2 0x0 /* PA24 periph B */ - 0 25 0x2 0x0 /* PA25 periph B */ - 0 26 0x2 0x0 /* PA26 periph B */ - 0 27 0x2 0x0 /* PA27 periph B */ - 0 28 0x2 0x0 /* PA28 periph B */ - 0 29 0x2 0x0>; /* PA29 periph B */ - }; - }; - - mmc0 { - pinctrl_mmc0_clk: mmc0_clk-0 { - atmel,pins = - <0 8 0x1 0x0>; /* PA8 periph A */ - }; - - pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 { - atmel,pins = - <0 7 0x1 0x1 /* PA7 periph A with pullup */ - 0 6 0x1 0x1>; /* PA6 periph A with pullup */ - }; - - pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 { - atmel,pins = - <0 9 0x1 0x1 /* PA9 periph A with pullup */ - 0 10 0x1 0x1 /* PA10 periph A with pullup */ - 0 11 0x1 0x1>; /* PA11 periph A with pullup */ - }; - - pinctrl_mmc0_slot1_cmd_dat0: mmc0_slot1_cmd_dat0-0 { - atmel,pins = - <0 1 0x2 0x1 /* PA1 periph B with pullup */ - 0 0 0x2 0x1>; /* PA0 periph B with pullup */ - }; - - pinctrl_mmc0_slot1_dat1_3: mmc0_slot1_dat1_3-0 { - atmel,pins = - <0 5 0x2 0x1 /* PA5 periph B with pullup */ - 0 4 0x2 0x1 /* PA4 periph B with pullup */ - 0 3 0x2 0x1>; /* PA3 periph B with pullup */ - }; - }; - - pioA: gpio@fffff400 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff400 0x200>; - interrupts = <2 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioA: gpio@fffff400 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff400 0x100>; + interrupts = <2 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioB: gpio@fffff600 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff600 0x200>; - interrupts = <3 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioB: gpio@fffff600 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff600 0x100>; + interrupts = <3 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioC: gpio@fffff800 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff800 0x200>; - interrupts = <4 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioC: gpio@fffff800 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff800 0x100>; + interrupts = <4 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; }; dbgu: serial@fffff200 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffff200 0x200>; interrupts = <1 4 7>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_dbgu>; status = "disabled"; }; @@ -351,8 +141,6 @@ interrupts = <6 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usart0>; status = "disabled"; }; @@ -362,8 +150,6 @@ interrupts = <7 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usart1>; status = "disabled"; }; @@ -373,8 +159,6 @@ interrupts = <8 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usart2>; status = "disabled"; }; @@ -384,30 +168,24 @@ interrupts = <23 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usart3>; status = "disabled"; }; - uart0: serial@fffd4000 { + usart4: serial@fffd4000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffd4000 0x200>; interrupts = <24 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart0>; status = "disabled"; }; - uart1: serial@fffd8000 { + usart5: serial@fffd8000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffd8000 0x200>; interrupts = <25 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart1>; status = "disabled"; }; @@ -415,8 +193,6 @@ compatible = "cdns,at32ap7000-macb", "cdns,macb"; reg = <0xfffc4000 0x100>; interrupts = <21 4 3>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_macb_rmii>; status = "disabled"; }; @@ -436,15 +212,6 @@ status = "disabled"; }; - mmc0: mmc@fffa8000 { - compatible = "atmel,hsmci"; - reg = <0xfffa8000 0x600>; - interrupts = <9 4 0>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - adc0: adc@fffe0000 { compatible = "atmel,at91sam9260-adc"; reg = <0xfffe0000 0x100>; @@ -490,8 +257,6 @@ >; atmel,nand-addr-offset = <21>; atmel,nand-cmd-offset = <22>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_nand>; gpios = <&pioC 13 0 &pioC 14 0 0 diff --git a/trunk/arch/arm/boot/dts/at91sam9263.dtsi b/trunk/arch/arm/boot/dts/at91sam9263.dtsi index 66106eecf1ed..3e6e5c1abbf3 100644 --- a/trunk/arch/arm/boot/dts/at91sam9263.dtsi +++ b/trunk/arch/arm/boot/dts/at91sam9263.dtsi @@ -89,243 +89,60 @@ reg = <0xfffffd10 0x10>; }; - pinctrl@fffff200 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "atmel,at91rm9200-pinctrl", "simple-bus"; - ranges = <0xfffff200 0xfffff200 0xa00>; - - atmel,mux-mask = < - /* A B */ - 0xfffffffb 0xffffe07f /* pioA */ - 0x0007ffff 0x39072fff /* pioB */ - 0xffffffff 0x3ffffff8 /* pioC */ - 0xfffffbff 0xffffffff /* pioD */ - 0xffe00fff 0xfbfcff00 /* pioE */ - >; - - /* shared pinctrl settings */ - dbgu { - pinctrl_dbgu: dbgu-0 { - atmel,pins = - <2 30 0x1 0x0 /* PC30 periph A */ - 2 31 0x1 0x1>; /* PC31 periph with pullup */ - }; - }; - - usart0 { - pinctrl_usart0: usart0-0 { - atmel,pins = - <0 26 0x1 0x1 /* PA26 periph A with pullup */ - 0 27 0x1 0x0>; /* PA27 periph A */ - }; - - pinctrl_usart0_rts: usart0_rts-0 { - atmel,pins = - <0 28 0x1 0x0>; /* PA28 periph A */ - }; - - pinctrl_usart0_cts: usart0_cts-0 { - atmel,pins = - <0 29 0x1 0x0>; /* PA29 periph A */ - }; - }; - - usart1 { - pinctrl_usart1: usart1-0 { - atmel,pins = - <3 0 0x1 0x1 /* PD0 periph A with pullup */ - 3 1 0x1 0x0>; /* PD1 periph A */ - }; - - pinctrl_usart1_rts: usart1_rts-0 { - atmel,pins = - <3 7 0x2 0x0>; /* PD7 periph B */ - }; - - pinctrl_usart1_cts: usart1_cts-0 { - atmel,pins = - <3 8 0x2 0x0>; /* PD8 periph B */ - }; - }; - - usart2 { - pinctrl_usart2: usart2-0 { - atmel,pins = - <3 2 0x1 0x1 /* PD2 periph A with pullup */ - 3 3 0x1 0x0>; /* PD3 periph A */ - }; - - pinctrl_usart2_rts: usart2_rts-0 { - atmel,pins = - <3 5 0x2 0x0>; /* PD5 periph B */ - }; - - pinctrl_usart2_cts: usart2_cts-0 { - atmel,pins = - <4 6 0x2 0x0>; /* PD6 periph B */ - }; - }; - - nand { - pinctrl_nand: nand-0 { - atmel,pins = - <0 22 0x0 0x1 /* PA22 gpio RDY pin pull_up*/ - 3 15 0x0 0x1>; /* PD15 gpio enable pin pull_up */ - }; - }; - - macb { - pinctrl_macb_rmii: macb_rmii-0 { - atmel,pins = - <2 25 0x2 0x0 /* PC25 periph B */ - 4 21 0x1 0x0 /* PE21 periph A */ - 4 23 0x1 0x0 /* PE23 periph A */ - 4 24 0x1 0x0 /* PE24 periph A */ - 4 25 0x1 0x0 /* PE25 periph A */ - 4 26 0x1 0x0 /* PE26 periph A */ - 4 27 0x1 0x0 /* PE27 periph A */ - 4 28 0x1 0x0 /* PE28 periph A */ - 4 29 0x1 0x0 /* PE29 periph A */ - 4 30 0x1 0x0>; /* PE30 periph A */ - }; - - pinctrl_macb_rmii_mii: macb_rmii_mii-0 { - atmel,pins = - <2 20 0x2 0x0 /* PC20 periph B */ - 2 21 0x2 0x0 /* PC21 periph B */ - 2 22 0x2 0x0 /* PC22 periph B */ - 2 23 0x2 0x0 /* PC23 periph B */ - 2 24 0x2 0x0 /* PC24 periph B */ - 2 25 0x2 0x0 /* PC25 periph B */ - 2 27 0x2 0x0 /* PC27 periph B */ - 4 22 0x2 0x0>; /* PE22 periph B */ - }; - }; - - mmc0 { - pinctrl_mmc0_clk: mmc0_clk-0 { - atmel,pins = - <0 12 0x1 0x0>; /* PA12 periph A */ - }; - - pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 { - atmel,pins = - <0 1 0x1 0x1 /* PA1 periph A with pullup */ - 0 0 0x1 0x1>; /* PA0 periph A with pullup */ - }; - - pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 { - atmel,pins = - <0 3 0x1 0x1 /* PA3 periph A with pullup */ - 0 4 0x1 0x1 /* PA4 periph A with pullup */ - 0 5 0x1 0x1>; /* PA5 periph A with pullup */ - }; - - pinctrl_mmc0_slot1_cmd_dat0: mmc0_slot1_cmd_dat0-0 { - atmel,pins = - <0 16 0x1 0x1 /* PA16 periph A with pullup */ - 0 17 0x1 0x1>; /* PA17 periph A with pullup */ - }; - - pinctrl_mmc0_slot1_dat1_3: mmc0_slot1_dat1_3-0 { - atmel,pins = - <0 18 0x1 0x1 /* PA18 periph A with pullup */ - 0 19 0x1 0x1 /* PA19 periph A with pullup */ - 0 20 0x1 0x1>; /* PA20 periph A with pullup */ - }; - }; - - mmc1 { - pinctrl_mmc1_clk: mmc1_clk-0 { - atmel,pins = - <0 6 0x1 0x0>; /* PA6 periph A */ - }; - - pinctrl_mmc1_slot0_cmd_dat0: mmc1_slot0_cmd_dat0-0 { - atmel,pins = - <0 7 0x1 0x1 /* PA7 periph A with pullup */ - 0 8 0x1 0x1>; /* PA8 periph A with pullup */ - }; - - pinctrl_mmc1_slot0_dat1_3: mmc1_slot0_dat1_3-0 { - atmel,pins = - <0 9 0x1 0x1 /* PA9 periph A with pullup */ - 0 10 0x1 0x1 /* PA10 periph A with pullup */ - 0 11 0x1 0x1>; /* PA11 periph A with pullup */ - }; - - pinctrl_mmc1_slot1_cmd_dat0: mmc1_slot1_cmd_dat0-0 { - atmel,pins = - <0 21 0x1 0x1 /* PA21 periph A with pullup */ - 0 22 0x1 0x1>; /* PA22 periph A with pullup */ - }; - - pinctrl_mmc1_slot1_dat1_3: mmc1_slot1_dat1_3-0 { - atmel,pins = - <0 23 0x1 0x1 /* PA23 periph A with pullup */ - 0 24 0x1 0x1 /* PA24 periph A with pullup */ - 0 25 0x1 0x1>; /* PA25 periph A with pullup */ - }; - }; - - pioA: gpio@fffff200 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff200 0x200>; - interrupts = <2 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioA: gpio@fffff200 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff200 0x100>; + interrupts = <2 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioB: gpio@fffff400 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff400 0x200>; - interrupts = <3 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioB: gpio@fffff400 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff400 0x100>; + interrupts = <3 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioC: gpio@fffff600 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff600 0x200>; - interrupts = <4 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioC: gpio@fffff600 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff600 0x100>; + interrupts = <4 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioD: gpio@fffff800 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff800 0x200>; - interrupts = <4 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioD: gpio@fffff800 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff800 0x100>; + interrupts = <4 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioE: gpio@fffffa00 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffffa00 0x200>; - interrupts = <4 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioE: gpio@fffffa00 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffffa00 0x100>; + interrupts = <4 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; }; dbgu: serial@ffffee00 { compatible = "atmel,at91sam9260-usart"; reg = <0xffffee00 0x200>; interrupts = <1 4 7>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_dbgu>; status = "disabled"; }; @@ -335,8 +152,6 @@ interrupts = <7 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usart0>; status = "disabled"; }; @@ -346,8 +161,6 @@ interrupts = <8 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usart1>; status = "disabled"; }; @@ -357,8 +170,6 @@ interrupts = <9 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usart2>; status = "disabled"; }; @@ -366,8 +177,6 @@ compatible = "cdns,at32ap7000-macb", "cdns,macb"; reg = <0xfffbc000 0x100>; interrupts = <21 4 3>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_macb_rmii>; status = "disabled"; }; @@ -386,24 +195,6 @@ #size-cells = <0>; status = "disabled"; }; - - mmc0: mmc@fff80000 { - compatible = "atmel,hsmci"; - reg = <0xfff80000 0x600>; - interrupts = <10 4 0>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - - mmc1: mmc@fff84000 { - compatible = "atmel,hsmci"; - reg = <0xfff84000 0x600>; - interrupts = <11 4 0>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; }; nand0: nand@40000000 { @@ -415,8 +206,6 @@ >; atmel,nand-addr-offset = <21>; atmel,nand-cmd-offset = <22>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_nand>; gpios = <&pioA 22 0 &pioD 15 0 0 diff --git a/trunk/arch/arm/boot/dts/at91sam9263ek.dts b/trunk/arch/arm/boot/dts/at91sam9263ek.dts index 1eb08728f527..f86ac4b609fc 100644 --- a/trunk/arch/arm/boot/dts/at91sam9263ek.dts +++ b/trunk/arch/arm/boot/dts/at91sam9263ek.dts @@ -38,10 +38,6 @@ }; usart0: serial@fff8c000 { - pinctrl-0 = < - &pinctrl_usart0 - &pinctrl_usart0_rts - &pinctrl_usart0_cts>; status = "okay"; }; @@ -54,31 +50,6 @@ atmel,vbus-gpio = <&pioA 25 0>; status = "okay"; }; - - mmc0: mmc@fff80000 { - pinctrl-0 = < - &pinctrl_board_mmc0 - &pinctrl_mmc0_clk - &pinctrl_mmc0_slot0_cmd_dat0 - &pinctrl_mmc0_slot0_dat1_3>; - status = "okay"; - slot@0 { - reg = <0>; - bus-width = <4>; - cd-gpios = <&pioE 18 0>; - wp-gpios = <&pioE 19 0>; - }; - }; - - pinctrl@fffff200 { - mmc0 { - pinctrl_board_mmc0: mmc0-board { - atmel,pins = - <5 18 0x0 0x5 /* PE18 gpio CD pin pull up and deglitch */ - 5 19 0x0 0x1>; /* PE19 gpio WP pin pull up */ - }; - }; - }; }; nand0: nand@40000000 { diff --git a/trunk/arch/arm/boot/dts/at91sam9g15.dtsi b/trunk/arch/arm/boot/dts/at91sam9g15.dtsi deleted file mode 100644 index fbe7a7089c2a..000000000000 --- a/trunk/arch/arm/boot/dts/at91sam9g15.dtsi +++ /dev/null @@ -1,28 +0,0 @@ -/* - * at91sam9g15.dtsi - Device Tree Include file for AT91SAM9G15 SoC - * - * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD - * - * Licensed under GPLv2. - */ - -/include/ "at91sam9x5.dtsi" - -/ { - model = "Atmel AT91SAM9G15 SoC"; - compatible = "atmel, at91sam9g15, atmel,at91sam9x5"; - - ahb { - apb { - pinctrl@fffff400 { - atmel,mux-mask = < - /* A B C */ - 0xffffffff 0xffe0399f 0x00000000 /* pioA */ - 0x00040000 0x00047e3f 0x00000000 /* pioB */ - 0xfdffffff 0x00000000 0xb83fffff /* pioC */ - 0x003fffff 0x003f8000 0x00000000 /* pioD */ - >; - }; - }; - }; -}; diff --git a/trunk/arch/arm/boot/dts/at91sam9g15ek.dts b/trunk/arch/arm/boot/dts/at91sam9g15ek.dts deleted file mode 100644 index 86dd3f6d938f..000000000000 --- a/trunk/arch/arm/boot/dts/at91sam9g15ek.dts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * at91sam9g15ek.dts - Device Tree file for AT91SAM9G15-EK board - * - * Copyright (C) 2012 Atmel, - * 2012 Nicolas Ferre - * - * Licensed under GPLv2 or later. - */ -/dts-v1/; -/include/ "at91sam9g15.dtsi" -/include/ "at91sam9x5ek.dtsi" - -/ { - model = "Atmel AT91SAM9G25-EK"; - compatible = "atmel,at91sam9g15ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9"; -}; diff --git a/trunk/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts b/trunk/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts index 66467b113126..f1b2e148ac8c 100644 --- a/trunk/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts +++ b/trunk/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts @@ -12,32 +12,6 @@ model = "Atmel at91sam9g20ek 2 mmc"; compatible = "atmel,at91sam9g20ek_2mmc", "atmel,at91sam9g20", "atmel,at91sam9"; - ahb { - apb{ - mmc0: mmc@fffa8000 { - /* clk already mux wuth slot0 */ - pinctrl-0 = < - &pinctrl_board_mmc0_slot0 - &pinctrl_mmc0_slot0_cmd_dat0 - &pinctrl_mmc0_slot0_dat1_3>; - slot@0 { - reg = <0>; - bus-width = <4>; - cd-gpios = <&pioC 2 0>; - }; - }; - - pinctrl@fffff400 { - mmc0_slot0 { - pinctrl_board_mmc0_slot0: mmc0_slot0-board { - atmel,pins = - <2 2 0x0 0x5>; /* PC2 gpio CD pin pull up and deglitch */ - }; - }; - }; - }; - }; - leds { compatible = "gpio-leds"; diff --git a/trunk/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/trunk/arch/arm/boot/dts/at91sam9g20ek_common.dtsi index 32a500a0e481..b06c0db273b1 100644 --- a/trunk/arch/arm/boot/dts/at91sam9g20ek_common.dtsi +++ b/trunk/arch/arm/boot/dts/at91sam9g20ek_common.dtsi @@ -35,13 +35,6 @@ }; usart0: serial@fffb0000 { - pinctrl-0 = - <&pinctrl_usart0 - &pinctrl_usart0_rts - &pinctrl_usart0_cts - &pinctrl_usart0_dtr_dsr - &pinctrl_usart0_dcd - &pinctrl_usart0_ri>; status = "okay"; }; @@ -58,29 +51,6 @@ atmel,vbus-gpio = <&pioC 5 0>; status = "okay"; }; - - mmc0: mmc@fffa8000 { - pinctrl-0 = < - &pinctrl_board_mmc0_slot1 - &pinctrl_mmc0_clk - &pinctrl_mmc0_slot1_cmd_dat0 - &pinctrl_mmc0_slot1_dat1_3>; - status = "okay"; - slot@1 { - reg = <1>; - bus-width = <4>; - cd-gpios = <&pioC 9 0>; - }; - }; - - pinctrl@fffff400 { - mmc0_slot1 { - pinctrl_board_mmc0_slot1: mmc0_slot1-board { - atmel,pins = - <2 9 0x0 0x5>; /* PC9 gpio CD pin pull up and deglitch */ - }; - }; - }; }; nand0: nand@40000000 { @@ -156,14 +126,14 @@ #size-cells = <0>; btn3 { - label = "Button 3"; + label = "Buttin 3"; gpios = <&pioA 30 1>; linux,code = <0x103>; gpio-key,wakeup; }; btn4 { - label = "Button 4"; + label = "Buttin 4"; gpios = <&pioA 31 1>; linux,code = <0x104>; gpio-key,wakeup; diff --git a/trunk/arch/arm/boot/dts/at91sam9g25.dtsi b/trunk/arch/arm/boot/dts/at91sam9g25.dtsi deleted file mode 100644 index 05a718fb83c4..000000000000 --- a/trunk/arch/arm/boot/dts/at91sam9g25.dtsi +++ /dev/null @@ -1,28 +0,0 @@ -/* - * at91sam9g25.dtsi - Device Tree Include file for AT91SAM9G25 SoC - * - * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD - * - * Licensed under GPLv2. - */ - -/include/ "at91sam9x5.dtsi" - -/ { - model = "Atmel AT91SAM9G25 SoC"; - compatible = "atmel, at91sam9g25, atmel,at91sam9x5"; - - ahb { - apb { - pinctrl@fffff400 { - atmel,mux-mask = < - /* A B C */ - 0xffffffff 0xffe0399f 0xc000001c /* pioA */ - 0x0007ffff 0x8000fe3f 0x00000000 /* pioB */ - 0x80000000 0x07c0ffff 0xb83fffff /* pioC */ - 0x003fffff 0x003f8000 0x00000000 /* pioD */ - >; - }; - }; - }; -}; diff --git a/trunk/arch/arm/boot/dts/at91sam9g25ek.dts b/trunk/arch/arm/boot/dts/at91sam9g25ek.dts index c5ab16fba059..877c08f06763 100644 --- a/trunk/arch/arm/boot/dts/at91sam9g25ek.dts +++ b/trunk/arch/arm/boot/dts/at91sam9g25ek.dts @@ -7,10 +7,55 @@ * Licensed under GPLv2 or later. */ /dts-v1/; -/include/ "at91sam9g25.dtsi" -/include/ "at91sam9x5ek.dtsi" +/include/ "at91sam9x5.dtsi" +/include/ "at91sam9x5cm.dtsi" / { model = "Atmel AT91SAM9G25-EK"; compatible = "atmel,at91sam9g25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9"; + + chosen { + bootargs = "console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs"; + }; + + ahb { + apb { + dbgu: serial@fffff200 { + status = "okay"; + }; + + usart0: serial@f801c000 { + status = "okay"; + }; + + macb0: ethernet@f802c000 { + phy-mode = "rmii"; + status = "okay"; + }; + + i2c0: i2c@f8010000 { + status = "okay"; + }; + + i2c1: i2c@f8014000 { + status = "okay"; + }; + + i2c2: i2c@f8018000 { + status = "okay"; + }; + }; + + usb0: ohci@00600000 { + status = "okay"; + num-ports = <2>; + atmel,vbus-gpio = <&pioD 19 1 + &pioD 20 1 + >; + }; + + usb1: ehci@00700000 { + status = "okay"; + }; + }; }; diff --git a/trunk/arch/arm/boot/dts/at91sam9g35.dtsi b/trunk/arch/arm/boot/dts/at91sam9g35.dtsi deleted file mode 100644 index f9d14a722794..000000000000 --- a/trunk/arch/arm/boot/dts/at91sam9g35.dtsi +++ /dev/null @@ -1,28 +0,0 @@ -/* - * at91sam9g35.dtsi - Device Tree Include file for AT91SAM9G35 SoC - * - * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD - * - * Licensed under GPLv2. - */ - -/include/ "at91sam9x5.dtsi" - -/ { - model = "Atmel AT91SAM9G35 SoC"; - compatible = "atmel, at91sam9g35, atmel,at91sam9x5"; - - ahb { - apb { - pinctrl@fffff400 { - atmel,mux-mask = < - /* A B C */ - 0xffffffff 0xffe0399f 0xc000000c /* pioA */ - 0x000406ff 0x00047e3f 0x00000000 /* pioB */ - 0xfdffffff 0x00000000 0xb83fffff /* pioC */ - 0x003fffff 0x003f8000 0x00000000 /* pioD */ - >; - }; - }; - }; -}; diff --git a/trunk/arch/arm/boot/dts/at91sam9g35ek.dts b/trunk/arch/arm/boot/dts/at91sam9g35ek.dts deleted file mode 100644 index 95944bdd798d..000000000000 --- a/trunk/arch/arm/boot/dts/at91sam9g35ek.dts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * at91sam9g35ek.dts - Device Tree file for AT91SAM9G35-EK board - * - * Copyright (C) 2012 Atmel, - * 2012 Nicolas Ferre - * - * Licensed under GPLv2 or later. - */ -/dts-v1/; -/include/ "at91sam9g35.dtsi" -/include/ "at91sam9x5ek.dtsi" - -/ { - model = "Atmel AT91SAM9G35-EK"; - compatible = "atmel,at91sam9g35ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9"; -}; diff --git a/trunk/arch/arm/boot/dts/at91sam9g45.dtsi b/trunk/arch/arm/boot/dts/at91sam9g45.dtsi index 0741caeeced1..3add030d61f8 100644 --- a/trunk/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/trunk/arch/arm/boot/dts/at91sam9g45.dtsi @@ -108,243 +108,60 @@ interrupts = <21 4 0>; }; - pinctrl@fffff200 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "atmel,at91rm9200-pinctrl", "simple-bus"; - ranges = <0xfffff200 0xfffff200 0xa00>; - - atmel,mux-mask = < - /* A B */ - 0xffffffff 0xffc003ff /* pioA */ - 0xffffffff 0x800f8f00 /* pioB */ - 0xffffffff 0x00000e00 /* pioC */ - 0xffffffff 0xff0c1381 /* pioD */ - 0xffffffff 0x81ffff81 /* pioE */ - >; - - /* shared pinctrl settings */ - dbgu { - pinctrl_dbgu: dbgu-0 { - atmel,pins = - <1 12 0x1 0x0 /* PB12 periph A */ - 1 13 0x1 0x0>; /* PB13 periph A */ - }; - }; - - usart0 { - pinctrl_usart0: usart0-0 { - atmel,pins = - <1 19 0x1 0x1 /* PB19 periph A with pullup */ - 1 18 0x1 0x0>; /* PB18 periph A */ - }; - - pinctrl_usart0_rts: usart0_rts-0 { - atmel,pins = - <1 17 0x2 0x0>; /* PB17 periph B */ - }; - - pinctrl_usart0_cts: usart0_cts-0 { - atmel,pins = - <1 15 0x2 0x0>; /* PB15 periph B */ - }; - }; - - uart1 { - pinctrl_usart1: usart1-0 { - atmel,pins = - <1 4 0x1 0x1 /* PB4 periph A with pullup */ - 1 5 0x1 0x0>; /* PB5 periph A */ - }; - - pinctrl_usart1_rts: usart1_rts-0 { - atmel,pins = - <3 16 0x1 0x0>; /* PD16 periph A */ - }; - - pinctrl_usart1_cts: usart1_cts-0 { - atmel,pins = - <3 17 0x1 0x0>; /* PD17 periph A */ - }; - }; - - usart2 { - pinctrl_usart2: usart2-0 { - atmel,pins = - <1 6 0x1 0x1 /* PB6 periph A with pullup */ - 1 7 0x1 0x0>; /* PB7 periph A */ - }; - - pinctrl_usart2_rts: usart2_rts-0 { - atmel,pins = - <2 9 0x2 0x0>; /* PC9 periph B */ - }; - - pinctrl_usart2_cts: usart2_cts-0 { - atmel,pins = - <2 11 0x2 0x0>; /* PC11 periph B */ - }; - }; - - usart3 { - pinctrl_usart3: usart3-0 { - atmel,pins = - <1 8 0x1 0x1 /* PB9 periph A with pullup */ - 1 9 0x1 0x0>; /* PB8 periph A */ - }; - - pinctrl_usart3_rts: usart3_rts-0 { - atmel,pins = - <0 23 0x2 0x0>; /* PA23 periph B */ - }; - - pinctrl_usart3_cts: usart3_cts-0 { - atmel,pins = - <0 24 0x2 0x0>; /* PA24 periph B */ - }; - }; - - nand { - pinctrl_nand: nand-0 { - atmel,pins = - <2 8 0x0 0x1 /* PC8 gpio RDY pin pull_up*/ - 2 14 0x0 0x1>; /* PC14 gpio enable pin pull_up */ - }; - }; - - macb { - pinctrl_macb_rmii: macb_rmii-0 { - atmel,pins = - <0 10 0x1 0x0 /* PA10 periph A */ - 0 11 0x1 0x0 /* PA11 periph A */ - 0 12 0x1 0x0 /* PA12 periph A */ - 0 13 0x1 0x0 /* PA13 periph A */ - 0 14 0x1 0x0 /* PA14 periph A */ - 0 15 0x1 0x0 /* PA15 periph A */ - 0 16 0x1 0x0 /* PA16 periph A */ - 0 17 0x1 0x0 /* PA17 periph A */ - 0 18 0x1 0x0 /* PA18 periph A */ - 0 19 0x1 0x0>; /* PA19 periph A */ - }; - - pinctrl_macb_rmii_mii: macb_rmii_mii-0 { - atmel,pins = - <0 6 0x2 0x0 /* PA6 periph B */ - 0 7 0x2 0x0 /* PA7 periph B */ - 0 8 0x2 0x0 /* PA8 periph B */ - 0 9 0x2 0x0 /* PA9 periph B */ - 0 27 0x2 0x0 /* PA27 periph B */ - 0 28 0x2 0x0 /* PA28 periph B */ - 0 29 0x2 0x0 /* PA29 periph B */ - 0 30 0x2 0x0>; /* PA30 periph B */ - }; - }; - - mmc0 { - pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 { - atmel,pins = - <0 0 0x1 0x0 /* PA0 periph A */ - 0 1 0x1 0x1 /* PA1 periph A with pullup */ - 0 2 0x1 0x1>; /* PA2 periph A with pullup */ - }; - - pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 { - atmel,pins = - <0 3 0x1 0x1 /* PA3 periph A with pullup */ - 0 4 0x1 0x1 /* PA4 periph A with pullup */ - 0 5 0x1 0x1>; /* PA5 periph A with pullup */ - }; - - pinctrl_mmc0_slot0_dat4_7: mmc0_slot0_dat4_7-0 { - atmel,pins = - <0 6 0x1 0x1 /* PA6 periph A with pullup */ - 0 7 0x1 0x1 /* PA7 periph A with pullup */ - 0 8 0x1 0x1 /* PA8 periph A with pullup */ - 0 9 0x1 0x1>; /* PA9 periph A with pullup */ - }; - }; - - mmc1 { - pinctrl_mmc1_slot0_clk_cmd_dat0: mmc1_slot0_clk_cmd_dat0-0 { - atmel,pins = - <0 31 0x1 0x0 /* PA31 periph A */ - 0 22 0x1 0x1 /* PA22 periph A with pullup */ - 0 23 0x1 0x1>; /* PA23 periph A with pullup */ - }; - - pinctrl_mmc1_slot0_dat1_3: mmc1_slot0_dat1_3-0 { - atmel,pins = - <0 24 0x1 0x1 /* PA24 periph A with pullup */ - 0 25 0x1 0x1 /* PA25 periph A with pullup */ - 0 26 0x1 0x1>; /* PA26 periph A with pullup */ - }; - - pinctrl_mmc1_slot0_dat4_7: mmc1_slot0_dat4_7-0 { - atmel,pins = - <0 27 0x1 0x1 /* PA27 periph A with pullup */ - 0 28 0x1 0x1 /* PA28 periph A with pullup */ - 0 29 0x1 0x1 /* PA29 periph A with pullup */ - 0 20 0x1 0x1>; /* PA30 periph A with pullup */ - }; - }; - - pioA: gpio@fffff200 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff200 0x200>; - interrupts = <2 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioA: gpio@fffff200 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff200 0x100>; + interrupts = <2 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioB: gpio@fffff400 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff400 0x200>; - interrupts = <3 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioB: gpio@fffff400 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff400 0x100>; + interrupts = <3 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioC: gpio@fffff600 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff600 0x200>; - interrupts = <4 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioC: gpio@fffff600 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff600 0x100>; + interrupts = <4 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioD: gpio@fffff800 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff800 0x200>; - interrupts = <5 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioD: gpio@fffff800 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff800 0x100>; + interrupts = <5 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioE: gpio@fffffa00 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffffa00 0x200>; - interrupts = <5 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioE: gpio@fffffa00 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffffa00 0x100>; + interrupts = <5 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; }; dbgu: serial@ffffee00 { compatible = "atmel,at91sam9260-usart"; reg = <0xffffee00 0x200>; interrupts = <1 4 7>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_dbgu>; status = "disabled"; }; @@ -354,8 +171,6 @@ interrupts = <7 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usart0>; status = "disabled"; }; @@ -365,8 +180,6 @@ interrupts = <8 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usart1>; status = "disabled"; }; @@ -376,8 +189,6 @@ interrupts = <9 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usart2>; status = "disabled"; }; @@ -387,8 +198,6 @@ interrupts = <10 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usart3>; status = "disabled"; }; @@ -396,8 +205,6 @@ compatible = "cdns,at32ap7000-macb", "cdns,macb"; reg = <0xfffbc000 0x100>; interrupts = <25 4 3>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_macb_rmii>; status = "disabled"; }; @@ -455,24 +262,6 @@ trigger-value = <0x6>; }; }; - - mmc0: mmc@fff80000 { - compatible = "atmel,hsmci"; - reg = <0xfff80000 0x600>; - interrupts = <11 4 0>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - - mmc1: mmc@fffd0000 { - compatible = "atmel,hsmci"; - reg = <0xfffd0000 0x600>; - interrupts = <29 4 0>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; }; nand0: nand@40000000 { @@ -484,8 +273,6 @@ >; atmel,nand-addr-offset = <21>; atmel,nand-cmd-offset = <22>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_nand>; gpios = <&pioC 8 0 &pioC 14 0 0 diff --git a/trunk/arch/arm/boot/dts/at91sam9m10g45ek.dts b/trunk/arch/arm/boot/dts/at91sam9m10g45ek.dts index 20c31913c270..15e1dd43f625 100644 --- a/trunk/arch/arm/boot/dts/at91sam9m10g45ek.dts +++ b/trunk/arch/arm/boot/dts/at91sam9m10g45ek.dts @@ -39,10 +39,6 @@ }; usart1: serial@fff90000 { - pinctrl-0 = - <&pinctrl_usart1 - &pinctrl_usart1_rts - &pinctrl_usart1_cts>; status = "okay"; }; @@ -58,50 +54,6 @@ i2c1: i2c@fff88000 { status = "okay"; }; - - mmc0: mmc@fff80000 { - pinctrl-0 = < - &pinctrl_board_mmc0 - &pinctrl_mmc0_slot0_clk_cmd_dat0 - &pinctrl_mmc0_slot0_dat1_3>; - status = "okay"; - slot@0 { - reg = <0>; - bus-width = <4>; - cd-gpios = <&pioD 10 0>; - }; - }; - - mmc1: mmc@fffd0000 { - pinctrl-0 = < - &pinctrl_board_mmc1 - &pinctrl_mmc1_slot0_clk_cmd_dat0 - &pinctrl_mmc1_slot0_dat1_3>; - status = "okay"; - slot@0 { - reg = <0>; - bus-width = <4>; - cd-gpios = <&pioD 11 0>; - wp-gpios = <&pioD 29 0>; - }; - }; - - pinctrl@fffff200 { - mmc0 { - pinctrl_board_mmc0: mmc0-board { - atmel,pins = - <3 10 0x0 0x5>; /* PD10 gpio CD pin pull up and deglitch */ - }; - }; - - mmc1 { - pinctrl_board_mmc1: mmc1-board { - atmel,pins = - <3 11 0x0 0x5 /* PD11 gpio CD pin pull up and deglitch */ - 3 29 0x0 0x1>; /* PD29 gpio WP pin pull up */ - }; - }; - }; }; nand0: nand@40000000 { diff --git a/trunk/arch/arm/boot/dts/at91sam9n12.dtsi b/trunk/arch/arm/boot/dts/at91sam9n12.dtsi index e9efb34f4379..82508d68aa7e 100644 --- a/trunk/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/trunk/arch/arm/boot/dts/at91sam9n12.dtsi @@ -84,15 +84,6 @@ reg = <0xfffffe10 0x10>; }; - mmc0: mmc@f0008000 { - compatible = "atmel,hsmci"; - reg = <0xf0008000 0x600>; - interrupts = <12 4 0>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - tcb0: timer@f8008000 { compatible = "atmel,at91sam9x5-tcb"; reg = <0xf8008000 0x100>; @@ -111,186 +102,50 @@ interrupts = <20 4 0>; }; - pinctrl@fffff400 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus"; - ranges = <0xfffff400 0xfffff400 0x800>; - - atmel,mux-mask = < - /* A B C */ - 0xffffffff 0xffe07983 0x00000000 /* pioA */ - 0x00040000 0x00047e0f 0x00000000 /* pioB */ - 0xfdffffff 0x07c00000 0xb83fffff /* pioC */ - 0x003fffff 0x003f8000 0x00000000 /* pioD */ - >; - - /* shared pinctrl settings */ - dbgu { - pinctrl_dbgu: dbgu-0 { - atmel,pins = - <0 9 0x1 0x0 /* PA9 periph A */ - 0 10 0x1 0x1>; /* PA10 periph with pullup */ - }; - }; - - usart0 { - pinctrl_usart0: usart0-0 { - atmel,pins = - <0 1 0x1 0x1 /* PA1 periph A with pullup */ - 0 0 0x1 0x0>; /* PA0 periph A */ - }; - - pinctrl_usart0_rts: usart0_rts-0 { - atmel,pins = - <0 2 0x1 0x0>; /* PA2 periph A */ - }; - - pinctrl_usart0_cts: usart0_cts-0 { - atmel,pins = - <0 3 0x1 0x0>; /* PA3 periph A */ - }; - }; - - usart1 { - pinctrl_usart1: usart1-0 { - atmel,pins = - <0 6 0x1 0x1 /* PA6 periph A with pullup */ - 0 5 0x1 0x0>; /* PA5 periph A */ - }; - }; - - usart2 { - pinctrl_usart2: usart2-0 { - atmel,pins = - <0 8 0x1 0x1 /* PA8 periph A with pullup */ - 0 7 0x1 0x0>; /* PA7 periph A */ - }; - - pinctrl_usart2_rts: usart2_rts-0 { - atmel,pins = - <1 0 0x2 0x0>; /* PB0 periph B */ - }; - - pinctrl_usart2_cts: usart2_cts-0 { - atmel,pins = - <1 1 0x2 0x0>; /* PB1 periph B */ - }; - }; - - usart3 { - pinctrl_usart3: usart3-0 { - atmel,pins = - <2 23 0x2 0x1 /* PC23 periph B with pullup */ - 2 22 0x2 0x0>; /* PC22 periph B */ - }; - - pinctrl_usart3_rts: usart3_rts-0 { - atmel,pins = - <2 24 0x2 0x0>; /* PC24 periph B */ - }; - - pinctrl_usart3_cts: usart3_cts-0 { - atmel,pins = - <2 25 0x2 0x0>; /* PC25 periph B */ - }; - }; - - uart0 { - pinctrl_uart0: uart0-0 { - atmel,pins = - <2 9 0x3 0x1 /* PC9 periph C with pullup */ - 2 8 0x3 0x0>; /* PC8 periph C */ - }; - }; - - uart1 { - pinctrl_uart1: uart1-0 { - atmel,pins = - <2 16 0x3 0x1 /* PC17 periph C with pullup */ - 2 17 0x3 0x0>; /* PC16 periph C */ - }; - }; - - nand { - pinctrl_nand: nand-0 { - atmel,pins = - <3 5 0x0 0x1 /* PD5 gpio RDY pin pull_up*/ - 3 4 0x0 0x1>; /* PD4 gpio enable pin pull_up */ - }; - }; - - mmc0 { - pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 { - atmel,pins = - <0 17 0x1 0x0 /* PA17 periph A */ - 0 16 0x1 0x1 /* PA16 periph A with pullup */ - 0 15 0x1 0x1>; /* PA15 periph A with pullup */ - }; - - pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 { - atmel,pins = - <0 18 0x1 0x1 /* PA18 periph A with pullup */ - 0 19 0x1 0x1 /* PA19 periph A with pullup */ - 0 20 0x1 0x1>; /* PA20 periph A with pullup */ - }; - - pinctrl_mmc0_slot0_dat4_7: mmc0_slot0_dat4_7-0 { - atmel,pins = - <0 11 0x2 0x1 /* PA11 periph B with pullup */ - 0 12 0x2 0x1 /* PA12 periph B with pullup */ - 0 13 0x2 0x1 /* PA13 periph B with pullup */ - 0 14 0x2 0x1>; /* PA14 periph B with pullup */ - }; - }; - - pioA: gpio@fffff400 { - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; - reg = <0xfffff400 0x200>; - interrupts = <2 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioA: gpio@fffff400 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffff400 0x100>; + interrupts = <2 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioB: gpio@fffff600 { - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; - reg = <0xfffff600 0x200>; - interrupts = <2 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioB: gpio@fffff600 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffff600 0x100>; + interrupts = <2 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioC: gpio@fffff800 { - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; - reg = <0xfffff800 0x200>; - interrupts = <3 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioC: gpio@fffff800 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffff800 0x100>; + interrupts = <3 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioD: gpio@fffffa00 { - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; - reg = <0xfffffa00 0x200>; - interrupts = <3 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioD: gpio@fffffa00 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffffa00 0x100>; + interrupts = <3 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; }; dbgu: serial@fffff200 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffff200 0x200>; interrupts = <1 4 7>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_dbgu>; status = "disabled"; }; @@ -300,8 +155,6 @@ interrupts = <5 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usart0>; status = "disabled"; }; @@ -311,8 +164,6 @@ interrupts = <6 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usart1>; status = "disabled"; }; @@ -322,8 +173,6 @@ interrupts = <7 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usart2>; status = "disabled"; }; @@ -333,8 +182,6 @@ interrupts = <8 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usart3>; status = "disabled"; }; @@ -368,8 +215,6 @@ >; atmel,nand-addr-offset = <21>; atmel,nand-cmd-offset = <22>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_nand>; gpios = <&pioD 5 0 &pioD 4 0 0 diff --git a/trunk/arch/arm/boot/dts/at91sam9n12ek.dts b/trunk/arch/arm/boot/dts/at91sam9n12ek.dts index 0376bf4fd66b..912b2c283d6f 100644 --- a/trunk/arch/arm/boot/dts/at91sam9n12ek.dts +++ b/trunk/arch/arm/boot/dts/at91sam9n12ek.dts @@ -45,28 +45,6 @@ i2c1: i2c@f8014000 { status = "okay"; }; - - mmc0: mmc@f0008000 { - pinctrl-0 = < - &pinctrl_board_mmc0 - &pinctrl_mmc0_slot0_clk_cmd_dat0 - &pinctrl_mmc0_slot0_dat1_3>; - status = "okay"; - slot@0 { - reg = <0>; - bus-width = <4>; - cd-gpios = <&pioA 7 0>; - }; - }; - - pinctrl@fffff400 { - mmc0 { - pinctrl_board_mmc0: mmc0-board { - atmel,pins = - <0 7 0x0 0x5>; /* PA7 gpio CD pin pull up and deglitch */ - }; - }; - }; }; nand0: nand@40000000 { diff --git a/trunk/arch/arm/boot/dts/at91sam9x25.dtsi b/trunk/arch/arm/boot/dts/at91sam9x25.dtsi deleted file mode 100644 index 54eb33ba6d22..000000000000 --- a/trunk/arch/arm/boot/dts/at91sam9x25.dtsi +++ /dev/null @@ -1,49 +0,0 @@ -/* - * at91sam9x25.dtsi - Device Tree Include file for AT91SAM9X25 SoC - * - * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD - * - * Licensed under GPLv2. - */ - -/include/ "at91sam9x5.dtsi" - -/ { - model = "Atmel AT91SAM9X25 SoC"; - compatible = "atmel, at91sam9x25, atmel,at91sam9x5"; - - ahb { - apb { - pinctrl@fffff400 { - atmel,mux-mask = < - /* A B C */ - 0xffffffff 0xffe03fff 0xc000001c /* pioA */ - 0x0007ffff 0x00047e3f 0x00000000 /* pioB */ - 0x80000000 0xfffd0000 0xb83fffff /* pioC */ - 0x003fffff 0x003f8000 0x00000000 /* pioD */ - >; - - macb1 { - pinctrl_macb1_rmii: macb1_rmii-0 { - atmel,pins = - <2 16 0x2 0x0 /* PC16 periph B */ - 2 18 0x2 0x0 /* PC18 periph B */ - 2 19 0x2 0x0 /* PC19 periph B */ - 2 20 0x2 0x0 /* PC20 periph B */ - 2 21 0x2 0x0 /* PC21 periph B */ - 2 27 0x2 0x0 /* PC27 periph B */ - 2 28 0x2 0x0 /* PC28 periph B */ - 2 29 0x2 0x0 /* PC29 periph B */ - 2 30 0x2 0x0 /* PC30 periph B */ - 2 31 0x2 0x0>; /* PC31 periph B */ - }; - }; - }; - - macb1: ethernet@f8030000 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_macb1_rmii>; - }; - }; - }; -}; diff --git a/trunk/arch/arm/boot/dts/at91sam9x25ek.dts b/trunk/arch/arm/boot/dts/at91sam9x25ek.dts deleted file mode 100644 index af907eaa1f25..000000000000 --- a/trunk/arch/arm/boot/dts/at91sam9x25ek.dts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * at91sam9x25ek.dts - Device Tree file for AT91SAM9X25-EK board - * - * Copyright (C) 2012 Atmel, - * 2012 Nicolas Ferre - * - * Licensed under GPLv2 or later. - */ -/dts-v1/; -/include/ "at91sam9x25.dtsi" -/include/ "at91sam9x5ek.dtsi" - -/ { - model = "Atmel AT91SAM9G25-EK"; - compatible = "atmel,at91sam9x25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9"; -}; diff --git a/trunk/arch/arm/boot/dts/at91sam9x35.dtsi b/trunk/arch/arm/boot/dts/at91sam9x35.dtsi deleted file mode 100644 index fb102d6126ce..000000000000 --- a/trunk/arch/arm/boot/dts/at91sam9x35.dtsi +++ /dev/null @@ -1,28 +0,0 @@ -/* - * at91sam9x35.dtsi - Device Tree Include file for AT91SAM9X35 SoC - * - * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD - * - * Licensed under GPLv2. - */ - -/include/ "at91sam9x5.dtsi" - -/ { - model = "Atmel AT91SAM9X35 SoC"; - compatible = "atmel, at91sam9x35, atmel,at91sam9x5"; - - ahb { - apb { - pinctrl@fffff400 { - atmel,mux-mask = < - /* A B C */ - 0xffffffff 0xffe03fff 0xc000000c /* pioA */ - 0x000406ff 0x00047e3f 0x00000000 /* pioB */ - 0xfdffffff 0x00000000 0xb83fffff /* pioC */ - 0x003fffff 0x003f8000 0x00000000 /* pioD */ - >; - }; - }; - }; -}; diff --git a/trunk/arch/arm/boot/dts/at91sam9x35ek.dts b/trunk/arch/arm/boot/dts/at91sam9x35ek.dts deleted file mode 100644 index 5ccb607b5414..000000000000 --- a/trunk/arch/arm/boot/dts/at91sam9x35ek.dts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * at91sam9x35ek.dts - Device Tree file for AT91SAM9X35-EK board - * - * Copyright (C) 2012 Atmel, - * 2012 Nicolas Ferre - * - * Licensed under GPLv2 or later. - */ -/dts-v1/; -/include/ "at91sam9x35.dtsi" -/include/ "at91sam9x5ek.dtsi" - -/ { - model = "Atmel AT91SAM9X35-EK"; - compatible = "atmel,at91sam9x35ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9"; -}; diff --git a/trunk/arch/arm/boot/dts/at91sam9x5.dtsi b/trunk/arch/arm/boot/dts/at91sam9x5.dtsi index 7ee49e8daf98..03fc136421c5 100644 --- a/trunk/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/trunk/arch/arm/boot/dts/at91sam9x5.dtsi @@ -111,244 +111,50 @@ interrupts = <21 4 0>; }; - pinctrl@fffff400 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus"; - ranges = <0xfffff400 0xfffff400 0x800>; - - /* shared pinctrl settings */ - dbgu { - pinctrl_dbgu: dbgu-0 { - atmel,pins = - <0 9 0x1 0x0 /* PA9 periph A */ - 0 10 0x1 0x1>; /* PA10 periph A with pullup */ - }; - }; - - usart0 { - pinctrl_usart0: usart0-0 { - atmel,pins = - <0 0 0x1 0x1 /* PA0 periph A with pullup */ - 0 1 0x1 0x0>; /* PA1 periph A */ - }; - - pinctrl_usart0_rts: usart0_rts-0 { - atmel,pins = - <0 2 0x1 0x0>; /* PA2 periph A */ - }; - - pinctrl_usart0_cts: usart0_cts-0 { - atmel,pins = - <0 3 0x1 0x0>; /* PA3 periph A */ - }; - }; - - usart1 { - pinctrl_usart1: usart1-0 { - atmel,pins = - <0 5 0x1 0x1 /* PA5 periph A with pullup */ - 0 6 0x1 0x0>; /* PA6 periph A */ - }; - - pinctrl_usart1_rts: usart1_rts-0 { - atmel,pins = - <3 27 0x3 0x0>; /* PC27 periph C */ - }; - - pinctrl_usart1_cts: usart1_cts-0 { - atmel,pins = - <3 28 0x3 0x0>; /* PC28 periph C */ - }; - }; - - usart2 { - pinctrl_usart2: usart2-0 { - atmel,pins = - <0 7 0x1 0x1 /* PA7 periph A with pullup */ - 0 8 0x1 0x0>; /* PA8 periph A */ - }; - - pinctrl_uart2_rts: uart2_rts-0 { - atmel,pins = - <0 0 0x2 0x0>; /* PB0 periph B */ - }; - - pinctrl_uart2_cts: uart2_cts-0 { - atmel,pins = - <0 1 0x2 0x0>; /* PB1 periph B */ - }; - }; - - usart3 { - pinctrl_uart3: usart3-0 { - atmel,pins = - <3 23 0x2 0x1 /* PC22 periph B with pullup */ - 3 23 0x2 0x0>; /* PC23 periph B */ - }; - - pinctrl_usart3_rts: usart3_rts-0 { - atmel,pins = - <3 24 0x2 0x0>; /* PC24 periph B */ - }; - - pinctrl_usart3_cts: usart3_cts-0 { - atmel,pins = - <3 25 0x2 0x0>; /* PC25 periph B */ - }; - }; - - uart0 { - pinctrl_uart0: uart0-0 { - atmel,pins = - <3 8 0x3 0x0 /* PC8 periph C */ - 3 9 0x3 0x1>; /* PC9 periph C with pullup */ - }; - }; - - uart1 { - pinctrl_uart1: uart1-0 { - atmel,pins = - <3 16 0x3 0x0 /* PC16 periph C */ - 3 17 0x3 0x1>; /* PC17 periph C with pullup */ - }; - }; - - nand { - pinctrl_nand: nand-0 { - atmel,pins = - <3 4 0x0 0x1 /* PD5 gpio RDY pin pull_up */ - 3 5 0x0 0x1>; /* PD4 gpio enable pin pull_up */ - }; - }; - - macb0 { - pinctrl_macb0_rmii: macb0_rmii-0 { - atmel,pins = - <1 0 0x1 0x0 /* PB0 periph A */ - 1 1 0x1 0x0 /* PB1 periph A */ - 1 2 0x1 0x0 /* PB2 periph A */ - 1 3 0x1 0x0 /* PB3 periph A */ - 1 4 0x1 0x0 /* PB4 periph A */ - 1 5 0x1 0x0 /* PB5 periph A */ - 1 6 0x1 0x0 /* PB6 periph A */ - 1 7 0x1 0x0 /* PB7 periph A */ - 1 9 0x1 0x0 /* PB9 periph A */ - 1 10 0x1 0x0>; /* PB10 periph A */ - }; - - pinctrl_macb0_rmii_mii: macb0_rmii_mii-0 { - atmel,pins = - <1 8 0x1 0x0 /* PA8 periph A */ - 1 11 0x1 0x0 /* PA11 periph A */ - 1 12 0x1 0x0 /* PA12 periph A */ - 1 13 0x1 0x0 /* PA13 periph A */ - 1 14 0x1 0x0 /* PA14 periph A */ - 1 15 0x1 0x0 /* PA15 periph A */ - 1 16 0x1 0x0 /* PA16 periph A */ - 1 17 0x1 0x0>; /* PA17 periph A */ - }; - }; - - mmc0 { - pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 { - atmel,pins = - <0 17 0x1 0x0 /* PA17 periph A */ - 0 16 0x1 0x1 /* PA16 periph A with pullup */ - 0 15 0x1 0x1>; /* PA15 periph A with pullup */ - }; - - pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 { - atmel,pins = - <0 18 0x1 0x1 /* PA18 periph A with pullup */ - 0 19 0x1 0x1 /* PA19 periph A with pullup */ - 0 20 0x1 0x1>; /* PA20 periph A with pullup */ - }; - }; - - mmc1 { - pinctrl_mmc1_slot0_clk_cmd_dat0: mmc1_slot0_clk_cmd_dat0-0 { - atmel,pins = - <0 13 0x2 0x0 /* PA13 periph B */ - 0 12 0x2 0x1 /* PA12 periph B with pullup */ - 0 11 0x2 0x1>; /* PA11 periph B with pullup */ - }; - - pinctrl_mmc1_slot0_dat1_3: mmc1_slot0_dat1_3-0 { - atmel,pins = - <0 2 0x2 0x1 /* PA2 periph B with pullup */ - 0 3 0x2 0x1 /* PA3 periph B with pullup */ - 0 4 0x2 0x1>; /* PA4 periph B with pullup */ - }; - }; - - pioA: gpio@fffff400 { - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; - reg = <0xfffff400 0x200>; - interrupts = <2 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; - - pioB: gpio@fffff600 { - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; - reg = <0xfffff600 0x200>; - interrupts = <2 4 1>; - #gpio-cells = <2>; - gpio-controller; - #gpio-lines = <19>; - interrupt-controller; - #interrupt-cells = <2>; - }; - - pioC: gpio@fffff800 { - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; - reg = <0xfffff800 0x200>; - interrupts = <3 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioA: gpio@fffff400 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffff400 0x100>; + interrupts = <2 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioD: gpio@fffffa00 { - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; - reg = <0xfffffa00 0x200>; - interrupts = <3 4 1>; - #gpio-cells = <2>; - gpio-controller; - #gpio-lines = <22>; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioB: gpio@fffff600 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffff600 0x100>; + interrupts = <2 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; }; - mmc0: mmc@f0008000 { - compatible = "atmel,hsmci"; - reg = <0xf0008000 0x600>; - interrupts = <12 4 0>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; + pioC: gpio@fffff800 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffff800 0x100>; + interrupts = <3 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; }; - mmc1: mmc@f000c000 { - compatible = "atmel,hsmci"; - reg = <0xf000c000 0x600>; - interrupts = <26 4 0>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; + pioD: gpio@fffffa00 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffffa00 0x100>; + interrupts = <3 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; }; dbgu: serial@fffff200 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffff200 0x200>; interrupts = <1 4 7>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_dbgu>; status = "disabled"; }; @@ -358,8 +164,6 @@ interrupts = <5 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usart0>; status = "disabled"; }; @@ -369,8 +173,6 @@ interrupts = <6 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usart1>; status = "disabled"; }; @@ -380,8 +182,6 @@ interrupts = <7 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usart2>; status = "disabled"; }; @@ -389,8 +189,6 @@ compatible = "cdns,at32ap7000-macb", "cdns,macb"; reg = <0xf802c000 0x100>; interrupts = <24 4 3>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_macb0_rmii>; status = "disabled"; }; @@ -475,8 +273,6 @@ >; atmel,nand-addr-offset = <21>; atmel,nand-cmd-offset = <22>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_nand>; gpios = <&pioD 5 0 &pioD 4 0 0 diff --git a/trunk/arch/arm/boot/dts/at91sam9x5ek.dtsi b/trunk/arch/arm/boot/dts/at91sam9x5ek.dtsi deleted file mode 100644 index 8a7cf1d9cf5d..000000000000 --- a/trunk/arch/arm/boot/dts/at91sam9x5ek.dtsi +++ /dev/null @@ -1,101 +0,0 @@ -/* - * at91sam9x5ek.dtsi - Device Tree file for AT91SAM9x5CM Base board - * - * Copyright (C) 2012 Atmel, - * 2012 Nicolas Ferre - * - * Licensed under GPLv2 or later. - */ -/include/ "at91sam9x5cm.dtsi" - -/ { - model = "Atmel AT91SAM9X5-EK"; - compatible = "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9"; - - chosen { - bootargs = "128M console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs"; - }; - - ahb { - apb { - mmc0: mmc@f0008000 { - pinctrl-0 = < - &pinctrl_board_mmc0 - &pinctrl_mmc0_slot0_clk_cmd_dat0 - &pinctrl_mmc0_slot0_dat1_3>; - status = "okay"; - slot@0 { - reg = <0>; - bus-width = <4>; - cd-gpios = <&pioD 15 0>; - }; - }; - - mmc1: mmc@f000c000 { - pinctrl-0 = < - &pinctrl_board_mmc1 - &pinctrl_mmc1_slot0_clk_cmd_dat0 - &pinctrl_mmc1_slot0_dat1_3>; - status = "okay"; - slot@0 { - reg = <0>; - bus-width = <4>; - cd-gpios = <&pioD 14 0>; - }; - }; - - dbgu: serial@fffff200 { - status = "okay"; - }; - - usart0: serial@f801c000 { - status = "okay"; - }; - - macb0: ethernet@f802c000 { - phy-mode = "rmii"; - status = "okay"; - }; - - i2c0: i2c@f8010000 { - status = "okay"; - }; - - i2c1: i2c@f8014000 { - status = "okay"; - }; - - i2c2: i2c@f8018000 { - status = "okay"; - }; - - pinctrl@fffff400 { - mmc0 { - pinctrl_board_mmc0: mmc0-board { - atmel,pins = - <3 15 0x0 0x5>; /* PD15 gpio CD pin pull up and deglitch */ - }; - }; - - mmc1 { - pinctrl_board_mmc1: mmc1-board { - atmel,pins = - <3 14 0x0 0x5>; /* PD14 gpio CD pin pull up and deglitch */ - }; - }; - }; - }; - - usb0: ohci@00600000 { - status = "okay"; - num-ports = <2>; - atmel,vbus-gpio = <&pioD 19 1 - &pioD 20 1 - >; - }; - - usb1: ehci@00700000 { - status = "okay"; - }; - }; -}; diff --git a/trunk/arch/arm/boot/dts/dbx5x0.dtsi b/trunk/arch/arm/boot/dts/dbx5x0.dtsi index 4b0e0ca08f40..748ba7aa746c 100644 --- a/trunk/arch/arm/boot/dts/dbx5x0.dtsi +++ b/trunk/arch/arm/boot/dts/dbx5x0.dtsi @@ -483,8 +483,6 @@ compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell"; reg = <0x80004000 0x1000>; interrupts = <0 21 0x4>; - arm,primecell-periphid = <0x180024>; - #address-cells = <1>; #size-cells = <0>; v-i2c-supply = <&db8500_vape_reg>; @@ -496,8 +494,6 @@ compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell"; reg = <0x80122000 0x1000>; interrupts = <0 22 0x4>; - arm,primecell-periphid = <0x180024>; - #address-cells = <1>; #size-cells = <0>; v-i2c-supply = <&db8500_vape_reg>; @@ -509,8 +505,6 @@ compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell"; reg = <0x80128000 0x1000>; interrupts = <0 55 0x4>; - arm,primecell-periphid = <0x180024>; - #address-cells = <1>; #size-cells = <0>; v-i2c-supply = <&db8500_vape_reg>; @@ -522,8 +516,6 @@ compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell"; reg = <0x80110000 0x1000>; interrupts = <0 12 0x4>; - arm,primecell-periphid = <0x180024>; - #address-cells = <1>; #size-cells = <0>; v-i2c-supply = <&db8500_vape_reg>; @@ -535,8 +527,6 @@ compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell"; reg = <0x8012a000 0x1000>; interrupts = <0 51 0x4>; - arm,primecell-periphid = <0x180024>; - #address-cells = <1>; #size-cells = <0>; v-i2c-supply = <&db8500_vape_reg>; @@ -583,38 +573,33 @@ interrupts = <0 60 0x4>; status = "disabled"; }; - sdi@80118000 { compatible = "arm,pl18x", "arm,primecell"; reg = <0x80118000 0x1000>; interrupts = <0 50 0x4>; status = "disabled"; }; - sdi@80005000 { compatible = "arm,pl18x", "arm,primecell"; reg = <0x80005000 0x1000>; interrupts = <0 41 0x4>; status = "disabled"; }; - sdi@80119000 { compatible = "arm,pl18x", "arm,primecell"; reg = <0x80119000 0x1000>; interrupts = <0 59 0x4>; status = "disabled"; }; - sdi@80114000 { compatible = "arm,pl18x", "arm,primecell"; reg = <0x80114000 0x1000>; interrupts = <0 99 0x4>; status = "disabled"; }; - sdi@80008000 { compatible = "arm,pl18x", "arm,primecell"; - reg = <0x80008000 0x1000>; + reg = <0x80114000 0x1000>; interrupts = <0 100 0x4>; status = "disabled"; }; diff --git a/trunk/arch/arm/boot/dts/exynos4210-trats.dts b/trunk/arch/arm/boot/dts/exynos4210-trats.dts index a21511c14071..73567b843e72 100644 --- a/trunk/arch/arm/boot/dts/exynos4210-trats.dts +++ b/trunk/arch/arm/boot/dts/exynos4210-trats.dts @@ -20,10 +20,8 @@ compatible = "samsung,trats", "samsung,exynos4210"; memory { - reg = <0x40000000 0x10000000 - 0x50000000 0x10000000 - 0x60000000 0x10000000 - 0x70000000 0x10000000>; + reg = <0x40000000 0x20000000 + 0x60000000 0x20000000>; }; chosen { diff --git a/trunk/arch/arm/boot/dts/imx23.dtsi b/trunk/arch/arm/boot/dts/imx23.dtsi index 6d31aa383460..9ca4ca70c1bc 100644 --- a/trunk/arch/arm/boot/dts/imx23.dtsi +++ b/trunk/arch/arm/boot/dts/imx23.dtsi @@ -69,7 +69,6 @@ interrupts = <13>, <56>; interrupt-names = "gpmi-dma", "bch"; clocks = <&clks 34>; - clock-names = "gpmi_io"; fsl,gpmi-dma-channel = <4>; status = "disabled"; }; diff --git a/trunk/arch/arm/boot/dts/imx28.dtsi b/trunk/arch/arm/boot/dts/imx28.dtsi index 55c57ea6169e..e16d63155480 100644 --- a/trunk/arch/arm/boot/dts/imx28.dtsi +++ b/trunk/arch/arm/boot/dts/imx28.dtsi @@ -85,7 +85,6 @@ interrupts = <88>, <41>; interrupt-names = "gpmi-dma", "bch"; clocks = <&clks 50>; - clock-names = "gpmi_io"; fsl,gpmi-dma-channel = <4>; status = "disabled"; }; diff --git a/trunk/arch/arm/boot/dts/omap3.dtsi b/trunk/arch/arm/boot/dts/omap3.dtsi index 696e929d0304..f38ea8771b44 100644 --- a/trunk/arch/arm/boot/dts/omap3.dtsi +++ b/trunk/arch/arm/boot/dts/omap3.dtsi @@ -257,7 +257,7 @@ interrupt-names = "common", "tx", "rx", "sidetone"; interrupt-parent = <&intc>; ti,buffer-size = <1280>; - ti,hwmods = "mcbsp2", "mcbsp2_sidetone"; + ti,hwmods = "mcbsp2"; }; mcbsp3: mcbsp@49024000 { @@ -272,7 +272,7 @@ interrupt-names = "common", "tx", "rx", "sidetone"; interrupt-parent = <&intc>; ti,buffer-size = <128>; - ti,hwmods = "mcbsp3", "mcbsp3_sidetone"; + ti,hwmods = "mcbsp3"; }; mcbsp4: mcbsp@49026000 { diff --git a/trunk/arch/arm/boot/dts/pm9g45.dts b/trunk/arch/arm/boot/dts/pm9g45.dts deleted file mode 100644 index 387fedb58988..000000000000 --- a/trunk/arch/arm/boot/dts/pm9g45.dts +++ /dev/null @@ -1,165 +0,0 @@ -/* - * pm9g45.dts - Device Tree file for Ronetix pm9g45 board - * - * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD - * - * Licensed under GPLv2. - */ -/dts-v1/; -/include/ "at91sam9g45.dtsi" - -/ { - model = "Ronetix pm9g45"; - compatible = "ronetix,pm9g45", "atmel,at91sam9g45", "atmel,at91sam9"; - - chosen { - bootargs = "console=ttyS0,115200"; - }; - - memory { - reg = <0x70000000 0x8000000>; - }; - - clocks { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - main_clock: clock@0 { - compatible = "atmel,osc", "fixed-clock"; - clock-frequency = <12000000>; - }; - }; - - ahb { - apb { - dbgu: serial@ffffee00 { - status = "okay"; - }; - - pinctrl@fffff200 { - - board { - pinctrl_board_nand: nand0-board { - atmel,pins = - <3 3 0x0 0x1 /* PD3 gpio RDY pin pull_up*/ - 2 14 0x0 0x1>; /* PC14 gpio enable pin pull_up */ - }; - }; - - mmc { - pinctrl_board_mmc: mmc0-board { - atmel,pins = - <3 6 0x0 0x5>; /* PD6 gpio CD pin pull_up and deglitch */ - }; - }; - }; - - mmc0: mmc@fff80000 { - pinctrl-0 = < - &pinctrl_board_mmc - &pinctrl_mmc0_slot0_clk_cmd_dat0 - &pinctrl_mmc0_slot0_dat1_3>; - status = "okay"; - slot@0 { - reg = <0>; - bus-width = <4>; - cd-gpios = <&pioD 6 0>; - }; - }; - - macb0: ethernet@fffbc000 { - phy-mode = "rmii"; - status = "okay"; - }; - - }; - - nand0: nand@40000000 { - nand-bus-width = <8>; - nand-ecc-mode = "soft"; - nand-on-flash-bbt; - pinctrl-0 = <&pinctrl_board_nand>; - - gpios = <&pioD 3 0 - &pioC 14 0 - 0 - >; - - status = "okay"; - - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x20000>; - }; - - barebox@20000 { - label = "barebox"; - reg = <0x20000 0x40000>; - }; - - bareboxenv@60000 { - label = "bareboxenv"; - reg = <0x60000 0x1A0000>; - }; - - kernel@200000 { - label = "bareboxenv2"; - reg = <0x200000 0x300000>; - }; - - kernel@500000 { - label = "root"; - reg = <0x500000 0x400000>; - }; - - data@900000 { - label = "data"; - reg = <0x900000 0x8340000>; - }; - }; - - usb0: ohci@00700000 { - status = "okay"; - num-ports = <2>; - }; - - usb1: ehci@00800000 { - status = "okay"; - }; - }; - - leds { - compatible = "gpio-leds"; - - led0 { - label = "led0"; - gpios = <&pioD 0 1>; - linux,default-trigger = "nand-disk"; - }; - - led1 { - label = "led1"; - gpios = <&pioD 31 0>; - linux,default-trigger = "heartbeat"; - }; - }; - - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - - right { - label = "SW4"; - gpios = <&pioE 7 1>; - linux,code = <106>; - }; - - up { - label = "SW3"; - gpios = <&pioE 8 1>; - linux,code = <103>; - }; - }; -}; diff --git a/trunk/arch/arm/boot/dts/spear1310-evb.dts b/trunk/arch/arm/boot/dts/spear1310-evb.dts index 2e4c5727468e..dd4358bc26e2 100644 --- a/trunk/arch/arm/boot/dts/spear1310-evb.dts +++ b/trunk/arch/arm/boot/dts/spear1310-evb.dts @@ -181,10 +181,6 @@ status = "okay"; }; - gpio@d8400000 { - status = "okay"; - }; - i2c0: i2c@e0280000 { status = "okay"; }; diff --git a/trunk/arch/arm/boot/dts/spear1310.dtsi b/trunk/arch/arm/boot/dts/spear1310.dtsi index 7cd25eb4f8e0..419ea7413d23 100644 --- a/trunk/arch/arm/boot/dts/spear1310.dtsi +++ b/trunk/arch/arm/boot/dts/spear1310.dtsi @@ -70,12 +70,6 @@ status = "disabled"; }; - pinmux: pinmux@e0700000 { - compatible = "st,spear1310-pinmux"; - reg = <0xe0700000 0x1000>; - #gpio-range-cells = <2>; - }; - spi1: spi@5d400000 { compatible = "arm,pl022", "arm,primecell"; reg = <0x5d400000 0x1000>; @@ -185,27 +179,6 @@ thermal@e07008c4 { st,thermal-flags = <0x7000>; }; - - gpiopinctrl: gpio@d8400000 { - compatible = "st,spear-plgpio"; - reg = <0xd8400000 0x1000>; - interrupts = <0 100 0x4>; - #interrupt-cells = <1>; - interrupt-controller; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pinmux 0 246>; - status = "disabled"; - - st-plgpio,ngpio = <246>; - st-plgpio,enb-reg = <0xd0>; - st-plgpio,wdata-reg = <0x90>; - st-plgpio,dir-reg = <0xb0>; - st-plgpio,ie-reg = <0x30>; - st-plgpio,rdata-reg = <0x70>; - st-plgpio,mis-reg = <0x10>; - st-plgpio,eit-reg = <0x50>; - }; }; }; }; diff --git a/trunk/arch/arm/boot/dts/spear1340-evb.dts b/trunk/arch/arm/boot/dts/spear1340-evb.dts index 045f7123ffac..c9a54e06fb68 100644 --- a/trunk/arch/arm/boot/dts/spear1340-evb.dts +++ b/trunk/arch/arm/boot/dts/spear1340-evb.dts @@ -193,10 +193,6 @@ status = "okay"; }; - gpio@e2800000 { - status = "okay"; - }; - i2c0: i2c@e0280000 { status = "okay"; }; diff --git a/trunk/arch/arm/boot/dts/spear1340.dtsi b/trunk/arch/arm/boot/dts/spear1340.dtsi index 6c09eb0a1b2b..d71fe2a68f09 100644 --- a/trunk/arch/arm/boot/dts/spear1340.dtsi +++ b/trunk/arch/arm/boot/dts/spear1340.dtsi @@ -24,12 +24,6 @@ status = "disabled"; }; - pinmux: pinmux@e0700000 { - compatible = "st,spear1340-pinmux"; - reg = <0xe0700000 0x1000>; - #gpio-range-cells = <2>; - }; - spi1: spi@5d400000 { compatible = "arm,pl022", "arm,primecell"; reg = <0x5d400000 0x1000>; @@ -57,26 +51,6 @@ thermal@e07008c4 { st,thermal-flags = <0x2a00>; }; - - gpiopinctrl: gpio@e2800000 { - compatible = "st,spear-plgpio"; - reg = <0xe2800000 0x1000>; - interrupts = <0 107 0x4>; - #interrupt-cells = <1>; - interrupt-controller; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pinmux 0 252>; - status = "disabled"; - - st-plgpio,ngpio = <250>; - st-plgpio,wdata-reg = <0x40>; - st-plgpio,dir-reg = <0x00>; - st-plgpio,ie-reg = <0x80>; - st-plgpio,rdata-reg = <0x20>; - st-plgpio,mis-reg = <0xa0>; - st-plgpio,eit-reg = <0x60>; - }; }; }; }; diff --git a/trunk/arch/arm/boot/dts/spear310.dtsi b/trunk/arch/arm/boot/dts/spear310.dtsi index 930303e48df9..62fc4fb3e5f9 100644 --- a/trunk/arch/arm/boot/dts/spear310.dtsi +++ b/trunk/arch/arm/boot/dts/spear310.dtsi @@ -22,10 +22,9 @@ 0xb0000000 0xb0000000 0x10000000 0xd0000000 0xd0000000 0x30000000>; - pinmux: pinmux@b4000000 { + pinmux@b4000000 { compatible = "st,spear310-pinmux"; reg = <0xb4000000 0x1000>; - #gpio-range-cells = <2>; }; fsmc: flash@44000000 { @@ -76,25 +75,6 @@ reg = <0xb2200000 0x1000>; status = "disabled"; }; - - gpiopinctrl: gpio@b4000000 { - compatible = "st,spear-plgpio"; - reg = <0xb4000000 0x1000>; - #interrupt-cells = <1>; - interrupt-controller; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pinmux 0 102>; - status = "disabled"; - - st-plgpio,ngpio = <102>; - st-plgpio,enb-reg = <0x10>; - st-plgpio,wdata-reg = <0x20>; - st-plgpio,dir-reg = <0x30>; - st-plgpio,ie-reg = <0x50>; - st-plgpio,rdata-reg = <0x40>; - st-plgpio,mis-reg = <0x60>; - }; }; }; }; diff --git a/trunk/arch/arm/boot/dts/spear320-evb.dts b/trunk/arch/arm/boot/dts/spear320-evb.dts index ad4bfc68ee05..082328bd64ab 100644 --- a/trunk/arch/arm/boot/dts/spear320-evb.dts +++ b/trunk/arch/arm/boot/dts/spear320-evb.dts @@ -164,10 +164,6 @@ status = "okay"; }; - gpio@b3000000 { - status = "okay"; - }; - i2c0: i2c@d0180000 { status = "okay"; }; diff --git a/trunk/arch/arm/boot/dts/spear320.dtsi b/trunk/arch/arm/boot/dts/spear320.dtsi index 67d7ada71275..1f49d69595a0 100644 --- a/trunk/arch/arm/boot/dts/spear320.dtsi +++ b/trunk/arch/arm/boot/dts/spear320.dtsi @@ -21,10 +21,9 @@ ranges = <0x40000000 0x40000000 0x80000000 0xd0000000 0xd0000000 0x30000000>; - pinmux: pinmux@b3000000 { + pinmux@b3000000 { compatible = "st,spear320-pinmux"; reg = <0xb3000000 0x1000>; - #gpio-range-cells = <2>; }; clcd@90000000 { @@ -91,26 +90,6 @@ reg = <0xa4000000 0x1000>; status = "disabled"; }; - - gpiopinctrl: gpio@b3000000 { - compatible = "st,spear-plgpio"; - reg = <0xb3000000 0x1000>; - #interrupt-cells = <1>; - interrupt-controller; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pinmux 0 102>; - status = "disabled"; - - st-plgpio,ngpio = <102>; - st-plgpio,enb-reg = <0x24>; - st-plgpio,wdata-reg = <0x34>; - st-plgpio,dir-reg = <0x44>; - st-plgpio,ie-reg = <0x64>; - st-plgpio,rdata-reg = <0x54>; - st-plgpio,mis-reg = <0x84>; - st-plgpio,eit-reg = <0x94>; - }; }; }; }; diff --git a/trunk/arch/arm/boot/dts/tegra30.dtsi b/trunk/arch/arm/boot/dts/tegra30.dtsi index df7f2270fc91..b1497c7d7d68 100644 --- a/trunk/arch/arm/boot/dts/tegra30.dtsi +++ b/trunk/arch/arm/boot/dts/tegra30.dtsi @@ -73,8 +73,8 @@ pinmux: pinmux { compatible = "nvidia,tegra30-pinmux"; - reg = <0x70000868 0xd4 /* Pad control registers */ - 0x70003000 0x3e4>; /* Mux registers */ + reg = <0x70000868 0xd0 /* Pad control registers */ + 0x70003000 0x3e0>; /* Mux registers */ }; serial@70006000 { diff --git a/trunk/arch/arm/common/timer-sp.c b/trunk/arch/arm/common/timer-sp.c index 9d2d3ba339ff..df13a3ffff35 100644 --- a/trunk/arch/arm/common/timer-sp.c +++ b/trunk/arch/arm/common/timer-sp.c @@ -162,6 +162,7 @@ static struct clock_event_device sp804_clockevent = { .set_mode = sp804_set_mode, .set_next_event = sp804_set_next_event, .rating = 300, + .cpumask = cpu_all_mask, }; static struct irqaction sp804_timer_irq = { @@ -184,7 +185,6 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq, clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ); evt->name = name; evt->irq = irq; - evt->cpumask = cpu_possible_mask; setup_irq(irq, &sp804_timer_irq); clockevents_config_and_register(evt, rate, 0xf, 0xffffffff); diff --git a/trunk/arch/arm/configs/at91_dt_defconfig b/trunk/arch/arm/configs/at91_dt_defconfig index b175577d7abb..67bc571ed0c3 100644 --- a/trunk/arch/arm/configs/at91_dt_defconfig +++ b/trunk/arch/arm/configs/at91_dt_defconfig @@ -111,7 +111,6 @@ CONFIG_I2C=y CONFIG_I2C_GPIO=y CONFIG_SPI=y CONFIG_SPI_ATMEL=y -CONFIG_PINCTRL_AT91=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y CONFIG_AT91SAM9X_WATCHDOG=y diff --git a/trunk/arch/arm/configs/imx_v6_v7_defconfig b/trunk/arch/arm/configs/imx_v6_v7_defconfig index 394ded624e37..66aa7a6db884 100644 --- a/trunk/arch/arm/configs/imx_v6_v7_defconfig +++ b/trunk/arch/arm/configs/imx_v6_v7_defconfig @@ -139,7 +139,6 @@ CONFIG_I2C_IMX=y CONFIG_SPI=y CONFIG_SPI_IMX=y CONFIG_GPIO_SYSFS=y -CONFIG_GPIO_MC9S08DZ60=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y CONFIG_IMX2_WDT=y @@ -156,7 +155,6 @@ CONFIG_SOC_CAMERA=y CONFIG_SOC_CAMERA_OV2640=y CONFIG_VIDEO_MX3=y CONFIG_FB=y -CONFIG_LCD_PLATFORM=y CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_LCD_L4F00242T03=y diff --git a/trunk/arch/arm/configs/mvebu_defconfig b/trunk/arch/arm/configs/mvebu_defconfig index 3458752c4bb2..7bcf850eddcd 100644 --- a/trunk/arch/arm/configs/mvebu_defconfig +++ b/trunk/arch/arm/configs/mvebu_defconfig @@ -1,6 +1,6 @@ CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y -CONFIG_IRQ_DOMAIN_DEBUG=y +CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y @@ -9,12 +9,10 @@ CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_ARCH_MVEBU=y -CONFIG_MACH_ARMADA_370=y -CONFIG_MACH_ARMADA_XP=y -# CONFIG_CACHE_L2X0 is not set +CONFIG_MACH_ARMADA_370_XP=y CONFIG_AEABI=y CONFIG_HIGHMEM=y -# CONFIG_COMPACTION is not set +CONFIG_USE_OF=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_ARM_APPENDED_DTB=y @@ -25,8 +23,6 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y -# CONFIG_USB_SUPPORT is not set -# CONFIG_IOMMU_SUPPORT is not set CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set diff --git a/trunk/arch/arm/configs/versatile_defconfig b/trunk/arch/arm/configs/versatile_defconfig index 2ba9e63d0f17..cdd4d2bd3962 100644 --- a/trunk/arch/arm/configs/versatile_defconfig +++ b/trunk/arch/arm/configs/versatile_defconfig @@ -1,4 +1,3 @@ -CONFIG_ARCH_VERSATILE=y CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y diff --git a/trunk/arch/arm/include/asm/flat.h b/trunk/arch/arm/include/asm/flat.h index e847d23351ed..59426a4595c9 100644 --- a/trunk/arch/arm/include/asm/flat.h +++ b/trunk/arch/arm/include/asm/flat.h @@ -8,7 +8,7 @@ #define flat_argvp_envp_on_stack() 1 #define flat_old_ram_flag(flags) (flags) #define flat_reloc_valid(reloc, size) ((reloc) <= (size)) -#define flat_get_addr_from_rp(rp, relval, flags, persistent) ((void)persistent,get_unaligned(rp)) +#define flat_get_addr_from_rp(rp, relval, flags, persistent) get_unaligned(rp) #define flat_put_addr_at_rp(rp, val, relval) put_unaligned(val,rp) #define flat_get_relocate_addr(rel) (rel) #define flat_set_persistent(relval, p) 0 diff --git a/trunk/arch/arm/include/asm/hardware/sp810.h b/trunk/arch/arm/include/asm/hardware/sp810.h index afd7e916472f..6b9b077d86b3 100644 --- a/trunk/arch/arm/include/asm/hardware/sp810.h +++ b/trunk/arch/arm/include/asm/hardware/sp810.h @@ -56,8 +56,6 @@ #define SCCTRL_TIMEREN1SEL_REFCLK (0 << 17) #define SCCTRL_TIMEREN1SEL_TIMCLK (1 << 17) -#define SCCTRL_TIMERENnSEL_SHIFT(n) (15 + ((n) * 2)) - static inline void sysctl_soft_reset(void __iomem *base) { /* switch to slow mode */ diff --git a/trunk/arch/arm/include/asm/io.h b/trunk/arch/arm/include/asm/io.h index 42f042ee4ada..35c1ed89b936 100644 --- a/trunk/arch/arm/include/asm/io.h +++ b/trunk/arch/arm/include/asm/io.h @@ -64,7 +64,7 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen); static inline void __raw_writew(u16 val, volatile void __iomem *addr) { asm volatile("strh %1, %0" - : "+Q" (*(volatile u16 __force *)addr) + : "+Qo" (*(volatile u16 __force *)addr) : "r" (val)); } @@ -72,7 +72,7 @@ static inline u16 __raw_readw(const volatile void __iomem *addr) { u16 val; asm volatile("ldrh %1, %0" - : "+Q" (*(volatile u16 __force *)addr), + : "+Qo" (*(volatile u16 __force *)addr), "=r" (val)); return val; } diff --git a/trunk/arch/arm/include/asm/sched_clock.h b/trunk/arch/arm/include/asm/sched_clock.h index e3f757263438..05b8e82ec9f5 100644 --- a/trunk/arch/arm/include/asm/sched_clock.h +++ b/trunk/arch/arm/include/asm/sched_clock.h @@ -10,5 +10,7 @@ extern void sched_clock_postinit(void); extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate); +extern void setup_sched_clock_needs_suspend(u32 (*read)(void), int bits, + unsigned long rate); #endif diff --git a/trunk/arch/arm/include/asm/uaccess.h b/trunk/arch/arm/include/asm/uaccess.h index 7e1f76027f66..77bd79f2ffdb 100644 --- a/trunk/arch/arm/include/asm/uaccess.h +++ b/trunk/arch/arm/include/asm/uaccess.h @@ -200,8 +200,8 @@ extern int __put_user_8(void *, unsigned long long); #define USER_DS KERNEL_DS #define segment_eq(a,b) (1) -#define __addr_ok(addr) ((void)(addr),1) -#define __range_ok(addr,size) ((void)(addr),0) +#define __addr_ok(addr) (1) +#define __range_ok(addr,size) (0) #define get_fs() (KERNEL_DS) static inline void set_fs(mm_segment_t fs) diff --git a/trunk/arch/arm/include/asm/vfpmacros.h b/trunk/arch/arm/include/asm/vfpmacros.h index 301c1db3e99b..6a6f1e485f41 100644 --- a/trunk/arch/arm/include/asm/vfpmacros.h +++ b/trunk/arch/arm/include/asm/vfpmacros.h @@ -27,9 +27,9 @@ #if __LINUX_ARM_ARCH__ <= 6 ldr \tmp, =elf_hwcap @ may not have MVFR regs ldr \tmp, [\tmp, #0] - tst \tmp, #HWCAP_VFPD32 - ldcnel p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} - addeq \base, \base, #32*4 @ step over unused register space + tst \tmp, #HWCAP_VFPv3D16 + ldceql p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} + addne \base, \base, #32*4 @ step over unused register space #else VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field @@ -51,9 +51,9 @@ #if __LINUX_ARM_ARCH__ <= 6 ldr \tmp, =elf_hwcap @ may not have MVFR regs ldr \tmp, [\tmp, #0] - tst \tmp, #HWCAP_VFPD32 - stcnel p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} - addeq \base, \base, #32*4 @ step over unused register space + tst \tmp, #HWCAP_VFPv3D16 + stceql p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} + addne \base, \base, #32*4 @ step over unused register space #else VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field diff --git a/trunk/arch/arm/include/asm/xen/interface.h b/trunk/arch/arm/include/asm/xen/interface.h index 5000397134b4..ae05e56dd17d 100644 --- a/trunk/arch/arm/include/asm/xen/interface.h +++ b/trunk/arch/arm/include/asm/xen/interface.h @@ -29,22 +29,16 @@ #ifndef __ASSEMBLY__ /* Explicitly size integers that represent pfns in the interface with - * Xen so that we can have one ABI that works for 32 and 64 bit guests. - * Note that this means that the xen_pfn_t type may be capable of - * representing pfn's which the guest cannot represent in its own pfn - * type. However since pfn space is controlled by the guest this is - * fine since it simply wouldn't be able to create any sure pfns in - * the first place. - */ + * Xen so that we can have one ABI that works for 32 and 64 bit guests. */ typedef uint64_t xen_pfn_t; -#define PRI_xen_pfn "llx" typedef uint64_t xen_ulong_t; -#define PRI_xen_ulong "llx" /* Guest handles for primitive C types. */ __DEFINE_GUEST_HANDLE(uchar, unsigned char); __DEFINE_GUEST_HANDLE(uint, unsigned int); +__DEFINE_GUEST_HANDLE(ulong, unsigned long); DEFINE_GUEST_HANDLE(char); DEFINE_GUEST_HANDLE(int); +DEFINE_GUEST_HANDLE(long); DEFINE_GUEST_HANDLE(void); DEFINE_GUEST_HANDLE(uint64_t); DEFINE_GUEST_HANDLE(uint32_t); diff --git a/trunk/arch/arm/include/asm/xen/page.h b/trunk/arch/arm/include/asm/xen/page.h index c6b9096cef95..174202318dff 100644 --- a/trunk/arch/arm/include/asm/xen/page.h +++ b/trunk/arch/arm/include/asm/xen/page.h @@ -10,7 +10,7 @@ #include #define pfn_to_mfn(pfn) (pfn) -#define phys_to_machine_mapping_valid(pfn) (1) +#define phys_to_machine_mapping_valid (1) #define mfn_to_pfn(mfn) (mfn) #define mfn_to_virt(m) (__va(mfn_to_pfn(m) << PAGE_SHIFT)) @@ -30,8 +30,6 @@ typedef struct xpaddr { #define XMADDR(x) ((xmaddr_t) { .maddr = (x) }) #define XPADDR(x) ((xpaddr_t) { .paddr = (x) }) -#define INVALID_P2M_ENTRY (~0UL) - static inline xmaddr_t phys_to_machine(xpaddr_t phys) { unsigned offset = phys.paddr & ~PAGE_MASK; @@ -76,14 +74,9 @@ static inline int m2p_remove_override(struct page *page, bool clear_pte) return 0; } -static inline bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn) -{ - BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY); - return true; -} - static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn) { - return __set_phys_to_machine(pfn, mfn); + BUG(); + return false; } #endif /* _ASM_ARM_XEN_PAGE_H */ diff --git a/trunk/arch/arm/include/debug/8250_32.S b/trunk/arch/arm/include/debug/8250_32.S deleted file mode 100644 index 8db01eeabbb4..000000000000 --- a/trunk/arch/arm/include/debug/8250_32.S +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2011 Picochip Ltd., Jamie Iles - * - * 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. - * - * Derived from arch/arm/mach-davinci/include/mach/debug-macro.S to use 32-bit - * accesses to the 8250. - */ - -#include - - .macro senduart,rd,rx - str \rd, [\rx, #UART_TX << UART_SHIFT] - .endm - - .macro busyuart,rd,rx -1002: ldr \rd, [\rx, #UART_LSR << UART_SHIFT] - and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE - teq \rd, #UART_LSR_TEMT | UART_LSR_THRE - bne 1002b - .endm - - /* The UART's don't have any flow control IO's wired up. */ - .macro waituart,rd,rx - .endm diff --git a/trunk/arch/arm/include/debug/picoxcell.S b/trunk/arch/arm/include/debug/picoxcell.S index bc1f07c49cd4..7419deb1b948 100644 --- a/trunk/arch/arm/include/debug/picoxcell.S +++ b/trunk/arch/arm/include/debug/picoxcell.S @@ -5,7 +5,10 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * + * Derived from arch/arm/mach-davinci/include/mach/debug-macro.S to use 32-bit + * accesses to the 8250. */ +#include #define UART_SHIFT 2 #define PICOXCELL_UART1_BASE 0x80230000 @@ -16,4 +19,17 @@ ldr \rp, =PICOXCELL_UART1_BASE .endm -#include "8250_32.S" + .macro senduart,rd,rx + str \rd, [\rx, #UART_TX << UART_SHIFT] + .endm + + .macro busyuart,rd,rx +1002: ldr \rd, [\rx, #UART_LSR << UART_SHIFT] + and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE + teq \rd, #UART_LSR_TEMT | UART_LSR_THRE + bne 1002b + .endm + + /* The UART's don't have any flow control IO's wired up. */ + .macro waituart,rd,rx + .endm diff --git a/trunk/arch/arm/include/debug/socfpga.S b/trunk/arch/arm/include/debug/socfpga.S index 966b2f994946..d6f26d23374f 100644 --- a/trunk/arch/arm/include/debug/socfpga.S +++ b/trunk/arch/arm/include/debug/socfpga.S @@ -7,9 +7,6 @@ * published by the Free Software Foundation. */ -#define UART_SHIFT 2 -#define DEBUG_LL_UART_OFFSET 0x00002000 - .macro addruart, rp, rv, tmp mov \rp, #DEBUG_LL_UART_OFFSET orr \rp, \rp, #0x00c00000 @@ -17,5 +14,3 @@ orr \rp, \rp, #0xff000000 @ physical base .endm -#include "8250_32.S" - diff --git a/trunk/arch/arm/include/uapi/asm/hwcap.h b/trunk/arch/arm/include/uapi/asm/hwcap.h index 3688fd15a32d..f254f6503cce 100644 --- a/trunk/arch/arm/include/uapi/asm/hwcap.h +++ b/trunk/arch/arm/include/uapi/asm/hwcap.h @@ -18,12 +18,11 @@ #define HWCAP_THUMBEE (1 << 11) #define HWCAP_NEON (1 << 12) #define HWCAP_VFPv3 (1 << 13) -#define HWCAP_VFPv3D16 (1 << 14) /* also set for VFPv4-D16 */ +#define HWCAP_VFPv3D16 (1 << 14) #define HWCAP_TLS (1 << 15) #define HWCAP_VFPv4 (1 << 16) #define HWCAP_IDIVA (1 << 17) #define HWCAP_IDIVT (1 << 18) -#define HWCAP_VFPD32 (1 << 19) /* set if VFP has 32 regs (not 16) */ #define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT) diff --git a/trunk/arch/arm/kernel/irq.c b/trunk/arch/arm/kernel/irq.c index 896165096d6a..16cedb42c0c3 100644 --- a/trunk/arch/arm/kernel/irq.c +++ b/trunk/arch/arm/kernel/irq.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -110,7 +109,6 @@ void set_irq_flags(unsigned int irq, unsigned int iflags) /* Order is clear bits in "clr" then set bits in "set" */ irq_modify_status(irq, clr, set & ~clr); } -EXPORT_SYMBOL_GPL(set_irq_flags); void __init init_IRQ(void) { diff --git a/trunk/arch/arm/kernel/kprobes-test-arm.c b/trunk/arch/arm/kernel/kprobes-test-arm.c index 839312905067..38c1a3b103a0 100644 --- a/trunk/arch/arm/kernel/kprobes-test-arm.c +++ b/trunk/arch/arm/kernel/kprobes-test-arm.c @@ -366,9 +366,7 @@ void kprobe_arm_test_cases(void) TEST_UNSUPPORTED(".word 0xe04f0392 @ umaal r0, pc, r2, r3") TEST_UNSUPPORTED(".word 0xe0500090 @ undef") TEST_UNSUPPORTED(".word 0xe05fff9f @ undef") -#endif -#if __LINUX_ARM_ARCH__ >= 7 TEST_RRR( "mls r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"") TEST_RRR( "mlshi r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") TEST_RR( "mls lr, r",1, VAL2,", r",2, VAL3,", r13") @@ -458,8 +456,6 @@ void kprobe_arm_test_cases(void) TEST_UNSUPPORTED(".word 0xe1700090") /* Unallocated space */ #if __LINUX_ARM_ARCH__ >= 6 TEST_UNSUPPORTED("ldrex r2, [sp]") -#endif -#if (__LINUX_ARM_ARCH__ >= 7) || defined(CONFIG_CPU_32v6K) TEST_UNSUPPORTED("strexd r0, r2, r3, [sp]") TEST_UNSUPPORTED("ldrexd r2, r3, [sp]") TEST_UNSUPPORTED("strexb r0, r2, [sp]") diff --git a/trunk/arch/arm/kernel/machine_kexec.c b/trunk/arch/arm/kernel/machine_kexec.c index 8ef8c9337809..e29c3337ca81 100644 --- a/trunk/arch/arm/kernel/machine_kexec.c +++ b/trunk/arch/arm/kernel/machine_kexec.c @@ -45,9 +45,10 @@ int machine_kexec_prepare(struct kimage *image) for (i = 0; i < image->nr_segments; i++) { current_segment = &image->segment[i]; - if (!memblock_is_region_memory(current_segment->mem, - current_segment->memsz)) - return -EINVAL; + err = memblock_is_region_memory(current_segment->mem, + current_segment->memsz); + if (err) + return - EINVAL; err = get_user(header, (__be32*)current_segment->buf); if (err) diff --git a/trunk/arch/arm/kernel/perf_event.c b/trunk/arch/arm/kernel/perf_event.c index 53c0304b734a..93971b1a4f0b 100644 --- a/trunk/arch/arm/kernel/perf_event.c +++ b/trunk/arch/arm/kernel/perf_event.c @@ -96,10 +96,6 @@ armpmu_event_set_period(struct perf_event *event, s64 period = hwc->sample_period; int ret = 0; - /* The period may have been changed by PERF_EVENT_IOC_PERIOD */ - if (unlikely(period != hwc->last_period)) - left = period - (hwc->last_period - left); - if (unlikely(left <= -period)) { left = period; local64_set(&hwc->period_left, left); diff --git a/trunk/arch/arm/kernel/sched_clock.c b/trunk/arch/arm/kernel/sched_clock.c index fc6692e2b603..e21bac20d90d 100644 --- a/trunk/arch/arm/kernel/sched_clock.c +++ b/trunk/arch/arm/kernel/sched_clock.c @@ -107,6 +107,13 @@ static void sched_clock_poll(unsigned long wrap_ticks) update_sched_clock(); } +void __init setup_sched_clock_needs_suspend(u32 (*read)(void), int bits, + unsigned long rate) +{ + setup_sched_clock(read, bits, rate); + cd.needs_suspend = true; +} + void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) { unsigned long r, w; @@ -182,15 +189,18 @@ void __init sched_clock_postinit(void) static int sched_clock_suspend(void) { sched_clock_poll(sched_clock_timer.data); - cd.suspended = true; + if (cd.needs_suspend) + cd.suspended = true; return 0; } static void sched_clock_resume(void) { - cd.epoch_cyc = read_sched_clock(); - cd.epoch_cyc_copy = cd.epoch_cyc; - cd.suspended = false; + if (cd.needs_suspend) { + cd.epoch_cyc = read_sched_clock(); + cd.epoch_cyc_copy = cd.epoch_cyc; + cd.suspended = false; + } } static struct syscore_ops sched_clock_ops = { diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index fbc8b2623d82..8e20754dd31d 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -294,24 +294,18 @@ static void percpu_timer_setup(void); asmlinkage void __cpuinit secondary_start_kernel(void) { struct mm_struct *mm = &init_mm; - unsigned int cpu; - - /* - * The identity mapping is uncached (strongly ordered), so - * switch away from it before attempting any exclusive accesses. - */ - cpu_switch_mm(mm->pgd, mm); - enter_lazy_tlb(mm, current); - local_flush_tlb_all(); + unsigned int cpu = smp_processor_id(); /* * All kernel threads share the same mm context; grab a * reference and switch to it. */ - cpu = smp_processor_id(); atomic_inc(&mm->mm_count); current->active_mm = mm; cpumask_set_cpu(cpu, mm_cpumask(mm)); + cpu_switch_mm(mm->pgd, mm); + enter_lazy_tlb(mm, current); + local_flush_tlb_all(); printk("CPU%u: Booted secondary processor\n", cpu); diff --git a/trunk/arch/arm/kernel/smp_twd.c b/trunk/arch/arm/kernel/smp_twd.c index b22d700fea27..e1f906989bb8 100644 --- a/trunk/arch/arm/kernel/smp_twd.c +++ b/trunk/arch/arm/kernel/smp_twd.c @@ -42,10 +42,10 @@ static void twd_set_mode(enum clock_event_mode mode, switch (mode) { case CLOCK_EVT_MODE_PERIODIC: + /* timer load already set up */ ctrl = TWD_TIMER_CONTROL_ENABLE | TWD_TIMER_CONTROL_IT_ENABLE | TWD_TIMER_CONTROL_PERIODIC; - __raw_writel(DIV_ROUND_CLOSEST(twd_timer_rate, HZ), - twd_base + TWD_TIMER_LOAD); + __raw_writel(twd_timer_rate / HZ, twd_base + TWD_TIMER_LOAD); break; case CLOCK_EVT_MODE_ONESHOT: /* period set, and timer enabled in 'next_event' hook */ diff --git a/trunk/arch/arm/lib/delay.c b/trunk/arch/arm/lib/delay.c index 0dc53854a5d8..9d0a30032d7f 100644 --- a/trunk/arch/arm/lib/delay.c +++ b/trunk/arch/arm/lib/delay.c @@ -45,7 +45,6 @@ int read_current_timer(unsigned long *timer_val) *timer_val = delay_timer->read_current_timer(); return 0; } -EXPORT_SYMBOL_GPL(read_current_timer); static void __timer_delay(unsigned long cycles) { diff --git a/trunk/arch/arm/mach-at91/Kconfig b/trunk/arch/arm/mach-at91/Kconfig index e34c1bdb804d..b14207101938 100644 --- a/trunk/arch/arm/mach-at91/Kconfig +++ b/trunk/arch/arm/mach-at91/Kconfig @@ -21,13 +21,19 @@ config SOC_AT91SAM9 bool select CPU_ARM926T select GENERIC_CLOCKEVENTS - select MULTI_IRQ_HANDLER - select SPARSE_IRQ menu "Atmel AT91 System-on-Chip" comment "Atmel AT91 Processor" +config SOC_AT91SAM9 + bool + select AT91_SAM9_SMC + select AT91_SAM9_TIME + select CPU_ARM926T + select MULTI_IRQ_HANDLER + select SPARSE_IRQ + config SOC_AT91RM9200 bool "AT91RM9200" select CPU_ARM920T @@ -494,17 +500,8 @@ endif comment "Generic Board Type" -config MACH_AT91RM9200_DT - bool "Atmel AT91RM9200 Evaluation Kits with device-tree support" - depends on SOC_AT91RM9200 - select USE_OF - help - Select this if you want to experiment device-tree with - an Atmel RM9200 Evaluation Kit. - config MACH_AT91SAM_DT bool "Atmel AT91SAM Evaluation Kits with device-tree support" - depends on SOC_AT91SAM9 select USE_OF help Select this if you want to experiment device-tree with diff --git a/trunk/arch/arm/mach-at91/Makefile b/trunk/arch/arm/mach-at91/Makefile index b38a1dcb79b8..3bb7a51efc9d 100644 --- a/trunk/arch/arm/mach-at91/Makefile +++ b/trunk/arch/arm/mach-at91/Makefile @@ -88,7 +88,6 @@ obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o # AT91SAM board with device-tree -obj-$(CONFIG_MACH_AT91RM9200_DT) += board-rm9200-dt.o obj-$(CONFIG_MACH_AT91SAM_DT) += board-dt.o # AT91X40 board-specific support diff --git a/trunk/arch/arm/mach-at91/at91rm9200.c b/trunk/arch/arm/mach-at91/at91rm9200.c index 6cceb42a4c33..b4f0565aff63 100644 --- a/trunk/arch/arm/mach-at91/at91rm9200.c +++ b/trunk/arch/arm/mach-at91/at91rm9200.c @@ -187,31 +187,13 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), - CLKDEV_CON_DEV_ID(NULL, "i2c-at91rm9200.0", &twi_clk), + CLKDEV_CON_DEV_ID(NULL, "i2c-at91rm9200", &twi_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), CLKDEV_CON_ID("pioA", &pioA_clk), CLKDEV_CON_ID("pioB", &pioB_clk), CLKDEV_CON_ID("pioC", &pioC_clk), CLKDEV_CON_ID("pioD", &pioD_clk), - /* usart lookup table for DT entries */ - CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), - CLKDEV_CON_DEV_ID("usart", "fffc0000.serial", &usart0_clk), - CLKDEV_CON_DEV_ID("usart", "fffc4000.serial", &usart1_clk), - CLKDEV_CON_DEV_ID("usart", "fffc8000.serial", &usart2_clk), - CLKDEV_CON_DEV_ID("usart", "fffcc000.serial", &usart3_clk), - /* tc lookup table for DT entries */ - CLKDEV_CON_DEV_ID("t0_clk", "fffa0000.timer", &tc0_clk), - CLKDEV_CON_DEV_ID("t1_clk", "fffa0000.timer", &tc1_clk), - CLKDEV_CON_DEV_ID("t2_clk", "fffa0000.timer", &tc2_clk), - CLKDEV_CON_DEV_ID("t0_clk", "fffa4000.timer", &tc3_clk), - CLKDEV_CON_DEV_ID("t1_clk", "fffa4000.timer", &tc4_clk), - CLKDEV_CON_DEV_ID("t2_clk", "fffa4000.timer", &tc5_clk), - CLKDEV_CON_DEV_ID("hclk", "300000.ohci", &ohci_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioA_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioB_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioC_clk), - CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioD_clk), }; static struct clk_lookup usart_clocks_lookups[] = { @@ -379,10 +361,10 @@ static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = { 0 /* Advanced Interrupt Controller (IRQ6) */ }; -AT91_SOC_START(rm9200) +struct at91_init_soc __initdata at91rm9200_soc = { .map_io = at91rm9200_map_io, .default_irq_priority = at91rm9200_default_irq_priority, .ioremap_registers = at91rm9200_ioremap_registers, .register_clocks = at91rm9200_register_clocks, .init = at91rm9200_initialize, -AT91_SOC_END +}; diff --git a/trunk/arch/arm/mach-at91/at91rm9200_devices.c b/trunk/arch/arm/mach-at91/at91rm9200_devices.c index 3cee0e6ea7c3..a563189cdfc3 100644 --- a/trunk/arch/arm/mach-at91/at91rm9200_devices.c +++ b/trunk/arch/arm/mach-at91/at91rm9200_devices.c @@ -68,7 +68,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable overcurrent notification */ for (i = 0; i < data->ports; i++) { - if (gpio_is_valid(data->overcurrent_pin[i])) + if (data->overcurrent_pin[i]) at91_set_gpio_input(data->overcurrent_pin[i], 1); } @@ -479,7 +479,7 @@ static struct i2c_gpio_platform_data pdata = { static struct platform_device at91rm9200_twi_device = { .name = "i2c-gpio", - .id = 0, + .id = -1, .dev.platform_data = &pdata, }; @@ -512,7 +512,7 @@ static struct resource twi_resources[] = { static struct platform_device at91rm9200_twi_device = { .name = "i2c-at91rm9200", - .id = 0, + .id = -1, .resource = twi_resources, .num_resources = ARRAY_SIZE(twi_resources), }; diff --git a/trunk/arch/arm/mach-at91/at91rm9200_time.c b/trunk/arch/arm/mach-at91/at91rm9200_time.c index cafe98836c8a..aaa443b48c91 100644 --- a/trunk/arch/arm/mach-at91/at91rm9200_time.c +++ b/trunk/arch/arm/mach-at91/at91rm9200_time.c @@ -24,9 +24,6 @@ #include #include #include -#include -#include -#include #include @@ -94,8 +91,7 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) static struct irqaction at91rm9200_timer_irq = { .name = "at91_tick", .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = at91rm9200_timer_interrupt, - .irq = NR_IRQS_LEGACY + AT91_ID_SYS, + .handler = at91rm9200_timer_interrupt }; static cycle_t read_clk32k(struct clocksource *cs) @@ -183,60 +179,8 @@ static struct clock_event_device clkevt = { void __iomem *at91_st_base; EXPORT_SYMBOL_GPL(at91_st_base); -#ifdef CONFIG_OF -static struct of_device_id at91rm9200_st_timer_ids[] = { - { .compatible = "atmel,at91rm9200-st" }, - { /* sentinel */ } -}; - -static int __init of_at91rm9200_st_init(void) -{ - struct device_node *np; - int ret; - - np = of_find_matching_node(NULL, at91rm9200_st_timer_ids); - if (!np) - goto err; - - at91_st_base = of_iomap(np, 0); - if (!at91_st_base) - goto node_err; - - /* Get the interrupts property */ - ret = irq_of_parse_and_map(np, 0); - if (!ret) - goto ioremap_err; - at91rm9200_timer_irq.irq = ret; - - of_node_put(np); - - return 0; - -ioremap_err: - iounmap(at91_st_base); -node_err: - of_node_put(np); -err: - return -EINVAL; -} -#else -static int __init of_at91rm9200_st_init(void) -{ - return -EINVAL; -} -#endif - void __init at91rm9200_ioremap_st(u32 addr) { -#ifdef CONFIG_OF - struct device_node *np; - - np = of_find_matching_node(NULL, at91rm9200_st_timer_ids); - if (np) { - of_node_put(np); - return; - } -#endif at91_st_base = ioremap(addr, 256); if (!at91_st_base) panic("Impossible to ioremap ST\n"); @@ -247,16 +191,13 @@ void __init at91rm9200_ioremap_st(u32 addr) */ void __init at91rm9200_timer_init(void) { - /* For device tree enabled device: initialize here */ - of_at91rm9200_st_init(); - /* Disable all timer interrupts, and clear any pending ones */ at91_st_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS); at91_st_read(AT91_ST_SR); /* Make IRQs happen for the system timer */ - setup_irq(at91rm9200_timer_irq.irq, &at91rm9200_timer_irq); + setup_irq(NR_IRQS_LEGACY + AT91_ID_SYS, &at91rm9200_timer_irq); /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used * directly for the clocksource and all clockevents, after adjusting diff --git a/trunk/arch/arm/mach-at91/at91sam9260.c b/trunk/arch/arm/mach-at91/at91sam9260.c index c9e029e44d8a..ad29f93f20ca 100644 --- a/trunk/arch/arm/mach-at91/at91sam9260.c +++ b/trunk/arch/arm/mach-at91/at91sam9260.c @@ -211,8 +211,8 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk), - CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260.0", &twi_clk), - CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi_clk), + CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260", &twi_clk), + CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20", &twi_clk), /* more usart lookup table for DT entries */ CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk), @@ -230,15 +230,11 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("t1_clk", "fffdc000.timer", &tc4_clk), CLKDEV_CON_DEV_ID("t2_clk", "fffdc000.timer", &tc5_clk), CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &ohci_clk), - CLKDEV_CON_DEV_ID("mci_clk", "fffa8000.mmc", &mmc_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), CLKDEV_CON_ID("pioA", &pioA_clk), CLKDEV_CON_ID("pioB", &pioB_clk), CLKDEV_CON_ID("pioC", &pioC_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioA_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioB_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioC_clk), }; static struct clk_lookup usart_clocks_lookups[] = { @@ -394,10 +390,10 @@ static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller */ }; -AT91_SOC_START(sam9260) +struct at91_init_soc __initdata at91sam9260_soc = { .map_io = at91sam9260_map_io, .default_irq_priority = at91sam9260_default_irq_priority, .ioremap_registers = at91sam9260_ioremap_registers, .register_clocks = at91sam9260_register_clocks, .init = at91sam9260_initialize, -AT91_SOC_END +}; diff --git a/trunk/arch/arm/mach-at91/at91sam9260_devices.c b/trunk/arch/arm/mach-at91/at91sam9260_devices.c index 414bd855fb0c..a76b8684f52d 100644 --- a/trunk/arch/arm/mach-at91/at91sam9260_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9260_devices.c @@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable overcurrent notification */ for (i = 0; i < data->ports; i++) { - if (gpio_is_valid(data->overcurrent_pin[i])) + if (data->overcurrent_pin[i]) at91_set_gpio_input(data->overcurrent_pin[i], 1); } @@ -389,7 +389,7 @@ static struct i2c_gpio_platform_data pdata = { static struct platform_device at91sam9260_twi_device = { .name = "i2c-gpio", - .id = 0, + .id = -1, .dev.platform_data = &pdata, }; @@ -421,7 +421,7 @@ static struct resource twi_resources[] = { }; static struct platform_device at91sam9260_twi_device = { - .id = 0, + .id = -1, .resource = twi_resources, .num_resources = ARRAY_SIZE(twi_resources), }; diff --git a/trunk/arch/arm/mach-at91/at91sam9261.c b/trunk/arch/arm/mach-at91/at91sam9261.c index 4d262f346fd9..8d999eb1a137 100644 --- a/trunk/arch/arm/mach-at91/at91sam9261.c +++ b/trunk/arch/arm/mach-at91/at91sam9261.c @@ -178,8 +178,8 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &hck0), - CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9261.0", &twi_clk), - CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.0", &twi_clk), + CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9261", &twi_clk), + CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10", &twi_clk), CLKDEV_CON_ID("pioA", &pioA_clk), CLKDEV_CON_ID("pioB", &pioB_clk), CLKDEV_CON_ID("pioC", &pioC_clk), @@ -334,10 +334,10 @@ static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller */ }; -AT91_SOC_START(sam9261) +struct at91_init_soc __initdata at91sam9261_soc = { .map_io = at91sam9261_map_io, .default_irq_priority = at91sam9261_default_irq_priority, .ioremap_registers = at91sam9261_ioremap_registers, .register_clocks = at91sam9261_register_clocks, .init = at91sam9261_initialize, -AT91_SOC_END +}; diff --git a/trunk/arch/arm/mach-at91/at91sam9261_devices.c b/trunk/arch/arm/mach-at91/at91sam9261_devices.c index cd604aad8e96..9752f17efba9 100644 --- a/trunk/arch/arm/mach-at91/at91sam9261_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9261_devices.c @@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable overcurrent notification */ for (i = 0; i < data->ports; i++) { - if (gpio_is_valid(data->overcurrent_pin[i])) + if (data->overcurrent_pin[i]) at91_set_gpio_input(data->overcurrent_pin[i], 1); } @@ -285,7 +285,7 @@ static struct i2c_gpio_platform_data pdata = { static struct platform_device at91sam9261_twi_device = { .name = "i2c-gpio", - .id = 0, + .id = -1, .dev.platform_data = &pdata, }; @@ -317,7 +317,7 @@ static struct resource twi_resources[] = { }; static struct platform_device at91sam9261_twi_device = { - .id = 0, + .id = -1, .resource = twi_resources, .num_resources = ARRAY_SIZE(twi_resources), }; diff --git a/trunk/arch/arm/mach-at91/at91sam9263.c b/trunk/arch/arm/mach-at91/at91sam9263.c index ed390f6fa232..6a01d0360dfb 100644 --- a/trunk/arch/arm/mach-at91/at91sam9263.c +++ b/trunk/arch/arm/mach-at91/at91sam9263.c @@ -193,7 +193,7 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk), - CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260.0", &twi_clk), + CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260", &twi_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), CLKDEV_CON_ID("pioA", &pioA_clk), @@ -211,14 +211,7 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("hclk", "a00000.ohci", &ohci_clk), CLKDEV_CON_DEV_ID("spi_clk", "fffa4000.spi", &spi0_clk), CLKDEV_CON_DEV_ID("spi_clk", "fffa8000.spi", &spi1_clk), - CLKDEV_CON_DEV_ID("mci_clk", "fff80000.mmc", &mmc0_clk), - CLKDEV_CON_DEV_ID("mci_clk", "fff84000.mmc", &mmc1_clk), CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioB_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioCDE_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCDE_clk), - CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioCDE_clk), }; static struct clk_lookup usart_clocks_lookups[] = { @@ -372,10 +365,10 @@ static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller (IRQ1) */ }; -AT91_SOC_START(sam9263) +struct at91_init_soc __initdata at91sam9263_soc = { .map_io = at91sam9263_map_io, .default_irq_priority = at91sam9263_default_irq_priority, .ioremap_registers = at91sam9263_ioremap_registers, .register_clocks = at91sam9263_register_clocks, .init = at91sam9263_initialize, -AT91_SOC_END +}; diff --git a/trunk/arch/arm/mach-at91/at91sam9263_devices.c b/trunk/arch/arm/mach-at91/at91sam9263_devices.c index 9c61e59a2104..8dde220b42b6 100644 --- a/trunk/arch/arm/mach-at91/at91sam9263_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9263_devices.c @@ -78,7 +78,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable overcurrent notification */ for (i = 0; i < data->ports; i++) { - if (gpio_is_valid(data->overcurrent_pin[i])) + if (data->overcurrent_pin[i]) at91_set_gpio_input(data->overcurrent_pin[i], 1); } @@ -567,7 +567,7 @@ static struct i2c_gpio_platform_data pdata = { static struct platform_device at91sam9263_twi_device = { .name = "i2c-gpio", - .id = 0, + .id = -1, .dev.platform_data = &pdata, }; @@ -600,7 +600,7 @@ static struct resource twi_resources[] = { static struct platform_device at91sam9263_twi_device = { .name = "i2c-at91sam9260", - .id = 0, + .id = -1, .resource = twi_resources, .num_resources = ARRAY_SIZE(twi_resources), }; diff --git a/trunk/arch/arm/mach-at91/at91sam9g45.c b/trunk/arch/arm/mach-at91/at91sam9g45.c index c5c2acc4bf22..84af1b506d92 100644 --- a/trunk/arch/arm/mach-at91/at91sam9g45.c +++ b/trunk/arch/arm/mach-at91/at91sam9g45.c @@ -256,18 +256,10 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("t0_clk", "fffd4000.timer", &tcb0_clk), CLKDEV_CON_DEV_ID("hclk", "700000.ohci", &uhphs_clk), CLKDEV_CON_DEV_ID("ehci_clk", "800000.ehci", &uhphs_clk), - CLKDEV_CON_DEV_ID("mci_clk", "fff80000.mmc", &mmc0_clk), - CLKDEV_CON_DEV_ID("mci_clk", "fffd0000.mmc", &mmc1_clk), CLKDEV_CON_DEV_ID(NULL, "fff84000.i2c", &twi0_clk), CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi1_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioB_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioC_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioDE_clk), - CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioDE_clk), - CLKDEV_CON_ID("pioA", &pioA_clk), CLKDEV_CON_ID("pioB", &pioB_clk), CLKDEV_CON_ID("pioC", &pioC_clk), @@ -417,10 +409,10 @@ static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller (IRQ0) */ }; -AT91_SOC_START(sam9g45) +struct at91_init_soc __initdata at91sam9g45_soc = { .map_io = at91sam9g45_map_io, .default_irq_priority = at91sam9g45_default_irq_priority, .ioremap_registers = at91sam9g45_ioremap_registers, .register_clocks = at91sam9g45_register_clocks, .init = at91sam9g45_initialize, -AT91_SOC_END +}; diff --git a/trunk/arch/arm/mach-at91/at91sam9g45_devices.c b/trunk/arch/arm/mach-at91/at91sam9g45_devices.c index fcd233cb33d2..b1596072dcc2 100644 --- a/trunk/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9g45_devices.c @@ -1841,8 +1841,8 @@ static struct resource sha_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, + .start = AT91SAM9G45_ID_AESTDESSHA, + .end = AT91SAM9G45_ID_AESTDESSHA, .flags = IORESOURCE_IRQ, }, }; @@ -1874,8 +1874,8 @@ static struct resource tdes_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, + .start = AT91SAM9G45_ID_AESTDESSHA, + .end = AT91SAM9G45_ID_AESTDESSHA, .flags = IORESOURCE_IRQ, }, }; @@ -1910,8 +1910,8 @@ static struct resource aes_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, - .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, + .start = AT91SAM9G45_ID_AESTDESSHA, + .end = AT91SAM9G45_ID_AESTDESSHA, .flags = IORESOURCE_IRQ, }, }; diff --git a/trunk/arch/arm/mach-at91/at91sam9n12.c b/trunk/arch/arm/mach-at91/at91sam9n12.c index 70b3a99244ab..732d3d3f4ec5 100644 --- a/trunk/arch/arm/mach-at91/at91sam9n12.c +++ b/trunk/arch/arm/mach-at91/at91sam9n12.c @@ -168,14 +168,13 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk), CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb_clk), CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb_clk), - CLKDEV_CON_DEV_ID("mci_clk", "f0008000.mmc", &mmc_clk), CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma_clk), CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk), CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioAB_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioAB_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCD_clk), - CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioCD_clk), + CLKDEV_CON_ID("pioA", &pioAB_clk), + CLKDEV_CON_ID("pioB", &pioAB_clk), + CLKDEV_CON_ID("pioC", &pioCD_clk), + CLKDEV_CON_ID("pioD", &pioCD_clk), /* additional fake clock for macb_hclk */ CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &uhp_clk), CLKDEV_CON_DEV_ID("ohci_clk", "500000.ohci", &uhp_clk), @@ -224,10 +223,13 @@ static void __init at91sam9n12_map_io(void) void __init at91sam9n12_initialize(void) { at91_extern_irq = (1 << AT91SAM9N12_ID_IRQ0); + + /* Register GPIO subsystem (using DT) */ + at91_gpio_init(NULL, 0); } -AT91_SOC_START(sam9n12) +struct at91_init_soc __initdata at91sam9n12_soc = { .map_io = at91sam9n12_map_io, .register_clocks = at91sam9n12_register_clocks, .init = at91sam9n12_initialize, -AT91_SOC_END +}; diff --git a/trunk/arch/arm/mach-at91/at91sam9rl.c b/trunk/arch/arm/mach-at91/at91sam9rl.c index cbe72e44c13f..72e908412222 100644 --- a/trunk/arch/arm/mach-at91/at91sam9rl.c +++ b/trunk/arch/arm/mach-at91/at91sam9rl.c @@ -338,10 +338,10 @@ static unsigned int at91sam9rl_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller */ }; -AT91_SOC_START(sam9rl) +struct at91_init_soc __initdata at91sam9rl_soc = { .map_io = at91sam9rl_map_io, .default_irq_priority = at91sam9rl_default_irq_priority, .ioremap_registers = at91sam9rl_ioremap_registers, .register_clocks = at91sam9rl_register_clocks, .init = at91sam9rl_initialize, -AT91_SOC_END +}; diff --git a/trunk/arch/arm/mach-at91/at91sam9rl_devices.c b/trunk/arch/arm/mach-at91/at91sam9rl_devices.c index 5047bdc92adf..d6ca0543ce8d 100644 --- a/trunk/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9rl_devices.c @@ -314,7 +314,7 @@ static struct i2c_gpio_platform_data pdata = { static struct platform_device at91sam9rl_twi_device = { .name = "i2c-gpio", - .id = 0, + .id = -1, .dev.platform_data = &pdata, }; @@ -347,7 +347,7 @@ static struct resource twi_resources[] = { static struct platform_device at91sam9rl_twi_device = { .name = "i2c-at91sam9g20", - .id = 0, + .id = -1, .resource = twi_resources, .num_resources = ARRAY_SIZE(twi_resources), }; diff --git a/trunk/arch/arm/mach-at91/at91sam9x5.c b/trunk/arch/arm/mach-at91/at91sam9x5.c index 3c729f0e2d3c..e5035380dcbc 100644 --- a/trunk/arch/arm/mach-at91/at91sam9x5.c +++ b/trunk/arch/arm/mach-at91/at91sam9x5.c @@ -229,17 +229,15 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk), CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb0_clk), CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk), - CLKDEV_CON_DEV_ID("mci_clk", "f0008000.mmc", &mmc0_clk), - CLKDEV_CON_DEV_ID("mci_clk", "f000c000.mmc", &mmc1_clk), CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma0_clk), CLKDEV_CON_DEV_ID("dma_clk", "ffffee00.dma-controller", &dma1_clk), CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk), CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk), CLKDEV_CON_DEV_ID(NULL, "f8018000.i2c", &twi2_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioAB_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioAB_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCD_clk), - CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioCD_clk), + CLKDEV_CON_ID("pioA", &pioAB_clk), + CLKDEV_CON_ID("pioB", &pioAB_clk), + CLKDEV_CON_ID("pioC", &pioCD_clk), + CLKDEV_CON_ID("pioD", &pioCD_clk), /* additional fake clock for macb_hclk */ CLKDEV_CON_DEV_ID("hclk", "f802c000.ethernet", &macb0_clk), CLKDEV_CON_DEV_ID("hclk", "f8030000.ethernet", &macb1_clk), @@ -315,11 +313,18 @@ static void __init at91sam9x5_map_io(void) at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE); } +void __init at91sam9x5_initialize(void) +{ + /* Register GPIO subsystem (using DT) */ + at91_gpio_init(NULL, 0); +} + /* -------------------------------------------------------------------- * Interrupt initialization * -------------------------------------------------------------------- */ -AT91_SOC_START(sam9x5) +struct at91_init_soc __initdata at91sam9x5_soc = { .map_io = at91sam9x5_map_io, .register_clocks = at91sam9x5_register_clocks, -AT91_SOC_END + .init = at91sam9x5_initialize, +}; diff --git a/trunk/arch/arm/mach-at91/at91x40.c b/trunk/arch/arm/mach-at91/at91x40.c index bb7f54474b92..6bd7300a2bc5 100644 --- a/trunk/arch/arm/mach-at91/at91x40.c +++ b/trunk/arch/arm/mach-at91/at91x40.c @@ -88,6 +88,6 @@ void __init at91x40_init_interrupts(unsigned int priority[NR_AIC_IRQS]) if (!priority) priority = at91x40_default_irq_priority; - at91_aic_init(priority, at91_extern_irq); + at91_aic_init(priority); } diff --git a/trunk/arch/arm/mach-at91/board-dt.c b/trunk/arch/arm/mach-at91/board-dt.c index 3b6a94820fa0..e8f45c4e0ea8 100644 --- a/trunk/arch/arm/mach-at91/board-dt.c +++ b/trunk/arch/arm/mach-at91/board-dt.c @@ -30,6 +30,8 @@ static const struct of_device_id irq_of_match[] __initconst = { { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init }, + { .compatible = "atmel,at91rm9200-gpio", .data = at91_gpio_of_irq_setup }, + { .compatible = "atmel,at91sam9x5-gpio", .data = at91_gpio_of_irq_setup }, { /*sentinel*/ } }; diff --git a/trunk/arch/arm/mach-at91/board-neocore926.c b/trunk/arch/arm/mach-at91/board-neocore926.c index 6960778af4c2..9cda3fd346ae 100644 --- a/trunk/arch/arm/mach-at91/board-neocore926.c +++ b/trunk/arch/arm/mach-at91/board-neocore926.c @@ -129,7 +129,7 @@ static struct spi_board_info neocore926_spi_devices[] = { .max_speed_hz = 125000 * 16, .bus_num = 0, .platform_data = &ads_info, - .irq = NR_IRQS_LEGACY + AT91SAM9263_ID_IRQ1, + .irq = AT91SAM9263_ID_IRQ1, }, #endif }; diff --git a/trunk/arch/arm/mach-at91/board-rm9200-dt.c b/trunk/arch/arm/mach-at91/board-rm9200-dt.c deleted file mode 100644 index 5f9ce3da3fde..000000000000 --- a/trunk/arch/arm/mach-at91/board-rm9200-dt.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Setup code for AT91RM9200 Evaluation Kits with Device Tree support - * - * Copyright (C) 2011 Atmel, - * 2011 Nicolas Ferre - * 2012 Joachim Eastwood - * - * Licensed under GPLv2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "at91_aic.h" -#include "generic.h" - - -static const struct of_device_id irq_of_match[] __initconst = { - { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init }, - { /*sentinel*/ } -}; - -static void __init at91rm9200_dt_init_irq(void) -{ - of_irq_init(irq_of_match); -} - -static void __init at91rm9200_dt_device_init(void) -{ - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); -} - -static const char *at91rm9200_dt_board_compat[] __initdata = { - "atmel,at91rm9200", - NULL -}; - -DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)") - .timer = &at91rm9200_timer, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = at91rm9200_dt_initialize, - .init_irq = at91rm9200_dt_init_irq, - .init_machine = at91rm9200_dt_device_init, - .dt_compat = at91rm9200_dt_board_compat, -MACHINE_END diff --git a/trunk/arch/arm/mach-at91/board-sam9261ek.c b/trunk/arch/arm/mach-at91/board-sam9261ek.c index a9167dd45f96..27b3af1a3047 100644 --- a/trunk/arch/arm/mach-at91/board-sam9261ek.c +++ b/trunk/arch/arm/mach-at91/board-sam9261ek.c @@ -309,7 +309,7 @@ static struct spi_board_info ek_spi_devices[] = { .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ .bus_num = 0, .platform_data = &ads_info, - .irq = NR_IRQS_LEGACY + AT91SAM9261_ID_IRQ0, + .irq = AT91SAM9261_ID_IRQ0, .controller_data = (void *) AT91_PIN_PA28, /* CS pin */ }, #endif diff --git a/trunk/arch/arm/mach-at91/board-sam9263ek.c b/trunk/arch/arm/mach-at91/board-sam9263ek.c index b87dbe2be0d6..073e17403d98 100644 --- a/trunk/arch/arm/mach-at91/board-sam9263ek.c +++ b/trunk/arch/arm/mach-at91/board-sam9263ek.c @@ -132,7 +132,7 @@ static struct spi_board_info ek_spi_devices[] = { .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ .bus_num = 0, .platform_data = &ads_info, - .irq = NR_IRQS_LEGACY + AT91SAM9263_ID_IRQ1, + .irq = AT91SAM9263_ID_IRQ1, }, #endif }; diff --git a/trunk/arch/arm/mach-at91/generic.h b/trunk/arch/arm/mach-at91/generic.h index fc593d615e7d..f49650677653 100644 --- a/trunk/arch/arm/mach-at91/generic.h +++ b/trunk/arch/arm/mach-at91/generic.h @@ -20,15 +20,13 @@ extern void __init at91_init_sram(int bank, unsigned long base, extern void __init at91rm9200_set_type(int type); extern void __init at91_initialize(unsigned long main_clock); extern void __init at91x40_initialize(unsigned long main_clock); -extern void __init at91rm9200_dt_initialize(void); extern void __init at91_dt_initialize(void); /* Interrupts */ extern void __init at91_init_irq_default(void); extern void __init at91_init_interrupts(unsigned int priority[]); extern void __init at91x40_init_interrupts(unsigned int priority[]); -extern void __init at91_aic_init(unsigned int priority[], - unsigned int ext_irq_mask); +extern void __init at91_aic_init(unsigned int priority[]); extern int __init at91_aic_of_init(struct device_node *node, struct device_node *parent); extern int __init at91_aic5_of_init(struct device_node *node, diff --git a/trunk/arch/arm/mach-at91/gpio.c b/trunk/arch/arm/mach-at91/gpio.c index c5d7e1e9d757..be42cf0e74bd 100644 --- a/trunk/arch/arm/mach-at91/gpio.c +++ b/trunk/arch/arm/mach-at91/gpio.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include @@ -31,8 +33,6 @@ #include "generic.h" -#define MAX_NB_GPIO_PER_BANK 32 - struct at91_gpio_chip { struct gpio_chip chip; struct at91_gpio_chip *next; /* Bank sharing same clock */ @@ -46,7 +46,6 @@ struct at91_gpio_chip { #define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip) -static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset); static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip); static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val); static int at91_gpiolib_get(struct gpio_chip *chip, unsigned offset); @@ -56,27 +55,26 @@ static int at91_gpiolib_direction_input(struct gpio_chip *chip, unsigned offset); static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset); -#define AT91_GPIO_CHIP(name) \ +#define AT91_GPIO_CHIP(name, nr_gpio) \ { \ .chip = { \ .label = name, \ - .request = at91_gpiolib_request, \ .direction_input = at91_gpiolib_direction_input, \ .direction_output = at91_gpiolib_direction_output, \ .get = at91_gpiolib_get, \ .set = at91_gpiolib_set, \ .dbg_show = at91_gpiolib_dbg_show, \ .to_irq = at91_gpiolib_to_irq, \ - .ngpio = MAX_NB_GPIO_PER_BANK, \ + .ngpio = nr_gpio, \ }, \ } static struct at91_gpio_chip gpio_chip[] = { - AT91_GPIO_CHIP("pioA"), - AT91_GPIO_CHIP("pioB"), - AT91_GPIO_CHIP("pioC"), - AT91_GPIO_CHIP("pioD"), - AT91_GPIO_CHIP("pioE"), + AT91_GPIO_CHIP("pioA", 32), + AT91_GPIO_CHIP("pioB", 32), + AT91_GPIO_CHIP("pioC", 32), + AT91_GPIO_CHIP("pioD", 32), + AT91_GPIO_CHIP("pioE", 32), }; static int gpio_banks; @@ -91,7 +89,7 @@ static unsigned long at91_gpio_caps; static inline void __iomem *pin_to_controller(unsigned pin) { - pin /= MAX_NB_GPIO_PER_BANK; + pin /= 32; if (likely(pin < gpio_banks)) return gpio_chip[pin].regbase; @@ -100,7 +98,7 @@ static inline void __iomem *pin_to_controller(unsigned pin) static inline unsigned pin_to_mask(unsigned pin) { - return 1 << (pin % MAX_NB_GPIO_PER_BANK); + return 1 << (pin % 32); } @@ -715,6 +713,80 @@ postcore_initcall(at91_gpio_debugfs_init); */ static struct lock_class_key gpio_lock_class; +#if defined(CONFIG_OF) +static int at91_gpio_irq_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) +{ + struct at91_gpio_chip *at91_gpio = h->host_data; + + irq_set_lockdep_class(virq, &gpio_lock_class); + + /* + * Can use the "simple" and not "edge" handler since it's + * shorter, and the AIC handles interrupts sanely. + */ + irq_set_chip_and_handler(virq, &gpio_irqchip, + handle_simple_irq); + set_irq_flags(virq, IRQF_VALID); + irq_set_chip_data(virq, at91_gpio); + + return 0; +} + +static struct irq_domain_ops at91_gpio_ops = { + .map = at91_gpio_irq_map, + .xlate = irq_domain_xlate_twocell, +}; + +int __init at91_gpio_of_irq_setup(struct device_node *node, + struct device_node *parent) +{ + struct at91_gpio_chip *prev = NULL; + int alias_idx = of_alias_get_id(node, "gpio"); + struct at91_gpio_chip *at91_gpio = &gpio_chip[alias_idx]; + + /* Setup proper .irq_set_type function */ + if (has_pio3()) + gpio_irqchip.irq_set_type = alt_gpio_irq_type; + else + gpio_irqchip.irq_set_type = gpio_irq_type; + + /* Disable irqs of this PIO controller */ + __raw_writel(~0, at91_gpio->regbase + PIO_IDR); + + /* Setup irq domain */ + at91_gpio->domain = irq_domain_add_linear(node, at91_gpio->chip.ngpio, + &at91_gpio_ops, at91_gpio); + if (!at91_gpio->domain) + panic("at91_gpio.%d: couldn't allocate irq domain (DT).\n", + at91_gpio->pioc_idx); + + /* Setup chained handler */ + if (at91_gpio->pioc_idx) + prev = &gpio_chip[at91_gpio->pioc_idx - 1]; + + /* The toplevel handler handles one bank of GPIOs, except + * on some SoC it can handles up to three... + * We only set up the handler for the first of the list. + */ + if (prev && prev->next == at91_gpio) + return 0; + + at91_gpio->pioc_virq = irq_create_mapping(irq_find_host(parent), + at91_gpio->pioc_hwirq); + irq_set_chip_data(at91_gpio->pioc_virq, at91_gpio); + irq_set_chained_handler(at91_gpio->pioc_virq, gpio_irq_handler); + + return 0; +} +#else +int __init at91_gpio_of_irq_setup(struct device_node *node, + struct device_node *parent) +{ + return -EINVAL; +} +#endif + /* * irqdomain initialization: pile up irqdomains on top of AIC range */ @@ -790,16 +862,6 @@ void __init at91_gpio_irq_setup(void) } /* gpiolib support */ -static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset) -{ - struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); - void __iomem *pio = at91_gpio->regbase; - unsigned mask = 1 << offset; - - __raw_writel(mask, pio + PIO_PER); - return 0; -} - static int at91_gpiolib_direction_input(struct gpio_chip *chip, unsigned offset) { @@ -913,11 +975,81 @@ static int __init at91_gpio_setup_clk(int idx) return -EINVAL; } +#ifdef CONFIG_OF_GPIO +static void __init of_at91_gpio_init_one(struct device_node *np) +{ + int alias_idx; + struct at91_gpio_chip *at91_gpio; + + if (!np) + return; + + alias_idx = of_alias_get_id(np, "gpio"); + if (alias_idx >= MAX_GPIO_BANKS) { + pr_err("at91_gpio, failed alias idx(%d) > MAX_GPIO_BANKS(%d), ignoring.\n", + alias_idx, MAX_GPIO_BANKS); + return; + } + + at91_gpio = &gpio_chip[alias_idx]; + at91_gpio->chip.base = alias_idx * at91_gpio->chip.ngpio; + + at91_gpio->regbase = of_iomap(np, 0); + if (!at91_gpio->regbase) { + pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", + alias_idx); + return; + } + + /* Get the interrupts property */ + if (of_property_read_u32(np, "interrupts", &at91_gpio->pioc_hwirq)) { + pr_err("at91_gpio.%d, failed to get interrupts property, ignoring.\n", + alias_idx); + goto ioremap_err; + } + + /* Get capabilities from compatibility property */ + if (of_device_is_compatible(np, "atmel,at91sam9x5-gpio")) + at91_gpio_caps |= AT91_GPIO_CAP_PIO3; + + /* Setup clock */ + if (at91_gpio_setup_clk(alias_idx)) + goto ioremap_err; + + at91_gpio->chip.of_node = np; + gpio_banks = max(gpio_banks, alias_idx + 1); + at91_gpio->pioc_idx = alias_idx; + return; + +ioremap_err: + iounmap(at91_gpio->regbase); +} + +static int __init of_at91_gpio_init(void) +{ + struct device_node *np = NULL; + + /* + * This isn't ideal, but it gets things hooked up until this + * driver is converted into a platform_device + */ + for_each_compatible_node(np, NULL, "atmel,at91rm9200-gpio") + of_at91_gpio_init_one(np); + + return gpio_banks > 0 ? 0 : -EINVAL; +} +#else +static int __init of_at91_gpio_init(void) +{ + return -EINVAL; +} +#endif + static void __init at91_gpio_init_one(int idx, u32 regbase, int pioc_hwirq) { struct at91_gpio_chip *at91_gpio = &gpio_chip[idx]; - at91_gpio->chip.base = idx * MAX_NB_GPIO_PER_BANK; + at91_gpio->chip.base = idx * at91_gpio->chip.ngpio; at91_gpio->pioc_hwirq = pioc_hwirq; at91_gpio->pioc_idx = idx; @@ -947,11 +1079,11 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) BUG_ON(nr_banks > MAX_GPIO_BANKS); - if (of_have_populated_dt()) - return; - - for (i = 0; i < nr_banks; i++) - at91_gpio_init_one(i, data[i].regbase, data[i].id); + if (of_at91_gpio_init() < 0) { + /* No GPIO controller found in device tree */ + for (i = 0; i < nr_banks; i++) + at91_gpio_init_one(i, data[i].regbase, data[i].id); + } for (i = 0; i < gpio_banks; i++) { at91_gpio = &gpio_chip[i]; diff --git a/trunk/arch/arm/mach-at91/include/mach/board.h b/trunk/arch/arm/mach-at91/include/mach/board.h index a0d92a960f46..c55a4364ffb4 100644 --- a/trunk/arch/arm/mach-at91/include/mach/board.h +++ b/trunk/arch/arm/mach-at91/include/mach/board.h @@ -70,6 +70,16 @@ struct at91_cf_data { extern void __init at91_add_device_cf(struct at91_cf_data *data); /* MMC / SD */ + /* at91_mci platform config */ +struct at91_mmc_data { + int det_pin; /* card detect IRQ */ + unsigned slot_b:1; /* uses Slot B */ + unsigned wire4:1; /* (SD) supports DAT0..DAT3 */ + int wp_pin; /* (SD) writeprotect detect */ + int vcc_pin; /* power switching (high == on) */ +}; +extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data); + /* atmel-mci platform config */ extern void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data); diff --git a/trunk/arch/arm/mach-at91/irq.c b/trunk/arch/arm/mach-at91/irq.c index febc2ee901a5..1e02c0e49dcc 100644 --- a/trunk/arch/arm/mach-at91/irq.c +++ b/trunk/arch/arm/mach-at91/irq.c @@ -502,19 +502,14 @@ int __init at91_aic5_of_init(struct device_node *node, /* * Initialize the AIC interrupt controller. */ -void __init at91_aic_init(unsigned int *priority, unsigned int ext_irq_mask) +void __init at91_aic_init(unsigned int *priority) { unsigned int i; int irq_base; - at91_extern_irq = kzalloc(BITS_TO_LONGS(n_irqs) - * sizeof(*at91_extern_irq), GFP_KERNEL); - - if (at91_aic_pm_init() || at91_extern_irq == NULL) + if (at91_aic_pm_init()) panic("Unable to allocate bit maps\n"); - *at91_extern_irq = ext_irq_mask; - at91_aic_base = ioremap(AT91_AIC, 512); if (!at91_aic_base) panic("Unable to ioremap AIC registers\n"); diff --git a/trunk/arch/arm/mach-at91/setup.c b/trunk/arch/arm/mach-at91/setup.c index 19cdd0b5b391..da9881b161e1 100644 --- a/trunk/arch/arm/mach-at91/setup.c +++ b/trunk/arch/arm/mach-at91/setup.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include @@ -48,7 +47,7 @@ void __init at91_init_irq_default(void) void __init at91_init_interrupts(unsigned int *priority) { /* Initialize the AIC interrupt controller */ - at91_aic_init(priority, at91_extern_irq); + at91_aic_init(priority); /* Enable GPIO interrupts */ at91_gpio_irq_setup(); @@ -152,7 +151,7 @@ static void __init soc_detect(u32 dbgu_base) } /* at91sam9g10 */ - if ((socid & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) { + if ((cidr & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) { at91_soc_initdata.type = AT91_SOC_SAM9G10; at91_boot_soc = at91sam9261_soc; } @@ -339,7 +338,6 @@ static void at91_dt_rstc(void) } static struct of_device_id ramc_ids[] = { - { .compatible = "atmel,at91rm9200-sdramc" }, { .compatible = "atmel,at91sam9260-sdramc" }, { .compatible = "atmel,at91sam9g45-ddramc" }, { /*sentinel*/ } @@ -438,19 +436,6 @@ static void at91_dt_shdwc(void) of_node_put(np); } -void __init at91rm9200_dt_initialize(void) -{ - at91_dt_ramc(); - - /* Init clock subsystem */ - at91_dt_clock_init(); - - /* Register the processor-specific clocks */ - at91_boot_soc.register_clocks(); - - at91_boot_soc.init(); -} - void __init at91_dt_initialize(void) { at91_dt_rstc(); @@ -463,8 +448,7 @@ void __init at91_dt_initialize(void) /* Register the processor-specific clocks */ at91_boot_soc.register_clocks(); - if (at91_boot_soc.init) - at91_boot_soc.init(); + at91_boot_soc.init(); } #endif @@ -479,6 +463,4 @@ void __init at91_initialize(unsigned long main_clock) at91_boot_soc.register_clocks(); at91_boot_soc.init(); - - pinctrl_provide_dummies(); } diff --git a/trunk/arch/arm/mach-at91/soc.h b/trunk/arch/arm/mach-at91/soc.h index 9c6d3d4f9a23..a9cfeb153719 100644 --- a/trunk/arch/arm/mach-at91/soc.h +++ b/trunk/arch/arm/mach-at91/soc.h @@ -5,7 +5,6 @@ */ struct at91_init_soc { - int builtin; unsigned int *default_irq_priority; void (*map_io)(void); void (*ioremap_registers)(void); @@ -23,18 +22,9 @@ extern struct at91_init_soc at91sam9rl_soc; extern struct at91_init_soc at91sam9x5_soc; extern struct at91_init_soc at91sam9n12_soc; -#define AT91_SOC_START(_name) \ -struct at91_init_soc __initdata at91##_name##_soc \ - __used \ - = { \ - .builtin = 1, \ - -#define AT91_SOC_END \ -}; - static inline int at91_soc_is_enabled(void) { - return at91_boot_soc.builtin; + return at91_boot_soc.init != NULL; } #if !defined(CONFIG_SOC_AT91RM9200) diff --git a/trunk/arch/arm/mach-davinci/dm644x.c b/trunk/arch/arm/mach-davinci/dm644x.c index 14e9947bad6e..cd0c8b1e1ecf 100644 --- a/trunk/arch/arm/mach-davinci/dm644x.c +++ b/trunk/arch/arm/mach-davinci/dm644x.c @@ -713,7 +713,8 @@ static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type, break; case VPBE_ENC_CUSTOM_TIMINGS: if (pclock <= 27000000) { - v |= DM644X_VPSS_DACCLKEN; + v |= DM644X_VPSS_MUXSEL_PLL2_MODE | + DM644X_VPSS_DACCLKEN; writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL)); } else { /* diff --git a/trunk/arch/arm/mach-dove/include/mach/pm.h b/trunk/arch/arm/mach-dove/include/mach/pm.h index b47f75038686..7bcd0dfce4b1 100644 --- a/trunk/arch/arm/mach-dove/include/mach/pm.h +++ b/trunk/arch/arm/mach-dove/include/mach/pm.h @@ -63,7 +63,7 @@ static inline int pmu_to_irq(int pin) static inline int irq_to_pmu(int irq) { - if (IRQ_DOVE_PMU_START <= irq && irq < NR_IRQS) + if (IRQ_DOVE_PMU_START < irq && irq < NR_IRQS) return irq - IRQ_DOVE_PMU_START; return -EINVAL; diff --git a/trunk/arch/arm/mach-dove/irq.c b/trunk/arch/arm/mach-dove/irq.c index bc4344aa1009..087711524e8a 100644 --- a/trunk/arch/arm/mach-dove/irq.c +++ b/trunk/arch/arm/mach-dove/irq.c @@ -46,20 +46,8 @@ static void pmu_irq_ack(struct irq_data *d) int pin = irq_to_pmu(d->irq); u32 u; - /* - * The PMU mask register is not RW0C: it is RW. This means that - * the bits take whatever value is written to them; if you write - * a '1', you will set the interrupt. - * - * Unfortunately this means there is NO race free way to clear - * these interrupts. - * - * So, let's structure the code so that the window is as small as - * possible. - */ u = ~(1 << (pin & 31)); - u &= readl_relaxed(PMU_INTERRUPT_CAUSE); - writel_relaxed(u, PMU_INTERRUPT_CAUSE); + writel(u, PMU_INTERRUPT_CAUSE); } static struct irq_chip pmu_irq_chip = { diff --git a/trunk/arch/arm/mach-exynos/common.c b/trunk/arch/arm/mach-exynos/common.c index 1947be8e5f5b..715b690e5009 100644 --- a/trunk/arch/arm/mach-exynos/common.c +++ b/trunk/arch/arm/mach-exynos/common.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include "common.h" @@ -347,8 +346,6 @@ static void __init exynos4_map_io(void) s5p_fb_setname(0, "exynos4-fb"); s5p_hdmi_setname("exynos4-hdmi"); - - s3c64xx_spi_setname("exynos4210-spi"); } static void __init exynos5_map_io(void) @@ -369,8 +366,6 @@ static void __init exynos5_map_io(void) s3c_i2c0_setname("s3c2440-i2c"); s3c_i2c1_setname("s3c2440-i2c"); s3c_i2c2_setname("s3c2440-i2c"); - - s3c64xx_spi_setname("exynos4210-spi"); } static void __init exynos4_init_clocks(int xtal) diff --git a/trunk/arch/arm/mach-exynos/dma.c b/trunk/arch/arm/mach-exynos/dma.c index 87e07d6fc615..21d568b3b149 100644 --- a/trunk/arch/arm/mach-exynos/dma.c +++ b/trunk/arch/arm/mach-exynos/dma.c @@ -275,9 +275,6 @@ static int __init exynos_dma_init(void) exynos_pdma1_pdata.nr_valid_peri = ARRAY_SIZE(exynos4210_pdma1_peri); exynos_pdma1_pdata.peri_id = exynos4210_pdma1_peri; - - if (samsung_rev() == EXYNOS4210_REV_0) - exynos_mdma1_device.res.start = EXYNOS4_PA_S_MDMA1; } else if (soc_is_exynos4212() || soc_is_exynos4412()) { exynos_pdma0_pdata.nr_valid_peri = ARRAY_SIZE(exynos4212_pdma0_peri); diff --git a/trunk/arch/arm/mach-exynos/include/mach/map.h b/trunk/arch/arm/mach-exynos/include/mach/map.h index ed4da4544cd2..8480849affb9 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/map.h +++ b/trunk/arch/arm/mach-exynos/include/mach/map.h @@ -90,7 +90,6 @@ #define EXYNOS4_PA_MDMA0 0x10810000 #define EXYNOS4_PA_MDMA1 0x12850000 -#define EXYNOS4_PA_S_MDMA1 0x12840000 #define EXYNOS4_PA_PDMA0 0x12680000 #define EXYNOS4_PA_PDMA1 0x12690000 #define EXYNOS5_PA_MDMA0 0x10800000 diff --git a/trunk/arch/arm/mach-exynos/mach-exynos4-dt.c b/trunk/arch/arm/mach-exynos/mach-exynos4-dt.c index eadf4b59e7d2..e58d786faf78 100644 --- a/trunk/arch/arm/mach-exynos/mach-exynos4-dt.c +++ b/trunk/arch/arm/mach-exynos/mach-exynos4-dt.c @@ -99,7 +99,6 @@ static char const *exynos4_dt_compat[] __initdata = { DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)") /* Maintainer: Thomas Abraham */ - .smp = smp_ops(exynos_smp_ops), .init_irq = exynos4_init_irq, .map_io = exynos4_dt_map_io, .handle_irq = gic_handle_irq, diff --git a/trunk/arch/arm/mach-highbank/system.c b/trunk/arch/arm/mach-highbank/system.c index 86e37cd9376c..82c27230d4a9 100644 --- a/trunk/arch/arm/mach-highbank/system.c +++ b/trunk/arch/arm/mach-highbank/system.c @@ -28,7 +28,6 @@ void highbank_restart(char mode, const char *cmd) hignbank_set_pwr_soft_reset(); scu_power_mode(scu_base_addr, SCU_PM_POWEROFF); - while (1) - cpu_do_idle(); + cpu_do_idle(); } diff --git a/trunk/arch/arm/mach-imx/clk-busy.c b/trunk/arch/arm/mach-imx/clk-busy.c index 1ab91b5209e6..1a7a8dd045a1 100644 --- a/trunk/arch/arm/mach-imx/clk-busy.c +++ b/trunk/arch/arm/mach-imx/clk-busy.c @@ -108,7 +108,7 @@ struct clk *imx_clk_busy_divider(const char *name, const char *parent_name, busy->div.hw.init = &init; clk = clk_register(NULL, &busy->div.hw); - if (IS_ERR(clk)) + if (!clk) kfree(busy); return clk; diff --git a/trunk/arch/arm/mach-imx/clk-gate2.c b/trunk/arch/arm/mach-imx/clk-gate2.c index cc49c7ae186e..3c1b8ff9a0a6 100644 --- a/trunk/arch/arm/mach-imx/clk-gate2.c +++ b/trunk/arch/arm/mach-imx/clk-gate2.c @@ -112,7 +112,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name, clk = clk_register(dev, &gate->hw); if (IS_ERR(clk)) - kfree(gate); + kfree(clk); return clk; } diff --git a/trunk/arch/arm/mach-imx/clk-imx25.c b/trunk/arch/arm/mach-imx/clk-imx25.c index 01e2f843bf2e..d20d4795f4ea 100644 --- a/trunk/arch/arm/mach-imx/clk-imx25.c +++ b/trunk/arch/arm/mach-imx/clk-imx25.c @@ -127,8 +127,8 @@ int __init mx25_clocks_init(void) clk[esdhc2_ipg_per] = imx_clk_gate("esdhc2_ipg_per", "per4", ccm(CCM_CGCR0), 4); clk[gpt_ipg_per] = imx_clk_gate("gpt_ipg_per", "per5", ccm(CCM_CGCR0), 5); clk[i2c_ipg_per] = imx_clk_gate("i2c_ipg_per", "per6", ccm(CCM_CGCR0), 6); - clk[lcdc_ipg_per] = imx_clk_gate("lcdc_ipg_per", "per7", ccm(CCM_CGCR0), 7); - clk[nfc_ipg_per] = imx_clk_gate("nfc_ipg_per", "per8", ccm(CCM_CGCR0), 8); + clk[lcdc_ipg_per] = imx_clk_gate("lcdc_ipg_per", "per8", ccm(CCM_CGCR0), 7); + clk[nfc_ipg_per] = imx_clk_gate("nfc_ipg_per", "ipg_per", ccm(CCM_CGCR0), 8); clk[ssi1_ipg_per] = imx_clk_gate("ssi1_ipg_per", "per13", ccm(CCM_CGCR0), 13); clk[ssi2_ipg_per] = imx_clk_gate("ssi2_ipg_per", "per14", ccm(CCM_CGCR0), 14); clk[uart_ipg_per] = imx_clk_gate("uart_ipg_per", "per15", ccm(CCM_CGCR0), 15); diff --git a/trunk/arch/arm/mach-imx/clk-imx27.c b/trunk/arch/arm/mach-imx/clk-imx27.c index 366e5d59d886..3b6b640eed24 100644 --- a/trunk/arch/arm/mach-imx/clk-imx27.c +++ b/trunk/arch/arm/mach-imx/clk-imx27.c @@ -109,7 +109,7 @@ int __init mx27_clocks_init(unsigned long fref) clk[per3_div] = imx_clk_divider("per3_div", "mpll_main2", CCM_PCDR1, 16, 6); clk[per4_div] = imx_clk_divider("per4_div", "mpll_main2", CCM_PCDR1, 24, 6); clk[vpu_sel] = imx_clk_mux("vpu_sel", CCM_CSCR, 21, 1, vpu_sel_clks, ARRAY_SIZE(vpu_sel_clks)); - clk[vpu_div] = imx_clk_divider("vpu_div", "vpu_sel", CCM_PCDR0, 10, 6); + clk[vpu_div] = imx_clk_divider("vpu_div", "vpu_sel", CCM_PCDR0, 10, 3); clk[usb_div] = imx_clk_divider("usb_div", "spll", CCM_CSCR, 28, 3); clk[cpu_sel] = imx_clk_mux("cpu_sel", CCM_CSCR, 15, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks)); clk[clko_sel] = imx_clk_mux("clko_sel", CCM_CCSR, 0, 5, clko_sel_clks, ARRAY_SIZE(clko_sel_clks)); @@ -121,7 +121,7 @@ int __init mx27_clocks_init(unsigned long fref) clk[ssi1_sel] = imx_clk_mux("ssi1_sel", CCM_CSCR, 22, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks)); clk[ssi2_sel] = imx_clk_mux("ssi2_sel", CCM_CSCR, 23, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks)); clk[ssi1_div] = imx_clk_divider("ssi1_div", "ssi1_sel", CCM_PCDR0, 16, 6); - clk[ssi2_div] = imx_clk_divider("ssi2_div", "ssi2_sel", CCM_PCDR0, 26, 6); + clk[ssi2_div] = imx_clk_divider("ssi2_div", "ssi2_sel", CCM_PCDR0, 26, 3); clk[clko_en] = imx_clk_gate("clko_en", "clko_div", CCM_PCCR0, 0); clk[ssi2_ipg_gate] = imx_clk_gate("ssi2_ipg_gate", "ipg", CCM_PCCR0, 0); clk[ssi1_ipg_gate] = imx_clk_gate("ssi1_ipg_gate", "ipg", CCM_PCCR0, 1); diff --git a/trunk/arch/arm/mach-imx/ehci-imx25.c b/trunk/arch/arm/mach-imx/ehci-imx25.c index 576af7446952..412c583a24b0 100644 --- a/trunk/arch/arm/mach-imx/ehci-imx25.c +++ b/trunk/arch/arm/mach-imx/ehci-imx25.c @@ -30,7 +30,7 @@ #define MX25_H1_SIC_SHIFT 21 #define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT) #define MX25_H1_PP_BIT (1 << 18) -#define MX25_H1_PM_BIT (1 << 16) +#define MX25_H1_PM_BIT (1 << 8) #define MX25_H1_IPPUE_UP_BIT (1 << 7) #define MX25_H1_IPPUE_DOWN_BIT (1 << 6) #define MX25_H1_TLL_BIT (1 << 5) diff --git a/trunk/arch/arm/mach-imx/ehci-imx35.c b/trunk/arch/arm/mach-imx/ehci-imx35.c index 293397852e4e..779e16eb65cb 100644 --- a/trunk/arch/arm/mach-imx/ehci-imx35.c +++ b/trunk/arch/arm/mach-imx/ehci-imx35.c @@ -30,7 +30,7 @@ #define MX35_H1_SIC_SHIFT 21 #define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT) #define MX35_H1_PP_BIT (1 << 18) -#define MX35_H1_PM_BIT (1 << 16) +#define MX35_H1_PM_BIT (1 << 8) #define MX35_H1_IPPUE_UP_BIT (1 << 7) #define MX35_H1_IPPUE_DOWN_BIT (1 << 6) #define MX35_H1_TLL_BIT (1 << 5) diff --git a/trunk/arch/arm/mach-imx/mm-imx3.c b/trunk/arch/arm/mach-imx/mm-imx3.c index b5deb0554552..9d2c843bde02 100644 --- a/trunk/arch/arm/mach-imx/mm-imx3.c +++ b/trunk/arch/arm/mach-imx/mm-imx3.c @@ -108,8 +108,9 @@ void __init imx3_init_l2x0(void) } l2x0_base = ioremap(MX3x_L2CC_BASE_ADDR, 4096); - if (!l2x0_base) { - printk(KERN_ERR "remapping L2 cache area failed\n"); + if (IS_ERR(l2x0_base)) { + printk(KERN_ERR "remapping L2 cache area failed with %ld\n", + PTR_ERR(l2x0_base)); return; } diff --git a/trunk/arch/arm/mach-integrator/impd1.c b/trunk/arch/arm/mach-integrator/impd1.c index b3d86d7081a0..e428f3ab15c7 100644 --- a/trunk/arch/arm/mach-integrator/impd1.c +++ b/trunk/arch/arm/mach-integrator/impd1.c @@ -21,9 +21,10 @@ #include #include #include -#include #include +#include +#include #include #include #include @@ -35,6 +36,45 @@ MODULE_PARM_DESC(lmid, "logic module stack position"); struct impd1_module { void __iomem *base; + struct clk vcos[2]; + struct clk_lookup *clks[3]; +}; + +static const struct icst_params impd1_vco_params = { + .ref = 24000000, /* 24 MHz */ + .vco_max = ICST525_VCO_MAX_3V, + .vco_min = ICST525_VCO_MIN, + .vd_min = 12, + .vd_max = 519, + .rd_min = 3, + .rd_max = 120, + .s2div = icst525_s2div, + .idx2s = icst525_idx2s, +}; + +static void impd1_setvco(struct clk *clk, struct icst_vco vco) +{ + struct impd1_module *impd1 = clk->data; + u32 val = vco.v | (vco.r << 9) | (vco.s << 16); + + writel(0xa05f, impd1->base + IMPD1_LOCK); + writel(val, clk->vcoreg); + writel(0, impd1->base + IMPD1_LOCK); + +#ifdef DEBUG + vco.v = val & 0x1ff; + vco.r = (val >> 9) & 0x7f; + vco.s = (val >> 16) & 7; + + pr_debug("IM-PD1: VCO%d clock is %ld Hz\n", + vconr, icst525_hz(&impd1_vco_params, vco)); +#endif +} + +static const struct clk_ops impd1_clk_ops = { + .round = icst_clk_round, + .set = icst_clk_set, + .setvco = impd1_setvco, }; void impd1_tweak_control(struct device *dev, u32 mask, u32 val) @@ -304,6 +344,10 @@ static struct impd1_device impd1_devs[] = { } }; +static struct clk fixed_14745600 = { + .rate = 14745600, +}; + static int impd1_probe(struct lm_device *dev) { struct impd1_module *impd1; @@ -332,7 +376,23 @@ static int impd1_probe(struct lm_device *dev) printk("IM-PD1 found at 0x%08lx\n", (unsigned long)dev->resource.start); - integrator_impd1_clk_init(impd1->base, dev->id); + for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) { + impd1->vcos[i].ops = &impd1_clk_ops, + impd1->vcos[i].owner = THIS_MODULE, + impd1->vcos[i].params = &impd1_vco_params, + impd1->vcos[i].data = impd1; + } + impd1->vcos[0].vcoreg = impd1->base + IMPD1_OSC1; + impd1->vcos[1].vcoreg = impd1->base + IMPD1_OSC2; + + impd1->clks[0] = clkdev_alloc(&impd1->vcos[0], NULL, "lm%x:01000", + dev->id); + impd1->clks[1] = clkdev_alloc(&fixed_14745600, NULL, "lm%x:00100", + dev->id); + impd1->clks[2] = clkdev_alloc(&fixed_14745600, NULL, "lm%x:00200", + dev->id); + for (i = 0; i < ARRAY_SIZE(impd1->clks); i++) + clkdev_add(impd1->clks[i]); for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) { struct impd1_device *idev = impd1_devs + i; @@ -371,9 +431,12 @@ static int impd1_remove_one(struct device *dev, void *data) static void impd1_remove(struct lm_device *dev) { struct impd1_module *impd1 = lm_get_drvdata(dev); + int i; device_for_each_child(&dev->dev, NULL, impd1_remove_one); - integrator_impd1_clk_exit(dev->id); + + for (i = 0; i < ARRAY_SIZE(impd1->clks); i++) + clkdev_drop(impd1->clks[i]); lm_set_drvdata(dev, NULL); diff --git a/trunk/arch/arm/mach-ixp4xx/common-pci.c b/trunk/arch/arm/mach-ixp4xx/common-pci.c index 6d6bde3e15fa..1694f01ce2b6 100644 --- a/trunk/arch/arm/mach-ixp4xx/common-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/common-pci.c @@ -410,7 +410,6 @@ void __init ixp4xx_pci_preinit(void) * Enable the IO window to be way up high, at 0xfffffc00 */ local_write_config(PCI_BASE_ADDRESS_5, 4, 0xfffffc01); - local_write_config(0x40, 4, 0x000080FF); /* No TRDY time limit */ } else { printk("PCI: IXP4xx is target - No bus scan performed\n"); } diff --git a/trunk/arch/arm/mach-ixp4xx/common.c b/trunk/arch/arm/mach-ixp4xx/common.c index 8c0c0e2d0727..fdf91a160884 100644 --- a/trunk/arch/arm/mach-ixp4xx/common.c +++ b/trunk/arch/arm/mach-ixp4xx/common.c @@ -67,12 +67,15 @@ static struct map_desc ixp4xx_io_desc[] __initdata = { .pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS), .length = IXP4XX_PCI_CFG_REGION_SIZE, .type = MT_DEVICE - }, { /* Queue Manager */ - .virtual = (unsigned long)IXP4XX_QMGR_BASE_VIRT, - .pfn = __phys_to_pfn(IXP4XX_QMGR_BASE_PHYS), - .length = IXP4XX_QMGR_REGION_SIZE, - .type = MT_DEVICE }, +#ifdef CONFIG_DEBUG_LL + { /* Debug UART mapping */ + .virtual = (unsigned long)IXP4XX_DEBUG_UART_BASE_VIRT, + .pfn = __phys_to_pfn(IXP4XX_DEBUG_UART_BASE_PHYS), + .length = IXP4XX_DEBUG_UART_REGION_SIZE, + .type = MT_DEVICE + } +#endif }; void __init ixp4xx_map_io(void) diff --git a/trunk/arch/arm/mach-ixp4xx/goramo_mlr.c b/trunk/arch/arm/mach-ixp4xx/goramo_mlr.c index 53b8348dfcc2..b800a031207c 100644 --- a/trunk/arch/arm/mach-ixp4xx/goramo_mlr.c +++ b/trunk/arch/arm/mach-ixp4xx/goramo_mlr.c @@ -15,7 +15,6 @@ #include #include #include -#include #define SLOT_ETHA 0x0B /* IDSEL = AD21 */ #define SLOT_ETHB 0x0C /* IDSEL = AD20 */ @@ -330,7 +329,7 @@ static struct platform_device device_hss_tab[] = { }; -static struct platform_device *device_tab[7] __initdata = { +static struct platform_device *device_tab[6] __initdata = { &device_flash, /* index 0 */ }; diff --git a/trunk/arch/arm/mach-ixp4xx/include/mach/debug-macro.S b/trunk/arch/arm/mach-ixp4xx/include/mach/debug-macro.S index ff686cbc5df4..8c9f8d564492 100644 --- a/trunk/arch/arm/mach-ixp4xx/include/mach/debug-macro.S +++ b/trunk/arch/arm/mach-ixp4xx/include/mach/debug-macro.S @@ -17,8 +17,8 @@ #else mov \rp, #0 #endif - orr \rv, \rp, #0xfe000000 @ virtual - orr \rv, \rv, #0x00f00000 + orr \rv, \rp, #0xff000000 @ virtual + orr \rv, \rv, #0x00b00000 orr \rp, \rp, #0xc8000000 @ physical .endm diff --git a/trunk/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/trunk/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h index c5bae9c035d5..eb68b61ce975 100644 --- a/trunk/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h +++ b/trunk/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h @@ -30,43 +30,51 @@ * * 0x50000000 0x10000000 ioremap'd EXP BUS * - * 0xC8000000 0x00013000 0xFEF00000 On-Chip Peripherals + * 0x6000000 0x00004000 ioremap'd QMgr * - * 0xC0000000 0x00001000 0xFEF13000 PCI CFG + * 0xC0000000 0x00001000 0xffbff000 PCI CFG * - * 0xC4000000 0x00001000 0xFEF14000 EXP CFG + * 0xC4000000 0x00001000 0xffbfe000 EXP CFG * - * 0x60000000 0x00004000 0xFEF15000 QMgr + * 0xC8000000 0x00013000 0xffbeb000 On-Chip Peripherals */ /* * Queue Manager */ -#define IXP4XX_QMGR_BASE_PHYS 0x60000000 -#define IXP4XX_QMGR_BASE_VIRT IOMEM(0xFEF15000) -#define IXP4XX_QMGR_REGION_SIZE 0x00004000 +#define IXP4XX_QMGR_BASE_PHYS (0x60000000) +#define IXP4XX_QMGR_REGION_SIZE (0x00004000) /* - * Peripheral space, including debug UART. Must be section-aligned so that - * it can be used with the low-level debug code. + * Expansion BUS Configuration registers */ -#define IXP4XX_PERIPHERAL_BASE_PHYS 0xC8000000 -#define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFEF00000) -#define IXP4XX_PERIPHERAL_REGION_SIZE 0x00013000 +#define IXP4XX_EXP_CFG_BASE_PHYS (0xC4000000) +#define IXP4XX_EXP_CFG_BASE_VIRT IOMEM(0xFFBFE000) +#define IXP4XX_EXP_CFG_REGION_SIZE (0x00001000) /* * PCI Config registers */ -#define IXP4XX_PCI_CFG_BASE_PHYS 0xC0000000 -#define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFEF13000) -#define IXP4XX_PCI_CFG_REGION_SIZE 0x00001000 +#define IXP4XX_PCI_CFG_BASE_PHYS (0xC0000000) +#define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFFBFF000) +#define IXP4XX_PCI_CFG_REGION_SIZE (0x00001000) /* - * Expansion BUS Configuration registers + * Peripheral space + */ +#define IXP4XX_PERIPHERAL_BASE_PHYS (0xC8000000) +#define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFFBEB000) +#define IXP4XX_PERIPHERAL_REGION_SIZE (0x00013000) + +/* + * Debug UART + * + * This is basically a remap of UART1 into a region that is section + * aligned so that it * can be used with the low-level debug code. */ -#define IXP4XX_EXP_CFG_BASE_PHYS 0xC4000000 -#define IXP4XX_EXP_CFG_BASE_VIRT 0xFEF14000 -#define IXP4XX_EXP_CFG_REGION_SIZE 0x00001000 +#define IXP4XX_DEBUG_UART_BASE_PHYS (0xC8000000) +#define IXP4XX_DEBUG_UART_BASE_VIRT IOMEM(0xffb00000) +#define IXP4XX_DEBUG_UART_REGION_SIZE (0x00001000) #define IXP4XX_EXP_CS0_OFFSET 0x00 #define IXP4XX_EXP_CS1_OFFSET 0x04 diff --git a/trunk/arch/arm/mach-ixp4xx/include/mach/qmgr.h b/trunk/arch/arm/mach-ixp4xx/include/mach/qmgr.h index 4de8da536dbb..9e7cad2d54cb 100644 --- a/trunk/arch/arm/mach-ixp4xx/include/mach/qmgr.h +++ b/trunk/arch/arm/mach-ixp4xx/include/mach/qmgr.h @@ -86,7 +86,7 @@ void qmgr_release_queue(unsigned int queue); static inline void qmgr_put_entry(unsigned int queue, u32 val) { - struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; + extern struct qmgr_regs __iomem *qmgr_regs; #if DEBUG_QMGR BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */ @@ -99,7 +99,7 @@ static inline void qmgr_put_entry(unsigned int queue, u32 val) static inline u32 qmgr_get_entry(unsigned int queue) { u32 val; - const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; + extern struct qmgr_regs __iomem *qmgr_regs; val = __raw_readl(&qmgr_regs->acc[queue][0]); #if DEBUG_QMGR BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */ @@ -112,14 +112,14 @@ static inline u32 qmgr_get_entry(unsigned int queue) static inline int __qmgr_get_stat1(unsigned int queue) { - const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; + extern struct qmgr_regs __iomem *qmgr_regs; return (__raw_readl(&qmgr_regs->stat1[queue >> 3]) >> ((queue & 7) << 2)) & 0xF; } static inline int __qmgr_get_stat2(unsigned int queue) { - const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; + extern struct qmgr_regs __iomem *qmgr_regs; BUG_ON(queue >= HALF_QUEUES); return (__raw_readl(&qmgr_regs->stat2[queue >> 4]) >> ((queue & 0xF) << 1)) & 0x3; @@ -145,7 +145,7 @@ static inline int qmgr_stat_empty(unsigned int queue) */ static inline int qmgr_stat_below_low_watermark(unsigned int queue) { - const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; + extern struct qmgr_regs __iomem *qmgr_regs; if (queue >= HALF_QUEUES) return (__raw_readl(&qmgr_regs->statne_h) >> (queue - HALF_QUEUES)) & 0x01; @@ -172,7 +172,7 @@ static inline int qmgr_stat_above_high_watermark(unsigned int queue) */ static inline int qmgr_stat_full(unsigned int queue) { - const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; + extern struct qmgr_regs __iomem *qmgr_regs; if (queue >= HALF_QUEUES) return (__raw_readl(&qmgr_regs->statf_h) >> (queue - HALF_QUEUES)) & 0x01; diff --git a/trunk/arch/arm/mach-ixp4xx/ixp4xx_npe.c b/trunk/arch/arm/mach-ixp4xx/ixp4xx_npe.c index d4eb09a62863..a17ed79207a4 100644 --- a/trunk/arch/arm/mach-ixp4xx/ixp4xx_npe.c +++ b/trunk/arch/arm/mach-ixp4xx/ixp4xx_npe.c @@ -116,11 +116,7 @@ /* NPE mailbox_status value for reset */ #define RESET_MBOX_STAT 0x0000F0F0 -#define NPE_A_FIRMWARE "NPE-A" -#define NPE_B_FIRMWARE "NPE-B" -#define NPE_C_FIRMWARE "NPE-C" - -const char *npe_names[] = { NPE_A_FIRMWARE, NPE_B_FIRMWARE, NPE_C_FIRMWARE }; +const char *npe_names[] = { "NPE-A", "NPE-B", "NPE-C" }; #define print_npe(pri, npe, fmt, ...) \ printk(pri "%s: " fmt, npe_name(npe), ## __VA_ARGS__) @@ -728,9 +724,6 @@ module_exit(npe_cleanup_module); MODULE_AUTHOR("Krzysztof Halasa"); MODULE_LICENSE("GPL v2"); -MODULE_FIRMWARE(NPE_A_FIRMWARE); -MODULE_FIRMWARE(NPE_B_FIRMWARE); -MODULE_FIRMWARE(NPE_C_FIRMWARE); EXPORT_SYMBOL(npe_names); EXPORT_SYMBOL(npe_running); diff --git a/trunk/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c b/trunk/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c index 9d1b6b7c394c..852f7c9f87d0 100644 --- a/trunk/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c +++ b/trunk/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c @@ -14,7 +14,7 @@ #include #include -static struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; +struct qmgr_regs __iomem *qmgr_regs; static struct resource *mem_res; static spinlock_t qmgr_lock; static u32 used_sram_bitmap[4]; /* 128 16-dword pages */ @@ -293,6 +293,12 @@ static int qmgr_init(void) if (mem_res == NULL) return -EBUSY; + qmgr_regs = ioremap(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE); + if (qmgr_regs == NULL) { + err = -ENOMEM; + goto error_map; + } + /* reset qmgr registers */ for (i = 0; i < 4; i++) { __raw_writel(0x33333333, &qmgr_regs->stat1[i]); @@ -341,6 +347,8 @@ static int qmgr_init(void) error_irq2: free_irq(IRQ_IXP4XX_QM1, NULL); error_irq: + iounmap(qmgr_regs); +error_map: release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE); return err; } @@ -351,6 +359,7 @@ static void qmgr_remove(void) free_irq(IRQ_IXP4XX_QM2, NULL); synchronize_irq(IRQ_IXP4XX_QM1); synchronize_irq(IRQ_IXP4XX_QM2); + iounmap(qmgr_regs); release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE); } @@ -360,6 +369,7 @@ module_exit(qmgr_remove); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Krzysztof Halasa"); +EXPORT_SYMBOL(qmgr_regs); EXPORT_SYMBOL(qmgr_set_irq); EXPORT_SYMBOL(qmgr_enable_irq); EXPORT_SYMBOL(qmgr_disable_irq); diff --git a/trunk/arch/arm/mach-kirkwood/pcie.c b/trunk/arch/arm/mach-kirkwood/pcie.c index 74fc5a074fc4..ec544918b12c 100644 --- a/trunk/arch/arm/mach-kirkwood/pcie.c +++ b/trunk/arch/arm/mach-kirkwood/pcie.c @@ -207,19 +207,14 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys) return 1; } -/* - * The root complex has a hardwired class of PCI_CLASS_MEMORY_OTHER, when it - * is operating as a root complex this needs to be switched to - * PCI_CLASS_BRIDGE_HOST or Linux will errantly try to process the BAR's on - * the device. Decoding setup is handled by the orion code. - */ static void __devinit rc_pci_fixup(struct pci_dev *dev) { + /* + * Prevent enumeration of root complex. + */ if (dev->bus->parent == NULL && dev->devfn == 0) { int i; - dev->class &= 0xff; - dev->class |= PCI_CLASS_BRIDGE_HOST << 8; for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { dev->resource[i].start = 0; dev->resource[i].end = 0; diff --git a/trunk/arch/arm/mach-nomadik/board-nhk8815.c b/trunk/arch/arm/mach-nomadik/board-nhk8815.c index 22ef8a1abe08..bfa1eab91f41 100644 --- a/trunk/arch/arm/mach-nomadik/board-nhk8815.c +++ b/trunk/arch/arm/mach-nomadik/board-nhk8815.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -33,7 +32,9 @@ #include #include +#include #include +#include #include #include diff --git a/trunk/arch/arm/mach-nomadik/cpu-8815.c b/trunk/arch/arm/mach-nomadik/cpu-8815.c index 1273931303fb..b617eaed0ce5 100644 --- a/trunk/arch/arm/mach-nomadik/cpu-8815.c +++ b/trunk/arch/arm/mach-nomadik/cpu-8815.c @@ -26,8 +26,8 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/arch/arm/mach-nomadik/i2c-8815nhk.c b/trunk/arch/arm/mach-nomadik/i2c-8815nhk.c index 0c2f6628299a..6d14454d4609 100644 --- a/trunk/arch/arm/mach-nomadik/i2c-8815nhk.c +++ b/trunk/arch/arm/mach-nomadik/i2c-8815nhk.c @@ -4,7 +4,8 @@ #include #include #include -#include +#include +#include /* * There are two busses in the 8815NHK. diff --git a/trunk/arch/arm/mach-omap2/Kconfig b/trunk/arch/arm/mach-omap2/Kconfig index d669e227e00c..2a1a898c7f90 100644 --- a/trunk/arch/arm/mach-omap2/Kconfig +++ b/trunk/arch/arm/mach-omap2/Kconfig @@ -11,6 +11,7 @@ config ARCH_OMAP2PLUS_TYPICAL select I2C_OMAP select MENELAUS if ARCH_OMAP2 select NEON if ARCH_OMAP3 || ARCH_OMAP4 || SOC_OMAP5 + select PINCTRL select PM_RUNTIME select REGULATOR select SERIAL_OMAP diff --git a/trunk/arch/arm/mach-omap2/board-igep0020.c b/trunk/arch/arm/mach-omap2/board-igep0020.c index 378590694447..48d5e41dfbfa 100644 --- a/trunk/arch/arm/mach-omap2/board-igep0020.c +++ b/trunk/arch/arm/mach-omap2/board-igep0020.c @@ -580,11 +580,6 @@ static void __init igep_wlan_bt_init(void) } else return; - /* Make sure that the GPIO pins are muxed correctly */ - omap_mux_init_gpio(igep_wlan_bt_gpios[0].gpio, OMAP_PIN_OUTPUT); - omap_mux_init_gpio(igep_wlan_bt_gpios[1].gpio, OMAP_PIN_OUTPUT); - omap_mux_init_gpio(igep_wlan_bt_gpios[2].gpio, OMAP_PIN_OUTPUT); - err = gpio_request_array(igep_wlan_bt_gpios, ARRAY_SIZE(igep_wlan_bt_gpios)); if (err) { diff --git a/trunk/arch/arm/mach-omap2/board-omap3beagle.c b/trunk/arch/arm/mach-omap2/board-omap3beagle.c index d41ab98890ff..388c431c745a 100644 --- a/trunk/arch/arm/mach-omap2/board-omap3beagle.c +++ b/trunk/arch/arm/mach-omap2/board-omap3beagle.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -445,31 +444,27 @@ static struct omap_board_mux board_mux[] __initdata = { }; #endif -static int __init beagle_opp_init(void) +static void __init beagle_opp_init(void) { int r = 0; - if (!machine_is_omap3_beagle()) - return 0; - - /* Initialize the omap3 opp table if not already created. */ - r = omap3_opp_init(); - if (IS_ERR_VALUE(r) && (r != -EEXIST)) { + /* Initialize the omap3 opp table */ + if (omap3_opp_init()) { pr_err("%s: opp default init failed\n", __func__); - return r; + return; } /* Custom OPP enabled for all xM versions */ if (cpu_is_omap3630()) { struct device *mpu_dev, *iva_dev; - mpu_dev = get_cpu_device(0); + mpu_dev = omap_device_get_by_hwmod_name("mpu"); iva_dev = omap_device_get_by_hwmod_name("iva"); if (IS_ERR(mpu_dev) || IS_ERR(iva_dev)) { pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n", __func__, mpu_dev, iva_dev); - return -ENODEV; + return; } /* Enable MPU 1GHz and lower opps */ r = opp_enable(mpu_dev, 800000000); @@ -489,9 +484,8 @@ static int __init beagle_opp_init(void) opp_disable(iva_dev, 660000000); } } - return 0; + return; } -device_initcall(beagle_opp_init); static void __init omap3_beagle_init(void) { @@ -528,6 +522,8 @@ static void __init omap3_beagle_init(void) /* Ensure SDRC pins are mux'd for self-refresh */ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); + + beagle_opp_init(); } MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board") diff --git a/trunk/arch/arm/mach-omap2/clock33xx_data.c b/trunk/arch/arm/mach-omap2/clock33xx_data.c index 1a45d6bd2539..114ab4b8e0e3 100644 --- a/trunk/arch/arm/mach-omap2/clock33xx_data.c +++ b/trunk/arch/arm/mach-omap2/clock33xx_data.c @@ -1073,8 +1073,6 @@ static struct omap_clk am33xx_clks[] = { CLK(NULL, "gfx_fck_div_ck", &gfx_fck_div_ck, CK_AM33XX), CLK(NULL, "sysclkout_pre_ck", &sysclkout_pre_ck, CK_AM33XX), CLK(NULL, "clkout2_ck", &clkout2_ck, CK_AM33XX), - CLK(NULL, "timer_32k_ck", &clkdiv32k_ick, CK_AM33XX), - CLK(NULL, "timer_sys_ck", &sys_clkin_ck, CK_AM33XX), }; int __init am33xx_clk_init(void) diff --git a/trunk/arch/arm/mach-omap2/clockdomains44xx_data.c b/trunk/arch/arm/mach-omap2/clockdomains44xx_data.c index 95192a062d5d..b56d06b48782 100644 --- a/trunk/arch/arm/mach-omap2/clockdomains44xx_data.c +++ b/trunk/arch/arm/mach-omap2/clockdomains44xx_data.c @@ -359,7 +359,7 @@ static struct clockdomain iss_44xx_clkdm = { .clkdm_offs = OMAP4430_CM2_CAM_CAM_CDOFFS, .wkdep_srcs = iss_wkup_sleep_deps, .sleepdep_srcs = iss_wkup_sleep_deps, - .flags = CLKDM_CAN_SWSUP, + .flags = CLKDM_CAN_HWSUP_SWSUP, }; static struct clockdomain l3_dss_44xx_clkdm = { diff --git a/trunk/arch/arm/mach-omap2/common-board-devices.c b/trunk/arch/arm/mach-omap2/common-board-devices.c index 84551f205e46..48daac2581b4 100644 --- a/trunk/arch/arm/mach-omap2/common-board-devices.c +++ b/trunk/arch/arm/mach-omap2/common-board-devices.c @@ -64,36 +64,30 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce, struct spi_board_info *spi_bi = &ads7846_spi_board_info; int err; - /* - * If a board defines get_pendown_state() function, request the pendown - * GPIO and set the GPIO debounce time. - * If a board does not define the get_pendown_state() function, then - * the ads7846 driver will setup the pendown GPIO itself. - */ - if (board_pdata && board_pdata->get_pendown_state) { - err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown"); - if (err) { - pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err); - return; - } - - if (gpio_debounce) - gpio_set_debounce(gpio_pendown, gpio_debounce); - - gpio_export(gpio_pendown, 0); + err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown"); + if (err) { + pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err); + return; } + if (gpio_debounce) + gpio_set_debounce(gpio_pendown, gpio_debounce); + spi_bi->bus_num = bus_num; spi_bi->irq = gpio_to_irq(gpio_pendown); - ads7846_config.gpio_pendown = gpio_pendown; - if (board_pdata) { board_pdata->gpio_pendown = gpio_pendown; - board_pdata->gpio_pendown_debounce = gpio_debounce; spi_bi->platform_data = board_pdata; + if (board_pdata->get_pendown_state) + gpio_export(gpio_pendown, 0); + } else { + ads7846_config.gpio_pendown = gpio_pendown; } + if (!board_pdata || (board_pdata && !board_pdata->get_pendown_state)) + gpio_free(gpio_pendown); + spi_register_board_info(&ads7846_spi_board_info, 1); } #else diff --git a/trunk/arch/arm/mach-omap2/devices.c b/trunk/arch/arm/mach-omap2/devices.c index c72b5a727720..cba60e05e32e 100644 --- a/trunk/arch/arm/mach-omap2/devices.c +++ b/trunk/arch/arm/mach-omap2/devices.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -614,83 +613,6 @@ static void omap_init_vout(void) static inline void omap_init_vout(void) {} #endif -#if defined(CONFIG_OMAP_OCP2SCP) || defined(CONFIG_OMAP_OCP2SCP_MODULE) -static int count_ocp2scp_devices(struct omap_ocp2scp_dev *ocp2scp_dev) -{ - int cnt = 0; - - while (ocp2scp_dev->drv_name != NULL) { - cnt++; - ocp2scp_dev++; - } - - return cnt; -} - -static void omap_init_ocp2scp(void) -{ - struct omap_hwmod *oh; - struct platform_device *pdev; - int bus_id = -1, dev_cnt = 0, i; - struct omap_ocp2scp_dev *ocp2scp_dev; - const char *oh_name, *name; - struct omap_ocp2scp_platform_data *pdata; - - if (!cpu_is_omap44xx()) - return; - - oh_name = "ocp2scp_usb_phy"; - name = "omap-ocp2scp"; - - oh = omap_hwmod_lookup(oh_name); - if (!oh) { - pr_err("%s: could not find omap_hwmod for %s\n", __func__, - oh_name); - return; - } - - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - pr_err("%s: No memory for ocp2scp pdata\n", __func__); - return; - } - - ocp2scp_dev = oh->dev_attr; - dev_cnt = count_ocp2scp_devices(ocp2scp_dev); - - if (!dev_cnt) { - pr_err("%s: No devices connected to ocp2scp\n", __func__); - kfree(pdata); - return; - } - - pdata->devices = kzalloc(sizeof(struct omap_ocp2scp_dev *) - * dev_cnt, GFP_KERNEL); - if (!pdata->devices) { - pr_err("%s: No memory for ocp2scp pdata devices\n", __func__); - kfree(pdata); - return; - } - - for (i = 0; i < dev_cnt; i++, ocp2scp_dev++) - pdata->devices[i] = ocp2scp_dev; - - pdata->dev_cnt = dev_cnt; - - pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(*pdata), NULL, - 0, false); - if (IS_ERR(pdev)) { - pr_err("Could not build omap_device for %s %s\n", - name, oh_name); - kfree(pdata->devices); - kfree(pdata); - return; - } -} -#else -static inline void omap_init_ocp2scp(void) { } -#endif - /*-------------------------------------------------------------------------*/ static int __init omap2_init_devices(void) @@ -718,7 +640,6 @@ static int __init omap2_init_devices(void) omap_init_sham(); omap_init_aes(); omap_init_vout(); - omap_init_ocp2scp(); return 0; } diff --git a/trunk/arch/arm/mach-omap2/mux34xx.c b/trunk/arch/arm/mach-omap2/mux34xx.c index c47140bbbec4..17f80e4ab162 100644 --- a/trunk/arch/arm/mach-omap2/mux34xx.c +++ b/trunk/arch/arm/mach-omap2/mux34xx.c @@ -614,16 +614,16 @@ static struct omap_mux __initdata omap3_muxmodes[] = { "sys_off_mode", NULL, NULL, NULL, "gpio_9", NULL, NULL, "safe_mode"), _OMAP3_MUXENTRY(UART1_CTS, 150, - "uart1_cts", "ssi1_rdy_tx", NULL, NULL, + "uart1_cts", NULL, NULL, NULL, "gpio_150", "hsusb3_tll_clk", NULL, "safe_mode"), _OMAP3_MUXENTRY(UART1_RTS, 149, - "uart1_rts", "ssi1_flag_tx", NULL, NULL, + "uart1_rts", NULL, NULL, NULL, "gpio_149", NULL, NULL, "safe_mode"), _OMAP3_MUXENTRY(UART1_RX, 151, - "uart1_rx", "ss1_wake_tx", "mcbsp1_clkr", "mcspi4_clk", + "uart1_rx", NULL, "mcbsp1_clkr", "mcspi4_clk", "gpio_151", NULL, NULL, "safe_mode"), _OMAP3_MUXENTRY(UART1_TX, 148, - "uart1_tx", "ssi1_dat_tx", NULL, NULL, + "uart1_tx", NULL, NULL, NULL, "gpio_148", NULL, NULL, "safe_mode"), _OMAP3_MUXENTRY(UART2_CTS, 144, "uart2_cts", "mcbsp3_dx", "gpt9_pwm_evt", NULL, diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod.c b/trunk/arch/arm/mach-omap2/omap_hwmod.c index 87cc6d058de2..b969ab1d258b 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod.c @@ -421,38 +421,6 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v) return 0; } -/** - * _wait_softreset_complete - wait for an OCP softreset to complete - * @oh: struct omap_hwmod * to wait on - * - * Wait until the IP block represented by @oh reports that its OCP - * softreset is complete. This can be triggered by software (see - * _ocp_softreset()) or by hardware upon returning from off-mode (one - * example is HSMMC). Waits for up to MAX_MODULE_SOFTRESET_WAIT - * microseconds. Returns the number of microseconds waited. - */ -static int _wait_softreset_complete(struct omap_hwmod *oh) -{ - struct omap_hwmod_class_sysconfig *sysc; - u32 softrst_mask; - int c = 0; - - sysc = oh->class->sysc; - - if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS) - omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs) - & SYSS_RESETDONE_MASK), - MAX_MODULE_SOFTRESET_WAIT, c); - else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { - softrst_mask = (0x1 << sysc->sysc_fields->srst_shift); - omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs) - & softrst_mask), - MAX_MODULE_SOFTRESET_WAIT, c); - } - - return c; -} - /** * _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v * @oh: struct omap_hwmod * @@ -1314,18 +1282,6 @@ static void _enable_sysc(struct omap_hwmod *oh) if (!oh->class->sysc) return; - /* - * Wait until reset has completed, this is needed as the IP - * block is reset automatically by hardware in some cases - * (off-mode for example), and the drivers require the - * IP to be ready when they access it - */ - if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) - _enable_optional_clocks(oh); - _wait_softreset_complete(oh); - if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) - _disable_optional_clocks(oh); - v = oh->_sysc_cache; sf = oh->class->sysc->sysc_flags; @@ -1848,7 +1804,7 @@ static int _am33xx_disable_module(struct omap_hwmod *oh) */ static int _ocp_softreset(struct omap_hwmod *oh) { - u32 v; + u32 v, softrst_mask; int c = 0; int ret = 0; @@ -1878,7 +1834,19 @@ static int _ocp_softreset(struct omap_hwmod *oh) if (oh->class->sysc->srst_udelay) udelay(oh->class->sysc->srst_udelay); - c = _wait_softreset_complete(oh); + if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS) + omap_test_timeout((omap_hwmod_read(oh, + oh->class->sysc->syss_offs) + & SYSS_RESETDONE_MASK), + MAX_MODULE_SOFTRESET_WAIT, c); + else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { + softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift); + omap_test_timeout(!(omap_hwmod_read(oh, + oh->class->sysc->sysc_offs) + & softrst_mask), + MAX_MODULE_SOFTRESET_WAIT, c); + } + if (c == MAX_MODULE_SOFTRESET_WAIT) pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", oh->name, MAX_MODULE_SOFTRESET_WAIT); @@ -2384,9 +2352,6 @@ static int __init _setup_reset(struct omap_hwmod *oh) if (oh->_state != _HWMOD_STATE_INITIALIZED) return -EINVAL; - if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK) - return -EPERM; - if (oh->rst_lines_cnt == 0) { r = _enable(oh); if (r) { diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 0b1249e00398..652d0285bd6d 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -2126,14 +2125,6 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = { .name = "mcpdm", .class = &omap44xx_mcpdm_hwmod_class, .clkdm_name = "abe_clkdm", - /* - * It's suspected that the McPDM requires an off-chip main - * functional clock, controlled via I2C. This IP block is - * currently reset very early during boot, before I2C is - * available, so it doesn't seem that we have any choice in - * the kernel other than to avoid resetting it. - */ - .flags = HWMOD_EXT_OPT_MAIN_CLK, .mpu_irqs = omap44xx_mcpdm_irqs, .sdma_reqs = omap44xx_mcpdm_sdma_reqs, .main_clk = "mcpdm_fck", @@ -2690,32 +2681,6 @@ static struct omap_hwmod_class omap44xx_ocp2scp_hwmod_class = { .sysc = &omap44xx_ocp2scp_sysc, }; -/* ocp2scp dev_attr */ -static struct resource omap44xx_usb_phy_and_pll_addrs[] = { - { - .name = "usb_phy", - .start = 0x4a0ad080, - .end = 0x4a0ae000, - .flags = IORESOURCE_MEM, - }, - { - /* XXX: Remove this once control module driver is in place */ - .name = "ctrl_dev", - .start = 0x4a002300, - .end = 0x4a002303, - .flags = IORESOURCE_MEM, - }, - { } -}; - -static struct omap_ocp2scp_dev ocp2scp_dev_attr[] = { - { - .drv_name = "omap-usb2", - .res = omap44xx_usb_phy_and_pll_addrs, - }, - { } -}; - /* ocp2scp_usb_phy */ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { .name = "ocp2scp_usb_phy", @@ -2729,7 +2694,6 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { .modulemode = MODULEMODE_HWCTRL, }, }, - .dev_attr = ocp2scp_dev_attr, }; /* diff --git a/trunk/arch/arm/mach-omap2/pm.h b/trunk/arch/arm/mach-omap2/pm.h index 67d66131cfa7..686137d164da 100644 --- a/trunk/arch/arm/mach-omap2/pm.h +++ b/trunk/arch/arm/mach-omap2/pm.h @@ -91,7 +91,6 @@ extern void omap3_save_scratchpad_contents(void); #define PM_RTA_ERRATUM_i608 (1 << 0) #define PM_SDRC_WAKEUP_ERRATUM_i583 (1 << 1) -#define PM_PER_MEMORIES_ERRATUM_i582 (1 << 2) #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) extern u16 pm34xx_errata; diff --git a/trunk/arch/arm/mach-omap2/pm34xx.c b/trunk/arch/arm/mach-omap2/pm34xx.c index 3a904de4313e..ba670db1fd37 100644 --- a/trunk/arch/arm/mach-omap2/pm34xx.c +++ b/trunk/arch/arm/mach-omap2/pm34xx.c @@ -652,17 +652,14 @@ static void __init pm_errata_configure(void) /* Enable the l2 cache toggling in sleep logic */ enable_omap3630_toggle_l2_on_restore(); if (omap_rev() < OMAP3630_REV_ES1_2) - pm34xx_errata |= (PM_SDRC_WAKEUP_ERRATUM_i583 | - PM_PER_MEMORIES_ERRATUM_i582); - } else if (cpu_is_omap34xx()) { - pm34xx_errata |= PM_PER_MEMORIES_ERRATUM_i582; + pm34xx_errata |= PM_SDRC_WAKEUP_ERRATUM_i583; } } int __init omap3_pm_init(void) { struct power_state *pwrst, *tmp; - struct clockdomain *neon_clkdm, *mpu_clkdm, *per_clkdm, *wkup_clkdm; + struct clockdomain *neon_clkdm, *mpu_clkdm; int ret; if (!omap3_has_io_chain_ctrl()) @@ -714,8 +711,6 @@ int __init omap3_pm_init(void) neon_clkdm = clkdm_lookup("neon_clkdm"); mpu_clkdm = clkdm_lookup("mpu_clkdm"); - per_clkdm = clkdm_lookup("per_clkdm"); - wkup_clkdm = clkdm_lookup("wkup_clkdm"); #ifdef CONFIG_SUSPEND omap_pm_suspend = omap3_pm_suspend; @@ -732,27 +727,6 @@ int __init omap3_pm_init(void) if (IS_PM34XX_ERRATUM(PM_RTA_ERRATUM_i608)) omap3630_ctrl_disable_rta(); - /* - * The UART3/4 FIFO and the sidetone memory in McBSP2/3 are - * not correctly reset when the PER powerdomain comes back - * from OFF or OSWR when the CORE powerdomain is kept active. - * See OMAP36xx Erratum i582 "PER Domain reset issue after - * Domain-OFF/OSWR Wakeup". This wakeup dependency is not a - * complete workaround. The kernel must also prevent the PER - * powerdomain from going to OSWR/OFF while the CORE - * powerdomain is not going to OSWR/OFF. And if PER last - * power state was off while CORE last power state was ON, the - * UART3/4 and McBSP2/3 SIDETONE devices need to run a - * self-test using their loopback tests; if that fails, those - * devices are unusable until the PER/CORE can complete a transition - * from ON to OSWR/OFF and then back to ON. - * - * XXX Technically this workaround is only needed if off-mode - * or OSWR is enabled. - */ - if (IS_PM34XX_ERRATUM(PM_PER_MEMORIES_ERRATUM_i582)) - clkdm_add_wkdep(per_clkdm, wkup_clkdm); - clkdm_add_wkdep(neon_clkdm, mpu_clkdm); if (omap_type() != OMAP2_DEVICE_TYPE_GP) { omap3_secure_ram_storage = diff --git a/trunk/arch/arm/mach-omap2/serial.c b/trunk/arch/arm/mach-omap2/serial.c index a507cd6cf4f1..0405c8190803 100644 --- a/trunk/arch/arm/mach-omap2/serial.c +++ b/trunk/arch/arm/mach-omap2/serial.c @@ -329,11 +329,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata, oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt); - if (console_uart_id == bdata->id) { - omap_device_enable(pdev); - pm_runtime_set_active(&pdev->dev); - } - oh->dev_attr = uart; if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) diff --git a/trunk/arch/arm/mach-omap2/twl-common.c b/trunk/arch/arm/mach-omap2/twl-common.c index a256135d8e48..635e109f5ad3 100644 --- a/trunk/arch/arm/mach-omap2/twl-common.c +++ b/trunk/arch/arm/mach-omap2/twl-common.c @@ -73,7 +73,6 @@ void __init omap4_pmic_init(const char *pmic_type, { /* PMIC part*/ omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE); - omap_mux_init_signal("fref_clk0_out.sys_drm_msecure", OMAP_PIN_OUTPUT); omap_pmic_init(1, 400, pmic_type, 7 + OMAP44XX_IRQ_GIC_START, pmic_data); /* Register additional devices on i2c1 bus if needed */ @@ -367,7 +366,7 @@ static struct regulator_init_data omap4_clk32kg_idata = { }; static struct regulator_consumer_supply omap4_vdd1_supply[] = { - REGULATOR_SUPPLY("vcc", "cpu0"), + REGULATOR_SUPPLY("vcc", "mpu.0"), }; static struct regulator_consumer_supply omap4_vdd2_supply[] = { diff --git a/trunk/arch/arm/mach-omap2/vc.c b/trunk/arch/arm/mach-omap2/vc.c index 75878c37959b..880249b17012 100644 --- a/trunk/arch/arm/mach-omap2/vc.c +++ b/trunk/arch/arm/mach-omap2/vc.c @@ -264,7 +264,7 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm) if (initialized) { if (voltdm->pmic->i2c_high_speed != i2c_high_speed) - pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).\n", + pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).", __func__, voltdm->name, i2c_high_speed); return; } diff --git a/trunk/arch/arm/mach-pxa/hx4700.c b/trunk/arch/arm/mach-pxa/hx4700.c index e2c6391863fe..5ecbd17b5641 100644 --- a/trunk/arch/arm/mach-pxa/hx4700.c +++ b/trunk/arch/arm/mach-pxa/hx4700.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -557,7 +556,7 @@ static struct platform_device hx4700_lcd = { */ static struct platform_pwm_backlight_data backlight_data = { - .pwm_id = -1, /* Superseded by pwm_lookup */ + .pwm_id = 1, .max_brightness = 200, .dft_brightness = 100, .pwm_period_ns = 30923, @@ -572,10 +571,6 @@ static struct platform_device backlight = { }, }; -static struct pwm_lookup hx4700_pwm_lookup[] = { - PWM_LOOKUP("pxa27x-pwm.1", 0, "pwm-backlight", NULL), -}; - /* * USB "Transceiver" */ @@ -877,7 +872,6 @@ static void __init hx4700_init(void) pxa_set_stuart_info(NULL); platform_add_devices(devices, ARRAY_SIZE(devices)); - pwm_add_table(hx4700_pwm_lookup, ARRAY_SIZE(hx4700_pwm_lookup)); pxa_set_ficp_info(&ficp_info); pxa27x_set_i2c_power_info(NULL); diff --git a/trunk/arch/arm/mach-pxa/spitz_pm.c b/trunk/arch/arm/mach-pxa/spitz_pm.c index 842596d4d31e..438f02fe122a 100644 --- a/trunk/arch/arm/mach-pxa/spitz_pm.c +++ b/trunk/arch/arm/mach-pxa/spitz_pm.c @@ -86,7 +86,10 @@ static void spitz_discharge1(int on) gpio_set_value(SPITZ_GPIO_LED_GREEN, on); } -static unsigned long gpio18_config = GPIO18_GPIO; +static unsigned long gpio18_config[] = { + GPIO18_RDY, + GPIO18_GPIO, +}; static void spitz_presuspend(void) { @@ -109,7 +112,7 @@ static void spitz_presuspend(void) PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT; PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0); - pxa2xx_mfp_config(&gpio18_config, 1); + pxa2xx_mfp_config(&gpio18_config[0], 1); gpio_request_one(18, GPIOF_OUT_INIT_HIGH, "Unknown"); gpio_free(18); @@ -128,6 +131,7 @@ static void spitz_presuspend(void) static void spitz_postsuspend(void) { + pxa2xx_mfp_config(&gpio18_config[1], 1); } static int spitz_should_wakeup(unsigned int resume_on_alarm) diff --git a/trunk/arch/arm/mach-s3c24xx/s3c2416.c b/trunk/arch/arm/mach-s3c24xx/s3c2416.c index 77ee0b732237..ed5a95ece9eb 100644 --- a/trunk/arch/arm/mach-s3c24xx/s3c2416.c +++ b/trunk/arch/arm/mach-s3c24xx/s3c2416.c @@ -61,7 +61,6 @@ #include #include #include -#include static struct map_desc s3c2416_iodesc[] __initdata = { IODESC_ENT(WATCHDOG), @@ -133,7 +132,6 @@ void __init s3c2416_map_io(void) /* initialize device information early */ s3c2416_default_sdhci0(); s3c2416_default_sdhci1(); - s3c64xx_spi_setname("s3c2443-spi"); iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc)); } diff --git a/trunk/arch/arm/mach-s3c24xx/s3c2443.c b/trunk/arch/arm/mach-s3c24xx/s3c2443.c index 165b6a6b3daa..ab648ad8fa50 100644 --- a/trunk/arch/arm/mach-s3c24xx/s3c2443.c +++ b/trunk/arch/arm/mach-s3c24xx/s3c2443.c @@ -43,7 +43,6 @@ #include #include #include -#include static struct map_desc s3c2443_iodesc[] __initdata = { IODESC_ENT(WATCHDOG), @@ -101,9 +100,6 @@ void __init s3c2443_map_io(void) s3c24xx_gpiocfg_default.set_pull = s3c2443_gpio_setpull; s3c24xx_gpiocfg_default.get_pull = s3c2443_gpio_getpull; - /* initialize device information early */ - s3c64xx_spi_setname("s3c2443-spi"); - iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc)); } diff --git a/trunk/arch/arm/mach-s5p64x0/common.c b/trunk/arch/arm/mach-s5p64x0/common.c index 111e404a81fd..6e6a0a9d6778 100644 --- a/trunk/arch/arm/mach-s5p64x0/common.c +++ b/trunk/arch/arm/mach-s5p64x0/common.c @@ -44,7 +44,6 @@ #include #include #include -#include #include #include #include @@ -180,7 +179,6 @@ void __init s5p6440_map_io(void) /* initialize any device information early */ s3c_adc_setname("s3c64xx-adc"); s3c_fb_setname("s5p64x0-fb"); - s3c64xx_spi_setname("s5p64x0-spi"); s5p64x0_default_sdhci0(); s5p64x0_default_sdhci1(); @@ -195,7 +193,6 @@ void __init s5p6450_map_io(void) /* initialize any device information early */ s3c_adc_setname("s3c64xx-adc"); s3c_fb_setname("s5p64x0-fb"); - s3c64xx_spi_setname("s5p64x0-spi"); s5p64x0_default_sdhci0(); s5p64x0_default_sdhci1(); diff --git a/trunk/arch/arm/mach-s5pc100/common.c b/trunk/arch/arm/mach-s5pc100/common.c index cc6e561c9958..621908658861 100644 --- a/trunk/arch/arm/mach-s5pc100/common.c +++ b/trunk/arch/arm/mach-s5pc100/common.c @@ -45,7 +45,6 @@ #include #include #include -#include #include #include @@ -166,8 +165,6 @@ void __init s5pc100_map_io(void) s3c_onenand_setname("s5pc100-onenand"); s3c_fb_setname("s5pc100-fb"); s3c_cfcon_setname("s5pc100-pata"); - - s3c64xx_spi_setname("s5pc100-spi"); } void __init s5pc100_init_clocks(int xtal) diff --git a/trunk/arch/arm/mach-s5pv210/common.c b/trunk/arch/arm/mach-s5pv210/common.c index a0c50efe8145..4c9e9027df9a 100644 --- a/trunk/arch/arm/mach-s5pv210/common.c +++ b/trunk/arch/arm/mach-s5pv210/common.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include "common.h" @@ -197,8 +196,6 @@ void __init s5pv210_map_io(void) /* setup TV devices */ s5p_hdmi_setname("s5pv210-hdmi"); - - s3c64xx_spi_setname("s5pv210-spi"); } void __init s5pv210_init_clocks(int xtal) diff --git a/trunk/arch/arm/mach-shmobile/setup-r8a7779.c b/trunk/arch/arm/mach-shmobile/setup-r8a7779.c index ebbffc25f24f..2917668f0091 100644 --- a/trunk/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/trunk/arch/arm/mach-shmobile/setup-r8a7779.c @@ -247,7 +247,7 @@ void __init r8a7779_add_standard_devices(void) { #ifdef CONFIG_CACHE_L2X0 /* Early BRESP enable, Shared attribute override enable, 64K*16way */ - l2x0_init(IOMEM(0xf0100000), 0x40470000, 0x82000fff); + l2x0_init((void __iomem __force *)(0xf0100000), 0x40470000, 0x82000fff); #endif r8a7779_pm_init(); diff --git a/trunk/arch/arm/mach-spear13xx/include/mach/spear1310_misc_regs.h b/trunk/arch/arm/mach-spear13xx/include/mach/spear1310_misc_regs.h new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/trunk/arch/arm/mach-spear13xx/include/mach/spear1340_misc_regs.h b/trunk/arch/arm/mach-spear13xx/include/mach/spear1340_misc_regs.h new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/trunk/arch/arm/mach-u300/core.c b/trunk/arch/arm/mach-u300/core.c index ece8a2dfb814..b8efac4daed8 100644 --- a/trunk/arch/arm/mach-u300/core.c +++ b/trunk/arch/arm/mach-u300/core.c @@ -1445,6 +1445,8 @@ static struct platform_device pinctrl_device = { static struct u300_gpio_platform u300_gpio_plat = { .ports = 7, .gpio_base = 0, + .gpio_irq_base = IRQ_U300_GPIO_BASE, + .pinctrl_device = &pinctrl_device, }; static struct platform_device gpio_device = { @@ -1588,7 +1590,6 @@ static struct platform_device *platform_devs[] __initdata = { &i2c1_device, &keypad_device, &rtc_device, - &pinctrl_device, &gpio_device, &nand_device, &wdog_device, @@ -1803,7 +1804,7 @@ MACHINE_START(U300, "Ericsson AB U335 S335/B335 Prototype Board") /* Maintainer: Linus Walleij */ .atag_offset = 0x100, .map_io = u300_map_io, - .nr_irqs = 0, + .nr_irqs = NR_IRQS_U300, .init_irq = u300_init_irq, .handle_irq = vic_handle_irq, .timer = &u300_timer, diff --git a/trunk/arch/arm/mach-u300/include/mach/irqs.h b/trunk/arch/arm/mach-u300/include/mach/irqs.h index 21d5e76a6cd3..e27425a63fa1 100644 --- a/trunk/arch/arm/mach-u300/include/mach/irqs.h +++ b/trunk/arch/arm/mach-u300/include/mach/irqs.h @@ -12,69 +12,79 @@ #ifndef __MACH_IRQS_H #define __MACH_IRQS_H -#define IRQ_U300_INTCON0_START 32 -#define IRQ_U300_INTCON1_START 64 +#define IRQ_U300_INTCON0_START 1 +#define IRQ_U300_INTCON1_START 33 /* These are on INTCON0 - 30 lines */ -#define IRQ_U300_IRQ0_EXT 32 -#define IRQ_U300_IRQ1_EXT 33 -#define IRQ_U300_DMA 34 -#define IRQ_U300_VIDEO_ENC_0 35 -#define IRQ_U300_VIDEO_ENC_1 36 -#define IRQ_U300_AAIF_RX 37 -#define IRQ_U300_AAIF_TX 38 -#define IRQ_U300_AAIF_VGPIO 39 -#define IRQ_U300_AAIF_WAKEUP 40 -#define IRQ_U300_PCM_I2S0_FRAME 41 -#define IRQ_U300_PCM_I2S0_FIFO 42 -#define IRQ_U300_PCM_I2S1_FRAME 43 -#define IRQ_U300_PCM_I2S1_FIFO 44 -#define IRQ_U300_XGAM_GAMCON 45 -#define IRQ_U300_XGAM_CDI 46 -#define IRQ_U300_XGAM_CDICON 47 -#define IRQ_U300_XGAM_PDI 49 -#define IRQ_U300_XGAM_PDICON 50 -#define IRQ_U300_XGAM_GAMEACC 51 -#define IRQ_U300_XGAM_MCIDCT 52 -#define IRQ_U300_APEX 53 -#define IRQ_U300_UART0 54 -#define IRQ_U300_SPI 55 -#define IRQ_U300_TIMER_APP_OS 56 -#define IRQ_U300_TIMER_APP_DD 57 -#define IRQ_U300_TIMER_APP_GP1 58 -#define IRQ_U300_TIMER_APP_GP2 59 -#define IRQ_U300_TIMER_OS 60 -#define IRQ_U300_TIMER_MS 61 -#define IRQ_U300_KEYPAD_KEYBF 62 -#define IRQ_U300_KEYPAD_KEYBR 63 +#define IRQ_U300_IRQ0_EXT 1 +#define IRQ_U300_IRQ1_EXT 2 +#define IRQ_U300_DMA 3 +#define IRQ_U300_VIDEO_ENC_0 4 +#define IRQ_U300_VIDEO_ENC_1 5 +#define IRQ_U300_AAIF_RX 6 +#define IRQ_U300_AAIF_TX 7 +#define IRQ_U300_AAIF_VGPIO 8 +#define IRQ_U300_AAIF_WAKEUP 9 +#define IRQ_U300_PCM_I2S0_FRAME 10 +#define IRQ_U300_PCM_I2S0_FIFO 11 +#define IRQ_U300_PCM_I2S1_FRAME 12 +#define IRQ_U300_PCM_I2S1_FIFO 13 +#define IRQ_U300_XGAM_GAMCON 14 +#define IRQ_U300_XGAM_CDI 15 +#define IRQ_U300_XGAM_CDICON 16 +#define IRQ_U300_XGAM_PDI 18 +#define IRQ_U300_XGAM_PDICON 19 +#define IRQ_U300_XGAM_GAMEACC 20 +#define IRQ_U300_XGAM_MCIDCT 21 +#define IRQ_U300_APEX 22 +#define IRQ_U300_UART0 23 +#define IRQ_U300_SPI 24 +#define IRQ_U300_TIMER_APP_OS 25 +#define IRQ_U300_TIMER_APP_DD 26 +#define IRQ_U300_TIMER_APP_GP1 27 +#define IRQ_U300_TIMER_APP_GP2 28 +#define IRQ_U300_TIMER_OS 29 +#define IRQ_U300_TIMER_MS 30 +#define IRQ_U300_KEYPAD_KEYBF 31 +#define IRQ_U300_KEYPAD_KEYBR 32 /* These are on INTCON1 - 32 lines */ -#define IRQ_U300_GPIO_PORT0 64 -#define IRQ_U300_GPIO_PORT1 65 -#define IRQ_U300_GPIO_PORT2 66 +#define IRQ_U300_GPIO_PORT0 33 +#define IRQ_U300_GPIO_PORT1 34 +#define IRQ_U300_GPIO_PORT2 35 /* These are for DB3150, DB3200 and DB3350 */ -#define IRQ_U300_WDOG 67 -#define IRQ_U300_EVHIST 68 -#define IRQ_U300_MSPRO 69 -#define IRQ_U300_MMCSD_MCIINTR0 70 -#define IRQ_U300_MMCSD_MCIINTR1 71 -#define IRQ_U300_I2C0 72 -#define IRQ_U300_I2C1 73 -#define IRQ_U300_RTC 74 -#define IRQ_U300_NFIF 75 -#define IRQ_U300_NFIF2 76 +#define IRQ_U300_WDOG 36 +#define IRQ_U300_EVHIST 37 +#define IRQ_U300_MSPRO 38 +#define IRQ_U300_MMCSD_MCIINTR0 39 +#define IRQ_U300_MMCSD_MCIINTR1 40 +#define IRQ_U300_I2C0 41 +#define IRQ_U300_I2C1 42 +#define IRQ_U300_RTC 43 +#define IRQ_U300_NFIF 44 +#define IRQ_U300_NFIF2 45 /* The DB3350-specific interrupt lines */ -#define IRQ_U300_ISP_F0 77 -#define IRQ_U300_ISP_F1 78 -#define IRQ_U300_ISP_F2 79 -#define IRQ_U300_ISP_F3 80 -#define IRQ_U300_ISP_F4 81 -#define IRQ_U300_GPIO_PORT3 82 -#define IRQ_U300_SYSCON_PLL_LOCK 83 -#define IRQ_U300_UART1 84 -#define IRQ_U300_GPIO_PORT4 85 -#define IRQ_U300_GPIO_PORT5 86 -#define IRQ_U300_GPIO_PORT6 87 -#define U300_VIC_IRQS_END 88 +#define IRQ_U300_ISP_F0 46 +#define IRQ_U300_ISP_F1 47 +#define IRQ_U300_ISP_F2 48 +#define IRQ_U300_ISP_F3 49 +#define IRQ_U300_ISP_F4 50 +#define IRQ_U300_GPIO_PORT3 51 +#define IRQ_U300_SYSCON_PLL_LOCK 52 +#define IRQ_U300_UART1 53 +#define IRQ_U300_GPIO_PORT4 54 +#define IRQ_U300_GPIO_PORT5 55 +#define IRQ_U300_GPIO_PORT6 56 +#define U300_VIC_IRQS_END 57 + +/* Maximum 8*7 GPIO lines */ +#ifdef CONFIG_PINCTRL_COH901 +#define IRQ_U300_GPIO_BASE (U300_VIC_IRQS_END) +#define IRQ_U300_GPIO_END (IRQ_U300_GPIO_BASE + 56) +#else +#define IRQ_U300_GPIO_END (U300_VIC_IRQS_END) +#endif + +#define NR_IRQS_U300 (IRQ_U300_GPIO_END - IRQ_U300_INTCON0_START) #endif diff --git a/trunk/arch/arm/mach-ux500/board-mop500-audio.c b/trunk/arch/arm/mach-ux500/board-mop500-audio.c index 33631c9f1218..070629a95625 100644 --- a/trunk/arch/arm/mach-ux500/board-mop500-audio.c +++ b/trunk/arch/arm/mach-ux500/board-mop500-audio.c @@ -7,8 +7,9 @@ #include #include #include -#include +#include +#include #include #include diff --git a/trunk/arch/arm/mach-ux500/board-mop500-pins.c b/trunk/arch/arm/mach-ux500/board-mop500-pins.c index c34d4efd0d5c..a267c6d30e37 100644 --- a/trunk/arch/arm/mach-ux500/board-mop500-pins.c +++ b/trunk/arch/arm/mach-ux500/board-mop500-pins.c @@ -9,9 +9,10 @@ #include #include #include -#include #include +#include +#include #include diff --git a/trunk/arch/arm/mach-ux500/board-mop500.c b/trunk/arch/arm/mach-ux500/board-mop500.c index 0a3dd601a400..416d436111f2 100644 --- a/trunk/arch/arm/mach-ux500/board-mop500.c +++ b/trunk/arch/arm/mach-ux500/board-mop500.c @@ -37,13 +37,13 @@ #include #include #include -#include #include #include #include #include +#include #include #include diff --git a/trunk/arch/arm/mach-ux500/cpu-db8500.c b/trunk/arch/arm/mach-ux500/cpu-db8500.c index 91f028c1264a..bcdfe6b1d453 100644 --- a/trunk/arch/arm/mach-ux500/cpu-db8500.c +++ b/trunk/arch/arm/mach-ux500/cpu-db8500.c @@ -17,14 +17,14 @@ #include #include #include -#include -#include #include #include +#include #include #include #include +#include #include #include "devices-db8500.h" @@ -158,7 +158,7 @@ static void __init db8500_add_gpios(struct device *parent) dbx500_add_gpios(parent, ARRAY_AND_SIZE(db8500_gpio_base), IRQ_DB8500_GPIO0, &pdata); - dbx500_add_pinctrl(parent, "pinctrl-db8500", U8500_PRCMU_BASE); + dbx500_add_pinctrl(parent, "pinctrl-db8500"); } static int usb_db8500_rx_dma_cfg[] = { @@ -214,6 +214,9 @@ struct device * __init u8500_init_devices(struct ab8500_platform_data *ab8500) db8500_add_gpios(parent); db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); + platform_device_register_data(parent, + "cpufreq-u8500", -1, NULL, 0); + for (i = 0; i < ARRAY_SIZE(platform_devs); i++) platform_devs[i]->dev.parent = parent; @@ -233,6 +236,9 @@ struct device * __init u8500_of_init_devices(void) db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); + platform_device_register_data(parent, + "cpufreq-u8500", -1, NULL, 0); + u8500_dma40_device.dev.parent = parent; /* diff --git a/trunk/arch/arm/mach-ux500/cpu.c b/trunk/arch/arm/mach-ux500/cpu.c index 1f3fbc2bb776..2236cbd03cd7 100644 --- a/trunk/arch/arm/mach-ux500/cpu.c +++ b/trunk/arch/arm/mach-ux500/cpu.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/arm/mach-ux500/devices-common.c b/trunk/arch/arm/mach-ux500/devices-common.c index 692a77a1c153..dfdd4a54668d 100644 --- a/trunk/arch/arm/mach-ux500/devices-common.c +++ b/trunk/arch/arm/mach-ux500/devices-common.c @@ -11,7 +11,8 @@ #include #include #include -#include + +#include #include diff --git a/trunk/arch/arm/mach-ux500/devices-common.h b/trunk/arch/arm/mach-ux500/devices-common.h index 96fa4ac89e2e..7fbf0ba336e1 100644 --- a/trunk/arch/arm/mach-ux500/devices-common.h +++ b/trunk/arch/arm/mach-ux500/devices-common.h @@ -129,18 +129,12 @@ void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num, int irq, struct nmk_gpio_platform_data *pdata); static inline void -dbx500_add_pinctrl(struct device *parent, const char *name, - resource_size_t base) +dbx500_add_pinctrl(struct device *parent, const char *name) { - struct resource res[] = { - DEFINE_RES_MEM(base, SZ_8K), - }; struct platform_device_info pdevinfo = { .parent = parent, .name = name, .id = -1, - .res = res, - .num_res = ARRAY_SIZE(res), }; platform_device_register_full(&pdevinfo); diff --git a/trunk/arch/arm/mm/alignment.c b/trunk/arch/arm/mm/alignment.c index b820edaf3184..b9f60ebe3bc4 100644 --- a/trunk/arch/arm/mm/alignment.c +++ b/trunk/arch/arm/mm/alignment.c @@ -745,7 +745,7 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs, static int do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { - union offset_union uninitialized_var(offset); + union offset_union offset; unsigned long instr = 0, instrptr; int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs); unsigned int type; @@ -856,10 +856,8 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) if (thumb2_32b) { offset.un = 0; handler = do_alignment_t32_to_handler(&instr, regs, &offset); - } else { - offset.un = 0; + } else handler = do_alignment_ldmstm; - } break; default: diff --git a/trunk/arch/arm/mm/dma-mapping.c b/trunk/arch/arm/mm/dma-mapping.c index 58bc3e4d3bd0..477a2d23ddf1 100644 --- a/trunk/arch/arm/mm/dma-mapping.c +++ b/trunk/arch/arm/mm/dma-mapping.c @@ -610,7 +610,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, pgprot_t prot, bool is_coherent, const void *caller) { u64 mask = get_coherent_dma_mask(dev); - struct page *page = NULL; + struct page *page; void *addr; #ifdef CONFIG_DMA_API_DEBUG diff --git a/trunk/arch/arm/mm/proc-v6.S b/trunk/arch/arm/mm/proc-v6.S index 09c5233f4dfc..86b8b480634f 100644 --- a/trunk/arch/arm/mm/proc-v6.S +++ b/trunk/arch/arm/mm/proc-v6.S @@ -89,7 +89,7 @@ ENTRY(cpu_v6_dcache_clean_area) mov pc, lr /* - * cpu_v6_switch_mm(pgd_phys, tsk) + * cpu_arm926_switch_mm(pgd_phys, tsk) * * Set the translation table base pointer to be pgd_phys * diff --git a/trunk/arch/arm/mm/vmregion.h b/trunk/arch/arm/mm/vmregion.h index 0f5a5f2a2c7b..bf312c354a21 100644 --- a/trunk/arch/arm/mm/vmregion.h +++ b/trunk/arch/arm/mm/vmregion.h @@ -17,6 +17,7 @@ struct arm_vmregion { struct list_head vm_list; unsigned long vm_start; unsigned long vm_end; + void *priv; int vm_active; const void *caller; }; diff --git a/trunk/arch/arm/plat-mxc/devices/platform-mxc-mmc.c b/trunk/arch/arm/plat-mxc/devices/platform-mxc-mmc.c index e7b920b58675..540d3a7d92df 100644 --- a/trunk/arch/arm/plat-mxc/devices/platform-mxc-mmc.c +++ b/trunk/arch/arm/plat-mxc/devices/platform-mxc-mmc.c @@ -55,7 +55,7 @@ struct platform_device *__init imx_add_mxc_mmc( struct resource res[] = { { .start = data->iobase, - .end = data->iobase + data->iosize - 1, + .end = data->iobase + SZ_4K - 1, .flags = IORESOURCE_MEM, }, { .start = data->irq, diff --git a/trunk/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h b/trunk/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h new file mode 100644 index 000000000000..c08a54d9d889 --- /dev/null +++ b/trunk/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h @@ -0,0 +1,102 @@ +/* + * Structures and registers for GPIO access in the Nomadik SoC + * + * Copyright (C) 2008 STMicroelectronics + * Author: Prafulla WADASKAR + * Copyright (C) 2009 Alessandro Rubini + * + * 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. + */ + +#ifndef __PLAT_NOMADIK_GPIO +#define __PLAT_NOMADIK_GPIO + +/* + * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving + * the "gpio" namespace for generic and cross-machine functions + */ + +/* Register in the logic block */ +#define NMK_GPIO_DAT 0x00 +#define NMK_GPIO_DATS 0x04 +#define NMK_GPIO_DATC 0x08 +#define NMK_GPIO_PDIS 0x0c +#define NMK_GPIO_DIR 0x10 +#define NMK_GPIO_DIRS 0x14 +#define NMK_GPIO_DIRC 0x18 +#define NMK_GPIO_SLPC 0x1c +#define NMK_GPIO_AFSLA 0x20 +#define NMK_GPIO_AFSLB 0x24 +#define NMK_GPIO_LOWEMI 0x28 + +#define NMK_GPIO_RIMSC 0x40 +#define NMK_GPIO_FIMSC 0x44 +#define NMK_GPIO_IS 0x48 +#define NMK_GPIO_IC 0x4c +#define NMK_GPIO_RWIMSC 0x50 +#define NMK_GPIO_FWIMSC 0x54 +#define NMK_GPIO_WKS 0x58 + +/* Alternate functions: function C is set in hw by setting both A and B */ +#define NMK_GPIO_ALT_GPIO 0 +#define NMK_GPIO_ALT_A 1 +#define NMK_GPIO_ALT_B 2 +#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B) + +#define NMK_GPIO_ALT_CX_SHIFT 2 +#define NMK_GPIO_ALT_C1 ((1< - * Copyright (C) 2009 Alessandro Rubini + * License terms: GNU General Public License, version 2 + * Author: Rabin Vincent for ST-Ericsson * - * 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. + * Based on arch/arm/mach-pxa/include/mach/mfp.h: + * Copyright (C) 2007 Marvell International Ltd. + * eric miao */ -#ifndef __PLAT_NOMADIK_GPIO -#define __PLAT_NOMADIK_GPIO +#ifndef __PLAT_PINCFG_H +#define __PLAT_PINCFG_H /* * pin configurations are represented by 32-bit integers: @@ -167,100 +166,8 @@ typedef unsigned long pin_cfg_t; (PIN_CFG_DEFAULT |\ (PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val)) -/* - * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving - * the "gpio" namespace for generic and cross-machine functions - */ - -#define GPIO_BLOCK_SHIFT 5 -#define NMK_GPIO_PER_CHIP (1 << GPIO_BLOCK_SHIFT) - -/* Register in the logic block */ -#define NMK_GPIO_DAT 0x00 -#define NMK_GPIO_DATS 0x04 -#define NMK_GPIO_DATC 0x08 -#define NMK_GPIO_PDIS 0x0c -#define NMK_GPIO_DIR 0x10 -#define NMK_GPIO_DIRS 0x14 -#define NMK_GPIO_DIRC 0x18 -#define NMK_GPIO_SLPC 0x1c -#define NMK_GPIO_AFSLA 0x20 -#define NMK_GPIO_AFSLB 0x24 -#define NMK_GPIO_LOWEMI 0x28 - -#define NMK_GPIO_RIMSC 0x40 -#define NMK_GPIO_FIMSC 0x44 -#define NMK_GPIO_IS 0x48 -#define NMK_GPIO_IC 0x4c -#define NMK_GPIO_RWIMSC 0x50 -#define NMK_GPIO_FWIMSC 0x54 -#define NMK_GPIO_WKS 0x58 -/* These appear in DB8540 and later ASICs */ -#define NMK_GPIO_EDGELEVEL 0x5C -#define NMK_GPIO_LEVEL 0x60 - -/* Alternate functions: function C is set in hw by setting both A and B */ -#define NMK_GPIO_ALT_GPIO 0 -#define NMK_GPIO_ALT_A 1 -#define NMK_GPIO_ALT_B 2 -#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B) - -#define NMK_GPIO_ALT_CX_SHIFT 2 -#define NMK_GPIO_ALT_C1 ((1< #include #include -#include #include #include #include #include #include -#include #include #define OMAP_I2C_SIZE 0x3f @@ -129,16 +127,6 @@ static inline int omap1_i2c_add_bus(int bus_id) #ifdef CONFIG_ARCH_OMAP2PLUS -/* - * XXX This function is a temporary compatibility wrapper - only - * needed until the I2C driver can be converted to call - * omap_pm_set_max_dev_wakeup_lat() and handle a return code. - */ -static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t) -{ - omap_pm_set_max_mpu_wakeup_lat(dev, t); -} - static inline int omap2_i2c_add_bus(int bus_id) { int l; @@ -170,15 +158,6 @@ static inline int omap2_i2c_add_bus(int bus_id) dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr; pdata->flags = dev_attr->flags; - /* - * When waiting for completion of a i2c transfer, we need to - * set a wake up latency constraint for the MPU. This is to - * ensure quick enough wakeup from idle, when transfer - * completes. - * Only omap3 has support for constraints - */ - if (cpu_is_omap34xx()) - pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(struct omap_i2c_bus_platform_data), NULL, 0, 0); diff --git a/trunk/arch/arm/plat-omap/include/plat/mmc.h b/trunk/arch/arm/plat-omap/include/plat/mmc.h index 346af5b490be..8b4e4f2da2f5 100644 --- a/trunk/arch/arm/plat-omap/include/plat/mmc.h +++ b/trunk/arch/arm/plat-omap/include/plat/mmc.h @@ -126,7 +126,6 @@ struct omap_mmc_platform_data { /* we can put the features above into this variable */ #define HSMMC_HAS_PBIAS (1 << 0) #define HSMMC_HAS_UPDATED_RESET (1 << 1) -#define HSMMC_HAS_HSPE_SUPPORT (1 << 2) unsigned features; int switch_pin; /* gpio (card detect) */ diff --git a/trunk/arch/arm/plat-omap/include/plat/omap-serial.h b/trunk/arch/arm/plat-omap/include/plat/omap-serial.h index 1957a8516e93..f4a4cd014795 100644 --- a/trunk/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/trunk/arch/arm/plat-omap/include/plat/omap-serial.h @@ -40,10 +40,10 @@ #define OMAP_UART_WER_MOD_WKUP 0X7F /* Enable XON/XOFF flow control on output */ -#define OMAP_UART_SW_TX 0x04 +#define OMAP_UART_SW_TX 0x8 /* Enable XON/XOFF flow control on input */ -#define OMAP_UART_SW_RX 0x04 +#define OMAP_UART_SW_RX 0x2 #define OMAP_UART_SYSC_RESET 0X07 #define OMAP_UART_TCR_TRIG 0X0F diff --git a/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h b/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h index 1db029438022..b3349f7b1a2c 100644 --- a/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -443,11 +443,6 @@ struct omap_hwmod_omap4_prcm { * in order to complete the reset. Optional clocks will be disabled * again after the reset. * HWMOD_16BIT_REG: Module has 16bit registers - * HWMOD_EXT_OPT_MAIN_CLK: The only main functional clock source for - * this IP block comes from an off-chip source and is not always - * enabled. This prevents the hwmod code from being able to - * enable and reset the IP block early. XXX Eventually it should - * be possible to query the clock framework for this information. */ #define HWMOD_SWSUP_SIDLE (1 << 0) #define HWMOD_SWSUP_MSTANDBY (1 << 1) @@ -458,7 +453,6 @@ struct omap_hwmod_omap4_prcm { #define HWMOD_NO_IDLEST (1 << 6) #define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7) #define HWMOD_16BIT_REG (1 << 8) -#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9) /* * omap_hwmod._int_flags definitions diff --git a/trunk/arch/arm/plat-s3c24xx/dma.c b/trunk/arch/arm/plat-s3c24xx/dma.c index 0abd1c469887..db98e7021f0d 100644 --- a/trunk/arch/arm/plat-s3c24xx/dma.c +++ b/trunk/arch/arm/plat-s3c24xx/dma.c @@ -473,13 +473,12 @@ int s3c2410_dma_enqueue(enum dma_ch channel, void *id, pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n", chan->number, __func__, buf); - if (chan->end == NULL) { + if (chan->end == NULL) pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n", chan->number, __func__, chan); - } else { - chan->end->next = buf; - chan->end = buf; - } + + chan->end->next = buf; + chan->end = buf; } /* if necessary, update the next buffer field */ diff --git a/trunk/arch/arm/plat-samsung/include/plat/spi-core.h b/trunk/arch/arm/plat-samsung/include/plat/spi-core.h deleted file mode 100644 index 0b9428ab3fc3..000000000000 --- a/trunk/arch/arm/plat-samsung/include/plat/spi-core.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2012 Heiko Stuebner - * - * 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. - */ - -#ifndef __PLAT_S3C_SPI_CORE_H -#define __PLAT_S3C_SPI_CORE_H - -/* These functions are only for use with the core support code, such as - * the cpu specific initialisation code - */ - -/* re-define device name depending on support. */ -static inline void s3c64xx_spi_setname(char *name) -{ -#ifdef CONFIG_S3C64XX_DEV_SPI0 - s3c64xx_device_spi0.name = name; -#endif -#ifdef CONFIG_S3C64XX_DEV_SPI1 - s3c64xx_device_spi1.name = name; -#endif -#ifdef CONFIG_S3C64XX_DEV_SPI2 - s3c64xx_device_spi2.name = name; -#endif -} - -#endif /* __PLAT_S3C_SPI_CORE_H */ diff --git a/trunk/arch/arm/tools/Makefile b/trunk/arch/arm/tools/Makefile index 32d05c8219dc..635cb1865e4d 100644 --- a/trunk/arch/arm/tools/Makefile +++ b/trunk/arch/arm/tools/Makefile @@ -5,6 +5,6 @@ # include/generated/mach-types.h: $(src)/gen-mach-types $(src)/mach-types - @$(kecho) ' Generating $@' + @echo ' Generating $@' @mkdir -p $(dir $@) $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; } diff --git a/trunk/arch/arm/vfp/vfpmodule.c b/trunk/arch/arm/vfp/vfpmodule.c index 3b44e0dd0a93..c834b32af275 100644 --- a/trunk/arch/arm/vfp/vfpmodule.c +++ b/trunk/arch/arm/vfp/vfpmodule.c @@ -701,14 +701,11 @@ static int __init vfp_init(void) elf_hwcap |= HWCAP_VFPv3; /* - * Check for VFPv3 D16 and VFPv4 D16. CPUs in - * this configuration only have 16 x 64bit - * registers. + * Check for VFPv3 D16. CPUs in this configuration + * only have 16 x 64bit registers. */ if (((fmrx(MVFR0) & MVFR0_A_SIMD_MASK)) == 1) - elf_hwcap |= HWCAP_VFPv3D16; /* also v4-D16 */ - else - elf_hwcap |= HWCAP_VFPD32; + elf_hwcap |= HWCAP_VFPv3D16; } #endif /* diff --git a/trunk/arch/arm/xen/enlighten.c b/trunk/arch/arm/xen/enlighten.c index f57609275449..59bcb96ac369 100644 --- a/trunk/arch/arm/xen/enlighten.c +++ b/trunk/arch/arm/xen/enlighten.c @@ -166,14 +166,3 @@ void free_xenballooned_pages(int nr_pages, struct page **pages) *pages = NULL; } EXPORT_SYMBOL_GPL(free_xenballooned_pages); - -/* In the hypervisor.S file. */ -EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op); -EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op); -EXPORT_SYMBOL_GPL(HYPERVISOR_xen_version); -EXPORT_SYMBOL_GPL(HYPERVISOR_console_io); -EXPORT_SYMBOL_GPL(HYPERVISOR_sched_op); -EXPORT_SYMBOL_GPL(HYPERVISOR_hvm_op); -EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op); -EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op); -EXPORT_SYMBOL_GPL(privcmd_call); diff --git a/trunk/arch/arm/xen/grant-table.c b/trunk/arch/arm/xen/grant-table.c index 859a9bb002d5..dbd1330c0196 100644 --- a/trunk/arch/arm/xen/grant-table.c +++ b/trunk/arch/arm/xen/grant-table.c @@ -33,7 +33,7 @@ #include #include -int arch_gnttab_map_shared(xen_pfn_t *frames, unsigned long nr_gframes, +int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes, unsigned long max_nr_gframes, void **__shared) { diff --git a/trunk/arch/arm/xen/hypercall.S b/trunk/arch/arm/xen/hypercall.S index 71f723984cbd..074f5ed101b9 100644 --- a/trunk/arch/arm/xen/hypercall.S +++ b/trunk/arch/arm/xen/hypercall.S @@ -48,16 +48,20 @@ #include #include -#include #include -#define XEN_IMM 0xEA1 +/* HVC 0xEA1 */ +#ifdef CONFIG_THUMB2_KERNEL +#define xen_hvc .word 0xf7e08ea1 +#else +#define xen_hvc .word 0xe140ea71 +#endif #define HYPERCALL_SIMPLE(hypercall) \ ENTRY(HYPERVISOR_##hypercall) \ mov r12, #__HYPERVISOR_##hypercall; \ - __HVC(XEN_IMM); \ + xen_hvc; \ mov pc, lr; \ ENDPROC(HYPERVISOR_##hypercall) @@ -72,7 +76,7 @@ ENTRY(HYPERVISOR_##hypercall) \ stmdb sp!, {r4} \ ldr r4, [sp, #4] \ mov r12, #__HYPERVISOR_##hypercall; \ - __HVC(XEN_IMM); \ + xen_hvc \ ldm sp!, {r4} \ mov pc, lr \ ENDPROC(HYPERVISOR_##hypercall) @@ -96,7 +100,7 @@ ENTRY(privcmd_call) mov r2, r3 ldr r3, [sp, #8] ldr r4, [sp, #4] - __HVC(XEN_IMM) + xen_hvc ldm sp!, {r4} mov pc, lr ENDPROC(privcmd_call); diff --git a/trunk/arch/arm64/Kconfig b/trunk/arch/arm64/Kconfig index 15ac18a56c93..ef54a59a9e89 100644 --- a/trunk/arch/arm64/Kconfig +++ b/trunk/arch/arm64/Kconfig @@ -1,7 +1,6 @@ config ARM64 def_bool y select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE - select ARCH_WANT_COMPAT_IPC_PARSE_VERSION select GENERIC_CLOCKEVENTS select GENERIC_HARDIRQS_NO_DEPRECATED select GENERIC_IOMAP diff --git a/trunk/arch/arm64/include/asm/elf.h b/trunk/arch/arm64/include/asm/elf.h index 07fea290d7c1..cf284649dfcb 100644 --- a/trunk/arch/arm64/include/asm/elf.h +++ b/trunk/arch/arm64/include/asm/elf.h @@ -25,10 +25,12 @@ #include typedef unsigned long elf_greg_t; +typedef unsigned long elf_freg_t[3]; #define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t)) typedef elf_greg_t elf_gregset_t[ELF_NGREG]; -typedef struct user_fpsimd_state elf_fpregset_t; + +typedef struct user_fp elf_fpregset_t; #define EM_AARCH64 183 @@ -85,6 +87,7 @@ typedef struct user_fpsimd_state elf_fpregset_t; #define R_AARCH64_MOVW_PREL_G2_NC 292 #define R_AARCH64_MOVW_PREL_G3 293 + /* * These are used to set parameters in the core dumps. */ diff --git a/trunk/arch/arm64/include/asm/fpsimd.h b/trunk/arch/arm64/include/asm/fpsimd.h index c43b4ac13008..b42fab9f62a9 100644 --- a/trunk/arch/arm64/include/asm/fpsimd.h +++ b/trunk/arch/arm64/include/asm/fpsimd.h @@ -25,8 +25,9 @@ * - FPSR and FPCR * - 32 128-bit data registers * - * Note that user_fpsimd forms a prefix of this structure, which is - * relied upon in the ptrace FP/SIMD accessors. + * Note that user_fp forms a prefix of this structure, which is relied + * upon in the ptrace FP/SIMD accessors. struct user_fpsimd_state must + * form a prefix of struct fpsimd_state. */ struct fpsimd_state { union { diff --git a/trunk/arch/arm64/include/asm/io.h b/trunk/arch/arm64/include/asm/io.h index d2f05a608274..74a2a7d304a9 100644 --- a/trunk/arch/arm64/include/asm/io.h +++ b/trunk/arch/arm64/include/asm/io.h @@ -114,7 +114,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) * I/O port access primitives. */ #define IO_SPACE_LIMIT 0xffff -#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_2M)) +#define PCI_IOBASE ((void __iomem *)0xffffffbbfffe0000UL) static inline u8 inb(unsigned long addr) { @@ -222,12 +222,12 @@ extern void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot extern void __iounmap(volatile void __iomem *addr); #define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_DIRTY) -#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) +#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_XN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) #define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC)) -#define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) -#define ioremap_nocache(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) -#define ioremap_wc(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC)) +#define ioremap(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE) +#define ioremap_nocache(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE) +#define ioremap_wc(addr, size) __ioremap((addr), (size), PROT_NORMAL_NC) #define iounmap __iounmap #define ARCH_HAS_IOREMAP_WC diff --git a/trunk/arch/arm64/include/asm/pgtable-hwdef.h b/trunk/arch/arm64/include/asm/pgtable-hwdef.h index 75fd13d289b9..0f3b4581d925 100644 --- a/trunk/arch/arm64/include/asm/pgtable-hwdef.h +++ b/trunk/arch/arm64/include/asm/pgtable-hwdef.h @@ -38,8 +38,7 @@ #define PMD_SECT_S (_AT(pmdval_t, 3) << 8) #define PMD_SECT_AF (_AT(pmdval_t, 1) << 10) #define PMD_SECT_NG (_AT(pmdval_t, 1) << 11) -#define PMD_SECT_PXN (_AT(pmdval_t, 1) << 53) -#define PMD_SECT_UXN (_AT(pmdval_t, 1) << 54) +#define PMD_SECT_XN (_AT(pmdval_t, 1) << 54) /* * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). @@ -58,8 +57,7 @@ #define PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ #define PTE_AF (_AT(pteval_t, 1) << 10) /* Access Flag */ #define PTE_NG (_AT(pteval_t, 1) << 11) /* nG */ -#define PTE_PXN (_AT(pteval_t, 1) << 53) /* Privileged XN */ -#define PTE_UXN (_AT(pteval_t, 1) << 54) /* User XN */ +#define PTE_XN (_AT(pteval_t, 1) << 54) /* XN */ /* * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). diff --git a/trunk/arch/arm64/include/asm/pgtable.h b/trunk/arch/arm64/include/asm/pgtable.h index 14aba2db6776..8960239be722 100644 --- a/trunk/arch/arm64/include/asm/pgtable.h +++ b/trunk/arch/arm64/include/asm/pgtable.h @@ -62,23 +62,23 @@ extern pgprot_t pgprot_default; #define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b)) -#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) -#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) -#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN) -#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) -#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) -#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) -#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) -#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY) -#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY) - -#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) -#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) -#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) -#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) -#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) -#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) -#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) +#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_XN | PTE_RDONLY) +#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN) +#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG) +#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) +#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY) +#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) +#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY) +#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_XN | PTE_DIRTY) +#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_DIRTY) + +#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_XN | PTE_RDONLY) +#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN) +#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG) +#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) +#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY) +#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) +#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY) #endif /* __ASSEMBLY__ */ @@ -130,10 +130,10 @@ extern struct page *empty_zero_page; #define pte_young(pte) (pte_val(pte) & PTE_AF) #define pte_special(pte) (pte_val(pte) & PTE_SPECIAL) #define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY)) -#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) +#define pte_exec(pte) (!(pte_val(pte) & PTE_XN)) #define pte_present_exec_user(pte) \ - ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == \ + ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_XN)) == \ (PTE_VALID | PTE_USER)) #define PTE_BIT_FUNC(fn,op) \ @@ -262,7 +262,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { - const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY; + const pteval_t mask = PTE_USER | PTE_XN | PTE_RDONLY; pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); return pte; } diff --git a/trunk/arch/arm64/include/asm/processor.h b/trunk/arch/arm64/include/asm/processor.h index 77f696c14339..5d810044feda 100644 --- a/trunk/arch/arm64/include/asm/processor.h +++ b/trunk/arch/arm64/include/asm/processor.h @@ -43,8 +43,6 @@ #else #define STACK_TOP STACK_TOP_MAX #endif /* CONFIG_COMPAT */ - -#define ARCH_LOW_ADDRESS_LIMIT PHYS_MASK #endif /* __KERNEL__ */ struct debug_info { diff --git a/trunk/arch/arm64/include/asm/unistd.h b/trunk/arch/arm64/include/asm/unistd.h index 68aff2816e86..63f853f8b718 100644 --- a/trunk/arch/arm64/include/asm/unistd.h +++ b/trunk/arch/arm64/include/asm/unistd.h @@ -14,6 +14,7 @@ * along with this program. If not, see . */ #ifdef CONFIG_COMPAT +#define __ARCH_WANT_COMPAT_IPC_PARSE_VERSION #define __ARCH_WANT_COMPAT_STAT64 #define __ARCH_WANT_SYS_GETHOSTNAME #define __ARCH_WANT_SYS_PAUSE diff --git a/trunk/arch/arm64/include/asm/unistd32.h b/trunk/arch/arm64/include/asm/unistd32.h index 656a6f291a35..6d909faebf28 100644 --- a/trunk/arch/arm64/include/asm/unistd32.h +++ b/trunk/arch/arm64/include/asm/unistd32.h @@ -392,7 +392,7 @@ __SYSCALL(367, sys_fanotify_init) __SYSCALL(368, compat_sys_fanotify_mark_wrapper) __SYSCALL(369, sys_prlimit64) __SYSCALL(370, sys_name_to_handle_at) -__SYSCALL(371, compat_sys_open_by_handle_at) +__SYSCALL(371, sys_open_by_handle_at) __SYSCALL(372, sys_clock_adjtime) __SYSCALL(373, sys_syncfs) diff --git a/trunk/arch/arm64/kernel/perf_event.c b/trunk/arch/arm64/kernel/perf_event.c index c76c7241125b..ecbf2d81ec5c 100644 --- a/trunk/arch/arm64/kernel/perf_event.c +++ b/trunk/arch/arm64/kernel/perf_event.c @@ -613,11 +613,17 @@ enum armv8_pmuv3_perf_types { ARMV8_PMUV3_PERFCTR_BUS_ACCESS = 0x19, ARMV8_PMUV3_PERFCTR_MEM_ERROR = 0x1A, ARMV8_PMUV3_PERFCTR_BUS_CYCLES = 0x1D, + + /* + * This isn't an architected event. + * We detect this event number and use the cycle counter instead. + */ + ARMV8_PMUV3_PERFCTR_CPU_CYCLES = 0xFF, }; /* PMUv3 HW events mapping. */ static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = { - [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES, + [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES, [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED, [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS, [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL, @@ -1100,7 +1106,7 @@ static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc, unsigned long evtype = event->config_base & ARMV8_EVTYPE_EVENT; /* Always place a cycle counter into the cycle counter. */ - if (evtype == ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES) { + if (evtype == ARMV8_PMUV3_PERFCTR_CPU_CYCLES) { if (test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask)) return -EAGAIN; diff --git a/trunk/arch/arm64/kernel/process.c b/trunk/arch/arm64/kernel/process.c index e04cebdbb47f..f22965ea1cfc 100644 --- a/trunk/arch/arm64/kernel/process.c +++ b/trunk/arch/arm64/kernel/process.c @@ -309,6 +309,24 @@ struct task_struct *__switch_to(struct task_struct *prev, return last; } +/* + * Fill in the task's elfregs structure for a core dump. + */ +int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs) +{ + elf_core_copy_regs(elfregs, task_pt_regs(t)); + return 1; +} + +/* + * fill in the fpe structure for a core dump... + */ +int dump_fpu (struct pt_regs *regs, struct user_fp *fp) +{ + return 0; +} +EXPORT_SYMBOL(dump_fpu); + /* * Shuffle the argument into the correct register before calling the * thread function. x1 is the thread argument, x2 is the pointer to diff --git a/trunk/arch/arm64/kernel/smp.c b/trunk/arch/arm64/kernel/smp.c index 538300f2273d..226b6bf6e9c2 100644 --- a/trunk/arch/arm64/kernel/smp.c +++ b/trunk/arch/arm64/kernel/smp.c @@ -211,7 +211,8 @@ asmlinkage void __cpuinit secondary_start_kernel(void) * before we continue. */ set_cpu_online(cpu, true); - complete(&cpu_running); + while (!cpu_active(cpu)) + cpu_relax(); /* * OK, it's off to the idle thread for us diff --git a/trunk/arch/arm64/mm/init.c b/trunk/arch/arm64/mm/init.c index 4cd28931dba9..efbf7df05d3f 100644 --- a/trunk/arch/arm64/mm/init.c +++ b/trunk/arch/arm64/mm/init.c @@ -80,7 +80,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) #ifdef CONFIG_ZONE_DMA32 /* 4GB maximum for 32-bit only capable devices */ max_dma32 = min(max, MAX_DMA32_PFN); - zone_size[ZONE_DMA32] = max(min, max_dma32) - min; + zone_size[ZONE_DMA32] = max_dma32 - min; #endif zone_size[ZONE_NORMAL] = max - max_dma32; diff --git a/trunk/arch/c6x/include/asm/setup.h b/trunk/arch/c6x/include/asm/setup.h deleted file mode 100644 index ecead15872a6..000000000000 --- a/trunk/arch/c6x/include/asm/setup.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - * - * 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. - */ -#ifndef _ASM_C6X_SETUP_H -#define _ASM_C6X_SETUP_H - -#include - -#ifndef __ASSEMBLY__ -extern char c6x_command_line[COMMAND_LINE_SIZE]; - -extern int c6x_add_memory(phys_addr_t start, unsigned long size); - -extern unsigned long ram_start; -extern unsigned long ram_end; - -extern int c6x_num_cores; -extern unsigned int c6x_silicon_rev; -extern unsigned int c6x_devstat; -extern unsigned char c6x_fuse_mac[6]; - -extern void machine_init(unsigned long dt_ptr); -extern void time_init(void); - -#endif /* !__ASSEMBLY__ */ -#endif /* _ASM_C6X_SETUP_H */ diff --git a/trunk/arch/c6x/include/uapi/asm/Kbuild b/trunk/arch/c6x/include/uapi/asm/Kbuild index e9bc2b2b8147..c312b424c433 100644 --- a/trunk/arch/c6x/include/uapi/asm/Kbuild +++ b/trunk/arch/c6x/include/uapi/asm/Kbuild @@ -1,8 +1,6 @@ # UAPI Header export list include include/uapi/asm-generic/Kbuild.asm -generic-y += kvm_para.h - header-y += byteorder.h header-y += kvm_para.h header-y += ptrace.h diff --git a/trunk/arch/c6x/include/uapi/asm/kvm_para.h b/trunk/arch/c6x/include/uapi/asm/kvm_para.h new file mode 100644 index 000000000000..14fab8f0b957 --- /dev/null +++ b/trunk/arch/c6x/include/uapi/asm/kvm_para.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/c6x/include/uapi/asm/setup.h b/trunk/arch/c6x/include/uapi/asm/setup.h index ad9ac97a8dad..a01e31896fa9 100644 --- a/trunk/arch/c6x/include/uapi/asm/setup.h +++ b/trunk/arch/c6x/include/uapi/asm/setup.h @@ -1,6 +1,33 @@ -#ifndef _UAPI_ASM_C6X_SETUP_H -#define _UAPI_ASM_C6X_SETUP_H +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + * 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. + */ +#ifndef _ASM_C6X_SETUP_H +#define _ASM_C6X_SETUP_H #define COMMAND_LINE_SIZE 1024 -#endif /* _UAPI_ASM_C6X_SETUP_H */ +#ifndef __ASSEMBLY__ +extern char c6x_command_line[COMMAND_LINE_SIZE]; + +extern int c6x_add_memory(phys_addr_t start, unsigned long size); + +extern unsigned long ram_start; +extern unsigned long ram_end; + +extern int c6x_num_cores; +extern unsigned int c6x_silicon_rev; +extern unsigned int c6x_devstat; +extern unsigned char c6x_fuse_mac[6]; + +extern void machine_init(unsigned long dt_ptr); +extern void time_init(void); + +#endif /* !__ASSEMBLY__ */ +#endif /* _ASM_C6X_SETUP_H */ diff --git a/trunk/arch/c6x/kernel/entry.S b/trunk/arch/c6x/kernel/entry.S index 0ed6157dd256..5449c36018fe 100644 --- a/trunk/arch/c6x/kernel/entry.S +++ b/trunk/arch/c6x/kernel/entry.S @@ -277,8 +277,6 @@ work_rescheduled: [A1] BNOP .S1 work_resched,5 work_notifysig: - ;; enable interrupts for do_notify_resume() - UNMASK_INT B2 B .S2 do_notify_resume LDW .D2T1 *+SP(REGS__END+8),A6 ; syscall flag ADDKPC .S2 resume_userspace,B3,1 @@ -429,7 +427,8 @@ ENTRY(ret_from_kernel_execve) ENDPROC(ret_from_kernel_execve) ;; - ;; These are the interrupt handlers, responsible for calling c6x_do_IRQ() + ;; These are the interrupt handlers, responsible for calling __do_IRQ() + ;; int6 is used for syscalls (see _system_call entry) ;; .macro SAVE_ALL_INT SAVE_ALL IRP,ITSR diff --git a/trunk/arch/frv/Kconfig b/trunk/arch/frv/Kconfig index df2eb4bd9fa2..b7412504f08a 100644 --- a/trunk/arch/frv/Kconfig +++ b/trunk/arch/frv/Kconfig @@ -13,7 +13,6 @@ config FRV select GENERIC_CPU_DEVICES select ARCH_WANT_IPC_PARSE_VERSION select GENERIC_KERNEL_THREAD - select GENERIC_KERNEL_EXECVE config ZONE_DMA bool diff --git a/trunk/arch/frv/boot/Makefile b/trunk/arch/frv/boot/Makefile index 636d5bbcd53f..6ae3254da019 100644 --- a/trunk/arch/frv/boot/Makefile +++ b/trunk/arch/frv/boot/Makefile @@ -17,8 +17,6 @@ PARAMS_PHYS = 0x0207c000 INITRD_PHYS = 0x02180000 INITRD_VIRT = 0x02180000 -OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment - # # If you don't define ZRELADDR above, # then it defaults to ZTEXTADDR @@ -34,18 +32,18 @@ Image: $(obj)/Image targets: $(obj)/Image $(obj)/Image: vmlinux FORCE - $(OBJCOPY) $(OBJCOPYFLAGS) -S vmlinux $@ + $(OBJCOPY) -O binary -R .note -R .comment -S vmlinux $@ #$(obj)/Image: $(CONFIGURE) $(SYSTEM) -# $(OBJCOPY) $(OBJCOPYFLAGS) -g -S $(SYSTEM) $@ +# $(OBJCOPY) -O binary -R .note -R .comment -g -S $(SYSTEM) $@ bzImage: zImage zImage: $(CONFIGURE) compressed/$(LINUX) - $(OBJCOPY) $(OBJCOPYFLAGS) -S compressed/$(LINUX) $@ + $(OBJCOPY) -O binary -R .note -R .comment -S compressed/$(LINUX) $@ bootpImage: bootp/bootp - $(OBJCOPY) $(OBJCOPYFLAGS) -S bootp/bootp $@ + $(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@ compressed/$(LINUX): $(LINUX) dep @$(MAKE) -C compressed $(LINUX) diff --git a/trunk/arch/frv/include/asm/unistd.h b/trunk/arch/frv/include/asm/unistd.h index 2358634cacca..266a5b25a0c1 100644 --- a/trunk/arch/frv/include/asm/unistd.h +++ b/trunk/arch/frv/include/asm/unistd.h @@ -30,6 +30,7 @@ #define __ARCH_WANT_SYS_RT_SIGACTION #define __ARCH_WANT_SYS_RT_SIGSUSPEND #define __ARCH_WANT_SYS_EXECVE +#define __ARCH_WANT_KERNEL_EXECVE /* * "Conditional" syscalls diff --git a/trunk/arch/frv/kernel/entry.S b/trunk/arch/frv/kernel/entry.S index dfcd263c0517..ee0beb354e4d 100644 --- a/trunk/arch/frv/kernel/entry.S +++ b/trunk/arch/frv/kernel/entry.S @@ -869,6 +869,11 @@ ret_from_kernel_thread: call schedule_tail calll.p @(gr21,gr0) or gr20,gr20,gr8 + bra sys_exit + + .globl ret_from_kernel_execve +ret_from_kernel_execve: + ori gr28,0,sp bra __syscall_exit ################################################################################################### @@ -1075,10 +1080,27 @@ __entry_return_from_kernel_interrupt: subicc gr5,#0,gr0,icc0 beq icc0,#0,__entry_return_direct - subcc gr0,gr0,gr0,icc2 /* set Z and clear C */ - call preempt_schedule_irq -#endif +__entry_preempt_need_resched: + ldi @(gr15,#TI_FLAGS),gr4 + andicc gr4,#_TIF_NEED_RESCHED,gr0,icc0 + beq icc0,#1,__entry_return_direct + + setlos #PREEMPT_ACTIVE,gr5 + sti gr5,@(gr15,#TI_FLAGS) + + andi gr23,#~PSR_PIL,gr23 + movgs gr23,psr + + call schedule + sti gr0,@(gr15,#TI_PRE_COUNT) + + movsg psr,gr23 + ori gr23,#PSR_PIL_14,gr23 + movgs gr23,psr + bra __entry_preempt_need_resched +#else bra __entry_return_direct +#endif ############################################################################### diff --git a/trunk/arch/frv/kernel/process.c b/trunk/arch/frv/kernel/process.c index 7e33215f1d8f..e1e3aa196aa4 100644 --- a/trunk/arch/frv/kernel/process.c +++ b/trunk/arch/frv/kernel/process.c @@ -181,9 +181,6 @@ int copy_thread(unsigned long clone_flags, childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE); - /* set up the userspace frame (the only place that the USP is stored) */ - *childregs = *__kernel_frame0_ptr; - p->set_child_tid = p->clear_child_tid = NULL; p->thread.frame = childregs; @@ -194,8 +191,10 @@ int copy_thread(unsigned long clone_flags, p->thread.frame0 = childregs; if (unlikely(!regs)) { + memset(childregs, 0, sizeof(struct pt_regs)); childregs->gr9 = usp; /* function */ childregs->gr8 = arg; + childregs->psr = PSR_S; p->thread.pc = (unsigned long) ret_from_kernel_thread; save_user_regs(p->thread.user); return 0; diff --git a/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c b/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c index b99c2a7cc7a4..e47857f889b6 100644 --- a/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c +++ b/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c @@ -11,7 +11,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/h8300/include/asm/cache.h b/trunk/arch/h8300/include/asm/cache.h index 05887a1d80e5..c6350283649d 100644 --- a/trunk/arch/h8300/include/asm/cache.h +++ b/trunk/arch/h8300/include/asm/cache.h @@ -2,8 +2,7 @@ #define __ARCH_H8300_CACHE_H /* bytes per L1 cache line */ -#define L1_CACHE_SHIFT 2 -#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) +#define L1_CACHE_BYTES 4 /* m68k-elf-gcc 2.95.2 doesn't like these */ diff --git a/trunk/arch/ia64/include/asm/Kbuild b/trunk/arch/ia64/include/asm/Kbuild index dd02f09b6eda..4a159da23633 100644 --- a/trunk/arch/ia64/include/asm/Kbuild +++ b/trunk/arch/ia64/include/asm/Kbuild @@ -1,4 +1,3 @@ generic-y += clkdev.h generic-y += exec.h -generic-y += kvm_para.h diff --git a/trunk/arch/ia64/include/asm/kvm_para.h b/trunk/arch/ia64/include/asm/kvm_para.h new file mode 100644 index 000000000000..47c00f910434 --- /dev/null +++ b/trunk/arch/ia64/include/asm/kvm_para.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2007 Xiantao Zhang + * + * 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. + * + */ +#ifndef __IA64_KVM_PARA_H +#define __IA64_KVM_PARA_H + +#include + + +static inline unsigned int kvm_arch_para_features(void) +{ + return 0; +} + +static inline bool kvm_check_and_clear_guest_paused(void) +{ + return false; +} + +#endif diff --git a/trunk/arch/ia64/mm/init.c b/trunk/arch/ia64/mm/init.c index 082e383c1b6f..acd5b68e8871 100644 --- a/trunk/arch/ia64/mm/init.c +++ b/trunk/arch/ia64/mm/init.c @@ -637,6 +637,7 @@ mem_init (void) high_memory = __va(max_low_pfn * PAGE_SIZE); + reset_zone_present_pages(); for_each_online_pgdat(pgdat) if (pgdat->bdata->node_bootmem_map) totalram_pages += free_all_bootmem_node(pgdat); diff --git a/trunk/arch/m68k/include/asm/Kbuild b/trunk/arch/m68k/include/asm/Kbuild index 88fa3ac86fae..ecb540810ab3 100644 --- a/trunk/arch/m68k/include/asm/Kbuild +++ b/trunk/arch/m68k/include/asm/Kbuild @@ -1,3 +1,5 @@ +include include/asm-generic/Kbuild.asm +header-y += cachectl.h generic-y += bitsperlong.h generic-y += clkdev.h diff --git a/trunk/arch/m68k/include/uapi/asm/a.out.h b/trunk/arch/m68k/include/asm/a.out.h similarity index 100% rename from trunk/arch/m68k/include/uapi/asm/a.out.h rename to trunk/arch/m68k/include/asm/a.out.h diff --git a/trunk/arch/m68k/include/uapi/asm/auxvec.h b/trunk/arch/m68k/include/asm/auxvec.h similarity index 100% rename from trunk/arch/m68k/include/uapi/asm/auxvec.h rename to trunk/arch/m68k/include/asm/auxvec.h diff --git a/trunk/arch/m68k/include/uapi/asm/byteorder.h b/trunk/arch/m68k/include/asm/byteorder.h similarity index 100% rename from trunk/arch/m68k/include/uapi/asm/byteorder.h rename to trunk/arch/m68k/include/asm/byteorder.h diff --git a/trunk/arch/m68k/include/uapi/asm/cachectl.h b/trunk/arch/m68k/include/asm/cachectl.h similarity index 100% rename from trunk/arch/m68k/include/uapi/asm/cachectl.h rename to trunk/arch/m68k/include/asm/cachectl.h diff --git a/trunk/arch/m68k/include/uapi/asm/fcntl.h b/trunk/arch/m68k/include/asm/fcntl.h similarity index 100% rename from trunk/arch/m68k/include/uapi/asm/fcntl.h rename to trunk/arch/m68k/include/asm/fcntl.h diff --git a/trunk/arch/m68k/include/uapi/asm/ioctls.h b/trunk/arch/m68k/include/asm/ioctls.h similarity index 100% rename from trunk/arch/m68k/include/uapi/asm/ioctls.h rename to trunk/arch/m68k/include/asm/ioctls.h diff --git a/trunk/arch/m68k/include/uapi/asm/msgbuf.h b/trunk/arch/m68k/include/asm/msgbuf.h similarity index 100% rename from trunk/arch/m68k/include/uapi/asm/msgbuf.h rename to trunk/arch/m68k/include/asm/msgbuf.h diff --git a/trunk/arch/m68k/include/uapi/asm/param.h b/trunk/arch/m68k/include/asm/param.h similarity index 100% rename from trunk/arch/m68k/include/uapi/asm/param.h rename to trunk/arch/m68k/include/asm/param.h diff --git a/trunk/arch/m68k/include/uapi/asm/poll.h b/trunk/arch/m68k/include/asm/poll.h similarity index 100% rename from trunk/arch/m68k/include/uapi/asm/poll.h rename to trunk/arch/m68k/include/asm/poll.h diff --git a/trunk/arch/m68k/include/uapi/asm/posix_types.h b/trunk/arch/m68k/include/asm/posix_types.h similarity index 100% rename from trunk/arch/m68k/include/uapi/asm/posix_types.h rename to trunk/arch/m68k/include/asm/posix_types.h diff --git a/trunk/arch/m68k/include/asm/ptrace.h b/trunk/arch/m68k/include/asm/ptrace.h index 0f717045bdde..5e08b597f012 100644 --- a/trunk/arch/m68k/include/asm/ptrace.h +++ b/trunk/arch/m68k/include/asm/ptrace.h @@ -1,10 +1,82 @@ #ifndef _M68K_PTRACE_H #define _M68K_PTRACE_H -#include +#define PT_D1 0 +#define PT_D2 1 +#define PT_D3 2 +#define PT_D4 3 +#define PT_D5 4 +#define PT_D6 5 +#define PT_D7 6 +#define PT_A0 7 +#define PT_A1 8 +#define PT_A2 9 +#define PT_A3 10 +#define PT_A4 11 +#define PT_A5 12 +#define PT_A6 13 +#define PT_D0 14 +#define PT_USP 15 +#define PT_ORIG_D0 16 +#define PT_SR 17 +#define PT_PC 18 #ifndef __ASSEMBLY__ +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct pt_regs { + long d1; + long d2; + long d3; + long d4; + long d5; + long a0; + long a1; + long a2; + long d0; + long orig_d0; + long stkadj; +#ifdef CONFIG_COLDFIRE + unsigned format : 4; /* frame format specifier */ + unsigned vector : 12; /* vector offset */ + unsigned short sr; + unsigned long pc; +#else + unsigned short sr; + unsigned long pc; + unsigned format : 4; /* frame format specifier */ + unsigned vector : 12; /* vector offset */ +#endif +}; + +/* + * This is the extended stack used by signal handlers and the context + * switcher: it's pushed after the normal "struct pt_regs". + */ +struct switch_stack { + unsigned long d6; + unsigned long d7; + unsigned long a3; + unsigned long a4; + unsigned long a5; + unsigned long a6; + unsigned long retpc; +}; + +/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETFPREGS 14 +#define PTRACE_SETFPREGS 15 + +#define PTRACE_GET_THREAD_AREA 25 + +#define PTRACE_SINGLEBLOCK 33 /* resume execution until next branch */ + +#ifdef __KERNEL__ + #ifndef PS_S #define PS_S (0x2000) #define PS_M (0x1000) @@ -22,5 +94,6 @@ #define arch_has_block_step() (1) #endif +#endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ #endif /* _M68K_PTRACE_H */ diff --git a/trunk/arch/m68k/include/uapi/asm/sembuf.h b/trunk/arch/m68k/include/asm/sembuf.h similarity index 100% rename from trunk/arch/m68k/include/uapi/asm/sembuf.h rename to trunk/arch/m68k/include/asm/sembuf.h diff --git a/trunk/arch/m68k/include/asm/setup.h b/trunk/arch/m68k/include/asm/setup.h index 65e78a2dad64..00c2c5397d37 100644 --- a/trunk/arch/m68k/include/asm/setup.h +++ b/trunk/arch/m68k/include/asm/setup.h @@ -19,12 +19,33 @@ ** Redesign of the boot information structure; moved boot information ** structure to bootinfo.h */ + #ifndef _M68K_SETUP_H #define _M68K_SETUP_H -#include + /* + * Linux/m68k Architectures + */ + +#define MACH_AMIGA 1 +#define MACH_ATARI 2 +#define MACH_MAC 3 +#define MACH_APOLLO 4 +#define MACH_SUN3 5 +#define MACH_MVME147 6 +#define MACH_MVME16x 7 +#define MACH_BVME6000 8 +#define MACH_HP300 9 +#define MACH_Q40 10 +#define MACH_SUN3X 11 +#define MACH_M54XX 12 + +#define COMMAND_LINE_SIZE 256 + +#ifdef __KERNEL__ + #define CL_SIZE COMMAND_LINE_SIZE #ifndef __ASSEMBLY__ @@ -173,6 +194,63 @@ extern unsigned long m68k_machtype; # define MACH_TYPE (m68k_machtype) #endif +#endif /* __KERNEL__ */ + + + /* + * CPU, FPU and MMU types + * + * Note: we may rely on the following equalities: + * + * CPU_68020 == MMU_68851 + * CPU_68030 == MMU_68030 + * CPU_68040 == FPU_68040 == MMU_68040 + * CPU_68060 == FPU_68060 == MMU_68060 + */ + +#define CPUB_68020 0 +#define CPUB_68030 1 +#define CPUB_68040 2 +#define CPUB_68060 3 +#define CPUB_COLDFIRE 4 + +#define CPU_68020 (1< +#include +/* Avoid too many header ordering problems. */ +struct siginfo; + +#ifdef __KERNEL__ /* Most things should be clean enough to redefine this at will, if care is taken to make libc match. */ @@ -16,6 +20,92 @@ typedef struct { unsigned long sig[_NSIG_WORDS]; } sigset_t; +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +#define NSIG 32 +typedef unsigned long sigset_t; + +#endif /* __KERNEL__ */ + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO +/* +#define SIGLOST 29 +*/ +#define SIGPWR 30 +#define SIGSYS 31 +#define SIGUNUSED 31 + +/* These should not be considered constants from userland. */ +#define SIGRTMIN 32 +#define SIGRTMAX _NSIG + +/* + * SA_FLAGS values: + * + * SA_ONSTACK indicates that a registered stack_t will be used. + * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. + * SA_RESETHAND clears the handler when the signal is delivered. + * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. + * SA_NODEFER prevents the current signal from being masked in the handler. + * + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single + * Unix names RESETHAND and NODEFER respectively. + */ +#define SA_NOCLDSTOP 0x00000001 +#define SA_NOCLDWAIT 0x00000002 +#define SA_SIGINFO 0x00000004 +#define SA_ONSTACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_NODEFER 0x40000000 +#define SA_RESETHAND 0x80000000 + +#define SA_NOMASK SA_NODEFER +#define SA_ONESHOT SA_RESETHAND + +/* + * sigaltstack controls + */ +#define SS_ONSTACK 1 +#define SS_DISABLE 2 + +#define MINSIGSTKSZ 2048 +#define SIGSTKSZ 8192 + +#include + +#ifdef __KERNEL__ struct old_sigaction { __sighandler_t sa_handler; old_sigset_t sa_mask; @@ -33,6 +123,31 @@ struct sigaction { struct k_sigaction { struct sigaction sa; }; +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +struct sigaction { + union { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, struct siginfo *, void *); + } _u; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +#define sa_handler _u._sa_handler +#define sa_sigaction _u._sa_sigaction + +#endif /* __KERNEL__ */ + +typedef struct sigaltstack { + void __user *ss_sp; + int ss_flags; + size_t ss_size; +} stack_t; + +#ifdef __KERNEL__ #include #ifndef CONFIG_CPU_HAS_NO_BITFIELDS @@ -41,7 +156,7 @@ struct k_sigaction { static inline void sigaddset(sigset_t *set, int _sig) { asm ("bfset %0{%1,#1}" - : "+o" (*set) + : "+od" (*set) : "id" ((_sig - 1) ^ 31) : "cc"); } @@ -49,7 +164,7 @@ static inline void sigaddset(sigset_t *set, int _sig) static inline void sigdelset(sigset_t *set, int _sig) { asm ("bfclr %0{%1,#1}" - : "+o" (*set) + : "+od" (*set) : "id" ((_sig - 1) ^ 31) : "cc"); } @@ -65,7 +180,7 @@ static inline int __gen_sigismember(sigset_t *set, int _sig) int ret; asm ("bfextu %1{%2,#1},%0" : "=d" (ret) - : "o" (*set), "id" ((_sig-1) ^ 31) + : "od" (*set), "id" ((_sig-1) ^ 31) : "cc"); return ret; } @@ -93,4 +208,5 @@ struct pt_regs; extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie); #endif /* __uClinux__ */ +#endif /* __KERNEL__ */ #endif /* _M68K_SIGNAL_H */ diff --git a/trunk/arch/m68k/include/uapi/asm/socket.h b/trunk/arch/m68k/include/asm/socket.h similarity index 100% rename from trunk/arch/m68k/include/uapi/asm/socket.h rename to trunk/arch/m68k/include/asm/socket.h diff --git a/trunk/arch/m68k/include/uapi/asm/sockios.h b/trunk/arch/m68k/include/asm/sockios.h similarity index 100% rename from trunk/arch/m68k/include/uapi/asm/sockios.h rename to trunk/arch/m68k/include/asm/sockios.h diff --git a/trunk/arch/m68k/include/uapi/asm/stat.h b/trunk/arch/m68k/include/asm/stat.h similarity index 100% rename from trunk/arch/m68k/include/uapi/asm/stat.h rename to trunk/arch/m68k/include/asm/stat.h diff --git a/trunk/arch/m68k/include/uapi/asm/swab.h b/trunk/arch/m68k/include/asm/swab.h similarity index 100% rename from trunk/arch/m68k/include/uapi/asm/swab.h rename to trunk/arch/m68k/include/asm/swab.h diff --git a/trunk/arch/m68k/include/uapi/asm/termbits.h b/trunk/arch/m68k/include/asm/termbits.h similarity index 100% rename from trunk/arch/m68k/include/uapi/asm/termbits.h rename to trunk/arch/m68k/include/asm/termbits.h diff --git a/trunk/arch/m68k/include/asm/termios.h b/trunk/arch/m68k/include/asm/termios.h index ad8efb098663..0823032e4045 100644 --- a/trunk/arch/m68k/include/asm/termios.h +++ b/trunk/arch/m68k/include/asm/termios.h @@ -1,8 +1,27 @@ #ifndef _M68K_TERMIOS_H #define _M68K_TERMIOS_H -#include +#include +#include +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + +#ifdef __KERNEL__ /* intr=^C quit=^| erase=del kill=^U eof=^D vtime=\0 vmin=\1 sxtc=\0 start=^Q stop=^S susp=^Z eol=\0 @@ -10,6 +29,27 @@ eol2=\0 */ #define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" +#endif + +/* modem lines */ +#define TIOCM_LE 0x001 +#define TIOCM_DTR 0x002 +#define TIOCM_RTS 0x004 +#define TIOCM_ST 0x008 +#define TIOCM_SR 0x010 +#define TIOCM_CTS 0x020 +#define TIOCM_CAR 0x040 +#define TIOCM_RNG 0x080 +#define TIOCM_DSR 0x100 +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RI TIOCM_RNG +#define TIOCM_OUT1 0x2000 +#define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 + +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ + +#ifdef __KERNEL__ /* * Translate a "termio" structure into a "termios". Ugh. @@ -47,4 +87,6 @@ #define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios)) #define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios)) +#endif /* __KERNEL__ */ + #endif /* _M68K_TERMIOS_H */ diff --git a/trunk/arch/m68k/include/asm/unistd.h b/trunk/arch/m68k/include/asm/unistd.h index 5fc7f7bec1c8..c702ad716791 100644 --- a/trunk/arch/m68k/include/asm/unistd.h +++ b/trunk/arch/m68k/include/asm/unistd.h @@ -1,10 +1,361 @@ #ifndef _ASM_M68K_UNISTD_H_ #define _ASM_M68K_UNISTD_H_ -#include +/* + * This file contains the system call numbers. + */ + +#define __NR_restart_syscall 0 +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_chown 16 +/*#define __NR_break 17*/ +#define __NR_oldstat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_oldfstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +/*#define __NR_stty 31*/ +/*#define __NR_gtty 32*/ +#define __NR_access 33 +#define __NR_nice 34 +/*#define __NR_ftime 35*/ +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +/*#define __NR_prof 44*/ +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_umount2 52 +/*#define __NR_lock 53*/ +#define __NR_ioctl 54 +#define __NR_fcntl 55 +/*#define __NR_mpx 56*/ +#define __NR_setpgid 57 +/*#define __NR_ulimit 58*/ +/*#define __NR_oldolduname 59*/ +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_oldlstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_swapon 87 +#define __NR_reboot 88 +#define __NR_readdir 89 +#define __NR_mmap 90 +#define __NR_munmap 91 +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 +/*#define __NR_profil 98*/ +#define __NR_statfs 99 +#define __NR_fstatfs 100 +/*#define __NR_ioperm 101*/ +#define __NR_socketcall 102 +#define __NR_syslog 103 +#define __NR_setitimer 104 +#define __NR_getitimer 105 +#define __NR_stat 106 +#define __NR_lstat 107 +#define __NR_fstat 108 +/*#define __NR_olduname 109*/ +/*#define __NR_iopl 110*/ /* not supported */ +#define __NR_vhangup 111 +/*#define __NR_idle 112*/ /* Obsolete */ +/*#define __NR_vm86 113*/ /* not supported */ +#define __NR_wait4 114 +#define __NR_swapoff 115 +#define __NR_sysinfo 116 +#define __NR_ipc 117 +#define __NR_fsync 118 +#define __NR_sigreturn 119 +#define __NR_clone 120 +#define __NR_setdomainname 121 +#define __NR_uname 122 +#define __NR_cacheflush 123 +#define __NR_adjtimex 124 +#define __NR_mprotect 125 +#define __NR_sigprocmask 126 +#define __NR_create_module 127 +#define __NR_init_module 128 +#define __NR_delete_module 129 +#define __NR_get_kernel_syms 130 +#define __NR_quotactl 131 +#define __NR_getpgid 132 +#define __NR_fchdir 133 +#define __NR_bdflush 134 +#define __NR_sysfs 135 +#define __NR_personality 136 +/*#define __NR_afs_syscall 137*/ /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 +#define __NR__llseek 140 +#define __NR_getdents 141 +#define __NR__newselect 142 +#define __NR_flock 143 +#define __NR_msync 144 +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 +#define __NR_fdatasync 148 +#define __NR__sysctl 149 +#define __NR_mlock 150 +#define __NR_munlock 151 +#define __NR_mlockall 152 +#define __NR_munlockall 153 +#define __NR_sched_setparam 154 +#define __NR_sched_getparam 155 +#define __NR_sched_setscheduler 156 +#define __NR_sched_getscheduler 157 +#define __NR_sched_yield 158 +#define __NR_sched_get_priority_max 159 +#define __NR_sched_get_priority_min 160 +#define __NR_sched_rr_get_interval 161 +#define __NR_nanosleep 162 +#define __NR_mremap 163 +#define __NR_setresuid 164 +#define __NR_getresuid 165 +#define __NR_getpagesize 166 +#define __NR_query_module 167 +#define __NR_poll 168 +#define __NR_nfsservctl 169 +#define __NR_setresgid 170 +#define __NR_getresgid 171 +#define __NR_prctl 172 +#define __NR_rt_sigreturn 173 +#define __NR_rt_sigaction 174 +#define __NR_rt_sigprocmask 175 +#define __NR_rt_sigpending 176 +#define __NR_rt_sigtimedwait 177 +#define __NR_rt_sigqueueinfo 178 +#define __NR_rt_sigsuspend 179 +#define __NR_pread64 180 +#define __NR_pwrite64 181 +#define __NR_lchown 182 +#define __NR_getcwd 183 +#define __NR_capget 184 +#define __NR_capset 185 +#define __NR_sigaltstack 186 +#define __NR_sendfile 187 +#define __NR_getpmsg 188 /* some people actually want streams */ +#define __NR_putpmsg 189 /* some people actually want streams */ +#define __NR_vfork 190 +#define __NR_ugetrlimit 191 +#define __NR_mmap2 192 +#define __NR_truncate64 193 +#define __NR_ftruncate64 194 +#define __NR_stat64 195 +#define __NR_lstat64 196 +#define __NR_fstat64 197 +#define __NR_chown32 198 +#define __NR_getuid32 199 +#define __NR_getgid32 200 +#define __NR_geteuid32 201 +#define __NR_getegid32 202 +#define __NR_setreuid32 203 +#define __NR_setregid32 204 +#define __NR_getgroups32 205 +#define __NR_setgroups32 206 +#define __NR_fchown32 207 +#define __NR_setresuid32 208 +#define __NR_getresuid32 209 +#define __NR_setresgid32 210 +#define __NR_getresgid32 211 +#define __NR_lchown32 212 +#define __NR_setuid32 213 +#define __NR_setgid32 214 +#define __NR_setfsuid32 215 +#define __NR_setfsgid32 216 +#define __NR_pivot_root 217 +/* 218*/ +/* 219*/ +#define __NR_getdents64 220 +#define __NR_gettid 221 +#define __NR_tkill 222 +#define __NR_setxattr 223 +#define __NR_lsetxattr 224 +#define __NR_fsetxattr 225 +#define __NR_getxattr 226 +#define __NR_lgetxattr 227 +#define __NR_fgetxattr 228 +#define __NR_listxattr 229 +#define __NR_llistxattr 230 +#define __NR_flistxattr 231 +#define __NR_removexattr 232 +#define __NR_lremovexattr 233 +#define __NR_fremovexattr 234 +#define __NR_futex 235 +#define __NR_sendfile64 236 +#define __NR_mincore 237 +#define __NR_madvise 238 +#define __NR_fcntl64 239 +#define __NR_readahead 240 +#define __NR_io_setup 241 +#define __NR_io_destroy 242 +#define __NR_io_getevents 243 +#define __NR_io_submit 244 +#define __NR_io_cancel 245 +#define __NR_fadvise64 246 +#define __NR_exit_group 247 +#define __NR_lookup_dcookie 248 +#define __NR_epoll_create 249 +#define __NR_epoll_ctl 250 +#define __NR_epoll_wait 251 +#define __NR_remap_file_pages 252 +#define __NR_set_tid_address 253 +#define __NR_timer_create 254 +#define __NR_timer_settime 255 +#define __NR_timer_gettime 256 +#define __NR_timer_getoverrun 257 +#define __NR_timer_delete 258 +#define __NR_clock_settime 259 +#define __NR_clock_gettime 260 +#define __NR_clock_getres 261 +#define __NR_clock_nanosleep 262 +#define __NR_statfs64 263 +#define __NR_fstatfs64 264 +#define __NR_tgkill 265 +#define __NR_utimes 266 +#define __NR_fadvise64_64 267 +#define __NR_mbind 268 +#define __NR_get_mempolicy 269 +#define __NR_set_mempolicy 270 +#define __NR_mq_open 271 +#define __NR_mq_unlink 272 +#define __NR_mq_timedsend 273 +#define __NR_mq_timedreceive 274 +#define __NR_mq_notify 275 +#define __NR_mq_getsetattr 276 +#define __NR_waitid 277 +/*#define __NR_vserver 278*/ +#define __NR_add_key 279 +#define __NR_request_key 280 +#define __NR_keyctl 281 +#define __NR_ioprio_set 282 +#define __NR_ioprio_get 283 +#define __NR_inotify_init 284 +#define __NR_inotify_add_watch 285 +#define __NR_inotify_rm_watch 286 +#define __NR_migrate_pages 287 +#define __NR_openat 288 +#define __NR_mkdirat 289 +#define __NR_mknodat 290 +#define __NR_fchownat 291 +#define __NR_futimesat 292 +#define __NR_fstatat64 293 +#define __NR_unlinkat 294 +#define __NR_renameat 295 +#define __NR_linkat 296 +#define __NR_symlinkat 297 +#define __NR_readlinkat 298 +#define __NR_fchmodat 299 +#define __NR_faccessat 300 +#define __NR_pselect6 301 +#define __NR_ppoll 302 +#define __NR_unshare 303 +#define __NR_set_robust_list 304 +#define __NR_get_robust_list 305 +#define __NR_splice 306 +#define __NR_sync_file_range 307 +#define __NR_tee 308 +#define __NR_vmsplice 309 +#define __NR_move_pages 310 +#define __NR_sched_setaffinity 311 +#define __NR_sched_getaffinity 312 +#define __NR_kexec_load 313 +#define __NR_getcpu 314 +#define __NR_epoll_pwait 315 +#define __NR_utimensat 316 +#define __NR_signalfd 317 +#define __NR_timerfd_create 318 +#define __NR_eventfd 319 +#define __NR_fallocate 320 +#define __NR_timerfd_settime 321 +#define __NR_timerfd_gettime 322 +#define __NR_signalfd4 323 +#define __NR_eventfd2 324 +#define __NR_epoll_create1 325 +#define __NR_dup3 326 +#define __NR_pipe2 327 +#define __NR_inotify_init1 328 +#define __NR_preadv 329 +#define __NR_pwritev 330 +#define __NR_rt_tgsigqueueinfo 331 +#define __NR_perf_event_open 332 +#define __NR_get_thread_area 333 +#define __NR_set_thread_area 334 +#define __NR_atomic_cmpxchg_32 335 +#define __NR_atomic_barrier 336 +#define __NR_fanotify_init 337 +#define __NR_fanotify_mark 338 +#define __NR_prlimit64 339 +#define __NR_name_to_handle_at 340 +#define __NR_open_by_handle_at 341 +#define __NR_clock_adjtime 342 +#define __NR_syncfs 343 +#define __NR_setns 344 +#define __NR_process_vm_readv 345 +#define __NR_process_vm_writev 346 +#ifdef __KERNEL__ -#define NR_syscalls 348 +#define NR_syscalls 347 #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_STAT @@ -42,4 +393,5 @@ */ #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") +#endif /* __KERNEL__ */ #endif /* _ASM_M68K_UNISTD_H_ */ diff --git a/trunk/arch/m68k/include/uapi/asm/Kbuild b/trunk/arch/m68k/include/uapi/asm/Kbuild index 972bce120e1e..baebb3da1d44 100644 --- a/trunk/arch/m68k/include/uapi/asm/Kbuild +++ b/trunk/arch/m68k/include/uapi/asm/Kbuild @@ -1,26 +1,3 @@ # UAPI Header export list include include/uapi/asm-generic/Kbuild.asm -header-y += a.out.h -header-y += auxvec.h -header-y += byteorder.h -header-y += cachectl.h -header-y += fcntl.h -header-y += ioctls.h -header-y += msgbuf.h -header-y += param.h -header-y += poll.h -header-y += posix_types.h -header-y += ptrace.h -header-y += sembuf.h -header-y += setup.h -header-y += shmbuf.h -header-y += sigcontext.h -header-y += signal.h -header-y += socket.h -header-y += sockios.h -header-y += stat.h -header-y += swab.h -header-y += termbits.h -header-y += termios.h -header-y += unistd.h diff --git a/trunk/arch/m68k/include/uapi/asm/ptrace.h b/trunk/arch/m68k/include/uapi/asm/ptrace.h deleted file mode 100644 index caf92fd34939..000000000000 --- a/trunk/arch/m68k/include/uapi/asm/ptrace.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef _UAPI_M68K_PTRACE_H -#define _UAPI_M68K_PTRACE_H - -#define PT_D1 0 -#define PT_D2 1 -#define PT_D3 2 -#define PT_D4 3 -#define PT_D5 4 -#define PT_D6 5 -#define PT_D7 6 -#define PT_A0 7 -#define PT_A1 8 -#define PT_A2 9 -#define PT_A3 10 -#define PT_A4 11 -#define PT_A5 12 -#define PT_A6 13 -#define PT_D0 14 -#define PT_USP 15 -#define PT_ORIG_D0 16 -#define PT_SR 17 -#define PT_PC 18 - -#ifndef __ASSEMBLY__ - -/* this struct defines the way the registers are stored on the - stack during a system call. */ - -struct pt_regs { - long d1; - long d2; - long d3; - long d4; - long d5; - long a0; - long a1; - long a2; - long d0; - long orig_d0; - long stkadj; -#ifdef CONFIG_COLDFIRE - unsigned format : 4; /* frame format specifier */ - unsigned vector : 12; /* vector offset */ - unsigned short sr; - unsigned long pc; -#else - unsigned short sr; - unsigned long pc; - unsigned format : 4; /* frame format specifier */ - unsigned vector : 12; /* vector offset */ -#endif -}; - -/* - * This is the extended stack used by signal handlers and the context - * switcher: it's pushed after the normal "struct pt_regs". - */ -struct switch_stack { - unsigned long d6; - unsigned long d7; - unsigned long a3; - unsigned long a4; - unsigned long a5; - unsigned long a6; - unsigned long retpc; -}; - -/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ -#define PTRACE_GETREGS 12 -#define PTRACE_SETREGS 13 -#define PTRACE_GETFPREGS 14 -#define PTRACE_SETFPREGS 15 - -#define PTRACE_GET_THREAD_AREA 25 - -#define PTRACE_SINGLEBLOCK 33 /* resume execution until next branch */ - -#endif /* __ASSEMBLY__ */ -#endif /* _UAPI_M68K_PTRACE_H */ diff --git a/trunk/arch/m68k/include/uapi/asm/setup.h b/trunk/arch/m68k/include/uapi/asm/setup.h deleted file mode 100644 index 85579bff455c..000000000000 --- a/trunk/arch/m68k/include/uapi/asm/setup.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -** asm/setup.h -- Definition of the Linux/m68k setup information -** -** Copyright 1992 by Greg Harp -** -** 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 -** for more details. -** -** Created 09/29/92 by Greg Harp -** -** 5/2/94 Roman Hodek: -** Added bi_atari part of the machine dependent union bi_un; for now it -** contains just a model field to distinguish between TT and Falcon. -** 26/7/96 Roman Zippel: -** Renamed to setup.h; added some useful macros to allow gcc some -** optimizations if possible. -** 5/10/96 Geert Uytterhoeven: -** Redesign of the boot information structure; moved boot information -** structure to bootinfo.h -*/ - -#ifndef _UAPI_M68K_SETUP_H -#define _UAPI_M68K_SETUP_H - - - - /* - * Linux/m68k Architectures - */ - -#define MACH_AMIGA 1 -#define MACH_ATARI 2 -#define MACH_MAC 3 -#define MACH_APOLLO 4 -#define MACH_SUN3 5 -#define MACH_MVME147 6 -#define MACH_MVME16x 7 -#define MACH_BVME6000 8 -#define MACH_HP300 9 -#define MACH_Q40 10 -#define MACH_SUN3X 11 -#define MACH_M54XX 12 - -#define COMMAND_LINE_SIZE 256 - - - - /* - * CPU, FPU and MMU types - * - * Note: we may rely on the following equalities: - * - * CPU_68020 == MMU_68851 - * CPU_68030 == MMU_68030 - * CPU_68040 == FPU_68040 == MMU_68040 - * CPU_68060 == FPU_68060 == MMU_68060 - */ - -#define CPUB_68020 0 -#define CPUB_68030 1 -#define CPUB_68040 2 -#define CPUB_68060 3 -#define CPUB_COLDFIRE 4 - -#define CPU_68020 (1< - -/* Avoid too many header ordering problems. */ -struct siginfo; - -#ifndef __KERNEL__ -/* Here we must cater to libcs that poke about in kernel headers. */ - -#define NSIG 32 -typedef unsigned long sigset_t; - -#endif /* __KERNEL__ */ - -#define SIGHUP 1 -#define SIGINT 2 -#define SIGQUIT 3 -#define SIGILL 4 -#define SIGTRAP 5 -#define SIGABRT 6 -#define SIGIOT 6 -#define SIGBUS 7 -#define SIGFPE 8 -#define SIGKILL 9 -#define SIGUSR1 10 -#define SIGSEGV 11 -#define SIGUSR2 12 -#define SIGPIPE 13 -#define SIGALRM 14 -#define SIGTERM 15 -#define SIGSTKFLT 16 -#define SIGCHLD 17 -#define SIGCONT 18 -#define SIGSTOP 19 -#define SIGTSTP 20 -#define SIGTTIN 21 -#define SIGTTOU 22 -#define SIGURG 23 -#define SIGXCPU 24 -#define SIGXFSZ 25 -#define SIGVTALRM 26 -#define SIGPROF 27 -#define SIGWINCH 28 -#define SIGIO 29 -#define SIGPOLL SIGIO -/* -#define SIGLOST 29 -*/ -#define SIGPWR 30 -#define SIGSYS 31 -#define SIGUNUSED 31 - -/* These should not be considered constants from userland. */ -#define SIGRTMIN 32 -#define SIGRTMAX _NSIG - -/* - * SA_FLAGS values: - * - * SA_ONSTACK indicates that a registered stack_t will be used. - * SA_RESTART flag to get restarting signals (which were the default long ago) - * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. - * SA_RESETHAND clears the handler when the signal is delivered. - * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. - * SA_NODEFER prevents the current signal from being masked in the handler. - * - * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single - * Unix names RESETHAND and NODEFER respectively. - */ -#define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 -#define SA_SIGINFO 0x00000004 -#define SA_ONSTACK 0x08000000 -#define SA_RESTART 0x10000000 -#define SA_NODEFER 0x40000000 -#define SA_RESETHAND 0x80000000 - -#define SA_NOMASK SA_NODEFER -#define SA_ONESHOT SA_RESETHAND - -/* - * sigaltstack controls - */ -#define SS_ONSTACK 1 -#define SS_DISABLE 2 - -#define MINSIGSTKSZ 2048 -#define SIGSTKSZ 8192 - -#include - -#ifndef __KERNEL__ -/* Here we must cater to libcs that poke about in kernel headers. */ - -struct sigaction { - union { - __sighandler_t _sa_handler; - void (*_sa_sigaction)(int, struct siginfo *, void *); - } _u; - sigset_t sa_mask; - unsigned long sa_flags; - void (*sa_restorer)(void); -}; - -#define sa_handler _u._sa_handler -#define sa_sigaction _u._sa_sigaction - -#endif /* __KERNEL__ */ - -typedef struct sigaltstack { - void __user *ss_sp; - int ss_flags; - size_t ss_size; -} stack_t; - -#endif /* _UAPI_M68K_SIGNAL_H */ diff --git a/trunk/arch/m68k/include/uapi/asm/termios.h b/trunk/arch/m68k/include/uapi/asm/termios.h deleted file mode 100644 index ce2142c9ac1d..000000000000 --- a/trunk/arch/m68k/include/uapi/asm/termios.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _UAPI_M68K_TERMIOS_H -#define _UAPI_M68K_TERMIOS_H - -#include -#include - -struct winsize { - unsigned short ws_row; - unsigned short ws_col; - unsigned short ws_xpixel; - unsigned short ws_ypixel; -}; - -#define NCC 8 -struct termio { - unsigned short c_iflag; /* input mode flags */ - unsigned short c_oflag; /* output mode flags */ - unsigned short c_cflag; /* control mode flags */ - unsigned short c_lflag; /* local mode flags */ - unsigned char c_line; /* line discipline */ - unsigned char c_cc[NCC]; /* control characters */ -}; - - -/* modem lines */ -#define TIOCM_LE 0x001 -#define TIOCM_DTR 0x002 -#define TIOCM_RTS 0x004 -#define TIOCM_ST 0x008 -#define TIOCM_SR 0x010 -#define TIOCM_CTS 0x020 -#define TIOCM_CAR 0x040 -#define TIOCM_RNG 0x080 -#define TIOCM_DSR 0x100 -#define TIOCM_CD TIOCM_CAR -#define TIOCM_RI TIOCM_RNG -#define TIOCM_OUT1 0x2000 -#define TIOCM_OUT2 0x4000 -#define TIOCM_LOOP 0x8000 - -/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ - - -#endif /* _UAPI_M68K_TERMIOS_H */ diff --git a/trunk/arch/m68k/include/uapi/asm/unistd.h b/trunk/arch/m68k/include/uapi/asm/unistd.h deleted file mode 100644 index b94bfbf90705..000000000000 --- a/trunk/arch/m68k/include/uapi/asm/unistd.h +++ /dev/null @@ -1,357 +0,0 @@ -#ifndef _UAPI_ASM_M68K_UNISTD_H_ -#define _UAPI_ASM_M68K_UNISTD_H_ - -/* - * This file contains the system call numbers. - */ - -#define __NR_restart_syscall 0 -#define __NR_exit 1 -#define __NR_fork 2 -#define __NR_read 3 -#define __NR_write 4 -#define __NR_open 5 -#define __NR_close 6 -#define __NR_waitpid 7 -#define __NR_creat 8 -#define __NR_link 9 -#define __NR_unlink 10 -#define __NR_execve 11 -#define __NR_chdir 12 -#define __NR_time 13 -#define __NR_mknod 14 -#define __NR_chmod 15 -#define __NR_chown 16 -/*#define __NR_break 17*/ -#define __NR_oldstat 18 -#define __NR_lseek 19 -#define __NR_getpid 20 -#define __NR_mount 21 -#define __NR_umount 22 -#define __NR_setuid 23 -#define __NR_getuid 24 -#define __NR_stime 25 -#define __NR_ptrace 26 -#define __NR_alarm 27 -#define __NR_oldfstat 28 -#define __NR_pause 29 -#define __NR_utime 30 -/*#define __NR_stty 31*/ -/*#define __NR_gtty 32*/ -#define __NR_access 33 -#define __NR_nice 34 -/*#define __NR_ftime 35*/ -#define __NR_sync 36 -#define __NR_kill 37 -#define __NR_rename 38 -#define __NR_mkdir 39 -#define __NR_rmdir 40 -#define __NR_dup 41 -#define __NR_pipe 42 -#define __NR_times 43 -/*#define __NR_prof 44*/ -#define __NR_brk 45 -#define __NR_setgid 46 -#define __NR_getgid 47 -#define __NR_signal 48 -#define __NR_geteuid 49 -#define __NR_getegid 50 -#define __NR_acct 51 -#define __NR_umount2 52 -/*#define __NR_lock 53*/ -#define __NR_ioctl 54 -#define __NR_fcntl 55 -/*#define __NR_mpx 56*/ -#define __NR_setpgid 57 -/*#define __NR_ulimit 58*/ -/*#define __NR_oldolduname 59*/ -#define __NR_umask 60 -#define __NR_chroot 61 -#define __NR_ustat 62 -#define __NR_dup2 63 -#define __NR_getppid 64 -#define __NR_getpgrp 65 -#define __NR_setsid 66 -#define __NR_sigaction 67 -#define __NR_sgetmask 68 -#define __NR_ssetmask 69 -#define __NR_setreuid 70 -#define __NR_setregid 71 -#define __NR_sigsuspend 72 -#define __NR_sigpending 73 -#define __NR_sethostname 74 -#define __NR_setrlimit 75 -#define __NR_getrlimit 76 -#define __NR_getrusage 77 -#define __NR_gettimeofday 78 -#define __NR_settimeofday 79 -#define __NR_getgroups 80 -#define __NR_setgroups 81 -#define __NR_select 82 -#define __NR_symlink 83 -#define __NR_oldlstat 84 -#define __NR_readlink 85 -#define __NR_uselib 86 -#define __NR_swapon 87 -#define __NR_reboot 88 -#define __NR_readdir 89 -#define __NR_mmap 90 -#define __NR_munmap 91 -#define __NR_truncate 92 -#define __NR_ftruncate 93 -#define __NR_fchmod 94 -#define __NR_fchown 95 -#define __NR_getpriority 96 -#define __NR_setpriority 97 -/*#define __NR_profil 98*/ -#define __NR_statfs 99 -#define __NR_fstatfs 100 -/*#define __NR_ioperm 101*/ -#define __NR_socketcall 102 -#define __NR_syslog 103 -#define __NR_setitimer 104 -#define __NR_getitimer 105 -#define __NR_stat 106 -#define __NR_lstat 107 -#define __NR_fstat 108 -/*#define __NR_olduname 109*/ -/*#define __NR_iopl 110*/ /* not supported */ -#define __NR_vhangup 111 -/*#define __NR_idle 112*/ /* Obsolete */ -/*#define __NR_vm86 113*/ /* not supported */ -#define __NR_wait4 114 -#define __NR_swapoff 115 -#define __NR_sysinfo 116 -#define __NR_ipc 117 -#define __NR_fsync 118 -#define __NR_sigreturn 119 -#define __NR_clone 120 -#define __NR_setdomainname 121 -#define __NR_uname 122 -#define __NR_cacheflush 123 -#define __NR_adjtimex 124 -#define __NR_mprotect 125 -#define __NR_sigprocmask 126 -#define __NR_create_module 127 -#define __NR_init_module 128 -#define __NR_delete_module 129 -#define __NR_get_kernel_syms 130 -#define __NR_quotactl 131 -#define __NR_getpgid 132 -#define __NR_fchdir 133 -#define __NR_bdflush 134 -#define __NR_sysfs 135 -#define __NR_personality 136 -/*#define __NR_afs_syscall 137*/ /* Syscall for Andrew File System */ -#define __NR_setfsuid 138 -#define __NR_setfsgid 139 -#define __NR__llseek 140 -#define __NR_getdents 141 -#define __NR__newselect 142 -#define __NR_flock 143 -#define __NR_msync 144 -#define __NR_readv 145 -#define __NR_writev 146 -#define __NR_getsid 147 -#define __NR_fdatasync 148 -#define __NR__sysctl 149 -#define __NR_mlock 150 -#define __NR_munlock 151 -#define __NR_mlockall 152 -#define __NR_munlockall 153 -#define __NR_sched_setparam 154 -#define __NR_sched_getparam 155 -#define __NR_sched_setscheduler 156 -#define __NR_sched_getscheduler 157 -#define __NR_sched_yield 158 -#define __NR_sched_get_priority_max 159 -#define __NR_sched_get_priority_min 160 -#define __NR_sched_rr_get_interval 161 -#define __NR_nanosleep 162 -#define __NR_mremap 163 -#define __NR_setresuid 164 -#define __NR_getresuid 165 -#define __NR_getpagesize 166 -#define __NR_query_module 167 -#define __NR_poll 168 -#define __NR_nfsservctl 169 -#define __NR_setresgid 170 -#define __NR_getresgid 171 -#define __NR_prctl 172 -#define __NR_rt_sigreturn 173 -#define __NR_rt_sigaction 174 -#define __NR_rt_sigprocmask 175 -#define __NR_rt_sigpending 176 -#define __NR_rt_sigtimedwait 177 -#define __NR_rt_sigqueueinfo 178 -#define __NR_rt_sigsuspend 179 -#define __NR_pread64 180 -#define __NR_pwrite64 181 -#define __NR_lchown 182 -#define __NR_getcwd 183 -#define __NR_capget 184 -#define __NR_capset 185 -#define __NR_sigaltstack 186 -#define __NR_sendfile 187 -#define __NR_getpmsg 188 /* some people actually want streams */ -#define __NR_putpmsg 189 /* some people actually want streams */ -#define __NR_vfork 190 -#define __NR_ugetrlimit 191 -#define __NR_mmap2 192 -#define __NR_truncate64 193 -#define __NR_ftruncate64 194 -#define __NR_stat64 195 -#define __NR_lstat64 196 -#define __NR_fstat64 197 -#define __NR_chown32 198 -#define __NR_getuid32 199 -#define __NR_getgid32 200 -#define __NR_geteuid32 201 -#define __NR_getegid32 202 -#define __NR_setreuid32 203 -#define __NR_setregid32 204 -#define __NR_getgroups32 205 -#define __NR_setgroups32 206 -#define __NR_fchown32 207 -#define __NR_setresuid32 208 -#define __NR_getresuid32 209 -#define __NR_setresgid32 210 -#define __NR_getresgid32 211 -#define __NR_lchown32 212 -#define __NR_setuid32 213 -#define __NR_setgid32 214 -#define __NR_setfsuid32 215 -#define __NR_setfsgid32 216 -#define __NR_pivot_root 217 -/* 218*/ -/* 219*/ -#define __NR_getdents64 220 -#define __NR_gettid 221 -#define __NR_tkill 222 -#define __NR_setxattr 223 -#define __NR_lsetxattr 224 -#define __NR_fsetxattr 225 -#define __NR_getxattr 226 -#define __NR_lgetxattr 227 -#define __NR_fgetxattr 228 -#define __NR_listxattr 229 -#define __NR_llistxattr 230 -#define __NR_flistxattr 231 -#define __NR_removexattr 232 -#define __NR_lremovexattr 233 -#define __NR_fremovexattr 234 -#define __NR_futex 235 -#define __NR_sendfile64 236 -#define __NR_mincore 237 -#define __NR_madvise 238 -#define __NR_fcntl64 239 -#define __NR_readahead 240 -#define __NR_io_setup 241 -#define __NR_io_destroy 242 -#define __NR_io_getevents 243 -#define __NR_io_submit 244 -#define __NR_io_cancel 245 -#define __NR_fadvise64 246 -#define __NR_exit_group 247 -#define __NR_lookup_dcookie 248 -#define __NR_epoll_create 249 -#define __NR_epoll_ctl 250 -#define __NR_epoll_wait 251 -#define __NR_remap_file_pages 252 -#define __NR_set_tid_address 253 -#define __NR_timer_create 254 -#define __NR_timer_settime 255 -#define __NR_timer_gettime 256 -#define __NR_timer_getoverrun 257 -#define __NR_timer_delete 258 -#define __NR_clock_settime 259 -#define __NR_clock_gettime 260 -#define __NR_clock_getres 261 -#define __NR_clock_nanosleep 262 -#define __NR_statfs64 263 -#define __NR_fstatfs64 264 -#define __NR_tgkill 265 -#define __NR_utimes 266 -#define __NR_fadvise64_64 267 -#define __NR_mbind 268 -#define __NR_get_mempolicy 269 -#define __NR_set_mempolicy 270 -#define __NR_mq_open 271 -#define __NR_mq_unlink 272 -#define __NR_mq_timedsend 273 -#define __NR_mq_timedreceive 274 -#define __NR_mq_notify 275 -#define __NR_mq_getsetattr 276 -#define __NR_waitid 277 -/*#define __NR_vserver 278*/ -#define __NR_add_key 279 -#define __NR_request_key 280 -#define __NR_keyctl 281 -#define __NR_ioprio_set 282 -#define __NR_ioprio_get 283 -#define __NR_inotify_init 284 -#define __NR_inotify_add_watch 285 -#define __NR_inotify_rm_watch 286 -#define __NR_migrate_pages 287 -#define __NR_openat 288 -#define __NR_mkdirat 289 -#define __NR_mknodat 290 -#define __NR_fchownat 291 -#define __NR_futimesat 292 -#define __NR_fstatat64 293 -#define __NR_unlinkat 294 -#define __NR_renameat 295 -#define __NR_linkat 296 -#define __NR_symlinkat 297 -#define __NR_readlinkat 298 -#define __NR_fchmodat 299 -#define __NR_faccessat 300 -#define __NR_pselect6 301 -#define __NR_ppoll 302 -#define __NR_unshare 303 -#define __NR_set_robust_list 304 -#define __NR_get_robust_list 305 -#define __NR_splice 306 -#define __NR_sync_file_range 307 -#define __NR_tee 308 -#define __NR_vmsplice 309 -#define __NR_move_pages 310 -#define __NR_sched_setaffinity 311 -#define __NR_sched_getaffinity 312 -#define __NR_kexec_load 313 -#define __NR_getcpu 314 -#define __NR_epoll_pwait 315 -#define __NR_utimensat 316 -#define __NR_signalfd 317 -#define __NR_timerfd_create 318 -#define __NR_eventfd 319 -#define __NR_fallocate 320 -#define __NR_timerfd_settime 321 -#define __NR_timerfd_gettime 322 -#define __NR_signalfd4 323 -#define __NR_eventfd2 324 -#define __NR_epoll_create1 325 -#define __NR_dup3 326 -#define __NR_pipe2 327 -#define __NR_inotify_init1 328 -#define __NR_preadv 329 -#define __NR_pwritev 330 -#define __NR_rt_tgsigqueueinfo 331 -#define __NR_perf_event_open 332 -#define __NR_get_thread_area 333 -#define __NR_set_thread_area 334 -#define __NR_atomic_cmpxchg_32 335 -#define __NR_atomic_barrier 336 -#define __NR_fanotify_init 337 -#define __NR_fanotify_mark 338 -#define __NR_prlimit64 339 -#define __NR_name_to_handle_at 340 -#define __NR_open_by_handle_at 341 -#define __NR_clock_adjtime 342 -#define __NR_syncfs 343 -#define __NR_setns 344 -#define __NR_process_vm_readv 345 -#define __NR_process_vm_writev 346 -#define __NR_kcmp 347 - -#endif /* _UAPI_ASM_M68K_UNISTD_H_ */ diff --git a/trunk/arch/m68k/kernel/syscalltable.S b/trunk/arch/m68k/kernel/syscalltable.S index 4fc2e29b771b..ce827b376110 100644 --- a/trunk/arch/m68k/kernel/syscalltable.S +++ b/trunk/arch/m68k/kernel/syscalltable.S @@ -367,5 +367,4 @@ ENTRY(sys_call_table) .long sys_setns .long sys_process_vm_readv /* 345 */ .long sys_process_vm_writev - .long sys_kcmp diff --git a/trunk/arch/microblaze/kernel/signal.c b/trunk/arch/microblaze/kernel/signal.c index 3903e3d11f5a..3847e5b9c601 100644 --- a/trunk/arch/microblaze/kernel/signal.c +++ b/trunk/arch/microblaze/kernel/signal.c @@ -111,7 +111,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1) == -EFAULT) + if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1)) goto badframe; return rval; diff --git a/trunk/arch/mips/cavium-octeon/executive/cvmx-l2c.c b/trunk/arch/mips/cavium-octeon/executive/cvmx-l2c.c index 9f883bf76953..d38246e33ddb 100644 --- a/trunk/arch/mips/cavium-octeon/executive/cvmx-l2c.c +++ b/trunk/arch/mips/cavium-octeon/executive/cvmx-l2c.c @@ -30,7 +30,6 @@ * measurement, and debugging facilities. */ -#include #include #include #include diff --git a/trunk/arch/mips/fw/arc/misc.c b/trunk/arch/mips/fw/arc/misc.c index f9f5307434c2..7cf80ca2c1d2 100644 --- a/trunk/arch/mips/fw/arc/misc.c +++ b/trunk/arch/mips/fw/arc/misc.c @@ -11,7 +11,6 @@ */ #include #include -#include #include diff --git a/trunk/arch/mips/include/asm/bitops.h b/trunk/arch/mips/include/asm/bitops.h index 46ac73abd5ee..82ad35ce2b45 100644 --- a/trunk/arch/mips/include/asm/bitops.h +++ b/trunk/arch/mips/include/asm/bitops.h @@ -14,6 +14,7 @@ #endif #include +#include #include #include #include /* sigh ... */ @@ -43,24 +44,6 @@ #define smp_mb__before_clear_bit() smp_mb__before_llsc() #define smp_mb__after_clear_bit() smp_llsc_mb() - -/* - * These are the "slower" versions of the functions and are in bitops.c. - * These functions call raw_local_irq_{save,restore}(). - */ -void __mips_set_bit(unsigned long nr, volatile unsigned long *addr); -void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr); -void __mips_change_bit(unsigned long nr, volatile unsigned long *addr); -int __mips_test_and_set_bit(unsigned long nr, - volatile unsigned long *addr); -int __mips_test_and_set_bit_lock(unsigned long nr, - volatile unsigned long *addr); -int __mips_test_and_clear_bit(unsigned long nr, - volatile unsigned long *addr); -int __mips_test_and_change_bit(unsigned long nr, - volatile unsigned long *addr); - - /* * set_bit - Atomically set a bit in memory * @nr: the bit to set @@ -74,7 +57,7 @@ int __mips_test_and_change_bit(unsigned long nr, static inline void set_bit(unsigned long nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); - int bit = nr & SZLONG_MASK; + unsigned short bit = nr & SZLONG_MASK; unsigned long temp; if (kernel_uses_llsc && R10000_LLSC_WAR) { @@ -109,8 +92,17 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) : "=&r" (temp), "+m" (*m) : "ir" (1UL << bit)); } while (unlikely(!temp)); - } else - __mips_set_bit(nr, addr); + } else { + volatile unsigned long *a = addr; + unsigned long mask; + unsigned long flags; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + *a |= mask; + raw_local_irq_restore(flags); + } } /* @@ -126,7 +118,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); - int bit = nr & SZLONG_MASK; + unsigned short bit = nr & SZLONG_MASK; unsigned long temp; if (kernel_uses_llsc && R10000_LLSC_WAR) { @@ -161,8 +153,17 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) : "=&r" (temp), "+m" (*m) : "ir" (~(1UL << bit))); } while (unlikely(!temp)); - } else - __mips_clear_bit(nr, addr); + } else { + volatile unsigned long *a = addr; + unsigned long mask; + unsigned long flags; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + *a &= ~mask; + raw_local_irq_restore(flags); + } } /* @@ -190,7 +191,7 @@ static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *ad */ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) { - int bit = nr & SZLONG_MASK; + unsigned short bit = nr & SZLONG_MASK; if (kernel_uses_llsc && R10000_LLSC_WAR) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); @@ -219,8 +220,17 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) : "=&r" (temp), "+m" (*m) : "ir" (1UL << bit)); } while (unlikely(!temp)); - } else - __mips_change_bit(nr, addr); + } else { + volatile unsigned long *a = addr; + unsigned long mask; + unsigned long flags; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + *a ^= mask; + raw_local_irq_restore(flags); + } } /* @@ -234,7 +244,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) static inline int test_and_set_bit(unsigned long nr, volatile unsigned long *addr) { - int bit = nr & SZLONG_MASK; + unsigned short bit = nr & SZLONG_MASK; unsigned long res; smp_mb__before_llsc(); @@ -271,8 +281,18 @@ static inline int test_and_set_bit(unsigned long nr, } while (unlikely(!res)); res = temp & (1UL << bit); - } else - res = __mips_test_and_set_bit(nr, addr); + } else { + volatile unsigned long *a = addr; + unsigned long mask; + unsigned long flags; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + res = (mask & *a); + *a |= mask; + raw_local_irq_restore(flags); + } smp_llsc_mb(); @@ -290,7 +310,7 @@ static inline int test_and_set_bit(unsigned long nr, static inline int test_and_set_bit_lock(unsigned long nr, volatile unsigned long *addr) { - int bit = nr & SZLONG_MASK; + unsigned short bit = nr & SZLONG_MASK; unsigned long res; if (kernel_uses_llsc && R10000_LLSC_WAR) { @@ -325,8 +345,18 @@ static inline int test_and_set_bit_lock(unsigned long nr, } while (unlikely(!res)); res = temp & (1UL << bit); - } else - res = __mips_test_and_set_bit_lock(nr, addr); + } else { + volatile unsigned long *a = addr; + unsigned long mask; + unsigned long flags; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + res = (mask & *a); + *a |= mask; + raw_local_irq_restore(flags); + } smp_llsc_mb(); @@ -343,7 +373,7 @@ static inline int test_and_set_bit_lock(unsigned long nr, static inline int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr) { - int bit = nr & SZLONG_MASK; + unsigned short bit = nr & SZLONG_MASK; unsigned long res; smp_mb__before_llsc(); @@ -398,8 +428,18 @@ static inline int test_and_clear_bit(unsigned long nr, } while (unlikely(!res)); res = temp & (1UL << bit); - } else - res = __mips_test_and_clear_bit(nr, addr); + } else { + volatile unsigned long *a = addr; + unsigned long mask; + unsigned long flags; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + res = (mask & *a); + *a &= ~mask; + raw_local_irq_restore(flags); + } smp_llsc_mb(); @@ -417,7 +457,7 @@ static inline int test_and_clear_bit(unsigned long nr, static inline int test_and_change_bit(unsigned long nr, volatile unsigned long *addr) { - int bit = nr & SZLONG_MASK; + unsigned short bit = nr & SZLONG_MASK; unsigned long res; smp_mb__before_llsc(); @@ -454,8 +494,18 @@ static inline int test_and_change_bit(unsigned long nr, } while (unlikely(!res)); res = temp & (1UL << bit); - } else - res = __mips_test_and_change_bit(nr, addr); + } else { + volatile unsigned long *a = addr; + unsigned long mask; + unsigned long flags; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + res = (mask & *a); + *a ^= mask; + raw_local_irq_restore(flags); + } smp_llsc_mb(); diff --git a/trunk/arch/mips/include/asm/compat.h b/trunk/arch/mips/include/asm/compat.h index 3c5d1464b7bd..58277e0e9cd4 100644 --- a/trunk/arch/mips/include/asm/compat.h +++ b/trunk/arch/mips/include/asm/compat.h @@ -290,7 +290,7 @@ struct compat_shmid64_ds { static inline int is_compat_task(void) { - return test_thread_flag(TIF_32BIT_ADDR); + return test_thread_flag(TIF_32BIT); } #endif /* _ASM_COMPAT_H */ diff --git a/trunk/arch/mips/include/asm/hugetlb.h b/trunk/arch/mips/include/asm/hugetlb.h index ef99db994c2f..bd94946a18f3 100644 --- a/trunk/arch/mips/include/asm/hugetlb.h +++ b/trunk/arch/mips/include/asm/hugetlb.h @@ -95,17 +95,7 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, pte_t *ptep, pte_t pte, int dirty) { - int changed = !pte_same(*ptep, pte); - - if (changed) { - set_pte_at(vma->vm_mm, addr, ptep, pte); - /* - * There could be some standard sized pages in there, - * get them all. - */ - flush_tlb_range(vma, addr, addr + HPAGE_SIZE); - } - return changed; + return ptep_set_access_flags(vma, addr, ptep, pte, dirty); } static inline pte_t huge_ptep_get(pte_t *ptep) diff --git a/trunk/arch/mips/include/asm/io.h b/trunk/arch/mips/include/asm/io.h index ff2e0345e013..29d9c23c20c7 100644 --- a/trunk/arch/mips/include/asm/io.h +++ b/trunk/arch/mips/include/asm/io.h @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/mips/include/asm/irqflags.h b/trunk/arch/mips/include/asm/irqflags.h index 9f3384c789d7..309cbcd6909c 100644 --- a/trunk/arch/mips/include/asm/irqflags.h +++ b/trunk/arch/mips/include/asm/irqflags.h @@ -16,13 +16,83 @@ #include #include -#if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) +__asm__( + " .macro arch_local_irq_enable \n" + " .set push \n" + " .set reorder \n" + " .set noat \n" +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n" + " ori $1, 0x400 \n" + " xori $1, 0x400 \n" + " mtc0 $1, $2, 1 \n" +#elif defined(CONFIG_CPU_MIPSR2) + " ei \n" +#else + " mfc0 $1,$12 \n" + " ori $1,0x1f \n" + " xori $1,0x1e \n" + " mtc0 $1,$12 \n" +#endif + " irq_enable_hazard \n" + " .set pop \n" + " .endm"); +extern void smtc_ipi_replay(void); + +static inline void arch_local_irq_enable(void) +{ +#ifdef CONFIG_MIPS_MT_SMTC + /* + * SMTC kernel needs to do a software replay of queued + * IPIs, at the cost of call overhead on each local_irq_enable() + */ + smtc_ipi_replay(); +#endif + __asm__ __volatile__( + "arch_local_irq_enable" + : /* no outputs */ + : /* no inputs */ + : "memory"); +} + + +/* + * For cli() we have to insert nops to make sure that the new value + * has actually arrived in the status register before the end of this + * macro. + * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs + * no nops at all. + */ +/* + * For TX49, operating only IE bit is not enough. + * + * If mfc0 $12 follows store and the mfc0 is last instruction of a + * page and fetching the next instruction causes TLB miss, the result + * of the mfc0 might wrongly contain EXL bit. + * + * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 + * + * Workaround: mask EXL bit of the result or place a nop before mfc0. + */ __asm__( " .macro arch_local_irq_disable\n" " .set push \n" " .set noat \n" +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 $1, $2, 1 \n" + " ori $1, 0x400 \n" + " .set noreorder \n" + " mtc0 $1, $2, 1 \n" +#elif defined(CONFIG_CPU_MIPSR2) " di \n" +#else + " mfc0 $1,$12 \n" + " ori $1,0x1f \n" + " xori $1,0x1f \n" + " .set noreorder \n" + " mtc0 $1,$12 \n" +#endif " irq_disable_hazard \n" " .set pop \n" " .endm \n"); @@ -36,14 +106,46 @@ static inline void arch_local_irq_disable(void) : "memory"); } +__asm__( + " .macro arch_local_save_flags flags \n" + " .set push \n" + " .set reorder \n" +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 \\flags, $2, 1 \n" +#else + " mfc0 \\flags, $12 \n" +#endif + " .set pop \n" + " .endm \n"); + +static inline unsigned long arch_local_save_flags(void) +{ + unsigned long flags; + asm volatile("arch_local_save_flags %0" : "=r" (flags)); + return flags; +} __asm__( " .macro arch_local_irq_save result \n" " .set push \n" " .set reorder \n" " .set noat \n" +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 \\result, $2, 1 \n" + " ori $1, \\result, 0x400 \n" + " .set noreorder \n" + " mtc0 $1, $2, 1 \n" + " andi \\result, \\result, 0x400 \n" +#elif defined(CONFIG_CPU_MIPSR2) " di \\result \n" " andi \\result, 1 \n" +#else + " mfc0 \\result, $12 \n" + " ori $1, \\result, 0x1f \n" + " xori $1, 0x1f \n" + " .set noreorder \n" + " mtc0 $1, $12 \n" +#endif " irq_disable_hazard \n" " .set pop \n" " .endm \n"); @@ -58,37 +160,61 @@ static inline unsigned long arch_local_irq_save(void) return flags; } - __asm__( " .macro arch_local_irq_restore flags \n" " .set push \n" " .set noreorder \n" " .set noat \n" -#if defined(CONFIG_IRQ_CPU) +#ifdef CONFIG_MIPS_MT_SMTC + "mfc0 $1, $2, 1 \n" + "andi \\flags, 0x400 \n" + "ori $1, 0x400 \n" + "xori $1, 0x400 \n" + "or \\flags, $1 \n" + "mtc0 \\flags, $2, 1 \n" +#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) /* * Slow, but doesn't suffer from a relatively unlikely race * condition we're having since days 1. */ " beqz \\flags, 1f \n" - " di \n" + " di \n" " ei \n" "1: \n" -#else +#elif defined(CONFIG_CPU_MIPSR2) /* * Fast, dangerous. Life is fun, life is good. */ " mfc0 $1, $12 \n" " ins $1, \\flags, 0, 1 \n" " mtc0 $1, $12 \n" +#else + " mfc0 $1, $12 \n" + " andi \\flags, 1 \n" + " ori $1, 0x1f \n" + " xori $1, 0x1f \n" + " or \\flags, $1 \n" + " mtc0 \\flags, $12 \n" #endif " irq_disable_hazard \n" " .set pop \n" " .endm \n"); + static inline void arch_local_irq_restore(unsigned long flags) { unsigned long __tmp1; +#ifdef CONFIG_MIPS_MT_SMTC + /* + * SMTC kernel needs to do a software replay of queued + * IPIs, at the cost of branch and call overhead on each + * local_irq_restore() + */ + if (unlikely(!(flags & 0x0400))) + smtc_ipi_replay(); +#endif + __asm__ __volatile__( "arch_local_irq_restore\t%0" : "=r" (__tmp1) @@ -106,75 +232,6 @@ static inline void __arch_local_irq_restore(unsigned long flags) : "0" (flags) : "memory"); } -#else -/* Functions that require preempt_{dis,en}able() are in mips-atomic.c */ -void arch_local_irq_disable(void); -unsigned long arch_local_irq_save(void); -void arch_local_irq_restore(unsigned long flags); -void __arch_local_irq_restore(unsigned long flags); -#endif /* if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) */ - - -__asm__( - " .macro arch_local_irq_enable \n" - " .set push \n" - " .set reorder \n" - " .set noat \n" -#ifdef CONFIG_MIPS_MT_SMTC - " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n" - " ori $1, 0x400 \n" - " xori $1, 0x400 \n" - " mtc0 $1, $2, 1 \n" -#elif defined(CONFIG_CPU_MIPSR2) - " ei \n" -#else - " mfc0 $1,$12 \n" - " ori $1,0x1f \n" - " xori $1,0x1e \n" - " mtc0 $1,$12 \n" -#endif - " irq_enable_hazard \n" - " .set pop \n" - " .endm"); - -extern void smtc_ipi_replay(void); - -static inline void arch_local_irq_enable(void) -{ -#ifdef CONFIG_MIPS_MT_SMTC - /* - * SMTC kernel needs to do a software replay of queued - * IPIs, at the cost of call overhead on each local_irq_enable() - */ - smtc_ipi_replay(); -#endif - __asm__ __volatile__( - "arch_local_irq_enable" - : /* no outputs */ - : /* no inputs */ - : "memory"); -} - - -__asm__( - " .macro arch_local_save_flags flags \n" - " .set push \n" - " .set reorder \n" -#ifdef CONFIG_MIPS_MT_SMTC - " mfc0 \\flags, $2, 1 \n" -#else - " mfc0 \\flags, $12 \n" -#endif - " .set pop \n" - " .endm \n"); - -static inline unsigned long arch_local_save_flags(void) -{ - unsigned long flags; - asm volatile("arch_local_save_flags %0" : "=r" (flags)); - return flags; -} - static inline int arch_irqs_disabled_flags(unsigned long flags) { @@ -188,7 +245,7 @@ static inline int arch_irqs_disabled_flags(unsigned long flags) #endif } -#endif /* #ifndef __ASSEMBLY__ */ +#endif /* * Do the CPU's IRQ-state tracing from assembly code. diff --git a/trunk/arch/mips/include/asm/thread_info.h b/trunk/arch/mips/include/asm/thread_info.h index 18806a52061c..8debe9e91754 100644 --- a/trunk/arch/mips/include/asm/thread_info.h +++ b/trunk/arch/mips/include/asm/thread_info.h @@ -112,6 +112,12 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define TIF_LOAD_WATCH 25 /* If set, load watch registers */ #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ +#ifdef CONFIG_MIPS32_O32 +#define TIF_32BIT TIF_32BIT_REGS +#elif defined(CONFIG_MIPS32_N32) +#define TIF_32BIT _TIF_32BIT_ADDR +#endif /* CONFIG_MIPS32_O32 */ + #define _TIF_SYSCALL_TRACE (1<cputype = CPU_R3000A; __cpu_name[cpu] = "R3000A"; } + break; } else { c->cputype = CPU_R3000; __cpu_name[cpu] = "R3000"; diff --git a/trunk/arch/mips/kernel/entry.S b/trunk/arch/mips/kernel/entry.S index 9b00362f32f6..a6c133212003 100644 --- a/trunk/arch/mips/kernel/entry.S +++ b/trunk/arch/mips/kernel/entry.S @@ -36,11 +36,6 @@ FEXPORT(ret_from_exception) FEXPORT(ret_from_irq) LONG_S s0, TI_REGS($28) FEXPORT(__ret_from_irq) -/* - * We can be coming here from a syscall done in the kernel space, - * e.g. a failed kernel_execve(). - */ -resume_userspace_check: LONG_L t0, PT_STATUS(sp) # returning to kernel mode? andi t0, t0, KU_USER beqz t0, resume_kernel @@ -167,7 +162,7 @@ work_notifysig: # deal with pending signals and move a0, sp li a1, 0 jal do_notify_resume # a2 already loaded - j resume_userspace_check + j resume_userspace FEXPORT(syscall_exit_partial) local_irq_disable # make sure need_resched doesn't diff --git a/trunk/arch/mips/kernel/scall64-n32.S b/trunk/arch/mips/kernel/scall64-n32.S index 86ec03f0e00c..f6ba8381ee01 100644 --- a/trunk/arch/mips/kernel/scall64-n32.S +++ b/trunk/arch/mips/kernel/scall64-n32.S @@ -397,14 +397,14 @@ EXPORT(sysn32_call_table) PTR sys_timerfd_create PTR compat_sys_timerfd_gettime /* 6285 */ PTR compat_sys_timerfd_settime - PTR compat_sys_signalfd4 + PTR sys_signalfd4 PTR sys_eventfd2 PTR sys_epoll_create1 PTR sys_dup3 /* 6290 */ PTR sys_pipe2 PTR sys_inotify_init1 - PTR compat_sys_preadv - PTR compat_sys_pwritev + PTR sys_preadv + PTR sys_pwritev PTR compat_sys_rt_tgsigqueueinfo /* 6295 */ PTR sys_perf_event_open PTR sys_accept4 diff --git a/trunk/arch/mips/kernel/setup.c b/trunk/arch/mips/kernel/setup.c index 290dc6a1d7a3..a53f8ec37aac 100644 --- a/trunk/arch/mips/kernel/setup.c +++ b/trunk/arch/mips/kernel/setup.c @@ -79,7 +79,7 @@ static struct resource data_resource = { .name = "Kernel data", }; void __init add_memory_region(phys_t start, phys_t size, long type) { int x = boot_mem_map.nr_map; - int i; + struct boot_mem_map_entry *prev = boot_mem_map.map + x - 1; /* Sanity check */ if (start + size < start) { @@ -88,29 +88,15 @@ void __init add_memory_region(phys_t start, phys_t size, long type) } /* - * Try to merge with existing entry, if any. + * Try to merge with previous entry if any. This is far less than + * perfect but is sufficient for most real world cases. */ - for (i = 0; i < boot_mem_map.nr_map; i++) { - struct boot_mem_map_entry *entry = boot_mem_map.map + i; - unsigned long top; - - if (entry->type != type) - continue; - - if (start + size < entry->addr) - continue; /* no overlap */ - - if (entry->addr + entry->size < start) - continue; /* no overlap */ - - top = max(entry->addr + entry->size, start + size); - entry->addr = min(entry->addr, start); - entry->size = top - entry->addr; - + if (x && prev->addr + prev->size == start && prev->type == type) { + prev->size += size; return; } - if (boot_mem_map.nr_map == BOOT_MEM_MAP_MAX) { + if (x == BOOT_MEM_MAP_MAX) { pr_err("Ooops! Too many entries in the memory map!\n"); return; } diff --git a/trunk/arch/mips/lib/Makefile b/trunk/arch/mips/lib/Makefile index eeddc58802e1..c4a82e841c73 100644 --- a/trunk/arch/mips/lib/Makefile +++ b/trunk/arch/mips/lib/Makefile @@ -2,9 +2,8 @@ # Makefile for MIPS-specific library files.. # -lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \ - mips-atomic.o strlen_user.o strncpy_user.o \ - strnlen_user.o uncached.o +lib-y += csum_partial.o delay.o memcpy.o memset.o \ + strlen_user.o strncpy_user.o strnlen_user.o uncached.o obj-y += iomap.o obj-$(CONFIG_PCI) += iomap-pci.o diff --git a/trunk/arch/mips/lib/bitops.c b/trunk/arch/mips/lib/bitops.c deleted file mode 100644 index 239a9c957b02..000000000000 --- a/trunk/arch/mips/lib/bitops.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * 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 - * for more details. - * - * Copyright (c) 1994-1997, 99, 2000, 06, 07 Ralf Baechle (ralf@linux-mips.org) - * Copyright (c) 1999, 2000 Silicon Graphics, Inc. - */ -#include -#include -#include - - -/** - * __mips_set_bit - Atomically set a bit in memory. This is called by - * set_bit() if it cannot find a faster solution. - * @nr: the bit to set - * @addr: the address to start counting from - */ -void __mips_set_bit(unsigned long nr, volatile unsigned long *addr) -{ - volatile unsigned long *a = addr; - unsigned bit = nr & SZLONG_MASK; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - *a |= mask; - raw_local_irq_restore(flags); -} -EXPORT_SYMBOL(__mips_set_bit); - - -/** - * __mips_clear_bit - Clears a bit in memory. This is called by clear_bit() if - * it cannot find a faster solution. - * @nr: Bit to clear - * @addr: Address to start counting from - */ -void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr) -{ - volatile unsigned long *a = addr; - unsigned bit = nr & SZLONG_MASK; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - *a &= ~mask; - raw_local_irq_restore(flags); -} -EXPORT_SYMBOL(__mips_clear_bit); - - -/** - * __mips_change_bit - Toggle a bit in memory. This is called by change_bit() - * if it cannot find a faster solution. - * @nr: Bit to change - * @addr: Address to start counting from - */ -void __mips_change_bit(unsigned long nr, volatile unsigned long *addr) -{ - volatile unsigned long *a = addr; - unsigned bit = nr & SZLONG_MASK; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - *a ^= mask; - raw_local_irq_restore(flags); -} -EXPORT_SYMBOL(__mips_change_bit); - - -/** - * __mips_test_and_set_bit - Set a bit and return its old value. This is - * called by test_and_set_bit() if it cannot find a faster solution. - * @nr: Bit to set - * @addr: Address to count from - */ -int __mips_test_and_set_bit(unsigned long nr, - volatile unsigned long *addr) -{ - volatile unsigned long *a = addr; - unsigned bit = nr & SZLONG_MASK; - unsigned long mask; - unsigned long flags; - unsigned long res; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - res = (mask & *a); - *a |= mask; - raw_local_irq_restore(flags); - return res; -} -EXPORT_SYMBOL(__mips_test_and_set_bit); - - -/** - * __mips_test_and_set_bit_lock - Set a bit and return its old value. This is - * called by test_and_set_bit_lock() if it cannot find a faster solution. - * @nr: Bit to set - * @addr: Address to count from - */ -int __mips_test_and_set_bit_lock(unsigned long nr, - volatile unsigned long *addr) -{ - volatile unsigned long *a = addr; - unsigned bit = nr & SZLONG_MASK; - unsigned long mask; - unsigned long flags; - unsigned long res; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - res = (mask & *a); - *a |= mask; - raw_local_irq_restore(flags); - return res; -} -EXPORT_SYMBOL(__mips_test_and_set_bit_lock); - - -/** - * __mips_test_and_clear_bit - Clear a bit and return its old value. This is - * called by test_and_clear_bit() if it cannot find a faster solution. - * @nr: Bit to clear - * @addr: Address to count from - */ -int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr) -{ - volatile unsigned long *a = addr; - unsigned bit = nr & SZLONG_MASK; - unsigned long mask; - unsigned long flags; - unsigned long res; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - res = (mask & *a); - *a &= ~mask; - raw_local_irq_restore(flags); - return res; -} -EXPORT_SYMBOL(__mips_test_and_clear_bit); - - -/** - * __mips_test_and_change_bit - Change a bit and return its old value. This is - * called by test_and_change_bit() if it cannot find a faster solution. - * @nr: Bit to change - * @addr: Address to count from - */ -int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr) -{ - volatile unsigned long *a = addr; - unsigned bit = nr & SZLONG_MASK; - unsigned long mask; - unsigned long flags; - unsigned long res; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - res = (mask & *a); - *a ^= mask; - raw_local_irq_restore(flags); - return res; -} -EXPORT_SYMBOL(__mips_test_and_change_bit); diff --git a/trunk/arch/mips/lib/mips-atomic.c b/trunk/arch/mips/lib/mips-atomic.c deleted file mode 100644 index cd160be3ce4d..000000000000 --- a/trunk/arch/mips/lib/mips-atomic.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * 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 - * for more details. - * - * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle - * Copyright (C) 1996 by Paul M. Antoine - * Copyright (C) 1999 Silicon Graphics - * Copyright (C) 2000 MIPS Technologies, Inc. - */ -#include -#include -#include -#include -#include - -#if !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) - -/* - * For cli() we have to insert nops to make sure that the new value - * has actually arrived in the status register before the end of this - * macro. - * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs - * no nops at all. - */ -/* - * For TX49, operating only IE bit is not enough. - * - * If mfc0 $12 follows store and the mfc0 is last instruction of a - * page and fetching the next instruction causes TLB miss, the result - * of the mfc0 might wrongly contain EXL bit. - * - * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 - * - * Workaround: mask EXL bit of the result or place a nop before mfc0. - */ -__asm__( - " .macro arch_local_irq_disable\n" - " .set push \n" - " .set noat \n" -#ifdef CONFIG_MIPS_MT_SMTC - " mfc0 $1, $2, 1 \n" - " ori $1, 0x400 \n" - " .set noreorder \n" - " mtc0 $1, $2, 1 \n" -#elif defined(CONFIG_CPU_MIPSR2) - /* see irqflags.h for inline function */ -#else - " mfc0 $1,$12 \n" - " ori $1,0x1f \n" - " xori $1,0x1f \n" - " .set noreorder \n" - " mtc0 $1,$12 \n" -#endif - " irq_disable_hazard \n" - " .set pop \n" - " .endm \n"); - -notrace void arch_local_irq_disable(void) -{ - preempt_disable(); - __asm__ __volatile__( - "arch_local_irq_disable" - : /* no outputs */ - : /* no inputs */ - : "memory"); - preempt_enable(); -} -EXPORT_SYMBOL(arch_local_irq_disable); - - -__asm__( - " .macro arch_local_irq_save result \n" - " .set push \n" - " .set reorder \n" - " .set noat \n" -#ifdef CONFIG_MIPS_MT_SMTC - " mfc0 \\result, $2, 1 \n" - " ori $1, \\result, 0x400 \n" - " .set noreorder \n" - " mtc0 $1, $2, 1 \n" - " andi \\result, \\result, 0x400 \n" -#elif defined(CONFIG_CPU_MIPSR2) - /* see irqflags.h for inline function */ -#else - " mfc0 \\result, $12 \n" - " ori $1, \\result, 0x1f \n" - " xori $1, 0x1f \n" - " .set noreorder \n" - " mtc0 $1, $12 \n" -#endif - " irq_disable_hazard \n" - " .set pop \n" - " .endm \n"); - -notrace unsigned long arch_local_irq_save(void) -{ - unsigned long flags; - preempt_disable(); - asm volatile("arch_local_irq_save\t%0" - : "=r" (flags) - : /* no inputs */ - : "memory"); - preempt_enable(); - return flags; -} -EXPORT_SYMBOL(arch_local_irq_save); - - -__asm__( - " .macro arch_local_irq_restore flags \n" - " .set push \n" - " .set noreorder \n" - " .set noat \n" -#ifdef CONFIG_MIPS_MT_SMTC - "mfc0 $1, $2, 1 \n" - "andi \\flags, 0x400 \n" - "ori $1, 0x400 \n" - "xori $1, 0x400 \n" - "or \\flags, $1 \n" - "mtc0 \\flags, $2, 1 \n" -#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) - /* see irqflags.h for inline function */ -#elif defined(CONFIG_CPU_MIPSR2) - /* see irqflags.h for inline function */ -#else - " mfc0 $1, $12 \n" - " andi \\flags, 1 \n" - " ori $1, 0x1f \n" - " xori $1, 0x1f \n" - " or \\flags, $1 \n" - " mtc0 \\flags, $12 \n" -#endif - " irq_disable_hazard \n" - " .set pop \n" - " .endm \n"); - -notrace void arch_local_irq_restore(unsigned long flags) -{ - unsigned long __tmp1; - -#ifdef CONFIG_MIPS_MT_SMTC - /* - * SMTC kernel needs to do a software replay of queued - * IPIs, at the cost of branch and call overhead on each - * local_irq_restore() - */ - if (unlikely(!(flags & 0x0400))) - smtc_ipi_replay(); -#endif - preempt_disable(); - __asm__ __volatile__( - "arch_local_irq_restore\t%0" - : "=r" (__tmp1) - : "0" (flags) - : "memory"); - preempt_enable(); -} -EXPORT_SYMBOL(arch_local_irq_restore); - - -notrace void __arch_local_irq_restore(unsigned long flags) -{ - unsigned long __tmp1; - - preempt_disable(); - __asm__ __volatile__( - "arch_local_irq_restore\t%0" - : "=r" (__tmp1) - : "0" (flags) - : "memory"); - preempt_enable(); -} -EXPORT_SYMBOL(__arch_local_irq_restore); - -#endif /* !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) */ diff --git a/trunk/arch/mips/mm/tlb-r4k.c b/trunk/arch/mips/mm/tlb-r4k.c index 88e79ad6f811..4b9b935a070e 100644 --- a/trunk/arch/mips/mm/tlb-r4k.c +++ b/trunk/arch/mips/mm/tlb-r4k.c @@ -120,11 +120,18 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, if (cpu_context(cpu, mm) != 0) { unsigned long size, flags; + int huge = is_vm_hugetlb_page(vma); ENTER_CRITICAL(flags); - start = round_down(start, PAGE_SIZE << 1); - end = round_up(end, PAGE_SIZE << 1); - size = (end - start) >> (PAGE_SHIFT + 1); + if (huge) { + start = round_down(start, HPAGE_SIZE); + end = round_up(end, HPAGE_SIZE); + size = (end - start) >> HPAGE_SHIFT; + } else { + start = round_down(start, PAGE_SIZE << 1); + end = round_up(end, PAGE_SIZE << 1); + size = (end - start) >> (PAGE_SHIFT + 1); + } if (size <= current_cpu_data.tlbsize/2) { int oldpid = read_c0_entryhi(); int newpid = cpu_asid(cpu, mm); @@ -133,7 +140,10 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, int idx; write_c0_entryhi(start | newpid); - start += (PAGE_SIZE << 1); + if (huge) + start += HPAGE_SIZE; + else + start += (PAGE_SIZE << 1); mtc0_tlbw_hazard(); tlb_probe(); tlb_probe_hazard(); diff --git a/trunk/arch/mips/mti-malta/malta-platform.c b/trunk/arch/mips/mti-malta/malta-platform.c index 74732177851c..80562b81f0f2 100644 --- a/trunk/arch/mips/mti-malta/malta-platform.c +++ b/trunk/arch/mips/mti-malta/malta-platform.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #define SMC_PORT(base, int) \ @@ -49,7 +48,7 @@ static struct plat_serial8250_port uart8250_data[] = { SMC_PORT(0x2F8, 3), { .mapbase = 0x1f000900, /* The CBUS UART */ - .irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB2, + .irq = MIPS_CPU_IRQ_BASE + 2, .uartclk = 3686400, /* Twice the usual clk! */ .iotype = UPIO_MEM32, .flags = CBUS_UART_FLAGS, diff --git a/trunk/arch/openrisc/kernel/signal.c b/trunk/arch/openrisc/kernel/signal.c index ddedc8a77861..30110297f4f9 100644 --- a/trunk/arch/openrisc/kernel/signal.c +++ b/trunk/arch/openrisc/kernel/signal.c @@ -84,6 +84,7 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs) { struct rt_sigframe *frame = (struct rt_sigframe __user *)regs->sp; sigset_t set; + stack_t st; /* * Since we stacked the signal on a dword boundary, @@ -103,10 +104,11 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs) if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) goto badframe; + if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) + goto badframe; /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) - goto badframe; + do_sigaltstack(&st, NULL, regs->sp); return regs->gpr[11]; diff --git a/trunk/arch/parisc/kernel/signal32.c b/trunk/arch/parisc/kernel/signal32.c index 5dede04f2f3e..fd49aeda9eb8 100644 --- a/trunk/arch/parisc/kernel/signal32.c +++ b/trunk/arch/parisc/kernel/signal32.c @@ -65,8 +65,7 @@ put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) { compat_sigset_t s; - if (sz != sizeof *set) - return -EINVAL; + if (sz != sizeof *set) panic("put_sigset32()"); sigset_64to32(&s, set); return copy_to_user(up, &s, sizeof s); @@ -78,8 +77,7 @@ get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) compat_sigset_t s; int r; - if (sz != sizeof *set) - return -EINVAL; + if (sz != sizeof *set) panic("put_sigset32()"); if ((r = copy_from_user(&s, up, sz)) == 0) { sigset_32to64(set, &s); diff --git a/trunk/arch/parisc/kernel/sys_parisc.c b/trunk/arch/parisc/kernel/sys_parisc.c index f76c10863c62..7426e40699bd 100644 --- a/trunk/arch/parisc/kernel/sys_parisc.c +++ b/trunk/arch/parisc/kernel/sys_parisc.c @@ -73,8 +73,6 @@ static unsigned long get_shared_area(struct address_space *mapping, struct vm_area_struct *vma; int offset = mapping ? get_offset(mapping) : 0; - offset = (offset + (pgoff << PAGE_SHIFT)) & 0x3FF000; - addr = DCACHE_ALIGN(addr - offset) + offset; for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { diff --git a/trunk/arch/parisc/kernel/syscall_table.S b/trunk/arch/parisc/kernel/syscall_table.S index cbf5d59d5d6a..3735abd7f8f6 100644 --- a/trunk/arch/parisc/kernel/syscall_table.S +++ b/trunk/arch/parisc/kernel/syscall_table.S @@ -60,7 +60,7 @@ ENTRY_SAME(fork_wrapper) ENTRY_SAME(read) ENTRY_SAME(write) - ENTRY_COMP(open) /* 5 */ + ENTRY_SAME(open) /* 5 */ ENTRY_SAME(close) ENTRY_SAME(waitpid) ENTRY_SAME(creat) diff --git a/trunk/arch/powerpc/boot/dts/mpc5200b.dtsi b/trunk/arch/powerpc/boot/dts/mpc5200b.dtsi index 39ed65a44c5f..7ab286ab5300 100644 --- a/trunk/arch/powerpc/boot/dts/mpc5200b.dtsi +++ b/trunk/arch/powerpc/boot/dts/mpc5200b.dtsi @@ -231,12 +231,6 @@ interrupts = <2 7 0>; }; - sclpc@3c00 { - compatible = "fsl,mpc5200-lpbfifo"; - reg = <0x3c00 0x60>; - interrupts = <2 23 0>; - }; - i2c@3d00 { #address-cells = <1>; #size-cells = <0>; diff --git a/trunk/arch/powerpc/boot/dts/o2d.dtsi b/trunk/arch/powerpc/boot/dts/o2d.dtsi index 24f668039295..3444eb8f0ade 100644 --- a/trunk/arch/powerpc/boot/dts/o2d.dtsi +++ b/trunk/arch/powerpc/boot/dts/o2d.dtsi @@ -86,6 +86,12 @@ reg = <0>; }; }; + + sclpc@3c00 { + compatible = "fsl,mpc5200-lpbfifo"; + reg = <0x3c00 0x60>; + interrupts = <3 23 0>; + }; }; localbus { diff --git a/trunk/arch/powerpc/boot/dts/pcm030.dts b/trunk/arch/powerpc/boot/dts/pcm030.dts index 96512c058033..9e354997eb7e 100644 --- a/trunk/arch/powerpc/boot/dts/pcm030.dts +++ b/trunk/arch/powerpc/boot/dts/pcm030.dts @@ -59,7 +59,7 @@ #gpio-cells = <2>; }; - audioplatform: psc@2000 { /* PSC1 in ac97 mode */ + psc@2000 { /* PSC1 in ac97 mode */ compatible = "mpc5200b-psc-ac97","fsl,mpc5200b-psc-ac97"; cell-index = <0>; }; @@ -134,9 +134,4 @@ localbus { status = "disabled"; }; - - sound { - compatible = "phytec,pcm030-audio-fabric"; - asoc-platform = <&audioplatform>; - }; }; diff --git a/trunk/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/trunk/arch/powerpc/platforms/52xx/mpc52xx_pic.c index b89ef65392dc..8520b58a5e9a 100644 --- a/trunk/arch/powerpc/platforms/52xx/mpc52xx_pic.c +++ b/trunk/arch/powerpc/platforms/52xx/mpc52xx_pic.c @@ -372,11 +372,10 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq, case MPC52xx_IRQ_L1_MAIN: irqchip = &mpc52xx_main_irqchip; break; case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break; case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break; - case MPC52xx_IRQ_L1_CRIT: - pr_warn("%s: Critical IRQ #%d is unsupported! Nopping it.\n", - __func__, l2irq); - irq_set_chip(virq, &no_irq_chip); - return 0; + default: + pr_err("%s: invalid irq: virq=%i, l1=%i, l2=%i\n", + __func__, virq, l1irq, l2irq); + return -EINVAL; } irq_set_chip_and_handler(virq, irqchip, handle_level_irq); diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_pe.c b/trunk/arch/powerpc/platforms/pseries/eeh_pe.c index d16c8ded1084..797cd181dc3f 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh_pe.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh_pe.c @@ -449,7 +449,7 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe) if (list_empty(&pe->edevs)) { cnt = 0; list_for_each_entry(child, &pe->child_list, child) { - if (!(child->type & EEH_PE_INVALID)) { + if (!(pe->type & EEH_PE_INVALID)) { cnt++; break; } diff --git a/trunk/arch/powerpc/platforms/pseries/msi.c b/trunk/arch/powerpc/platforms/pseries/msi.c index e5b084723131..d19f4977c834 100644 --- a/trunk/arch/powerpc/platforms/pseries/msi.c +++ b/trunk/arch/powerpc/platforms/pseries/msi.c @@ -220,8 +220,7 @@ static struct device_node *find_pe_dn(struct pci_dev *dev, int *total) /* Get the top level device in the PE */ edev = of_node_to_eeh_dev(dn); - if (edev->pe) - edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list); + edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list); dn = eeh_dev_to_of_node(edev); if (!dn) return NULL; diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index d385f396dfee..3f3d9ca7a5b6 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -96,7 +96,6 @@ config S390 select HAVE_MEMBLOCK_NODE_MAP select HAVE_CMPXCHG_LOCAL select HAVE_CMPXCHG_DOUBLE - select HAVE_ALIGNED_STRUCT_PAGE if SLUB select HAVE_VIRT_CPU_ACCOUNTING select VIRT_CPU_ACCOUNTING select ARCH_DISCARD_MEMBLOCK @@ -131,7 +130,6 @@ config S390 select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE select HAVE_UID16 if 32BIT select ARCH_WANT_IPC_PARSE_VERSION - select HAVE_ARCH_TRANSPARENT_HUGEPAGE if 64BIT select GENERIC_SMP_IDLE_THREAD select GENERIC_TIME_VSYSCALL_OLD select GENERIC_CLOCKEVENTS diff --git a/trunk/arch/s390/boot/compressed/vmlinux.lds.S b/trunk/arch/s390/boot/compressed/vmlinux.lds.S index 8e1fb8239287..d80f79d8dd9c 100644 --- a/trunk/arch/s390/boot/compressed/vmlinux.lds.S +++ b/trunk/arch/s390/boot/compressed/vmlinux.lds.S @@ -5,7 +5,7 @@ OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") OUTPUT_ARCH(s390:64-bit) #else OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390") -OUTPUT_ARCH(s390:31-bit) +OUTPUT_ARCH(s390) #endif ENTRY(startup) diff --git a/trunk/arch/s390/include/asm/cio.h b/trunk/arch/s390/include/asm/cio.h index ad2b924167d7..55bde6035216 100644 --- a/trunk/arch/s390/include/asm/cio.h +++ b/trunk/arch/s390/include/asm/cio.h @@ -9,8 +9,6 @@ #define LPM_ANYPATH 0xff #define __MAX_CSSID 0 -#define __MAX_SUBCHANNEL 65535 -#define __MAX_SSID 3 #include diff --git a/trunk/arch/s390/include/asm/compat.h b/trunk/arch/s390/include/asm/compat.h index 18cd6b592650..a34a9d612fc0 100644 --- a/trunk/arch/s390/include/asm/compat.h +++ b/trunk/arch/s390/include/asm/compat.h @@ -20,7 +20,7 @@ #define PSW32_MASK_CC 0x00003000UL #define PSW32_MASK_PM 0x00000f00UL -#define PSW32_MASK_USER 0x0000FF00UL +#define PSW32_MASK_USER 0x00003F00UL #define PSW32_ADDR_AMODE 0x80000000UL #define PSW32_ADDR_INSN 0x7FFFFFFFUL diff --git a/trunk/arch/s390/include/asm/perf_event.h b/trunk/arch/s390/include/asm/perf_event.h index 5f0173a31693..7941968e12b4 100644 --- a/trunk/arch/s390/include/asm/perf_event.h +++ b/trunk/arch/s390/include/asm/perf_event.h @@ -9,7 +9,7 @@ #include /* CPU-measurement counter facility */ -#define PERF_CPUM_CF_MAX_CTR 256 +#define PERF_CPUM_CF_MAX_CTR 160 /* Per-CPU flags for PMU states */ #define PMU_F_RESERVED 0x1000 diff --git a/trunk/arch/s390/include/asm/pgtable.h b/trunk/arch/s390/include/asm/pgtable.h index 2d3b7cb26005..dd647c919a66 100644 --- a/trunk/arch/s390/include/asm/pgtable.h +++ b/trunk/arch/s390/include/asm/pgtable.h @@ -506,15 +506,12 @@ static inline int pud_bad(pud_t pud) static inline int pmd_present(pmd_t pmd) { - unsigned long mask = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO; - return (pmd_val(pmd) & mask) == _HPAGE_TYPE_NONE || - !(pmd_val(pmd) & _SEGMENT_ENTRY_INV); + return (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) != 0UL; } static inline int pmd_none(pmd_t pmd) { - return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) && - !(pmd_val(pmd) & _SEGMENT_ENTRY_RO); + return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) != 0UL; } static inline int pmd_large(pmd_t pmd) @@ -1226,11 +1223,6 @@ static inline void __pmd_idte(unsigned long address, pmd_t *pmdp) } #ifdef CONFIG_TRANSPARENT_HUGEPAGE - -#define SEGMENT_NONE __pgprot(_HPAGE_TYPE_NONE) -#define SEGMENT_RO __pgprot(_HPAGE_TYPE_RO) -#define SEGMENT_RW __pgprot(_HPAGE_TYPE_RW) - #define __HAVE_ARCH_PGTABLE_DEPOSIT extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable); @@ -1250,15 +1242,16 @@ static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot) { - /* - * pgprot is PAGE_NONE, PAGE_RO, or PAGE_RW (see __Pxxx / __Sxxx) - * Convert to segment table entry format. - */ - if (pgprot_val(pgprot) == pgprot_val(PAGE_NONE)) - return pgprot_val(SEGMENT_NONE); - if (pgprot_val(pgprot) == pgprot_val(PAGE_RO)) - return pgprot_val(SEGMENT_RO); - return pgprot_val(SEGMENT_RW); + unsigned long pgprot_pmd = 0; + + if (pgprot_val(pgprot) & _PAGE_INVALID) { + if (pgprot_val(pgprot) & _PAGE_SWT) + pgprot_pmd |= _HPAGE_TYPE_NONE; + pgprot_pmd |= _SEGMENT_ENTRY_INV; + } + if (pgprot_val(pgprot) & _PAGE_RO) + pgprot_pmd |= _SEGMENT_ENTRY_RO; + return pgprot_pmd; } static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) @@ -1276,9 +1269,7 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd) static inline pmd_t pmd_mkwrite(pmd_t pmd) { - /* Do not clobber _HPAGE_TYPE_NONE pages! */ - if (!(pmd_val(pmd) & _SEGMENT_ENTRY_INV)) - pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; + pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; return pmd; } diff --git a/trunk/arch/s390/include/asm/topology.h b/trunk/arch/s390/include/asm/topology.h index 9935cbd6a46f..9ca305383760 100644 --- a/trunk/arch/s390/include/asm/topology.h +++ b/trunk/arch/s390/include/asm/topology.h @@ -8,9 +8,6 @@ struct cpu; #ifdef CONFIG_SCHED_BOOK -extern unsigned char cpu_socket_id[NR_CPUS]; -#define topology_physical_package_id(cpu) (cpu_socket_id[cpu]) - extern unsigned char cpu_core_id[NR_CPUS]; extern cpumask_t cpu_core_map[NR_CPUS]; diff --git a/trunk/arch/s390/include/uapi/asm/Kbuild b/trunk/arch/s390/include/uapi/asm/Kbuild index 7bf68fff7c5d..59b67ed423b4 100644 --- a/trunk/arch/s390/include/uapi/asm/Kbuild +++ b/trunk/arch/s390/include/uapi/asm/Kbuild @@ -1,6 +1,8 @@ # UAPI Header export list include include/uapi/asm-generic/Kbuild.asm +generic-y += kvm_para.h + header-y += auxvec.h header-y += bitsperlong.h header-y += byteorder.h diff --git a/trunk/arch/s390/include/uapi/asm/chpid.h b/trunk/arch/s390/include/uapi/asm/chpid.h index 6b4fb29cc197..581992dfae27 100644 --- a/trunk/arch/s390/include/uapi/asm/chpid.h +++ b/trunk/arch/s390/include/uapi/asm/chpid.h @@ -1,5 +1,5 @@ /* - * Copyright IBM Corp. 2007, 2012 + * Copyright IBM Corp. 2007 * Author(s): Peter Oberparleiter */ @@ -12,10 +12,10 @@ #define __MAX_CHPID 255 struct chp_id { - __u8 reserved1; - __u8 cssid; - __u8 reserved2; - __u8 id; + u8 reserved1; + u8 cssid; + u8 reserved2; + u8 id; } __attribute__((packed)); diff --git a/trunk/arch/s390/include/uapi/asm/kvm_para.h b/trunk/arch/s390/include/uapi/asm/kvm_para.h deleted file mode 100644 index ff1f4e7b3015..000000000000 --- a/trunk/arch/s390/include/uapi/asm/kvm_para.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * User API definitions for paravirtual devices on s390 - * - * Copyright IBM Corp. 2008 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License (version 2 only) - * as published by the Free Software Foundation. - * - * Author(s): Christian Borntraeger - */ diff --git a/trunk/arch/s390/include/uapi/asm/ptrace.h b/trunk/arch/s390/include/uapi/asm/ptrace.h index a5ca214b34fd..705588a16d70 100644 --- a/trunk/arch/s390/include/uapi/asm/ptrace.h +++ b/trunk/arch/s390/include/uapi/asm/ptrace.h @@ -239,7 +239,7 @@ typedef struct #define PSW_MASK_EA 0x00000000UL #define PSW_MASK_BA 0x00000000UL -#define PSW_MASK_USER 0x0000FF00UL +#define PSW_MASK_USER 0x00003F00UL #define PSW_ADDR_AMODE 0x80000000UL #define PSW_ADDR_INSN 0x7FFFFFFFUL @@ -269,7 +269,7 @@ typedef struct #define PSW_MASK_EA 0x0000000100000000UL #define PSW_MASK_BA 0x0000000080000000UL -#define PSW_MASK_USER 0x0000FF8180000000UL +#define PSW_MASK_USER 0x00003F8180000000UL #define PSW_ADDR_AMODE 0x0000000000000000UL #define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL diff --git a/trunk/arch/s390/kernel/cache.c b/trunk/arch/s390/kernel/cache.c index 64b24650e4f8..8df8d8a19c98 100644 --- a/trunk/arch/s390/kernel/cache.c +++ b/trunk/arch/s390/kernel/cache.c @@ -59,8 +59,8 @@ enum { enum { CACHE_TI_UNIFIED = 0, - CACHE_TI_DATA = 0, - CACHE_TI_INSTRUCTION, + CACHE_TI_INSTRUCTION = 0, + CACHE_TI_DATA, }; struct cache_info { @@ -121,10 +121,7 @@ static int __init cache_add(int level, int private, int type) cache = kzalloc(sizeof(*cache), GFP_KERNEL); if (!cache) return -ENOMEM; - if (type == CACHE_TYPE_INSTRUCTION) - ti = CACHE_TI_INSTRUCTION; - else - ti = CACHE_TI_UNIFIED; + ti = type == CACHE_TYPE_DATA ? CACHE_TI_DATA : CACHE_TI_UNIFIED; cache->size = ecag(EXTRACT_SIZE, level, ti); cache->line_size = ecag(EXTRACT_LINE_SIZE, level, ti); cache->associativity = ecag(EXTRACT_ASSOCIATIVITY, level, ti); diff --git a/trunk/arch/s390/kernel/compat_signal.c b/trunk/arch/s390/kernel/compat_signal.c index 593fcc9253fc..a1e8a8694bb7 100644 --- a/trunk/arch/s390/kernel/compat_signal.c +++ b/trunk/arch/s390/kernel/compat_signal.c @@ -309,10 +309,6 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs) regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | (__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32 | (__u64)(regs32.psw.addr & PSW32_ADDR_AMODE); - /* Check for invalid user address space control. */ - if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) - regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | - (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN); for (i = 0; i < NUM_GPRS; i++) regs->gprs[i] = (__u64) regs32.gprs[i]; @@ -485,10 +481,7 @@ static int setup_frame32(int sig, struct k_sigaction *ka, /* Set up registers for signal handler */ regs->gprs[15] = (__force __u64) frame; - /* Force 31 bit amode and default user address space control. */ - regs->psw.mask = PSW_MASK_BA | - (psw_user_bits & PSW_MASK_ASC) | - (regs->psw.mask & ~PSW_MASK_ASC); + regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */ regs->psw.addr = (__force __u64) ka->sa.sa_handler; regs->gprs[2] = map_signal(sig); @@ -556,10 +549,7 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, /* Set up registers for signal handler */ regs->gprs[15] = (__force __u64) frame; - /* Force 31 bit amode and default user address space control. */ - regs->psw.mask = PSW_MASK_BA | - (psw_user_bits & PSW_MASK_ASC) | - (regs->psw.mask & ~PSW_MASK_ASC); + regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */ regs->psw.addr = (__u64) ka->sa.sa_handler; regs->gprs[2] = map_signal(sig); diff --git a/trunk/arch/s390/kernel/compat_wrapper.S b/trunk/arch/s390/kernel/compat_wrapper.S index 827e094a2f49..ad79b846535c 100644 --- a/trunk/arch/s390/kernel/compat_wrapper.S +++ b/trunk/arch/s390/kernel/compat_wrapper.S @@ -28,7 +28,7 @@ ENTRY(sys32_open_wrapper) llgtr %r2,%r2 # const char * lgfr %r3,%r3 # int lgfr %r4,%r4 # int - jg compat_sys_open # branch to system call + jg sys_open # branch to system call ENTRY(sys32_close_wrapper) llgfr %r2,%r2 # unsigned int diff --git a/trunk/arch/s390/kernel/head_kdump.S b/trunk/arch/s390/kernel/head_kdump.S index 085a95eb315f..acaaaf4b7055 100644 --- a/trunk/arch/s390/kernel/head_kdump.S +++ b/trunk/arch/s390/kernel/head_kdump.S @@ -85,10 +85,16 @@ .align 2 startup_kdump_relocated: basr %r13,0 -0: lpswe .Lrestart_psw-0b(%r13) # Start new kernel... +0: + mvc 0(8,%r0),.Lrestart_psw-0b(%r13) # Setup restart PSW + sam31 # Switch to 31 bit addr mode + sr %r1,%r1 # Erase register r1 + sr %r2,%r2 # Erase register r2 + sigp %r1,%r2,SIGP_SET_ARCHITECTURE # Switch to 31 bit arch mode + lpsw 0 # Start new kernel... .align 8 .Lrestart_psw: - .quad 0x0000000080000000,0x0000000000000000 + startup + .long 0x00080000,0x80000000 + startup #else .align 2 .Lep_startup_kdump: diff --git a/trunk/arch/s390/kernel/perf_cpum_cf.c b/trunk/arch/s390/kernel/perf_cpum_cf.c index c4e7269d4a09..9871b1971ed7 100644 --- a/trunk/arch/s390/kernel/perf_cpum_cf.c +++ b/trunk/arch/s390/kernel/perf_cpum_cf.c @@ -94,7 +94,7 @@ static int get_counter_set(u64 event) set = CPUMF_CTR_SET_USER; else if (event < 128) set = CPUMF_CTR_SET_CRYPTO; - else if (event < 256) + else if (event < 160) set = CPUMF_CTR_SET_EXT; return set; @@ -138,10 +138,6 @@ static int validate_ctr_version(const struct hw_perf_event *hwc) case CPUMF_CTR_SET_EXT: if (cpuhw->info.csvn < 1) err = -EOPNOTSUPP; - if ((cpuhw->info.csvn == 1 && hwc->config > 159) || - (cpuhw->info.csvn == 2 && hwc->config > 175) || - (cpuhw->info.csvn > 2 && hwc->config > 255)) - err = -EOPNOTSUPP; break; } diff --git a/trunk/arch/s390/kernel/sclp.S b/trunk/arch/s390/kernel/sclp.S index b6506ee32a36..bf053898630d 100644 --- a/trunk/arch/s390/kernel/sclp.S +++ b/trunk/arch/s390/kernel/sclp.S @@ -44,12 +44,6 @@ _sclp_wait_int: #endif mvc .LoldpswS1-.LbaseS1(16,%r13),0(%r8) mvc 0(16,%r8),0(%r9) -#ifdef CONFIG_64BIT - epsw %r6,%r7 # set current addressing mode - nill %r6,0x1 # in new psw (31 or 64 bit mode) - nilh %r7,0x8000 - stm %r6,%r7,0(%r8) -#endif lhi %r6,0x0200 # cr mask for ext int (cr0.54) ltr %r2,%r2 jz .LsetctS1 @@ -93,7 +87,7 @@ _sclp_wait_int: .long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int #ifdef CONFIG_64BIT .LextpswS1_64: - .quad 0, .LwaitS1 # PSW to handle ext int, 64 bit + .quad 0x0000000180000000, .LwaitS1 # PSW to handle ext int, 64 bit #endif .LwaitpswS1: .long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int diff --git a/trunk/arch/s390/kernel/signal.c b/trunk/arch/s390/kernel/signal.c index d1259d875074..c13a2a37ef00 100644 --- a/trunk/arch/s390/kernel/signal.c +++ b/trunk/arch/s390/kernel/signal.c @@ -136,10 +136,6 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) /* Use regs->psw.mask instead of psw_user_bits to preserve PER bit. */ regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | (user_sregs.regs.psw.mask & PSW_MASK_USER); - /* Check for invalid user address space control. */ - if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) - regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | - (regs->psw.mask & ~PSW_MASK_ASC); /* Check for invalid amode */ if (regs->psw.mask & PSW_MASK_EA) regs->psw.mask |= PSW_MASK_BA; @@ -277,10 +273,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, /* Set up registers for signal handler */ regs->gprs[15] = (unsigned long) frame; - /* Force default amode and default user address space control. */ - regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | - (psw_user_bits & PSW_MASK_ASC) | - (regs->psw.mask & ~PSW_MASK_ASC); + regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */ regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; regs->gprs[2] = map_signal(sig); @@ -353,10 +346,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, /* Set up registers for signal handler */ regs->gprs[15] = (unsigned long) frame; - /* Force default amode and default user address space control. */ - regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | - (psw_user_bits & PSW_MASK_ASC) | - (regs->psw.mask & ~PSW_MASK_ASC); + regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */ regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; regs->gprs[2] = map_signal(sig); diff --git a/trunk/arch/s390/kernel/topology.c b/trunk/arch/s390/kernel/topology.c index dd55f7c20104..54d93f4b6818 100644 --- a/trunk/arch/s390/kernel/topology.c +++ b/trunk/arch/s390/kernel/topology.c @@ -40,7 +40,6 @@ static DEFINE_SPINLOCK(topology_lock); static struct mask_info core_info; cpumask_t cpu_core_map[NR_CPUS]; unsigned char cpu_core_id[NR_CPUS]; -unsigned char cpu_socket_id[NR_CPUS]; static struct mask_info book_info; cpumask_t cpu_book_map[NR_CPUS]; @@ -84,12 +83,11 @@ static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu, cpumask_set_cpu(lcpu, &book->mask); cpu_book_id[lcpu] = book->id; cpumask_set_cpu(lcpu, &core->mask); - cpu_core_id[lcpu] = rcpu; if (one_core_per_cpu) { - cpu_socket_id[lcpu] = rcpu; + cpu_core_id[lcpu] = rcpu; core = core->next; } else { - cpu_socket_id[lcpu] = core->id; + cpu_core_id[lcpu] = core->id; } smp_cpu_set_polarization(lcpu, tl_cpu->pp); } diff --git a/trunk/arch/s390/kernel/vmlinux.lds.S b/trunk/arch/s390/kernel/vmlinux.lds.S index 79cb51adc741..de8fa9bbd35e 100644 --- a/trunk/arch/s390/kernel/vmlinux.lds.S +++ b/trunk/arch/s390/kernel/vmlinux.lds.S @@ -8,7 +8,7 @@ #ifndef CONFIG_64BIT OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390") -OUTPUT_ARCH(s390:31-bit) +OUTPUT_ARCH(s390) ENTRY(startup) jiffies = jiffies_64 + 4; #else diff --git a/trunk/arch/s390/lib/uaccess_pt.c b/trunk/arch/s390/lib/uaccess_pt.c index 9017a63dda3d..2d37bb861faf 100644 --- a/trunk/arch/s390/lib/uaccess_pt.c +++ b/trunk/arch/s390/lib/uaccess_pt.c @@ -39,7 +39,7 @@ static __always_inline unsigned long follow_table(struct mm_struct *mm, pmd = pmd_offset(pud, addr); if (pmd_none(*pmd)) return -0x10UL; - if (pmd_large(*pmd)) { + if (pmd_huge(*pmd)) { if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO)) return -0x04UL; return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK); diff --git a/trunk/arch/s390/mm/gup.c b/trunk/arch/s390/mm/gup.c index 1f5315d1215c..60acb93a4680 100644 --- a/trunk/arch/s390/mm/gup.c +++ b/trunk/arch/s390/mm/gup.c @@ -126,7 +126,7 @@ static inline int gup_pmd_range(pud_t *pudp, pud_t pud, unsigned long addr, */ if (pmd_none(pmd) || pmd_trans_splitting(pmd)) return 0; - if (unlikely(pmd_large(pmd))) { + if (unlikely(pmd_huge(pmd))) { if (!gup_huge_pmd(pmdp, pmd, addr, next, write, pages, nr)) return 0; @@ -180,7 +180,8 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, addr = start; len = (unsigned long) nr_pages << PAGE_SHIFT; end = start + len; - if ((end < start) || (end > TASK_SIZE)) + if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ, + (void __user *)start, len))) return 0; local_irq_save(flags); @@ -228,7 +229,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, addr = start; len = (unsigned long) nr_pages << PAGE_SHIFT; end = start + len; - if ((end < start) || (end > TASK_SIZE)) + if (end < start) goto slow_irqon; /* diff --git a/trunk/arch/score/kernel/signal.c b/trunk/arch/score/kernel/signal.c index 02353bde92d8..c268bbf8b410 100644 --- a/trunk/arch/score/kernel/signal.c +++ b/trunk/arch/score/kernel/signal.c @@ -148,6 +148,7 @@ score_rt_sigreturn(struct pt_regs *regs) { struct rt_sigframe __user *frame; sigset_t set; + stack_t st; int sig; /* Always make any pending restarted system calls return -EINTR */ @@ -167,10 +168,12 @@ score_rt_sigreturn(struct pt_regs *regs) else if (sig) force_sig(sig, current); + if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st))) + goto badframe; + /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - if (do_sigaltstack(&frame->rs_uc.uc_stack, NULL, regs->regs[0]) == -EFAULT) - goto badframe; + do_sigaltstack((stack_t __user *)&st, NULL, regs->regs[0]); regs->is_syscall = 0; __asm__ __volatile__( diff --git a/trunk/arch/sh/kernel/signal_64.c b/trunk/arch/sh/kernel/signal_64.c index d867cd95a622..23853814bd17 100644 --- a/trunk/arch/sh/kernel/signal_64.c +++ b/trunk/arch/sh/kernel/signal_64.c @@ -347,6 +347,7 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3, { struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (long) REF_REG_SP; sigset_t set; + stack_t __user st; long long ret; /* Always make any pending restarted system calls return -EINTR */ @@ -364,10 +365,11 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3, goto badframe; regs->pc -= 4; + if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) + goto badframe; /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - if (do_sigaltstack(&frame->uc.uc_stack, NULL, REF_REG_SP) == -EFAULT) - goto badframe; + do_sigaltstack(&st, NULL, REF_REG_SP); return (int) ret; diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig index 9f2edb5c5551..b6b442b0d793 100644 --- a/trunk/arch/sparc/Kconfig +++ b/trunk/arch/sparc/Kconfig @@ -20,7 +20,6 @@ config SPARC select HAVE_ARCH_TRACEHOOK select SYSCTL_EXCEPTION_TRACE select ARCH_WANT_OPTIONAL_GPIOLIB - select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select RTC_CLASS select RTC_DRV_M48T59 select HAVE_IRQ_WORK diff --git a/trunk/arch/sparc/boot/piggyback.c b/trunk/arch/sparc/boot/piggyback.c index bb7c95161d71..c0a798fcf030 100644 --- a/trunk/arch/sparc/boot/piggyback.c +++ b/trunk/arch/sparc/boot/piggyback.c @@ -81,18 +81,18 @@ static void usage(void) static int start_line(const char *line) { - if (strcmp(line + 10, " _start\n") == 0) + if (strcmp(line + 8, " T _start\n") == 0) return 1; - else if (strcmp(line + 18, " _start\n") == 0) + else if (strcmp(line + 16, " T _start\n") == 0) return 1; return 0; } static int end_line(const char *line) { - if (strcmp(line + 10, " _end\n") == 0) + if (strcmp(line + 8, " A _end\n") == 0) return 1; - else if (strcmp (line + 18, " _end\n") == 0) + else if (strcmp (line + 16, " A _end\n") == 0) return 1; return 0; } @@ -100,8 +100,8 @@ static int end_line(const char *line) /* * Find address for start and end in System.map. * The file looks like this: - * f0004000 ... _start - * f0379f79 ... _end + * f0004000 T _start + * f0379f79 A _end * 1234567890123456 * ^coloumn 1 * There is support for 64 bit addresses too. diff --git a/trunk/arch/sparc/crypto/Makefile b/trunk/arch/sparc/crypto/Makefile index 5d469d81761f..6ae1ad5e502b 100644 --- a/trunk/arch/sparc/crypto/Makefile +++ b/trunk/arch/sparc/crypto/Makefile @@ -13,13 +13,13 @@ obj-$(CONFIG_CRYPTO_DES_SPARC64) += camellia-sparc64.o obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o -sha1-sparc64-y := sha1_asm.o sha1_glue.o -sha256-sparc64-y := sha256_asm.o sha256_glue.o -sha512-sparc64-y := sha512_asm.o sha512_glue.o -md5-sparc64-y := md5_asm.o md5_glue.o +sha1-sparc64-y := sha1_asm.o sha1_glue.o crop_devid.o +sha256-sparc64-y := sha256_asm.o sha256_glue.o crop_devid.o +sha512-sparc64-y := sha512_asm.o sha512_glue.o crop_devid.o +md5-sparc64-y := md5_asm.o md5_glue.o crop_devid.o -aes-sparc64-y := aes_asm.o aes_glue.o -des-sparc64-y := des_asm.o des_glue.o -camellia-sparc64-y := camellia_asm.o camellia_glue.o +aes-sparc64-y := aes_asm.o aes_glue.o crop_devid.o +des-sparc64-y := des_asm.o des_glue.o crop_devid.o +camellia-sparc64-y := camellia_asm.o camellia_glue.o crop_devid.o -crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o +crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o crop_devid.o diff --git a/trunk/arch/sparc/crypto/aes_glue.c b/trunk/arch/sparc/crypto/aes_glue.c index 3965d1d36dfa..8f1c9980f637 100644 --- a/trunk/arch/sparc/crypto/aes_glue.c +++ b/trunk/arch/sparc/crypto/aes_glue.c @@ -475,5 +475,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("AES Secure Hash Algorithm, sparc64 aes opcode accelerated"); MODULE_ALIAS("aes"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/camellia_glue.c b/trunk/arch/sparc/crypto/camellia_glue.c index 62c89af3fd3f..42905c084299 100644 --- a/trunk/arch/sparc/crypto/camellia_glue.c +++ b/trunk/arch/sparc/crypto/camellia_glue.c @@ -320,5 +320,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated"); MODULE_ALIAS("aes"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/crc32c_glue.c b/trunk/arch/sparc/crypto/crc32c_glue.c index 5162fad912ce..0bd89cea8d8e 100644 --- a/trunk/arch/sparc/crypto/crc32c_glue.c +++ b/trunk/arch/sparc/crypto/crc32c_glue.c @@ -177,5 +177,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated"); MODULE_ALIAS("crc32c"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/des_glue.c b/trunk/arch/sparc/crypto/des_glue.c index 41524cebcc49..c4940c2d3073 100644 --- a/trunk/arch/sparc/crypto/des_glue.c +++ b/trunk/arch/sparc/crypto/des_glue.c @@ -527,5 +527,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated"); MODULE_ALIAS("des"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/md5_glue.c b/trunk/arch/sparc/crypto/md5_glue.c index 09a9ea1dfb69..603d723038ce 100644 --- a/trunk/arch/sparc/crypto/md5_glue.c +++ b/trunk/arch/sparc/crypto/md5_glue.c @@ -186,5 +186,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, sparc64 md5 opcode accelerated"); MODULE_ALIAS("md5"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/sha1_glue.c b/trunk/arch/sparc/crypto/sha1_glue.c index 6cd5f29e1e0d..2bbb20bee9f1 100644 --- a/trunk/arch/sparc/crypto/sha1_glue.c +++ b/trunk/arch/sparc/crypto/sha1_glue.c @@ -181,5 +181,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, sparc64 sha1 opcode accelerated"); MODULE_ALIAS("sha1"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/sha256_glue.c b/trunk/arch/sparc/crypto/sha256_glue.c index 04f555ab2680..591e656bd891 100644 --- a/trunk/arch/sparc/crypto/sha256_glue.c +++ b/trunk/arch/sparc/crypto/sha256_glue.c @@ -239,5 +239,3 @@ MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm, sparc64 sha256 op MODULE_ALIAS("sha224"); MODULE_ALIAS("sha256"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/sha512_glue.c b/trunk/arch/sparc/crypto/sha512_glue.c index f04d1994d19a..486f0a2b7001 100644 --- a/trunk/arch/sparc/crypto/sha512_glue.c +++ b/trunk/arch/sparc/crypto/sha512_glue.c @@ -224,5 +224,3 @@ MODULE_DESCRIPTION("SHA-384 and SHA-512 Secure Hash Algorithm, sparc64 sha512 op MODULE_ALIAS("sha384"); MODULE_ALIAS("sha512"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/include/asm/atomic_64.h b/trunk/arch/sparc/include/asm/atomic_64.h index be56a244c9cf..ce35a1cf1a20 100644 --- a/trunk/arch/sparc/include/asm/atomic_64.h +++ b/trunk/arch/sparc/include/asm/atomic_64.h @@ -1,7 +1,7 @@ /* atomic.h: Thankfully the V9 is at least reasonable for this * stuff. * - * Copyright (C) 1996, 1997, 2000, 2012 David S. Miller (davem@redhat.com) + * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com) */ #ifndef __ARCH_SPARC64_ATOMIC__ @@ -106,8 +106,6 @@ static inline long atomic64_add_unless(atomic64_t *v, long a, long u) #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) -extern long atomic64_dec_if_positive(atomic64_t *v); - /* Atomic operations are already serializing */ #define smp_mb__before_atomic_dec() barrier() #define smp_mb__after_atomic_dec() barrier() diff --git a/trunk/arch/sparc/include/asm/backoff.h b/trunk/arch/sparc/include/asm/backoff.h index 4e02086b839c..db3af0d30fb1 100644 --- a/trunk/arch/sparc/include/asm/backoff.h +++ b/trunk/arch/sparc/include/asm/backoff.h @@ -1,46 +1,6 @@ #ifndef _SPARC64_BACKOFF_H #define _SPARC64_BACKOFF_H -/* The macros in this file implement an exponential backoff facility - * for atomic operations. - * - * When multiple threads compete on an atomic operation, it is - * possible for one thread to be continually denied a successful - * completion of the compare-and-swap instruction. Heavily - * threaded cpu implementations like Niagara can compound this - * problem even further. - * - * When an atomic operation fails and needs to be retried, we spin a - * certain number of times. At each subsequent failure of the same - * operation we double the spin count, realizing an exponential - * backoff. - * - * When we spin, we try to use an operation that will cause the - * current cpu strand to block, and therefore make the core fully - * available to any other other runnable strands. There are two - * options, based upon cpu capabilities. - * - * On all cpus prior to SPARC-T4 we do three dummy reads of the - * condition code register. Each read blocks the strand for something - * between 40 and 50 cpu cycles. - * - * For SPARC-T4 and later we have a special "pause" instruction - * available. This is implemented using writes to register %asr27. - * The cpu will block the number of cycles written into the register, - * unless a disrupting trap happens first. SPARC-T4 specifically - * implements pause with a granularity of 8 cycles. Each strand has - * an internal pause counter which decrements every 8 cycles. So the - * chip shifts the %asr27 value down by 3 bits, and writes the result - * into the pause counter. If a value smaller than 8 is written, the - * chip blocks for 1 cycle. - * - * To achieve the same amount of backoff as the three %ccr reads give - * on earlier chips, we shift the backoff value up by 7 bits. (Three - * %ccr reads block for about 128 cycles, 1 << 7 == 128) We write the - * whole amount we want to block into the pause register, rather than - * loop writing 128 each time. - */ - #define BACKOFF_LIMIT (4 * 1024) #ifdef CONFIG_SMP @@ -51,25 +11,16 @@ #define BACKOFF_LABEL(spin_label, continue_label) \ spin_label -#define BACKOFF_SPIN(reg, tmp, label) \ - mov reg, tmp; \ -88: rd %ccr, %g0; \ - rd %ccr, %g0; \ - rd %ccr, %g0; \ - .section .pause_3insn_patch,"ax";\ - .word 88b; \ - sllx tmp, 7, tmp; \ - wr tmp, 0, %asr27; \ - clr tmp; \ - .previous; \ - brnz,pt tmp, 88b; \ - sub tmp, 1, tmp; \ - set BACKOFF_LIMIT, tmp; \ - cmp reg, tmp; \ - bg,pn %xcc, label; \ - nop; \ - ba,pt %xcc, label; \ - sllx reg, 1, reg; +#define BACKOFF_SPIN(reg, tmp, label) \ + mov reg, tmp; \ +88: brnz,pt tmp, 88b; \ + sub tmp, 1, tmp; \ + set BACKOFF_LIMIT, tmp; \ + cmp reg, tmp; \ + bg,pn %xcc, label; \ + nop; \ + ba,pt %xcc, label; \ + sllx reg, 1, reg; #else diff --git a/trunk/arch/sparc/include/asm/compat.h b/trunk/arch/sparc/include/asm/compat.h index 830502fe62b4..cef99fbc0a21 100644 --- a/trunk/arch/sparc/include/asm/compat.h +++ b/trunk/arch/sparc/include/asm/compat.h @@ -232,10 +232,9 @@ static inline void __user *arch_compat_alloc_user_space(long len) struct pt_regs *regs = current_thread_info()->kregs; unsigned long usp = regs->u_regs[UREG_I6]; - if (test_thread_64bit_stack(usp)) + if (!(test_thread_flag(TIF_32BIT))) usp += STACK_BIAS; - - if (test_thread_flag(TIF_32BIT)) + else usp &= 0xffffffffUL; usp -= len; diff --git a/trunk/arch/sparc/include/asm/processor_64.h b/trunk/arch/sparc/include/asm/processor_64.h index 721e25f0e2ea..4e5a483122a0 100644 --- a/trunk/arch/sparc/include/asm/processor_64.h +++ b/trunk/arch/sparc/include/asm/processor_64.h @@ -196,22 +196,7 @@ extern unsigned long get_wchan(struct task_struct *task); #define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc) #define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP]) -/* Please see the commentary in asm/backoff.h for a description of - * what these instructions are doing and how they have been choosen. - * To make a long story short, we are trying to yield the current cpu - * strand during busy loops. - */ -#define cpu_relax() asm volatile("\n99:\n\t" \ - "rd %%ccr, %%g0\n\t" \ - "rd %%ccr, %%g0\n\t" \ - "rd %%ccr, %%g0\n\t" \ - ".section .pause_3insn_patch,\"ax\"\n\t"\ - ".word 99b\n\t" \ - "wr %%g0, 128, %%asr27\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - ".previous" \ - ::: "memory") +#define cpu_relax() barrier() /* Prefetch support. This is tuned for UltraSPARC-III and later. * UltraSPARC-I will treat these as nops, and UltraSPARC-II has diff --git a/trunk/arch/sparc/include/asm/prom.h b/trunk/arch/sparc/include/asm/prom.h index 67c62578d170..c28765110706 100644 --- a/trunk/arch/sparc/include/asm/prom.h +++ b/trunk/arch/sparc/include/asm/prom.h @@ -63,13 +63,5 @@ extern char *of_console_options; extern void irq_trans_init(struct device_node *dp); extern char *build_path_component(struct device_node *dp); -/* SPARC has local implementations */ -extern int of_address_to_resource(struct device_node *dev, int index, - struct resource *r); -#define of_address_to_resource of_address_to_resource - -void __iomem *of_iomap(struct device_node *node, int index); -#define of_iomap of_iomap - #endif /* __KERNEL__ */ #endif /* _SPARC_PROM_H */ diff --git a/trunk/arch/sparc/include/asm/thread_info_64.h b/trunk/arch/sparc/include/asm/thread_info_64.h index a3fe4dcc0aa6..4e2276631081 100644 --- a/trunk/arch/sparc/include/asm/thread_info_64.h +++ b/trunk/arch/sparc/include/asm/thread_info_64.h @@ -259,11 +259,6 @@ static inline bool test_and_clear_restore_sigmask(void) #define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) -#define thread32_stack_is_64bit(__SP) (((__SP) & 0x1) != 0) -#define test_thread_64bit_stack(__SP) \ - ((test_thread_flag(TIF_32BIT) && !thread32_stack_is_64bit(__SP)) ? \ - false : true) - #endif /* !__ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/trunk/arch/sparc/include/asm/ttable.h b/trunk/arch/sparc/include/asm/ttable.h index 71b5a67522ab..48f2807d3265 100644 --- a/trunk/arch/sparc/include/asm/ttable.h +++ b/trunk/arch/sparc/include/asm/ttable.h @@ -372,9 +372,7 @@ etrap_spill_fixup_64bit: \ /* Normal 32bit spill */ #define SPILL_2_GENERIC(ASI) \ - and %sp, 1, %g3; \ - brnz,pn %g3, (. - (128 + 4)); \ - srl %sp, 0, %sp; \ + srl %sp, 0, %sp; \ stwa %l0, [%sp + %g0] ASI; \ mov 0x04, %g3; \ stwa %l1, [%sp + %g3] ASI; \ @@ -400,16 +398,14 @@ etrap_spill_fixup_64bit: \ stwa %i6, [%g1 + %g0] ASI; \ stwa %i7, [%g1 + %g3] ASI; \ saved; \ - retry; \ + retry; nop; nop; \ b,a,pt %xcc, spill_fixup_dax; \ b,a,pt %xcc, spill_fixup_mna; \ b,a,pt %xcc, spill_fixup; #define SPILL_2_GENERIC_ETRAP \ etrap_user_spill_32bit: \ - and %sp, 1, %g3; \ - brnz,pn %g3, etrap_user_spill_64bit; \ - srl %sp, 0, %sp; \ + srl %sp, 0, %sp; \ stwa %l0, [%sp + 0x00] %asi; \ stwa %l1, [%sp + 0x04] %asi; \ stwa %l2, [%sp + 0x08] %asi; \ @@ -431,7 +427,7 @@ etrap_user_spill_32bit: \ ba,pt %xcc, etrap_save; \ wrpr %g1, %cwp; \ nop; nop; nop; nop; \ - nop; nop; \ + nop; nop; nop; nop; \ ba,a,pt %xcc, etrap_spill_fixup_32bit; \ ba,a,pt %xcc, etrap_spill_fixup_32bit; \ ba,a,pt %xcc, etrap_spill_fixup_32bit; @@ -596,9 +592,7 @@ user_rtt_fill_64bit: \ /* Normal 32bit fill */ #define FILL_2_GENERIC(ASI) \ - and %sp, 1, %g3; \ - brnz,pn %g3, (. - (128 + 4)); \ - srl %sp, 0, %sp; \ + srl %sp, 0, %sp; \ lduwa [%sp + %g0] ASI, %l0; \ mov 0x04, %g2; \ mov 0x08, %g3; \ @@ -622,16 +616,14 @@ user_rtt_fill_64bit: \ lduwa [%g1 + %g3] ASI, %i6; \ lduwa [%g1 + %g5] ASI, %i7; \ restored; \ - retry; nop; nop; \ + retry; nop; nop; nop; nop; \ b,a,pt %xcc, fill_fixup_dax; \ b,a,pt %xcc, fill_fixup_mna; \ b,a,pt %xcc, fill_fixup; #define FILL_2_GENERIC_RTRAP \ user_rtt_fill_32bit: \ - and %sp, 1, %g3; \ - brnz,pn %g3, user_rtt_fill_64bit; \ - srl %sp, 0, %sp; \ + srl %sp, 0, %sp; \ lduwa [%sp + 0x00] %asi, %l0; \ lduwa [%sp + 0x04] %asi, %l1; \ lduwa [%sp + 0x08] %asi, %l2; \ @@ -651,7 +643,7 @@ user_rtt_fill_32bit: \ ba,pt %xcc, user_rtt_pre_restore; \ restored; \ nop; nop; nop; nop; nop; \ - nop; nop; nop; \ + nop; nop; nop; nop; nop; \ ba,a,pt %xcc, user_rtt_fill_fixup; \ ba,a,pt %xcc, user_rtt_fill_fixup; \ ba,a,pt %xcc, user_rtt_fill_fixup; diff --git a/trunk/arch/sparc/include/uapi/asm/unistd.h b/trunk/arch/sparc/include/uapi/asm/unistd.h index cac719d1bc5c..8974ef7ae920 100644 --- a/trunk/arch/sparc/include/uapi/asm/unistd.h +++ b/trunk/arch/sparc/include/uapi/asm/unistd.h @@ -405,13 +405,8 @@ #define __NR_setns 337 #define __NR_process_vm_readv 338 #define __NR_process_vm_writev 339 -#define __NR_kern_features 340 -#define __NR_kcmp 341 -#define NR_syscalls 342 - -/* Bitmask values returned from kern_features system call. */ -#define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 +#define NR_syscalls 340 #ifdef __32bit_syscall_numbers__ /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, diff --git a/trunk/arch/sparc/kernel/entry.h b/trunk/arch/sparc/kernel/entry.h index cc3c5cb47cda..0c218e4c0881 100644 --- a/trunk/arch/sparc/kernel/entry.h +++ b/trunk/arch/sparc/kernel/entry.h @@ -59,13 +59,6 @@ struct popc_6insn_patch_entry { extern struct popc_6insn_patch_entry __popc_6insn_patch, __popc_6insn_patch_end; -struct pause_patch_entry { - unsigned int addr; - unsigned int insns[3]; -}; -extern struct pause_patch_entry __pause_3insn_patch, - __pause_3insn_patch_end; - extern void __init per_cpu_patch(void); extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, struct sun4v_1insn_patch_entry *); diff --git a/trunk/arch/sparc/kernel/leon_kernel.c b/trunk/arch/sparc/kernel/leon_kernel.c index 87f60ee65433..f8b6eee40bde 100644 --- a/trunk/arch/sparc/kernel/leon_kernel.c +++ b/trunk/arch/sparc/kernel/leon_kernel.c @@ -56,13 +56,11 @@ static inline unsigned int leon_eirq_get(int cpu) static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc) { unsigned int eirq; - struct irq_bucket *p; int cpu = sparc_leon3_cpuid(); eirq = leon_eirq_get(cpu); - p = irq_map[eirq]; - if ((eirq & 0x10) && p && p->irq) /* bit4 tells if IRQ happened */ - generic_handle_irq(p->irq); + if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */ + generic_handle_irq(irq_map[eirq]->irq); } /* The extended IRQ controller has been found, this function registers it */ diff --git a/trunk/arch/sparc/kernel/perf_event.c b/trunk/arch/sparc/kernel/perf_event.c index b5c38faa4ead..885a8af74064 100644 --- a/trunk/arch/sparc/kernel/perf_event.c +++ b/trunk/arch/sparc/kernel/perf_event.c @@ -1762,25 +1762,15 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, ufp = regs->u_regs[UREG_I6] & 0xffffffffUL; do { + struct sparc_stackf32 *usf, sf; unsigned long pc; - if (thread32_stack_is_64bit(ufp)) { - struct sparc_stackf *usf, sf; + usf = (struct sparc_stackf32 *) ufp; + if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) + break; - ufp += STACK_BIAS; - usf = (struct sparc_stackf *) ufp; - if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) - break; - pc = sf.callers_pc & 0xffffffff; - ufp = ((unsigned long) sf.fp) & 0xffffffff; - } else { - struct sparc_stackf32 *usf, sf; - usf = (struct sparc_stackf32 *) ufp; - if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) - break; - pc = sf.callers_pc; - ufp = (unsigned long)sf.fp; - } + pc = sf.callers_pc; + ufp = (unsigned long)sf.fp; perf_callchain_store(entry, pc); } while (entry->nr < PERF_MAX_STACK_DEPTH); } diff --git a/trunk/arch/sparc/kernel/process_64.c b/trunk/arch/sparc/kernel/process_64.c index c6e0c2910043..d778248ef3f8 100644 --- a/trunk/arch/sparc/kernel/process_64.c +++ b/trunk/arch/sparc/kernel/process_64.c @@ -452,16 +452,13 @@ void flush_thread(void) /* It's a bit more tricky when 64-bit tasks are involved... */ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) { - bool stack_64bit = test_thread_64bit_stack(psp); unsigned long fp, distance, rval; - if (stack_64bit) { + if (!(test_thread_flag(TIF_32BIT))) { csp += STACK_BIAS; psp += STACK_BIAS; __get_user(fp, &(((struct reg_window __user *)psp)->ins[6])); fp += STACK_BIAS; - if (test_thread_flag(TIF_32BIT)) - fp &= 0xffffffff; } else __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6])); @@ -475,7 +472,7 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) rval = (csp - distance); if (copy_in_user((void __user *) rval, (void __user *) psp, distance)) rval = 0; - else if (!stack_64bit) { + else if (test_thread_flag(TIF_32BIT)) { if (put_user(((u32)csp), &(((struct reg_window32 __user *)rval)->ins[6]))) rval = 0; @@ -510,18 +507,18 @@ void synchronize_user_stack(void) flush_user_windows(); if ((window = get_thread_wsaved()) != 0) { + int winsize = sizeof(struct reg_window); + int bias = 0; + + if (test_thread_flag(TIF_32BIT)) + winsize = sizeof(struct reg_window32); + else + bias = STACK_BIAS; + window -= 1; do { + unsigned long sp = (t->rwbuf_stkptrs[window] + bias); struct reg_window *rwin = &t->reg_window[window]; - int winsize = sizeof(struct reg_window); - unsigned long sp; - - sp = t->rwbuf_stkptrs[window]; - - if (test_thread_64bit_stack(sp)) - sp += STACK_BIAS; - else - winsize = sizeof(struct reg_window32); if (!copy_to_user((char __user *)sp, rwin, winsize)) { shift_window_buffer(window, get_thread_wsaved() - 1, t); @@ -547,6 +544,13 @@ void fault_in_user_windows(void) { struct thread_info *t = current_thread_info(); unsigned long window; + int winsize = sizeof(struct reg_window); + int bias = 0; + + if (test_thread_flag(TIF_32BIT)) + winsize = sizeof(struct reg_window32); + else + bias = STACK_BIAS; flush_user_windows(); window = get_thread_wsaved(); @@ -554,16 +558,8 @@ void fault_in_user_windows(void) if (likely(window != 0)) { window -= 1; do { + unsigned long sp = (t->rwbuf_stkptrs[window] + bias); struct reg_window *rwin = &t->reg_window[window]; - int winsize = sizeof(struct reg_window); - unsigned long sp; - - sp = t->rwbuf_stkptrs[window]; - - if (test_thread_64bit_stack(sp)) - sp += STACK_BIAS; - else - winsize = sizeof(struct reg_window32); if (unlikely(sp & 0x7UL)) stack_unaligned(sp); diff --git a/trunk/arch/sparc/kernel/ptrace_64.c b/trunk/arch/sparc/kernel/ptrace_64.c index 7ff45e4ba681..484dabac7045 100644 --- a/trunk/arch/sparc/kernel/ptrace_64.c +++ b/trunk/arch/sparc/kernel/ptrace_64.c @@ -151,7 +151,7 @@ static int regwindow64_get(struct task_struct *target, { unsigned long rw_addr = regs->u_regs[UREG_I6]; - if (!test_thread_64bit_stack(rw_addr)) { + if (test_tsk_thread_flag(current, TIF_32BIT)) { struct reg_window32 win32; int i; @@ -176,7 +176,7 @@ static int regwindow64_set(struct task_struct *target, { unsigned long rw_addr = regs->u_regs[UREG_I6]; - if (!test_thread_64bit_stack(rw_addr)) { + if (test_tsk_thread_flag(current, TIF_32BIT)) { struct reg_window32 win32; int i; diff --git a/trunk/arch/sparc/kernel/setup_64.c b/trunk/arch/sparc/kernel/setup_64.c index 0eaf0059aaef..0800e71d8a88 100644 --- a/trunk/arch/sparc/kernel/setup_64.c +++ b/trunk/arch/sparc/kernel/setup_64.c @@ -316,25 +316,6 @@ static void __init popc_patch(void) } } -static void __init pause_patch(void) -{ - struct pause_patch_entry *p; - - p = &__pause_3insn_patch; - while (p < &__pause_3insn_patch_end) { - unsigned long i, addr = p->addr; - - for (i = 0; i < 3; i++) { - *(unsigned int *) (addr + (i * 4)) = p->insns[i]; - wmb(); - __asm__ __volatile__("flush %0" - : : "r" (addr + (i * 4))); - } - - p++; - } -} - #ifdef CONFIG_SMP void __init boot_cpu_id_too_large(int cpu) { @@ -547,8 +528,6 @@ static void __init init_sparc64_elf_hwcap(void) if (sparc64_elf_hwcap & AV_SPARC_POPC) popc_patch(); - if (sparc64_elf_hwcap & AV_SPARC_PAUSE) - pause_patch(); } void __init setup_arch(char **cmdline_p) diff --git a/trunk/arch/sparc/kernel/signal_64.c b/trunk/arch/sparc/kernel/signal_64.c index 689e1ba62809..867de2f8189c 100644 --- a/trunk/arch/sparc/kernel/signal_64.c +++ b/trunk/arch/sparc/kernel/signal_64.c @@ -295,7 +295,9 @@ void do_rt_sigreturn(struct pt_regs *regs) err |= restore_fpu_state(regs, fpu_save); err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); - if (err || do_sigaltstack(&sf->stack, NULL, (unsigned long)sf) == -EFAULT) + err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf); + + if (err) goto segv; err |= __get_user(rwin_save, &sf->rwin_save); diff --git a/trunk/arch/sparc/kernel/sys32.S b/trunk/arch/sparc/kernel/sys32.S index 8475a474273a..44025f4ba41f 100644 --- a/trunk/arch/sparc/kernel/sys32.S +++ b/trunk/arch/sparc/kernel/sys32.S @@ -47,7 +47,7 @@ STUB: sra REG1, 0, REG1; \ sra REG4, 0, REG4 SIGN1(sys32_exit, sparc_exit, %o0) -SIGN1(sys32_exit_group, sparc_exit_group, %o0) +SIGN1(sys32_exit_group, sys_exit_group, %o0) SIGN1(sys32_wait4, compat_sys_wait4, %o2) SIGN1(sys32_creat, sys_creat, %o1) SIGN1(sys32_mknod, sys_mknod, %o1) diff --git a/trunk/arch/sparc/kernel/sys_sparc_64.c b/trunk/arch/sparc/kernel/sys_sparc_64.c index 878ef3d5fec5..11c6c9603e71 100644 --- a/trunk/arch/sparc/kernel/sys_sparc_64.c +++ b/trunk/arch/sparc/kernel/sys_sparc_64.c @@ -751,8 +751,3 @@ int kernel_execve(const char *filename, : "cc"); return __res; } - -asmlinkage long sys_kern_features(void) -{ - return KERN_FEATURE_MIXED_MODE_STACK; -} diff --git a/trunk/arch/sparc/kernel/syscalls.S b/trunk/arch/sparc/kernel/syscalls.S index bf2347794e33..7f5f65d0b3fd 100644 --- a/trunk/arch/sparc/kernel/syscalls.S +++ b/trunk/arch/sparc/kernel/syscalls.S @@ -118,20 +118,10 @@ ret_from_syscall: ba,pt %xcc, ret_sys_call ldx [%sp + PTREGS_OFF + PT_V9_I0], %o0 - .globl sparc_exit_group - .type sparc_exit_group,#function -sparc_exit_group: - sethi %hi(sys_exit_group), %g7 - ba,pt %xcc, 1f - or %g7, %lo(sys_exit_group), %g7 - .size sparc_exit_group,.-sparc_exit_group - .globl sparc_exit .type sparc_exit,#function sparc_exit: - sethi %hi(sys_exit), %g7 - or %g7, %lo(sys_exit), %g7 -1: rdpr %pstate, %g2 + rdpr %pstate, %g2 wrpr %g2, PSTATE_IE, %pstate rdpr %otherwin, %g1 rdpr %cansave, %g3 @@ -139,7 +129,7 @@ sparc_exit: wrpr %g3, 0x0, %cansave wrpr %g0, 0x0, %otherwin wrpr %g2, 0x0, %pstate - jmpl %g7, %g0 + ba,pt %xcc, sys_exit stb %g0, [%g6 + TI_WSAVED] .size sparc_exit,.-sparc_exit diff --git a/trunk/arch/sparc/kernel/systbls_32.S b/trunk/arch/sparc/kernel/systbls_32.S index 5147f574f125..63402f9e9f51 100644 --- a/trunk/arch/sparc/kernel/systbls_32.S +++ b/trunk/arch/sparc/kernel/systbls_32.S @@ -85,4 +85,3 @@ sys_call_table: /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime /*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev -/*340*/ .long sys_ni_syscall, sys_kcmp diff --git a/trunk/arch/sparc/kernel/systbls_64.S b/trunk/arch/sparc/kernel/systbls_64.S index 017b74a63dcb..3a58e0d66f51 100644 --- a/trunk/arch/sparc/kernel/systbls_64.S +++ b/trunk/arch/sparc/kernel/systbls_64.S @@ -86,7 +86,6 @@ sys_call_table32: .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev -/*340*/ .word sys_kern_features, sys_kcmp #endif /* CONFIG_COMPAT */ @@ -133,7 +132,7 @@ sys_call_table: /*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr /*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall - .word sys_setpgid, sys_fremovexattr, sys_tkill, sparc_exit_group, sys_newuname + .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname /*190*/ .word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl .word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask /*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall @@ -164,4 +163,3 @@ sys_call_table: .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev -/*340*/ .word sys_kern_features, sys_kcmp diff --git a/trunk/arch/sparc/kernel/unaligned_64.c b/trunk/arch/sparc/kernel/unaligned_64.c index 8201c25e7669..f81d038f7340 100644 --- a/trunk/arch/sparc/kernel/unaligned_64.c +++ b/trunk/arch/sparc/kernel/unaligned_64.c @@ -113,24 +113,21 @@ static inline long sign_extend_imm13(long imm) static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) { - unsigned long value, fp; + unsigned long value; if (reg < 16) return (!reg ? 0 : regs->u_regs[reg]); - - fp = regs->u_regs[UREG_FP]; - if (regs->tstate & TSTATE_PRIV) { struct reg_window *win; - win = (struct reg_window *)(fp + STACK_BIAS); + win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); value = win->locals[reg - 16]; - } else if (!test_thread_64bit_stack(fp)) { + } else if (test_thread_flag(TIF_32BIT)) { struct reg_window32 __user *win32; - win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); + win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); get_user(value, &win32->locals[reg - 16]); } else { struct reg_window __user *win; - win = (struct reg_window __user *)(fp + STACK_BIAS); + win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); get_user(value, &win->locals[reg - 16]); } return value; @@ -138,24 +135,19 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs) { - unsigned long fp; - if (reg < 16) return ®s->u_regs[reg]; - - fp = regs->u_regs[UREG_FP]; - if (regs->tstate & TSTATE_PRIV) { struct reg_window *win; - win = (struct reg_window *)(fp + STACK_BIAS); + win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); return &win->locals[reg - 16]; - } else if (!test_thread_64bit_stack(fp)) { + } else if (test_thread_flag(TIF_32BIT)) { struct reg_window32 *win32; - win32 = (struct reg_window32 *)((unsigned long)((u32)fp)); + win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP])); return (unsigned long *)&win32->locals[reg - 16]; } else { struct reg_window *win; - win = (struct reg_window *)(fp + STACK_BIAS); + win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); return &win->locals[reg - 16]; } } @@ -400,15 +392,13 @@ int handle_popc(u32 insn, struct pt_regs *regs) if (rd) regs->u_regs[rd] = ret; } else { - unsigned long fp = regs->u_regs[UREG_FP]; - - if (!test_thread_64bit_stack(fp)) { + if (test_thread_flag(TIF_32BIT)) { struct reg_window32 __user *win32; - win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); + win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); put_user(ret, &win32->locals[rd - 16]); } else { struct reg_window __user *win; - win = (struct reg_window __user *)(fp + STACK_BIAS); + win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); put_user(ret, &win->locals[rd - 16]); } } @@ -564,7 +554,7 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs) reg[0] = 0; if ((insn & 0x780000) == 0x180000) reg[1] = 0; - } else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) { + } else if (test_thread_flag(TIF_32BIT)) { put_user(0, (int __user *) reg); if ((insn & 0x780000) == 0x180000) put_user(0, ((int __user *) reg) + 1); diff --git a/trunk/arch/sparc/kernel/visemul.c b/trunk/arch/sparc/kernel/visemul.c index c096c624ac4d..08e074b7eb6a 100644 --- a/trunk/arch/sparc/kernel/visemul.c +++ b/trunk/arch/sparc/kernel/visemul.c @@ -149,24 +149,21 @@ static inline void maybe_flush_windows(unsigned int rs1, unsigned int rs2, static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) { - unsigned long value, fp; + unsigned long value; if (reg < 16) return (!reg ? 0 : regs->u_regs[reg]); - - fp = regs->u_regs[UREG_FP]; - if (regs->tstate & TSTATE_PRIV) { struct reg_window *win; - win = (struct reg_window *)(fp + STACK_BIAS); + win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); value = win->locals[reg - 16]; - } else if (!test_thread_64bit_stack(fp)) { + } else if (test_thread_flag(TIF_32BIT)) { struct reg_window32 __user *win32; - win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); + win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); get_user(value, &win32->locals[reg - 16]); } else { struct reg_window __user *win; - win = (struct reg_window __user *)(fp + STACK_BIAS); + win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); get_user(value, &win->locals[reg - 16]); } return value; @@ -175,18 +172,16 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) static inline unsigned long __user *__fetch_reg_addr_user(unsigned int reg, struct pt_regs *regs) { - unsigned long fp = regs->u_regs[UREG_FP]; - BUG_ON(reg < 16); BUG_ON(regs->tstate & TSTATE_PRIV); - if (!test_thread_64bit_stack(fp)) { + if (test_thread_flag(TIF_32BIT)) { struct reg_window32 __user *win32; - win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); + win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); return (unsigned long __user *)&win32->locals[reg - 16]; } else { struct reg_window __user *win; - win = (struct reg_window __user *)(fp + STACK_BIAS); + win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); return &win->locals[reg - 16]; } } @@ -209,7 +204,7 @@ static void store_reg(struct pt_regs *regs, unsigned long val, unsigned long rd) } else { unsigned long __user *rd_user = __fetch_reg_addr_user(rd, regs); - if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) + if (test_thread_flag(TIF_32BIT)) __put_user((u32)val, (u32 __user *)rd_user); else __put_user(val, rd_user); diff --git a/trunk/arch/sparc/kernel/vmlinux.lds.S b/trunk/arch/sparc/kernel/vmlinux.lds.S index 0bacceb19150..89c2c29f154b 100644 --- a/trunk/arch/sparc/kernel/vmlinux.lds.S +++ b/trunk/arch/sparc/kernel/vmlinux.lds.S @@ -132,11 +132,6 @@ SECTIONS *(.popc_6insn_patch) __popc_6insn_patch_end = .; } - .pause_3insn_patch : { - __pause_3insn_patch = .; - *(.pause_3insn_patch) - __pause_3insn_patch_end = .; - } PERCPU_SECTION(SMP_CACHE_BYTES) . = ALIGN(PAGE_SIZE); diff --git a/trunk/arch/sparc/kernel/winfixup.S b/trunk/arch/sparc/kernel/winfixup.S index 1e67ce958369..a6b0863c27df 100644 --- a/trunk/arch/sparc/kernel/winfixup.S +++ b/trunk/arch/sparc/kernel/winfixup.S @@ -43,8 +43,6 @@ spill_fixup_mna: spill_fixup_dax: TRAP_LOAD_THREAD_REG(%g6, %g1) ldx [%g6 + TI_FLAGS], %g1 - andcc %sp, 0x1, %g0 - movne %icc, 0, %g1 andcc %g1, _TIF_32BIT, %g0 ldub [%g6 + TI_WSAVED], %g1 sll %g1, 3, %g3 diff --git a/trunk/arch/sparc/lib/atomic_64.S b/trunk/arch/sparc/lib/atomic_64.S index 85c233d0a340..4d502da3de78 100644 --- a/trunk/arch/sparc/lib/atomic_64.S +++ b/trunk/arch/sparc/lib/atomic_64.S @@ -1,6 +1,6 @@ /* atomic.S: These things are too big to do inline. * - * Copyright (C) 1999, 2007 2012 David S. Miller (davem@davemloft.net) + * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) */ #include @@ -117,17 +117,3 @@ ENTRY(atomic64_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */ sub %g1, %o0, %o0 2: BACKOFF_SPIN(%o2, %o3, 1b) ENDPROC(atomic64_sub_ret) - -ENTRY(atomic64_dec_if_positive) /* %o0 = atomic_ptr */ - BACKOFF_SETUP(%o2) -1: ldx [%o0], %g1 - brlez,pn %g1, 3f - sub %g1, 1, %g7 - casx [%o0], %g1, %g7 - cmp %g1, %g7 - bne,pn %xcc, BACKOFF_LABEL(2f, 1b) - nop -3: retl - sub %g1, 1, %o0 -2: BACKOFF_SPIN(%o2, %o3, 1b) -ENDPROC(atomic64_dec_if_positive) diff --git a/trunk/arch/sparc/lib/ksyms.c b/trunk/arch/sparc/lib/ksyms.c index 0c4e35e522fa..ee31b884c61b 100644 --- a/trunk/arch/sparc/lib/ksyms.c +++ b/trunk/arch/sparc/lib/ksyms.c @@ -116,7 +116,6 @@ EXPORT_SYMBOL(atomic64_add); EXPORT_SYMBOL(atomic64_add_ret); EXPORT_SYMBOL(atomic64_sub); EXPORT_SYMBOL(atomic64_sub_ret); -EXPORT_SYMBOL(atomic64_dec_if_positive); /* Atomic bit operations. */ EXPORT_SYMBOL(test_and_set_bit); diff --git a/trunk/arch/sparc/math-emu/math_64.c b/trunk/arch/sparc/math-emu/math_64.c index 034aadbff036..1704068da928 100644 --- a/trunk/arch/sparc/math-emu/math_64.c +++ b/trunk/arch/sparc/math-emu/math_64.c @@ -320,7 +320,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap) XR = 0; else if (freg < 16) XR = regs->u_regs[freg]; - else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) { + else if (test_thread_flag(TIF_32BIT)) { struct reg_window32 __user *win32; flushw_user (); win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); diff --git a/trunk/arch/tile/Makefile b/trunk/arch/tile/Makefile index 3d15364c6071..55640cf92597 100644 --- a/trunk/arch/tile/Makefile +++ b/trunk/arch/tile/Makefile @@ -26,10 +26,6 @@ $(error Set TILERA_ROOT or CROSS_COMPILE when building $(ARCH) on $(HOST_ARCH)) endif endif -# The tile compiler may emit .eh_frame information for backtracing. -# In kernel modules, this causes load failures due to unsupported relocations. -KBUILD_CFLAGS += -fno-asynchronous-unwind-tables - ifneq ($(CONFIG_DEBUG_EXTRA_FLAGS),"") KBUILD_CFLAGS += $(CONFIG_DEBUG_EXTRA_FLAGS) endif diff --git a/trunk/arch/tile/kernel/module.c b/trunk/arch/tile/kernel/module.c index 243ffebe38d6..001cbfa10ac6 100644 --- a/trunk/arch/tile/kernel/module.c +++ b/trunk/arch/tile/kernel/module.c @@ -24,6 +24,16 @@ #include #include +#ifdef __tilegx__ +# define Elf_Rela Elf64_Rela +# define ELF_R_SYM ELF64_R_SYM +# define ELF_R_TYPE ELF64_R_TYPE +#else +# define Elf_Rela Elf32_Rela +# define ELF_R_SYM ELF32_R_SYM +# define ELF_R_TYPE ELF32_R_TYPE +#endif + #ifdef MODULE_DEBUG #define DEBUGP printk #else diff --git a/trunk/arch/um/kernel/exec.c b/trunk/arch/um/kernel/exec.c index 0d7103c9eff3..3a8ece7d09ca 100644 --- a/trunk/arch/um/kernel/exec.c +++ b/trunk/arch/um/kernel/exec.c @@ -32,14 +32,13 @@ void flush_thread(void) "err = %d\n", ret); force_sig(SIGKILL, current); } - get_safe_registers(current_pt_regs()->regs.gp, - current_pt_regs()->regs.fp); __switch_mm(¤t->mm->context.id); } void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) { + get_safe_registers(regs->regs.gp, regs->regs.fp); PT_REGS_IP(regs) = eip; PT_REGS_SP(regs) = esp; current->ptrace &= ~PT_DTRACE; diff --git a/trunk/arch/unicore32/Kconfig b/trunk/arch/unicore32/Kconfig index c4fbb21e802b..e5c5473e69ce 100644 --- a/trunk/arch/unicore32/Kconfig +++ b/trunk/arch/unicore32/Kconfig @@ -16,8 +16,6 @@ config UNICORE32 select ARCH_WANT_FRAME_POINTERS select GENERIC_IOMAP select MODULES_USE_ELF_REL - select GENERIC_KERNEL_THREAD - select GENERIC_KERNEL_EXECVE help UniCore-32 is 32-bit Instruction Set Architecture, including a series of low-power-consumption RISC chip @@ -66,9 +64,6 @@ config GENERIC_CALIBRATE_DELAY config ARCH_MAY_HAVE_PC_FDC bool -config ZONE_DMA - def_bool y - config NEED_DMA_MAP_STATE def_bool y @@ -221,7 +216,7 @@ config PUV3_GPIO bool depends on !ARCH_FPGA select GENERIC_GPIO - select GPIO_SYSFS + select GPIO_SYSFS if EXPERIMENTAL default y if PUV3_NB0916 diff --git a/trunk/arch/unicore32/include/asm/Kbuild b/trunk/arch/unicore32/include/asm/Kbuild index 601e92f18af6..c910c9857e11 100644 --- a/trunk/arch/unicore32/include/asm/Kbuild +++ b/trunk/arch/unicore32/include/asm/Kbuild @@ -1,3 +1,4 @@ +include include/asm-generic/Kbuild.asm generic-y += atomic.h generic-y += auxvec.h diff --git a/trunk/arch/unicore32/include/asm/bug.h b/trunk/arch/unicore32/include/asm/bug.h index 93a56f3e2344..b1ff8cadb086 100644 --- a/trunk/arch/unicore32/include/asm/bug.h +++ b/trunk/arch/unicore32/include/asm/bug.h @@ -19,4 +19,9 @@ extern void die(const char *msg, struct pt_regs *regs, int err); extern void uc32_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, unsigned long err, unsigned long trap); +extern asmlinkage void __backtrace(void); +extern asmlinkage void c_backtrace(unsigned long fp, int pmode); + +extern void __show_regs(struct pt_regs *); + #endif /* __UNICORE_BUG_H__ */ diff --git a/trunk/arch/unicore32/include/uapi/asm/byteorder.h b/trunk/arch/unicore32/include/asm/byteorder.h similarity index 100% rename from trunk/arch/unicore32/include/uapi/asm/byteorder.h rename to trunk/arch/unicore32/include/asm/byteorder.h diff --git a/trunk/arch/unicore32/include/asm/cmpxchg.h b/trunk/arch/unicore32/include/asm/cmpxchg.h index 8e797ad4fa24..df4d5acfd19f 100644 --- a/trunk/arch/unicore32/include/asm/cmpxchg.h +++ b/trunk/arch/unicore32/include/asm/cmpxchg.h @@ -35,7 +35,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, : "memory", "cc"); break; default: - __xchg_bad_pointer(); + ret = __xchg_bad_pointer(); } return ret; diff --git a/trunk/arch/unicore32/include/asm/kvm_para.h b/trunk/arch/unicore32/include/asm/kvm_para.h new file mode 100644 index 000000000000..14fab8f0b957 --- /dev/null +++ b/trunk/arch/unicore32/include/asm/kvm_para.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/unicore32/include/asm/processor.h b/trunk/arch/unicore32/include/asm/processor.h index 4eaa42167667..14382cb09657 100644 --- a/trunk/arch/unicore32/include/asm/processor.h +++ b/trunk/arch/unicore32/include/asm/processor.h @@ -72,6 +72,11 @@ unsigned long get_wchan(struct task_struct *p); #define cpu_relax() barrier() +/* + * Create a new kernel thread + */ +extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); + #define task_pt_regs(p) \ ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) diff --git a/trunk/arch/unicore32/include/asm/ptrace.h b/trunk/arch/unicore32/include/asm/ptrace.h index 726749dab52f..b9caf9b0997b 100644 --- a/trunk/arch/unicore32/include/asm/ptrace.h +++ b/trunk/arch/unicore32/include/asm/ptrace.h @@ -12,10 +12,80 @@ #ifndef __UNICORE_PTRACE_H__ #define __UNICORE_PTRACE_H__ -#include +#define PTRACE_GET_THREAD_AREA 22 + +/* + * PSR bits + */ +#define USER_MODE 0x00000010 +#define REAL_MODE 0x00000011 +#define INTR_MODE 0x00000012 +#define PRIV_MODE 0x00000013 +#define ABRT_MODE 0x00000017 +#define EXTN_MODE 0x0000001b +#define SUSR_MODE 0x0000001f +#define MODE_MASK 0x0000001f +#define PSR_R_BIT 0x00000040 +#define PSR_I_BIT 0x00000080 +#define PSR_V_BIT 0x10000000 +#define PSR_C_BIT 0x20000000 +#define PSR_Z_BIT 0x40000000 +#define PSR_S_BIT 0x80000000 + +/* + * Groups of PSR bits + */ +#define PSR_f 0xff000000 /* Flags */ +#define PSR_c 0x000000ff /* Control */ #ifndef __ASSEMBLY__ +/* + * This struct defines the way the registers are stored on the + * stack during a system call. Note that sizeof(struct pt_regs) + * has to be a multiple of 8. + */ +struct pt_regs { + unsigned long uregs[34]; +}; + +#define UCreg_asr uregs[32] +#define UCreg_pc uregs[31] +#define UCreg_lr uregs[30] +#define UCreg_sp uregs[29] +#define UCreg_ip uregs[28] +#define UCreg_fp uregs[27] +#define UCreg_26 uregs[26] +#define UCreg_25 uregs[25] +#define UCreg_24 uregs[24] +#define UCreg_23 uregs[23] +#define UCreg_22 uregs[22] +#define UCreg_21 uregs[21] +#define UCreg_20 uregs[20] +#define UCreg_19 uregs[19] +#define UCreg_18 uregs[18] +#define UCreg_17 uregs[17] +#define UCreg_16 uregs[16] +#define UCreg_15 uregs[15] +#define UCreg_14 uregs[14] +#define UCreg_13 uregs[13] +#define UCreg_12 uregs[12] +#define UCreg_11 uregs[11] +#define UCreg_10 uregs[10] +#define UCreg_09 uregs[9] +#define UCreg_08 uregs[8] +#define UCreg_07 uregs[7] +#define UCreg_06 uregs[6] +#define UCreg_05 uregs[5] +#define UCreg_04 uregs[4] +#define UCreg_03 uregs[3] +#define UCreg_02 uregs[2] +#define UCreg_01 uregs[1] +#define UCreg_00 uregs[0] +#define UCreg_ORIG_00 uregs[33] + +#ifdef __KERNEL__ + #define user_mode(regs) \ (processor_mode(regs) == USER_MODE) @@ -55,5 +125,9 @@ static inline int valid_user_regs(struct pt_regs *regs) #define instruction_pointer(regs) ((regs)->UCreg_pc) +#endif /* __KERNEL__ */ + #endif /* __ASSEMBLY__ */ + #endif + diff --git a/trunk/arch/unicore32/include/uapi/asm/sigcontext.h b/trunk/arch/unicore32/include/asm/sigcontext.h similarity index 100% rename from trunk/arch/unicore32/include/uapi/asm/sigcontext.h rename to trunk/arch/unicore32/include/asm/sigcontext.h diff --git a/trunk/arch/unicore32/include/uapi/asm/unistd.h b/trunk/arch/unicore32/include/asm/unistd.h similarity index 92% rename from trunk/arch/unicore32/include/uapi/asm/unistd.h rename to trunk/arch/unicore32/include/asm/unistd.h index d18a3be89b38..2abcf61c615d 100644 --- a/trunk/arch/unicore32/include/uapi/asm/unistd.h +++ b/trunk/arch/unicore32/include/asm/unistd.h @@ -12,4 +12,3 @@ /* Use the standard ABI for syscalls. */ #include -#define __ARCH_WANT_SYS_EXECVE diff --git a/trunk/arch/unicore32/include/uapi/asm/Kbuild b/trunk/arch/unicore32/include/uapi/asm/Kbuild index 0514d7ad6855..baebb3da1d44 100644 --- a/trunk/arch/unicore32/include/uapi/asm/Kbuild +++ b/trunk/arch/unicore32/include/uapi/asm/Kbuild @@ -1,10 +1,3 @@ # UAPI Header export list include include/uapi/asm-generic/Kbuild.asm -header-y += byteorder.h -header-y += kvm_para.h -header-y += ptrace.h -header-y += sigcontext.h -header-y += unistd.h - -generic-y += kvm_para.h diff --git a/trunk/arch/unicore32/include/uapi/asm/ptrace.h b/trunk/arch/unicore32/include/uapi/asm/ptrace.h deleted file mode 100644 index 187aa2e98a53..000000000000 --- a/trunk/arch/unicore32/include/uapi/asm/ptrace.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * linux/arch/unicore32/include/asm/ptrace.h - * - * Code specific to PKUnity SoC and UniCore ISA - * - * Copyright (C) 2001-2010 GUAN Xue-tao - * - * 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. - */ -#ifndef _UAPI__UNICORE_PTRACE_H__ -#define _UAPI__UNICORE_PTRACE_H__ - -#define PTRACE_GET_THREAD_AREA 22 - -/* - * PSR bits - */ -#define USER_MODE 0x00000010 -#define REAL_MODE 0x00000011 -#define INTR_MODE 0x00000012 -#define PRIV_MODE 0x00000013 -#define ABRT_MODE 0x00000017 -#define EXTN_MODE 0x0000001b -#define SUSR_MODE 0x0000001f -#define MODE_MASK 0x0000001f -#define PSR_R_BIT 0x00000040 -#define PSR_I_BIT 0x00000080 -#define PSR_V_BIT 0x10000000 -#define PSR_C_BIT 0x20000000 -#define PSR_Z_BIT 0x40000000 -#define PSR_S_BIT 0x80000000 - -/* - * Groups of PSR bits - */ -#define PSR_f 0xff000000 /* Flags */ -#define PSR_c 0x000000ff /* Control */ - -#ifndef __ASSEMBLY__ - -/* - * This struct defines the way the registers are stored on the - * stack during a system call. Note that sizeof(struct pt_regs) - * has to be a multiple of 8. - */ -struct pt_regs { - unsigned long uregs[34]; -}; - -#define UCreg_asr uregs[32] -#define UCreg_pc uregs[31] -#define UCreg_lr uregs[30] -#define UCreg_sp uregs[29] -#define UCreg_ip uregs[28] -#define UCreg_fp uregs[27] -#define UCreg_26 uregs[26] -#define UCreg_25 uregs[25] -#define UCreg_24 uregs[24] -#define UCreg_23 uregs[23] -#define UCreg_22 uregs[22] -#define UCreg_21 uregs[21] -#define UCreg_20 uregs[20] -#define UCreg_19 uregs[19] -#define UCreg_18 uregs[18] -#define UCreg_17 uregs[17] -#define UCreg_16 uregs[16] -#define UCreg_15 uregs[15] -#define UCreg_14 uregs[14] -#define UCreg_13 uregs[13] -#define UCreg_12 uregs[12] -#define UCreg_11 uregs[11] -#define UCreg_10 uregs[10] -#define UCreg_09 uregs[9] -#define UCreg_08 uregs[8] -#define UCreg_07 uregs[7] -#define UCreg_06 uregs[6] -#define UCreg_05 uregs[5] -#define UCreg_04 uregs[4] -#define UCreg_03 uregs[3] -#define UCreg_02 uregs[2] -#define UCreg_01 uregs[1] -#define UCreg_00 uregs[0] -#define UCreg_ORIG_00 uregs[33] - - -#endif /* __ASSEMBLY__ */ - -#endif /* _UAPI__UNICORE_PTRACE_H__ */ diff --git a/trunk/arch/unicore32/kernel/entry.S b/trunk/arch/unicore32/kernel/entry.S index 7049350c790f..dcb87ab19ddd 100644 --- a/trunk/arch/unicore32/kernel/entry.S +++ b/trunk/arch/unicore32/kernel/entry.S @@ -573,16 +573,17 @@ ENDPROC(ret_to_user) */ ENTRY(ret_from_fork) b.l schedule_tail + get_thread_info tsk + ldw r1, [tsk+], #TI_FLAGS @ check for syscall tracing + mov why, #1 + cand.a r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? + beq ret_slow_syscall + mov r1, sp + mov r0, #1 @ trace exit [IP = 1] + b.l syscall_trace b ret_slow_syscall ENDPROC(ret_from_fork) -ENTRY(ret_from_kernel_thread) - b.l schedule_tail - mov r0, r5 - adr lr, ret_slow_syscall - mov pc, r4 -ENDPROC(ret_from_kernel_thread) - /*============================================================================= * SWI handler *----------------------------------------------------------------------------- @@ -668,6 +669,11 @@ __cr_alignment: #endif .ltorg +ENTRY(sys_execve) + add r3, sp, #S_OFF + b __sys_execve +ENDPROC(sys_execve) + ENTRY(sys_clone) add ip, sp, #S_OFF stw ip, [sp+], #4 diff --git a/trunk/arch/unicore32/kernel/process.c b/trunk/arch/unicore32/kernel/process.c index a8fe265ce2c0..b008586dad75 100644 --- a/trunk/arch/unicore32/kernel/process.c +++ b/trunk/arch/unicore32/kernel/process.c @@ -258,7 +258,6 @@ void release_thread(struct task_struct *dead_task) } asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); -asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread"); int copy_thread(unsigned long clone_flags, unsigned long stack_start, @@ -267,22 +266,17 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start, struct thread_info *thread = task_thread_info(p); struct pt_regs *childregs = task_pt_regs(p); + *childregs = *regs; + childregs->UCreg_00 = 0; + childregs->UCreg_sp = stack_start; + memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); thread->cpu_context.sp = (unsigned long)childregs; - if (unlikely(!regs)) { - thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread; - thread->cpu_context.r4 = stack_start; - thread->cpu_context.r5 = stk_sz; - memset(childregs, 0, sizeof(struct pt_regs)); - } else { - thread->cpu_context.pc = (unsigned long)ret_from_fork; - *childregs = *regs; - childregs->UCreg_00 = 0; - childregs->UCreg_sp = stack_start; + thread->cpu_context.pc = (unsigned long)ret_from_fork; + + if (clone_flags & CLONE_SETTLS) + childregs->UCreg_16 = regs->UCreg_03; - if (clone_flags & CLONE_SETTLS) - childregs->UCreg_16 = regs->UCreg_03; - } return 0; } @@ -311,6 +305,42 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fp) } EXPORT_SYMBOL(dump_fpu); +/* + * Shuffle the argument into the correct register before calling the + * thread function. r1 is the thread argument, r2 is the pointer to + * the thread function, and r3 points to the exit function. + */ +asm(".pushsection .text\n" +" .align\n" +" .type kernel_thread_helper, #function\n" +"kernel_thread_helper:\n" +" mov.a asr, r7\n" +" mov r0, r4\n" +" mov lr, r6\n" +" mov pc, r5\n" +" .size kernel_thread_helper, . - kernel_thread_helper\n" +" .popsection"); + +/* + * Create a kernel thread. + */ +pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) +{ + struct pt_regs regs; + + memset(®s, 0, sizeof(regs)); + + regs.UCreg_04 = (unsigned long)arg; + regs.UCreg_05 = (unsigned long)fn; + regs.UCreg_06 = (unsigned long)do_exit; + regs.UCreg_07 = PRIV_MODE; + regs.UCreg_pc = (unsigned long)kernel_thread_helper; + regs.UCreg_asr = regs.UCreg_07 | PSR_I_BIT; + + return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); +} +EXPORT_SYMBOL(kernel_thread); + unsigned long get_wchan(struct task_struct *p) { struct stackframe frame; diff --git a/trunk/arch/unicore32/kernel/setup.h b/trunk/arch/unicore32/kernel/setup.h index 30f749da8f73..f23955028a18 100644 --- a/trunk/arch/unicore32/kernel/setup.h +++ b/trunk/arch/unicore32/kernel/setup.h @@ -30,10 +30,4 @@ extern char __vectors_start[], __vectors_end[]; extern void kernel_thread_helper(void); extern void __init early_signal_init(void); - -extern asmlinkage void __backtrace(void); -extern asmlinkage void c_backtrace(unsigned long fp, int pmode); - -extern void __show_regs(struct pt_regs *); - #endif diff --git a/trunk/arch/unicore32/kernel/sys.c b/trunk/arch/unicore32/kernel/sys.c index 9680134b31f0..fabdee96110b 100644 --- a/trunk/arch/unicore32/kernel/sys.c +++ b/trunk/arch/unicore32/kernel/sys.c @@ -42,6 +42,69 @@ asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp, parent_tid, child_tid); } +/* sys_execve() executes a new program. + * This is called indirectly via a small wrapper + */ +asmlinkage long __sys_execve(const char __user *filename, + const char __user *const __user *argv, + const char __user *const __user *envp, + struct pt_regs *regs) +{ + int error; + struct filename *fn; + + fn = getname(filename); + error = PTR_ERR(fn); + if (IS_ERR(fn)) + goto out; + error = do_execve(fn->name, argv, envp, regs); + putname(fn); +out: + return error; +} + +int kernel_execve(const char *filename, + const char *const argv[], + const char *const envp[]) +{ + struct pt_regs regs; + int ret; + + memset(®s, 0, sizeof(struct pt_regs)); + ret = do_execve(filename, + (const char __user *const __user *)argv, + (const char __user *const __user *)envp, ®s); + if (ret < 0) + goto out; + + /* + * Save argc to the register structure for userspace. + */ + regs.UCreg_00 = ret; + + /* + * We were successful. We won't be returning to our caller, but + * instead to user space by manipulating the kernel stack. + */ + asm("add r0, %0, %1\n\t" + "mov r1, %2\n\t" + "mov r2, %3\n\t" + "mov r22, #0\n\t" /* not a syscall */ + "mov r23, %0\n\t" /* thread structure */ + "b.l memmove\n\t" /* copy regs to top of stack */ + "mov sp, r0\n\t" /* reposition stack pointer */ + "b ret_to_user" + : + : "r" (current_thread_info()), + "Ir" (THREAD_START_SP - sizeof(regs)), + "r" (®s), + "Ir" (sizeof(regs)) + : "r0", "r1", "r2", "r3", "ip", "lr", "memory"); + + out: + return ret; +} + /* Note: used by the compat code even in 64-bit Linux. */ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, unsigned long, prot, unsigned long, flags, diff --git a/trunk/arch/unicore32/mm/fault.c b/trunk/arch/unicore32/mm/fault.c index f9b5c10bccee..2eeb9c04cab0 100644 --- a/trunk/arch/unicore32/mm/fault.c +++ b/trunk/arch/unicore32/mm/fault.c @@ -168,7 +168,7 @@ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma) } static int __do_pf(struct mm_struct *mm, unsigned long addr, unsigned int fsr, - unsigned int flags, struct task_struct *tsk) + struct task_struct *tsk) { struct vm_area_struct *vma; int fault; @@ -194,7 +194,14 @@ static int __do_pf(struct mm_struct *mm, unsigned long addr, unsigned int fsr, * If for any reason at all we couldn't handle the fault, make * sure we exit gracefully rather than endlessly redo the fault. */ - fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, flags); + fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, + (!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0); + if (unlikely(fault & VM_FAULT_ERROR)) + return fault; + if (fault & VM_FAULT_MAJOR) + tsk->maj_flt++; + else + tsk->min_flt++; return fault; check_stack: @@ -209,8 +216,6 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) struct task_struct *tsk; struct mm_struct *mm; int fault, sig, code; - unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | - ((!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0); tsk = current; mm = tsk->mm; @@ -231,7 +236,6 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) if (!user_mode(regs) && !search_exception_tables(regs->UCreg_pc)) goto no_context; -retry: down_read(&mm->mmap_sem); } else { /* @@ -247,28 +251,7 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) #endif } - fault = __do_pf(mm, addr, fsr, flags, tsk); - - /* If we need to retry but a fatal signal is pending, handle the - * signal first. We do not need to release the mmap_sem because - * it would already be released in __lock_page_or_retry in - * mm/filemap.c. */ - if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) - return 0; - - if (!(fault & VM_FAULT_ERROR) && (flags & FAULT_FLAG_ALLOW_RETRY)) { - if (fault & VM_FAULT_MAJOR) - tsk->maj_flt++; - else - tsk->min_flt++; - if (fault & VM_FAULT_RETRY) { - /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk - * of starvation. */ - flags &= ~FAULT_FLAG_ALLOW_RETRY; - goto retry; - } - } - + fault = __do_pf(mm, addr, fsr, tsk); up_read(&mm->mmap_sem); /* diff --git a/trunk/arch/x86/boot/compressed/eboot.c b/trunk/arch/x86/boot/compressed/eboot.c index e87b0cac14b5..c760e073963e 100644 --- a/trunk/arch/x86/boot/compressed/eboot.c +++ b/trunk/arch/x86/boot/compressed/eboot.c @@ -12,8 +12,6 @@ #include #include -#undef memcpy /* Use memcpy from misc.c */ - #include "eboot.h" static efi_system_table_t *sys_table; diff --git a/trunk/arch/x86/boot/header.S b/trunk/arch/x86/boot/header.S index 8c132a625b94..2a017441b8b2 100644 --- a/trunk/arch/x86/boot/header.S +++ b/trunk/arch/x86/boot/header.S @@ -476,3 +476,6 @@ die: setup_corrupt: .byte 7 .string "No setup signature found...\n" + + .data +dummy: .long 0 diff --git a/trunk/arch/x86/include/asm/Kbuild b/trunk/arch/x86/include/asm/Kbuild index 79fd8a3418f9..66e5f0ef0523 100644 --- a/trunk/arch/x86/include/asm/Kbuild +++ b/trunk/arch/x86/include/asm/Kbuild @@ -12,7 +12,6 @@ header-y += mce.h header-y += msr-index.h header-y += msr.h header-y += mtrr.h -header-y += perf_regs.h header-y += posix_types_32.h header-y += posix_types_64.h header-y += posix_types_x32.h @@ -20,10 +19,8 @@ header-y += prctl.h header-y += processor-flags.h header-y += ptrace-abi.h header-y += sigcontext32.h -header-y += svm.h header-y += ucontext.h header-y += vm86.h -header-y += vmx.h header-y += vsyscall.h genhdr-y += unistd_32.h diff --git a/trunk/arch/x86/include/asm/efi.h b/trunk/arch/x86/include/asm/efi.h index 6e8fdf5ad113..c9dcc181d4d1 100644 --- a/trunk/arch/x86/include/asm/efi.h +++ b/trunk/arch/x86/include/asm/efi.h @@ -35,7 +35,7 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...); #define efi_call_virt6(f, a1, a2, a3, a4, a5, a6) \ efi_call_virt(f, a1, a2, a3, a4, a5, a6) -#define efi_ioremap(addr, size, type, attr) ioremap_cache(addr, size) +#define efi_ioremap(addr, size, type) ioremap_cache(addr, size) #else /* !CONFIG_X86_32 */ @@ -89,7 +89,7 @@ extern u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3, (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6)) extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size, - u32 type, u64 attribute); + u32 type); #endif /* CONFIG_X86_32 */ @@ -98,8 +98,6 @@ extern void efi_set_executable(efi_memory_desc_t *md, bool executable); extern int efi_memblock_x86_reserve_range(void); extern void efi_call_phys_prelog(void); extern void efi_call_phys_epilog(void); -extern void efi_unmap_memmap(void); -extern void efi_memory_uc(u64 addr, unsigned long size); #ifndef CONFIG_EFI /* diff --git a/trunk/arch/x86/include/asm/fpu-internal.h b/trunk/arch/x86/include/asm/fpu-internal.h index 41ab26ea6564..831dbb9c6c02 100644 --- a/trunk/arch/x86/include/asm/fpu-internal.h +++ b/trunk/arch/x86/include/asm/fpu-internal.h @@ -399,17 +399,14 @@ static inline void drop_init_fpu(struct task_struct *tsk) typedef struct { int preload; } fpu_switch_t; /* - * Must be run with preemption disabled: this clears the fpu_owner_task, - * on this CPU. + * FIXME! We could do a totally lazy restore, but we need to + * add a per-cpu "this was the task that last touched the FPU + * on this CPU" variable, and the task needs to have a "I last + * touched the FPU on this CPU" and check them. * - * This will disable any lazy FPU state restore of the current FPU state, - * but if the current thread owns the FPU, it will still be saved by. + * We don't do that yet, so "fpu_lazy_restore()" always returns + * false, but some day.. */ -static inline void __cpu_disable_lazy_restore(unsigned int cpu) -{ - per_cpu(fpu_owner_task, cpu) = NULL; -} - static inline int fpu_lazy_restore(struct task_struct *new, unsigned int cpu) { return new == this_cpu_read_stable(fpu_owner_task) && diff --git a/trunk/arch/x86/include/asm/ptrace.h b/trunk/arch/x86/include/asm/ptrace.h index 19f16ebaf4fa..dcfde52979c3 100644 --- a/trunk/arch/x86/include/asm/ptrace.h +++ b/trunk/arch/x86/include/asm/ptrace.h @@ -205,14 +205,21 @@ static inline bool user_64bit_mode(struct pt_regs *regs) } #endif -#ifdef CONFIG_X86_32 -extern unsigned long kernel_stack_pointer(struct pt_regs *regs); -#else +/* + * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode + * when it traps. The previous stack will be directly underneath the saved + * registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'. + * + * This is valid only for kernel mode traps. + */ static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) { +#ifdef CONFIG_X86_32 + return (unsigned long)(®s->sp); +#else return regs->sp; -} #endif +} #define GET_IP(regs) ((regs)->ip) #define GET_FP(regs) ((regs)->bp) diff --git a/trunk/arch/x86/include/asm/xen/hypercall.h b/trunk/arch/x86/include/asm/xen/hypercall.h index c20d1ce62dc6..59c226d120cd 100644 --- a/trunk/arch/x86/include/asm/xen/hypercall.h +++ b/trunk/arch/x86/include/asm/xen/hypercall.h @@ -359,14 +359,18 @@ HYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val, return _hypercall4(int, update_va_mapping, va, new_val.pte, new_val.pte >> 32, flags); } -extern int __must_check xen_event_channel_op_compat(int, void *); static inline int HYPERVISOR_event_channel_op(int cmd, void *arg) { int rc = _hypercall2(int, event_channel_op, cmd, arg); - if (unlikely(rc == -ENOSYS)) - rc = xen_event_channel_op_compat(cmd, arg); + if (unlikely(rc == -ENOSYS)) { + struct evtchn_op op; + op.cmd = cmd; + memcpy(&op.u, arg, sizeof(op.u)); + rc = _hypercall1(int, event_channel_op_compat, &op); + memcpy(arg, &op.u, sizeof(op.u)); + } return rc; } @@ -382,14 +386,17 @@ HYPERVISOR_console_io(int cmd, int count, char *str) return _hypercall3(int, console_io, cmd, count, str); } -extern int __must_check HYPERVISOR_physdev_op_compat(int, void *); - static inline int HYPERVISOR_physdev_op(int cmd, void *arg) { int rc = _hypercall2(int, physdev_op, cmd, arg); - if (unlikely(rc == -ENOSYS)) - rc = HYPERVISOR_physdev_op_compat(cmd, arg); + if (unlikely(rc == -ENOSYS)) { + struct physdev_op op; + op.cmd = cmd; + memcpy(&op.u, arg, sizeof(op.u)); + rc = _hypercall1(int, physdev_op_compat, &op); + memcpy(arg, &op.u, sizeof(op.u)); + } return rc; } diff --git a/trunk/arch/x86/include/asm/xen/hypervisor.h b/trunk/arch/x86/include/asm/xen/hypervisor.h index 125f344f06a9..66d0fff1ee84 100644 --- a/trunk/arch/x86/include/asm/xen/hypervisor.h +++ b/trunk/arch/x86/include/asm/xen/hypervisor.h @@ -33,6 +33,7 @@ #ifndef _ASM_X86_XEN_HYPERVISOR_H #define _ASM_X86_XEN_HYPERVISOR_H +/* arch/i386/kernel/setup.c */ extern struct shared_info *HYPERVISOR_shared_info; extern struct start_info *xen_start_info; diff --git a/trunk/arch/x86/include/asm/xen/interface.h b/trunk/arch/x86/include/asm/xen/interface.h index 54d52ff1304a..6d2f75a82a14 100644 --- a/trunk/arch/x86/include/asm/xen/interface.h +++ b/trunk/arch/x86/include/asm/xen/interface.h @@ -51,14 +51,14 @@ * with Xen so that on ARM we can have one ABI that works for 32 and 64 * bit guests. */ typedef unsigned long xen_pfn_t; -#define PRI_xen_pfn "lx" typedef unsigned long xen_ulong_t; -#define PRI_xen_ulong "lx" /* Guest handles for primitive C types. */ __DEFINE_GUEST_HANDLE(uchar, unsigned char); __DEFINE_GUEST_HANDLE(uint, unsigned int); +__DEFINE_GUEST_HANDLE(ulong, unsigned long); DEFINE_GUEST_HANDLE(char); DEFINE_GUEST_HANDLE(int); +DEFINE_GUEST_HANDLE(long); DEFINE_GUEST_HANDLE(void); DEFINE_GUEST_HANDLE(uint64_t); DEFINE_GUEST_HANDLE(uint32_t); diff --git a/trunk/arch/x86/kernel/apic/io_apic.c b/trunk/arch/x86/kernel/apic/io_apic.c index 1817fa911024..c265593ec2cd 100644 --- a/trunk/arch/x86/kernel/apic/io_apic.c +++ b/trunk/arch/x86/kernel/apic/io_apic.c @@ -2257,9 +2257,6 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void) continue; cfg = irq_cfg(irq); - if (!cfg) - continue; - raw_spin_lock(&desc->lock); /* diff --git a/trunk/arch/x86/kernel/cpu/amd.c b/trunk/arch/x86/kernel/cpu/amd.c index 1b7d1656a042..f7e98a2c0d12 100644 --- a/trunk/arch/x86/kernel/cpu/amd.c +++ b/trunk/arch/x86/kernel/cpu/amd.c @@ -631,20 +631,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) } } - /* - * The way access filter has a performance penalty on some workloads. - * Disable it on the affected CPUs. - */ - if ((c->x86 == 0x15) && - (c->x86_model >= 0x02) && (c->x86_model < 0x20)) { - u64 val; - - if (!rdmsrl_safe(0xc0011021, &val) && !(val & 0x1E)) { - val |= 0x1E; - wrmsrl_safe(0xc0011021, val); - } - } - cpu_detect_cache_sizes(c); /* Multi core CPU? */ diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce_amd.c b/trunk/arch/x86/kernel/cpu/mcheck/mce_amd.c index 1ac581f38dfa..698b6ec12e0f 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -6,7 +6,7 @@ * * Written by Jacob Shin - AMD, Inc. * - * Maintained by: Borislav Petkov + * Support: borislav.petkov@amd.com * * April 2006 * - added support for AMD Family 0x10 processors diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce_intel.c b/trunk/arch/x86/kernel/cpu/mcheck/mce_intel.c index 4f9a3cbfc4a3..5f88abf07e9c 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/mce_intel.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/mce_intel.c @@ -285,39 +285,34 @@ void cmci_clear(void) raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); } -static long cmci_rediscover_work_func(void *arg) -{ - int banks; - - /* Recheck banks in case CPUs don't all have the same */ - if (cmci_supported(&banks)) - cmci_discover(banks); - - return 0; -} - /* * After a CPU went down cycle through all the others and rediscover * Must run in process context. */ void cmci_rediscover(int dying) { - int cpu, banks; + int banks; + int cpu; + cpumask_var_t old; if (!cmci_supported(&banks)) return; + if (!alloc_cpumask_var(&old, GFP_KERNEL)) + return; + cpumask_copy(old, ¤t->cpus_allowed); for_each_online_cpu(cpu) { if (cpu == dying) continue; - - if (cpu == smp_processor_id()) { - cmci_rediscover_work_func(NULL); + if (set_cpus_allowed_ptr(current, cpumask_of(cpu))) continue; - } - - work_on_cpu(cpu, cmci_rediscover_work_func, NULL); + /* Recheck banks in case CPUs don't all have the same */ + if (cmci_supported(&banks)) + cmci_discover(banks); } + + set_cpus_allowed_ptr(current, old); + free_cpumask_var(old); } /* diff --git a/trunk/arch/x86/kernel/cpu/perf_event.c b/trunk/arch/x86/kernel/cpu/perf_event.c index 4a3374e61a93..3373f84d1397 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event.c +++ b/trunk/arch/x86/kernel/cpu/perf_event.c @@ -208,14 +208,12 @@ static bool check_hw_exists(void) } /* - * Read the current value, change it and read it back to see if it - * matches, this is needed to detect certain hardware emulators - * (qemu/kvm) that don't trap on the MSR access and always return 0s. + * Now write a value and read it back to see if it matches, + * this is needed to detect certain hardware emulators (qemu/kvm) + * that don't trap on the MSR access and always return 0s. */ + val = 0xabcdUL; reg = x86_pmu_event_addr(0); - if (rdmsrl_safe(reg, &val)) - goto msr_fail; - val ^= 0xffffUL; ret = wrmsrl_safe(reg, val); ret |= rdmsrl_safe(reg, &val_new); if (ret || val != val_new) diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 3cf3d97cce3a..99d96a4978b5 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -118,24 +118,22 @@ static void snbep_uncore_pci_disable_box(struct intel_uncore_box *box) { struct pci_dev *pdev = box->pci_dev; int box_ctl = uncore_pci_box_ctl(box); - u32 config = 0; + u32 config; - if (!pci_read_config_dword(pdev, box_ctl, &config)) { - config |= SNBEP_PMON_BOX_CTL_FRZ; - pci_write_config_dword(pdev, box_ctl, config); - } + pci_read_config_dword(pdev, box_ctl, &config); + config |= SNBEP_PMON_BOX_CTL_FRZ; + pci_write_config_dword(pdev, box_ctl, config); } static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box) { struct pci_dev *pdev = box->pci_dev; int box_ctl = uncore_pci_box_ctl(box); - u32 config = 0; + u32 config; - if (!pci_read_config_dword(pdev, box_ctl, &config)) { - config &= ~SNBEP_PMON_BOX_CTL_FRZ; - pci_write_config_dword(pdev, box_ctl, config); - } + pci_read_config_dword(pdev, box_ctl, &config); + config &= ~SNBEP_PMON_BOX_CTL_FRZ; + pci_write_config_dword(pdev, box_ctl, config); } static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event) @@ -158,7 +156,7 @@ static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, struct pe { struct pci_dev *pdev = box->pci_dev; struct hw_perf_event *hwc = &event->hw; - u64 count = 0; + u64 count; pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count); pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1); @@ -605,12 +603,11 @@ static struct pci_driver snbep_uncore_pci_driver = { /* * build pci bus to socket mapping */ -static int snbep_pci2phy_map_init(void) +static void snbep_pci2phy_map_init(void) { struct pci_dev *ubox_dev = NULL; int i, bus, nodeid; - int err = 0; - u32 config = 0; + u32 config; while (1) { /* find the UBOX device */ @@ -621,14 +618,10 @@ static int snbep_pci2phy_map_init(void) break; bus = ubox_dev->bus->number; /* get the Node ID of the local register */ - err = pci_read_config_dword(ubox_dev, 0x40, &config); - if (err) - break; + pci_read_config_dword(ubox_dev, 0x40, &config); nodeid = config; /* get the Node ID mapping */ - err = pci_read_config_dword(ubox_dev, 0x54, &config); - if (err) - break; + pci_read_config_dword(ubox_dev, 0x54, &config); /* * every three bits in the Node ID mapping register maps * to a particular node. @@ -640,11 +633,7 @@ static int snbep_pci2phy_map_init(void) } } }; - - if (ubox_dev) - pci_dev_put(ubox_dev); - - return err ? pcibios_err_to_errno(err) : 0; + return; } /* end of Sandy Bridge-EP uncore support */ @@ -1558,6 +1547,7 @@ void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event) { struct hw_perf_event *hwc = &event->hw; struct hw_perf_event_extra *reg1 = &hwc->extra_reg; + int port; /* adjust the main event selector and extra register index */ if (reg1->idx % 2) { @@ -1569,6 +1559,7 @@ void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event) } /* adjust extra register config */ + port = reg1->idx / 6 + box->pmu->pmu_idx * 4; switch (reg1->idx % 6) { case 2: /* shift the 8~15 bits to the 0~7 bits */ @@ -2587,11 +2578,9 @@ static int __init uncore_pci_init(void) switch (boot_cpu_data.x86_model) { case 45: /* Sandy Bridge-EP */ - ret = snbep_pci2phy_map_init(); - if (ret) - return ret; pci_uncores = snbep_pci_uncores; uncore_pci_driver = &snbep_uncore_pci_driver; + snbep_pci2phy_map_init(); break; default: return 0; @@ -2937,9 +2926,6 @@ static int __init intel_uncore_init(void) if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) return -ENODEV; - if (cpu_has_hypervisor) - return -ENODEV; - ret = uncore_pci_init(); if (ret) goto fail; diff --git a/trunk/arch/x86/kernel/cpu/perf_event_knc.c b/trunk/arch/x86/kernel/cpu/perf_event_knc.c index 4b7731bf23a8..7c46bfdbc373 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_knc.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_knc.c @@ -3,8 +3,6 @@ #include #include -#include - #include "perf_event.h" static const u64 knc_perfmon_event_map[] = @@ -175,100 +173,30 @@ static void knc_pmu_enable_all(int added) static inline void knc_pmu_disable_event(struct perf_event *event) { + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); struct hw_perf_event *hwc = &event->hw; u64 val; val = hwc->config; - val &= ~ARCH_PERFMON_EVENTSEL_ENABLE; + if (cpuc->enabled) + val &= ~ARCH_PERFMON_EVENTSEL_ENABLE; (void)wrmsrl_safe(hwc->config_base + hwc->idx, val); } static void knc_pmu_enable_event(struct perf_event *event) { + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); struct hw_perf_event *hwc = &event->hw; u64 val; val = hwc->config; - val |= ARCH_PERFMON_EVENTSEL_ENABLE; + if (cpuc->enabled) + val |= ARCH_PERFMON_EVENTSEL_ENABLE; (void)wrmsrl_safe(hwc->config_base + hwc->idx, val); } -static inline u64 knc_pmu_get_status(void) -{ - u64 status; - - rdmsrl(MSR_KNC_IA32_PERF_GLOBAL_STATUS, status); - - return status; -} - -static inline void knc_pmu_ack_status(u64 ack) -{ - wrmsrl(MSR_KNC_IA32_PERF_GLOBAL_OVF_CONTROL, ack); -} - -static int knc_pmu_handle_irq(struct pt_regs *regs) -{ - struct perf_sample_data data; - struct cpu_hw_events *cpuc; - int handled = 0; - int bit, loops; - u64 status; - - cpuc = &__get_cpu_var(cpu_hw_events); - - knc_pmu_disable_all(); - - status = knc_pmu_get_status(); - if (!status) { - knc_pmu_enable_all(0); - return handled; - } - - loops = 0; -again: - knc_pmu_ack_status(status); - if (++loops > 100) { - WARN_ONCE(1, "perf: irq loop stuck!\n"); - perf_event_print_debug(); - goto done; - } - - inc_irq_stat(apic_perf_irqs); - - for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) { - struct perf_event *event = cpuc->events[bit]; - - handled++; - - if (!test_bit(bit, cpuc->active_mask)) - continue; - - if (!intel_pmu_save_and_restart(event)) - continue; - - perf_sample_data_init(&data, 0, event->hw.last_period); - - if (perf_event_overflow(event, &data, regs)) - x86_pmu_stop(event, 0); - } - - /* - * Repeat if there is more work to be done: - */ - status = knc_pmu_get_status(); - if (status) - goto again; - -done: - knc_pmu_enable_all(0); - - return handled; -} - - PMU_FORMAT_ATTR(event, "config:0-7" ); PMU_FORMAT_ATTR(umask, "config:8-15" ); PMU_FORMAT_ATTR(edge, "config:18" ); @@ -286,7 +214,7 @@ static struct attribute *intel_knc_formats_attr[] = { static __initconst struct x86_pmu knc_pmu = { .name = "knc", - .handle_irq = knc_pmu_handle_irq, + .handle_irq = x86_pmu_handle_irq, .disable_all = knc_pmu_disable_all, .enable_all = knc_pmu_enable_all, .enable = knc_pmu_enable_event, @@ -298,11 +226,12 @@ static __initconst struct x86_pmu knc_pmu = { .event_map = knc_pmu_event_map, .max_events = ARRAY_SIZE(knc_perfmon_event_map), .apic = 1, - .max_period = (1ULL << 39) - 1, + .max_period = (1ULL << 31) - 1, .version = 0, .num_counters = 2, - .cntval_bits = 40, - .cntval_mask = (1ULL << 40) - 1, + /* in theory 40 bits, early silicon is buggy though */ + .cntval_bits = 32, + .cntval_mask = (1ULL << 32) - 1, .get_event_constraints = x86_get_event_constraints, .event_constraints = knc_event_constraints, .format_attrs = intel_knc_formats_attr, diff --git a/trunk/arch/x86/kernel/cpu/perf_event_p6.c b/trunk/arch/x86/kernel/cpu/perf_event_p6.c index 7d0270bd793e..e4dd0f7a0453 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_p6.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_p6.c @@ -8,106 +8,13 @@ */ static const u64 p6_perfmon_event_map[] = { - [PERF_COUNT_HW_CPU_CYCLES] = 0x0079, /* CPU_CLK_UNHALTED */ - [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, /* INST_RETIRED */ - [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0f2e, /* L2_RQSTS:M:E:S:I */ - [PERF_COUNT_HW_CACHE_MISSES] = 0x012e, /* L2_RQSTS:I */ - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4, /* BR_INST_RETIRED */ - [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5, /* BR_MISS_PRED_RETIRED */ - [PERF_COUNT_HW_BUS_CYCLES] = 0x0062, /* BUS_DRDY_CLOCKS */ - [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00a2, /* RESOURCE_STALLS */ - -}; - -static __initconst u64 p6_hw_cache_event_ids - [PERF_COUNT_HW_CACHE_MAX] - [PERF_COUNT_HW_CACHE_OP_MAX] - [PERF_COUNT_HW_CACHE_RESULT_MAX] = -{ - [ C(L1D) ] = { - [ C(OP_READ) ] = { - [ C(RESULT_ACCESS) ] = 0x0043, /* DATA_MEM_REFS */ - [ C(RESULT_MISS) ] = 0x0045, /* DCU_LINES_IN */ - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = 0, - [ C(RESULT_MISS) ] = 0x0f29, /* L2_LD:M:E:S:I */ - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = 0, - [ C(RESULT_MISS) ] = 0, - }, - }, - [ C(L1I ) ] = { - [ C(OP_READ) ] = { - [ C(RESULT_ACCESS) ] = 0x0080, /* IFU_IFETCH */ - [ C(RESULT_MISS) ] = 0x0f28, /* L2_IFETCH:M:E:S:I */ - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = -1, - [ C(RESULT_MISS) ] = -1, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = 0, - [ C(RESULT_MISS) ] = 0, - }, - }, - [ C(LL ) ] = { - [ C(OP_READ) ] = { - [ C(RESULT_ACCESS) ] = 0, - [ C(RESULT_MISS) ] = 0, - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = 0, - [ C(RESULT_MISS) ] = 0x0025, /* L2_M_LINES_INM */ - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = 0, - [ C(RESULT_MISS) ] = 0, - }, - }, - [ C(DTLB) ] = { - [ C(OP_READ) ] = { - [ C(RESULT_ACCESS) ] = 0x0043, /* DATA_MEM_REFS */ - [ C(RESULT_MISS) ] = 0, - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = 0, - [ C(RESULT_MISS) ] = 0, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = 0, - [ C(RESULT_MISS) ] = 0, - }, - }, - [ C(ITLB) ] = { - [ C(OP_READ) ] = { - [ C(RESULT_ACCESS) ] = 0x0080, /* IFU_IFETCH */ - [ C(RESULT_MISS) ] = 0x0085, /* ITLB_MISS */ - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = -1, - [ C(RESULT_MISS) ] = -1, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = -1, - [ C(RESULT_MISS) ] = -1, - }, - }, - [ C(BPU ) ] = { - [ C(OP_READ) ] = { - [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED */ - [ C(RESULT_MISS) ] = 0x00c5, /* BR_MISS_PRED_RETIRED */ - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = -1, - [ C(RESULT_MISS) ] = -1, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = -1, - [ C(RESULT_MISS) ] = -1, - }, - }, + [PERF_COUNT_HW_CPU_CYCLES] = 0x0079, + [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, + [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0f2e, + [PERF_COUNT_HW_CACHE_MISSES] = 0x012e, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4, + [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5, + [PERF_COUNT_HW_BUS_CYCLES] = 0x0062, }; static u64 p6_pmu_event_map(int hw_event) @@ -127,7 +34,7 @@ static struct event_constraint p6_event_constraints[] = { INTEL_EVENT_CONSTRAINT(0xc1, 0x1), /* FLOPS */ INTEL_EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */ - INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */ + INTEL_EVENT_CONSTRAINT(0x11, 0x1), /* FP_ASSIST */ INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */ INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */ INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */ @@ -157,25 +64,25 @@ static void p6_pmu_enable_all(int added) static inline void p6_pmu_disable_event(struct perf_event *event) { + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); struct hw_perf_event *hwc = &event->hw; u64 val = P6_NOP_EVENT; + if (cpuc->enabled) + val |= ARCH_PERFMON_EVENTSEL_ENABLE; + (void)wrmsrl_safe(hwc->config_base, val); } static void p6_pmu_enable_event(struct perf_event *event) { + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); struct hw_perf_event *hwc = &event->hw; u64 val; val = hwc->config; - - /* - * p6 only has a global event enable, set on PerfEvtSel0 - * We "disable" events by programming P6_NOP_EVENT - * and we rely on p6_pmu_enable_all() being called - * to actually enable the events. - */ + if (cpuc->enabled) + val |= ARCH_PERFMON_EVENTSEL_ENABLE; (void)wrmsrl_safe(hwc->config_base, val); } @@ -251,9 +158,5 @@ __init int p6_pmu_init(void) x86_pmu = p6_pmu; - memcpy(hw_cache_event_ids, p6_hw_cache_event_ids, - sizeof(hw_cache_event_ids)); - - return 0; } diff --git a/trunk/arch/x86/kernel/e820.c b/trunk/arch/x86/kernel/e820.c index df06ade26bef..ed858e9e9a74 100644 --- a/trunk/arch/x86/kernel/e820.c +++ b/trunk/arch/x86/kernel/e820.c @@ -1077,9 +1077,6 @@ void __init memblock_x86_fill(void) memblock_add(ei->addr, ei->size); } - /* throw away partial pages */ - memblock_trim_memory(PAGE_SIZE); - memblock_dump_all(); } diff --git a/trunk/arch/x86/kernel/entry_32.S b/trunk/arch/x86/kernel/entry_32.S index 88b725aa1d52..a1193aef6d7d 100644 --- a/trunk/arch/x86/kernel/entry_32.S +++ b/trunk/arch/x86/kernel/entry_32.S @@ -1035,7 +1035,7 @@ ENTRY(xen_sysenter_target) ENTRY(xen_hypervisor_callback) CFI_STARTPROC - pushl_cfi $-1 /* orig_ax = -1 => not a system call */ + pushl_cfi $0 SAVE_ALL TRACE_IRQS_OFF @@ -1077,16 +1077,14 @@ ENTRY(xen_failsafe_callback) 2: mov 8(%esp),%es 3: mov 12(%esp),%fs 4: mov 16(%esp),%gs - /* EAX == 0 => Category 1 (Bad segment) - EAX != 0 => Category 2 (Bad IRET) */ testl %eax,%eax popl_cfi %eax lea 16(%esp),%esp CFI_ADJUST_CFA_OFFSET -16 jz 5f addl $16,%esp - jmp iret_exc -5: pushl_cfi $-1 /* orig_ax = -1 => not a system call */ + jmp iret_exc # EAX != 0 => Category 2 (Bad IRET) +5: pushl_cfi $0 # EAX == 0 => Category 1 (Bad segment) SAVE_ALL jmp ret_from_exception CFI_ENDPROC diff --git a/trunk/arch/x86/kernel/entry_64.S b/trunk/arch/x86/kernel/entry_64.S index 1328fe49a3f1..0c58952d64e8 100644 --- a/trunk/arch/x86/kernel/entry_64.S +++ b/trunk/arch/x86/kernel/entry_64.S @@ -995,8 +995,8 @@ END(interrupt) */ .p2align CONFIG_X86_L1_CACHE_SHIFT common_interrupt: - XCPT_FRAME ASM_CLAC + XCPT_FRAME addq $-0x80,(%rsp) /* Adjust vector to [-256,-1] range */ interrupt do_IRQ /* 0(%rsp): old_rsp-ARGOFFSET */ @@ -1135,8 +1135,8 @@ END(common_interrupt) */ .macro apicinterrupt num sym do_sym ENTRY(\sym) - INTR_FRAME ASM_CLAC + INTR_FRAME pushq_cfi $~(\num) .Lcommon_\sym: interrupt \do_sym @@ -1190,8 +1190,8 @@ apicinterrupt IRQ_WORK_VECTOR \ */ .macro zeroentry sym do_sym ENTRY(\sym) - INTR_FRAME ASM_CLAC + INTR_FRAME PARAVIRT_ADJUST_EXCEPTION_FRAME pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ subq $ORIG_RAX-R15, %rsp @@ -1208,8 +1208,8 @@ END(\sym) .macro paranoidzeroentry sym do_sym ENTRY(\sym) - INTR_FRAME ASM_CLAC + INTR_FRAME PARAVIRT_ADJUST_EXCEPTION_FRAME pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ subq $ORIG_RAX-R15, %rsp @@ -1227,8 +1227,8 @@ END(\sym) #define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8) .macro paranoidzeroentry_ist sym do_sym ist ENTRY(\sym) - INTR_FRAME ASM_CLAC + INTR_FRAME PARAVIRT_ADJUST_EXCEPTION_FRAME pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ subq $ORIG_RAX-R15, %rsp @@ -1247,8 +1247,8 @@ END(\sym) .macro errorentry sym do_sym ENTRY(\sym) - XCPT_FRAME ASM_CLAC + XCPT_FRAME PARAVIRT_ADJUST_EXCEPTION_FRAME subq $ORIG_RAX-R15, %rsp CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 @@ -1266,8 +1266,8 @@ END(\sym) /* error code is on the stack already */ .macro paranoiderrorentry sym do_sym ENTRY(\sym) - XCPT_FRAME ASM_CLAC + XCPT_FRAME PARAVIRT_ADJUST_EXCEPTION_FRAME subq $ORIG_RAX-R15, %rsp CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 @@ -1435,7 +1435,7 @@ ENTRY(xen_failsafe_callback) CFI_RESTORE r11 addq $0x30,%rsp CFI_ADJUST_CFA_OFFSET -0x30 - pushq_cfi $-1 /* orig_ax = -1 => not a system call */ + pushq_cfi $0 SAVE_ALL jmp error_exit CFI_ENDPROC diff --git a/trunk/arch/x86/kernel/head_32.S b/trunk/arch/x86/kernel/head_32.S index 4dac2f68ed4a..957a47aec64e 100644 --- a/trunk/arch/x86/kernel/head_32.S +++ b/trunk/arch/x86/kernel/head_32.S @@ -292,8 +292,8 @@ default_entry: * be using the global pages. * * NOTE! If we are on a 486 we may have no cr4 at all! - * Specifically, cr4 exists if and only if CPUID exists - * and has flags other than the FPU flag set. + * Specifically, cr4 exists if and only if CPUID exists, + * which in turn exists if and only if EFLAGS.ID exists. */ movl $X86_EFLAGS_ID,%ecx pushl %ecx @@ -308,11 +308,6 @@ default_entry: testl %ecx,%eax jz 6f # No ID flag = no CPUID = no CR4 - movl $1,%eax - cpuid - andl $~1,%edx # Ignore CPUID.FPU - jz 6f # No flags or only CPUID.FPU = no CR4 - movl pa(mmu_cr4_features),%eax movl %eax,%cr4 diff --git a/trunk/arch/x86/kernel/kvm.c b/trunk/arch/x86/kernel/kvm.c index 4180a874c764..b3e5e51bc907 100644 --- a/trunk/arch/x86/kernel/kvm.c +++ b/trunk/arch/x86/kernel/kvm.c @@ -247,10 +247,7 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code) break; case KVM_PV_REASON_PAGE_NOT_PRESENT: /* page is swapped out by the host. */ - rcu_irq_enter(); - exit_idle(); kvm_async_pf_task_wait((u32)read_cr2()); - rcu_irq_exit(); break; case KVM_PV_REASON_PAGE_READY: rcu_irq_enter(); diff --git a/trunk/arch/x86/kernel/microcode_amd.c b/trunk/arch/x86/kernel/microcode_amd.c index efdec7cd8e01..7720ff5a9ee2 100644 --- a/trunk/arch/x86/kernel/microcode_amd.c +++ b/trunk/arch/x86/kernel/microcode_amd.c @@ -8,8 +8,8 @@ * Tigran Aivazian * * Maintainers: - * Andreas Herrmann - * Borislav Petkov + * Andreas Herrmann + * Borislav Petkov * * This driver allows to upgrade microcode on F10h AMD * CPUs and later. @@ -190,7 +190,6 @@ static unsigned int verify_patch_size(int cpu, u32 patch_size, #define F1XH_MPB_MAX_SIZE 2048 #define F14H_MPB_MAX_SIZE 1824 #define F15H_MPB_MAX_SIZE 4096 -#define F16H_MPB_MAX_SIZE 3458 switch (c->x86) { case 0x14: @@ -199,9 +198,6 @@ static unsigned int verify_patch_size(int cpu, u32 patch_size, case 0x15: max_size = F15H_MPB_MAX_SIZE; break; - case 0x16: - max_size = F16H_MPB_MAX_SIZE; - break; default: max_size = F1XH_MPB_MAX_SIZE; break; diff --git a/trunk/arch/x86/kernel/ptrace.c b/trunk/arch/x86/kernel/ptrace.c index 974b67e46dd0..b00b33a18390 100644 --- a/trunk/arch/x86/kernel/ptrace.c +++ b/trunk/arch/x86/kernel/ptrace.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -167,35 +166,6 @@ static inline bool invalid_selector(u16 value) #define FLAG_MASK FLAG_MASK_32 -/* - * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode - * when it traps. The previous stack will be directly underneath the saved - * registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'. - * - * Now, if the stack is empty, '®s->sp' is out of range. In this - * case we try to take the previous stack. To always return a non-null - * stack pointer we fall back to regs as stack if no previous stack - * exists. - * - * This is valid only for kernel mode traps. - */ -unsigned long kernel_stack_pointer(struct pt_regs *regs) -{ - unsigned long context = (unsigned long)regs & ~(THREAD_SIZE - 1); - unsigned long sp = (unsigned long)®s->sp; - struct thread_info *tinfo; - - if (context == (sp & ~(THREAD_SIZE - 1))) - return sp; - - tinfo = (struct thread_info *)context; - if (tinfo->previous_esp) - return tinfo->previous_esp; - - return (unsigned long)regs; -} -EXPORT_SYMBOL_GPL(kernel_stack_pointer); - static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno) { BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0); @@ -1541,13 +1511,6 @@ void syscall_trace_leave(struct pt_regs *regs) { bool step; - /* - * We may come here right after calling schedule_user() - * or do_notify_resume(), in which case we can be in RCU - * user mode. - */ - rcu_user_exit(); - audit_syscall_exit(regs); if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) diff --git a/trunk/arch/x86/kernel/setup.c b/trunk/arch/x86/kernel/setup.c index ca45696f30fb..468e98dfd44e 100644 --- a/trunk/arch/x86/kernel/setup.c +++ b/trunk/arch/x86/kernel/setup.c @@ -921,19 +921,18 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_X86_64 if (max_pfn > max_low_pfn) { int i; - unsigned long start, end; - unsigned long start_pfn, end_pfn; + for (i = 0; i < e820.nr_map; i++) { + struct e820entry *ei = &e820.map[i]; - for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, - NULL) { + if (ei->addr + ei->size <= 1UL << 32) + continue; - end = PFN_PHYS(end_pfn); - if (end <= (1UL<<32)) + if (ei->type == E820_RESERVED) continue; - start = PFN_PHYS(start_pfn); max_pfn_mapped = init_memory_mapping( - max((1UL<<32), start), end); + ei->addr < 1UL << 32 ? 1UL << 32 : ei->addr, + ei->addr + ei->size); } /* can we preseve max_low_pfn ?*/ @@ -1049,18 +1048,6 @@ void __init setup_arch(char **cmdline_p) arch_init_ideal_nops(); register_refined_jiffies(CLOCK_TICK_RATE); - -#ifdef CONFIG_EFI - /* Once setup is done above, disable efi_enabled on mismatched - * firmware/kernel archtectures since there is no support for - * runtime services. - */ - if (efi_enabled && IS_ENABLED(CONFIG_X86_64) != efi_64bit) { - pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); - efi_unmap_memmap(); - efi_enabled = 0; - } -#endif } #ifdef CONFIG_X86_32 diff --git a/trunk/arch/x86/kernel/signal.c b/trunk/arch/x86/kernel/signal.c index 70b27ee6118e..29ad351804e9 100644 --- a/trunk/arch/x86/kernel/signal.c +++ b/trunk/arch/x86/kernel/signal.c @@ -824,8 +824,10 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) mce_notify_process(); #endif /* CONFIG_X86_64 && CONFIG_X86_MCE */ - if (thread_info_flags & _TIF_UPROBE) + if (thread_info_flags & _TIF_UPROBE) { + clear_thread_flag(TIF_UPROBE); uprobe_notify_resume(regs); + } /* deal with pending signal delivery */ if (thread_info_flags & _TIF_SIGPENDING) diff --git a/trunk/arch/x86/kernel/smpboot.c b/trunk/arch/x86/kernel/smpboot.c index f3e2ec878b8c..c80a33bc528b 100644 --- a/trunk/arch/x86/kernel/smpboot.c +++ b/trunk/arch/x86/kernel/smpboot.c @@ -68,8 +68,6 @@ #include #include #include -#include -#include #include #include #include @@ -820,9 +818,6 @@ int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle) per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; - /* the FPU context is blank, nobody can own it */ - __cpu_disable_lazy_restore(cpu); - err = do_boot_cpu(apicid, cpu, tidle); if (err) { pr_debug("do_boot_cpu failed %d\n", err); diff --git a/trunk/arch/x86/kernel/uprobes.c b/trunk/arch/x86/kernel/uprobes.c index aafa5557b396..9538f00827a9 100644 --- a/trunk/arch/x86/kernel/uprobes.c +++ b/trunk/arch/x86/kernel/uprobes.c @@ -651,19 +651,31 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) /* * Skip these instructions as per the currently known x86 ISA. - * rep=0x66*; nop=0x90 + * 0x66* { 0x90 | 0x0f 0x1f | 0x0f 0x19 | 0x87 0xc0 } */ static bool __skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) { int i; for (i = 0; i < MAX_UINSN_BYTES; i++) { - if (auprobe->insn[i] == 0x66) + if ((auprobe->insn[i] == 0x66)) continue; if (auprobe->insn[i] == 0x90) return true; + if (i == (MAX_UINSN_BYTES - 1)) + break; + + if ((auprobe->insn[i] == 0x0f) && (auprobe->insn[i+1] == 0x1f)) + return true; + + if ((auprobe->insn[i] == 0x0f) && (auprobe->insn[i+1] == 0x19)) + return true; + + if ((auprobe->insn[i] == 0x87) && (auprobe->insn[i+1] == 0xc0)) + return true; + break; } return false; diff --git a/trunk/arch/x86/kvm/cpuid.h b/trunk/arch/x86/kvm/cpuid.h index 58fc51488828..a10e46016851 100644 --- a/trunk/arch/x86/kvm/cpuid.h +++ b/trunk/arch/x86/kvm/cpuid.h @@ -24,9 +24,6 @@ static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu) { struct kvm_cpuid_entry2 *best; - if (!static_cpu_has(X86_FEATURE_XSAVE)) - return 0; - best = kvm_find_cpuid_entry(vcpu, 1, 0); return best && (best->ecx & bit(X86_FEATURE_XSAVE)); } diff --git a/trunk/arch/x86/kvm/emulate.c b/trunk/arch/x86/kvm/emulate.c index bba39bfa1c4b..39171cb307ea 100644 --- a/trunk/arch/x86/kvm/emulate.c +++ b/trunk/arch/x86/kvm/emulate.c @@ -426,7 +426,8 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt) _ASM_EXTABLE(1b, 3b) \ : "=m" ((ctxt)->eflags), "=&r" (_tmp), \ "+a" (*rax), "+d" (*rdx), "+qm"(_ex) \ - : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val)); \ + : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val), \ + "a" (*rax), "d" (*rdx)); \ } while (0) /* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */ diff --git a/trunk/arch/x86/kvm/lapic.c b/trunk/arch/x86/kvm/lapic.c index 43e9fadca5d0..c6e6b721b6ee 100644 --- a/trunk/arch/x86/kvm/lapic.c +++ b/trunk/arch/x86/kvm/lapic.c @@ -1311,7 +1311,7 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) vcpu->arch.apic_base = value; if (apic_x2apic_mode(apic)) { u32 id = kvm_apic_id(apic); - u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf)); + u32 ldr = ((id & ~0xf) << 16) | (1 << (id & 0xf)); kvm_apic_set_ldr(apic, ldr); } apic->base_address = apic->vcpu->arch.apic_base & diff --git a/trunk/arch/x86/kvm/mmu.c b/trunk/arch/x86/kvm/mmu.c index 6f85fe0bf958..d289fee1ffb8 100644 --- a/trunk/arch/x86/kvm/mmu.c +++ b/trunk/arch/x86/kvm/mmu.c @@ -2497,7 +2497,8 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep, } } - kvm_release_pfn_clean(pfn); + if (!is_error_pfn(pfn)) + kvm_release_pfn_clean(pfn); } static void nonpaging_new_cr3(struct kvm_vcpu *vcpu) diff --git a/trunk/arch/x86/kvm/vmx.c b/trunk/arch/x86/kvm/vmx.c index f85815945fc6..ad6b1dd06f8b 100644 --- a/trunk/arch/x86/kvm/vmx.c +++ b/trunk/arch/x86/kvm/vmx.c @@ -6549,22 +6549,19 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) } } + exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); /* Exposing INVPCID only when PCID is exposed */ best = kvm_find_cpuid_entry(vcpu, 0x7, 0); if (vmx_invpcid_supported() && best && (best->ebx & bit(X86_FEATURE_INVPCID)) && guest_cpuid_has_pcid(vcpu)) { - exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); exec_control |= SECONDARY_EXEC_ENABLE_INVPCID; vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control); } else { - if (cpu_has_secondary_exec_ctrls()) { - exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); - exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID; - vmcs_write32(SECONDARY_VM_EXEC_CONTROL, - exec_control); - } + exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID; + vmcs_write32(SECONDARY_VM_EXEC_CONTROL, + exec_control); if (best) best->ebx &= ~bit(X86_FEATURE_INVPCID); } diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index 4f7641756be2..1eefebe5d727 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -3779,7 +3779,7 @@ static int write_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, { struct kvm_mmio_fragment *frag = &vcpu->mmio_fragments[0]; - memcpy(vcpu->run->mmio.data, frag->data, min(8u, frag->len)); + memcpy(vcpu->run->mmio.data, frag->data, frag->len); return X86EMUL_CONTINUE; } @@ -3832,11 +3832,18 @@ static int emulator_read_write_onepage(unsigned long addr, void *val, bytes -= handled; val += handled; - WARN_ON(vcpu->mmio_nr_fragments >= KVM_MAX_MMIO_FRAGMENTS); - frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++]; - frag->gpa = gpa; - frag->data = val; - frag->len = bytes; + while (bytes) { + unsigned now = min(bytes, 8U); + + frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++]; + frag->gpa = gpa; + frag->data = val; + frag->len = now; + + gpa += now; + val += now; + bytes -= now; + } return X86EMUL_CONTINUE; } @@ -3883,7 +3890,7 @@ int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr, vcpu->mmio_needed = 1; vcpu->mmio_cur_fragment = 0; - vcpu->run->mmio.len = min(8u, vcpu->mmio_fragments[0].len); + vcpu->run->mmio.len = vcpu->mmio_fragments[0].len; vcpu->run->mmio.is_write = vcpu->mmio_is_write = ops->write; vcpu->run->exit_reason = KVM_EXIT_MMIO; vcpu->run->mmio.phys_addr = gpa; @@ -5515,44 +5522,28 @@ static int complete_emulated_pio(struct kvm_vcpu *vcpu) * * read: * for each fragment - * for each mmio piece in the fragment - * write gpa, len - * exit - * copy data + * write gpa, len + * exit + * copy data * execute insn * * write: * for each fragment - * for each mmio piece in the fragment - * write gpa, len - * copy data - * exit + * write gpa, len + * copy data + * exit */ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) { struct kvm_run *run = vcpu->run; struct kvm_mmio_fragment *frag; - unsigned len; BUG_ON(!vcpu->mmio_needed); /* Complete previous fragment */ - frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment]; - len = min(8u, frag->len); + frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment++]; if (!vcpu->mmio_is_write) - memcpy(frag->data, run->mmio.data, len); - - if (frag->len <= 8) { - /* Switch to the next fragment. */ - frag++; - vcpu->mmio_cur_fragment++; - } else { - /* Go forward to the next mmio piece. */ - frag->data += len; - frag->gpa += len; - frag->len -= len; - } - + memcpy(frag->data, run->mmio.data, frag->len); if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) { vcpu->mmio_needed = 0; if (vcpu->mmio_is_write) @@ -5560,12 +5551,13 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) vcpu->mmio_read_completed = 1; return complete_emulated_io(vcpu); } - + /* Initiate next fragment */ + ++frag; run->exit_reason = KVM_EXIT_MMIO; run->mmio.phys_addr = frag->gpa; if (vcpu->mmio_is_write) - memcpy(run->mmio.data, frag->data, min(8u, frag->len)); - run->mmio.len = min(8u, frag->len); + memcpy(run->mmio.data, frag->data, frag->len); + run->mmio.len = frag->len; run->mmio.is_write = vcpu->mmio_is_write; vcpu->arch.complete_userspace_io = complete_emulated_mmio; return 0; @@ -5781,9 +5773,6 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, int pending_vec, max_bits, idx; struct desc_ptr dt; - if (!guest_cpuid_has_xsave(vcpu) && (sregs->cr4 & X86_CR4_OSXSAVE)) - return -EINVAL; - dt.size = sregs->idt.limit; dt.address = sregs->idt.base; kvm_x86_ops->set_idt(vcpu, &dt); diff --git a/trunk/arch/x86/mm/init.c b/trunk/arch/x86/mm/init.c index d7aea41563b3..ab1f6a93b527 100644 --- a/trunk/arch/x86/mm/init.c +++ b/trunk/arch/x86/mm/init.c @@ -35,44 +35,40 @@ struct map_range { unsigned page_size_mask; }; -/* - * First calculate space needed for kernel direct mapping page tables to cover - * mr[0].start to mr[nr_range - 1].end, while accounting for possible 2M and 1GB - * pages. Then find enough contiguous space for those page tables. - */ -static void __init find_early_table_space(struct map_range *mr, int nr_range) +static void __init find_early_table_space(struct map_range *mr, unsigned long end, + int use_pse, int use_gbpages) { - int i; - unsigned long puds = 0, pmds = 0, ptes = 0, tables; - unsigned long start = 0, good_end; + unsigned long puds, pmds, ptes, tables, start = 0, good_end = end; phys_addr_t base; - for (i = 0; i < nr_range; i++) { - unsigned long range, extra; + puds = (end + PUD_SIZE - 1) >> PUD_SHIFT; + tables = roundup(puds * sizeof(pud_t), PAGE_SIZE); + + if (use_gbpages) { + unsigned long extra; + + extra = end - ((end>>PUD_SHIFT) << PUD_SHIFT); + pmds = (extra + PMD_SIZE - 1) >> PMD_SHIFT; + } else + pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT; - range = mr[i].end - mr[i].start; - puds += (range + PUD_SIZE - 1) >> PUD_SHIFT; + tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE); - if (mr[i].page_size_mask & (1 << PG_LEVEL_1G)) { - extra = range - ((range >> PUD_SHIFT) << PUD_SHIFT); - pmds += (extra + PMD_SIZE - 1) >> PMD_SHIFT; - } else { - pmds += (range + PMD_SIZE - 1) >> PMD_SHIFT; - } + if (use_pse) { + unsigned long extra; - if (mr[i].page_size_mask & (1 << PG_LEVEL_2M)) { - extra = range - ((range >> PMD_SHIFT) << PMD_SHIFT); + extra = end - ((end>>PMD_SHIFT) << PMD_SHIFT); #ifdef CONFIG_X86_32 - extra += PMD_SIZE; + extra += PMD_SIZE; #endif - ptes += (extra + PAGE_SIZE - 1) >> PAGE_SHIFT; - } else { - ptes += (range + PAGE_SIZE - 1) >> PAGE_SHIFT; - } - } + /* The first 2/4M doesn't use large pages. */ + if (mr->start < PMD_SIZE) + extra += mr->end - mr->start; + + ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT; + } else + ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT; - tables = roundup(puds * sizeof(pud_t), PAGE_SIZE); - tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE); tables += roundup(ptes * sizeof(pte_t), PAGE_SIZE); #ifdef CONFIG_X86_32 @@ -90,7 +86,7 @@ static void __init find_early_table_space(struct map_range *mr, int nr_range) pgt_buf_top = pgt_buf_start + (tables >> PAGE_SHIFT); printk(KERN_DEBUG "kernel direct mapping tables up to %#lx @ [mem %#010lx-%#010lx]\n", - mr[nr_range - 1].end - 1, pgt_buf_start << PAGE_SHIFT, + end - 1, pgt_buf_start << PAGE_SHIFT, (pgt_buf_top << PAGE_SHIFT) - 1); } @@ -271,7 +267,7 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, * nodes are discovered. */ if (!after_bootmem) - find_early_table_space(mr, nr_range); + find_early_table_space(&mr[0], end, use_pse, use_gbpages); for (i = 0; i < nr_range; i++) ret = kernel_physical_mapping_init(mr[i].start, mr[i].end, diff --git a/trunk/arch/x86/mm/init_64.c b/trunk/arch/x86/mm/init_64.c index 3baff255adac..2b6b4a3c8beb 100644 --- a/trunk/arch/x86/mm/init_64.c +++ b/trunk/arch/x86/mm/init_64.c @@ -386,8 +386,7 @@ phys_pte_init(pte_t *pte_page, unsigned long addr, unsigned long end, * these mappings are more intelligent. */ if (pte_val(*pte)) { - if (!after_bootmem) - pages++; + pages++; continue; } @@ -452,8 +451,6 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end, * attributes. */ if (page_size_mask & (1 << PG_LEVEL_2M)) { - if (!after_bootmem) - pages++; last_map_addr = next; continue; } @@ -529,8 +526,6 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end, * attributes. */ if (page_size_mask & (1 << PG_LEVEL_1G)) { - if (!after_bootmem) - pages++; last_map_addr = next; continue; } diff --git a/trunk/arch/x86/mm/tlb.c b/trunk/arch/x86/mm/tlb.c index 60f926cd8b0e..0777f042e400 100644 --- a/trunk/arch/x86/mm/tlb.c +++ b/trunk/arch/x86/mm/tlb.c @@ -197,7 +197,7 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, } if (end == TLB_FLUSH_ALL || tlb_flushall_shift == -1 - || vmflag & VM_HUGETLB) { + || vmflag == VM_HUGETLB) { local_flush_tlb(); goto flush_all; } diff --git a/trunk/arch/x86/oprofile/nmi_int.c b/trunk/arch/x86/oprofile/nmi_int.c index 48768df2471a..26b8a8514ee5 100644 --- a/trunk/arch/x86/oprofile/nmi_int.c +++ b/trunk/arch/x86/oprofile/nmi_int.c @@ -55,7 +55,7 @@ u64 op_x86_get_ctrl(struct op_x86_model_spec const *model, val |= counter_config->extra; event &= model->event_mask ? model->event_mask : 0xFF; val |= event & 0xFF; - val |= (u64)(event & 0x0F00) << 24; + val |= (event & 0x0F00) << 24; return val; } diff --git a/trunk/arch/x86/pci/ce4100.c b/trunk/arch/x86/pci/ce4100.c index b914e20b5a00..41bd2a2d2c50 100644 --- a/trunk/arch/x86/pci/ce4100.c +++ b/trunk/arch/x86/pci/ce4100.c @@ -115,16 +115,6 @@ static void sata_revid_read(struct sim_dev_reg *reg, u32 *value) reg_read(reg, value); } -static void reg_noirq_read(struct sim_dev_reg *reg, u32 *value) -{ - unsigned long flags; - - raw_spin_lock_irqsave(&pci_config_lock, flags); - /* force interrupt pin value to 0 */ - *value = reg->sim_reg.value & 0xfff00ff; - raw_spin_unlock_irqrestore(&pci_config_lock, flags); -} - static struct sim_dev_reg bus1_fixups[] = { DEFINE_REG(2, 0, 0x10, (16*MB), reg_init, reg_read, reg_write) DEFINE_REG(2, 0, 0x14, (256), reg_init, reg_read, reg_write) @@ -154,7 +144,6 @@ static struct sim_dev_reg bus1_fixups[] = { DEFINE_REG(11, 5, 0x10, (64*KB), reg_init, reg_read, reg_write) DEFINE_REG(11, 6, 0x10, (256), reg_init, reg_read, reg_write) DEFINE_REG(11, 7, 0x10, (64*KB), reg_init, reg_read, reg_write) - DEFINE_REG(11, 7, 0x3c, 256, reg_init, reg_noirq_read, reg_write) DEFINE_REG(12, 0, 0x10, (128*KB), reg_init, reg_read, reg_write) DEFINE_REG(12, 0, 0x14, (256), reg_init, reg_read, reg_write) DEFINE_REG(12, 1, 0x10, (1024), reg_init, reg_read, reg_write) @@ -172,10 +161,8 @@ static struct sim_dev_reg bus1_fixups[] = { DEFINE_REG(16, 0, 0x10, (64*KB), reg_init, reg_read, reg_write) DEFINE_REG(16, 0, 0x14, (64*MB), reg_init, reg_read, reg_write) DEFINE_REG(16, 0, 0x18, (64*MB), reg_init, reg_read, reg_write) - DEFINE_REG(16, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write) DEFINE_REG(17, 0, 0x10, (128*KB), reg_init, reg_read, reg_write) DEFINE_REG(18, 0, 0x10, (1*KB), reg_init, reg_read, reg_write) - DEFINE_REG(18, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write) }; static void __init init_sim_regs(void) diff --git a/trunk/arch/x86/platform/ce4100/ce4100.c b/trunk/arch/x86/platform/ce4100/ce4100.c index 92525cb8e54c..4c61b52191eb 100644 --- a/trunk/arch/x86/platform/ce4100/ce4100.c +++ b/trunk/arch/x86/platform/ce4100/ce4100.c @@ -21,25 +21,12 @@ #include #include #include -#include static int ce4100_i8042_detect(void) { return 0; } -/* - * The CE4100 platform has an internal 8051 Microcontroller which is - * responsible for signaling to the external Power Management Unit the - * intention to reset, reboot or power off the system. This 8051 device has - * its command register mapped at I/O port 0xcf9 and the value 0x4 is used - * to power off the system. - */ -static void ce4100_power_off(void) -{ - outb(0x4, 0xcf9); -} - #ifdef CONFIG_SERIAL_8250 static unsigned int mem_serial_in(struct uart_port *p, int offset) @@ -152,19 +139,8 @@ void __init x86_ce4100_early_setup(void) x86_init.mpparse.find_smp_config = x86_init_noop; x86_init.pci.init = ce4100_pci_init; - /* - * By default, the reboot method is ACPI which is supported by the - * CE4100 bootloader CEFDK using FADT.ResetReg Address and ResetValue - * the bootloader will however issue a system power off instead of - * reboot. By using BOOT_KBD we ensure proper system reboot as - * expected. - */ - reboot_type = BOOT_KBD; - #ifdef CONFIG_X86_IO_APIC x86_init.pci.init_irq = sdv_pci_init; x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck; #endif - - pm_power_off = ce4100_power_off; } diff --git a/trunk/arch/x86/platform/efi/efi.c b/trunk/arch/x86/platform/efi/efi.c index ad4439145f85..aded2a91162a 100644 --- a/trunk/arch/x86/platform/efi/efi.c +++ b/trunk/arch/x86/platform/efi/efi.c @@ -70,15 +70,11 @@ EXPORT_SYMBOL(efi); struct efi_memory_map memmap; bool efi_64bit; +static bool efi_native; static struct efi efi_phys __initdata; static efi_system_table_t efi_systab __initdata; -static inline bool efi_is_native(void) -{ - return IS_ENABLED(CONFIG_X86_64) == efi_64bit; -} - static int __init setup_noefi(char *arg) { efi_enabled = 0; @@ -424,7 +420,7 @@ void __init efi_reserve_boot_services(void) } } -void __init efi_unmap_memmap(void) +static void __init efi_unmap_memmap(void) { if (memmap.map) { early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); @@ -436,7 +432,7 @@ void __init efi_free_boot_services(void) { void *p; - if (!efi_is_native()) + if (!efi_native) return; for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { @@ -688,10 +684,12 @@ void __init efi_init(void) return; } efi_phys.systab = (efi_system_table_t *)boot_params.efi_info.efi_systab; + efi_native = !efi_64bit; #else efi_phys.systab = (efi_system_table_t *) (boot_params.efi_info.efi_systab | ((__u64)boot_params.efi_info.efi_systab_hi<<32)); + efi_native = efi_64bit; #endif if (efi_systab_init(efi_phys.systab)) { @@ -725,7 +723,7 @@ void __init efi_init(void) * that doesn't match the kernel 32/64-bit mode. */ - if (!efi_is_native()) + if (!efi_native) pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n"); else if (efi_runtime_init()) { efi_enabled = 0; @@ -737,7 +735,7 @@ void __init efi_init(void) return; } #ifdef CONFIG_X86_32 - if (efi_is_native()) { + if (efi_native) { x86_platform.get_wallclock = efi_get_time; x86_platform.set_wallclock = efi_set_rtc_mmss; } @@ -812,16 +810,6 @@ void __iomem *efi_lookup_mapped_addr(u64 phys_addr) return NULL; } -void efi_memory_uc(u64 addr, unsigned long size) -{ - unsigned long page_shift = 1UL << EFI_PAGE_SHIFT; - u64 npages; - - npages = round_up(size, page_shift) / page_shift; - memrange_efi_to_native(&addr, &npages); - set_memory_uc(addr, npages); -} - /* * This function will switch the EFI runtime services to virtual mode. * Essentially, look through the EFI memmap and map every region that @@ -835,7 +823,7 @@ void __init efi_enter_virtual_mode(void) efi_memory_desc_t *md, *prev_md = NULL; efi_status_t status; unsigned long size; - u64 end, systab, end_pfn; + u64 end, systab, addr, npages, end_pfn; void *p, *va, *new_memmap = NULL; int count = 0; @@ -846,7 +834,7 @@ void __init efi_enter_virtual_mode(void) * non-native EFI */ - if (!efi_is_native()) { + if (!efi_native) { efi_unmap_memmap(); return; } @@ -891,14 +879,10 @@ void __init efi_enter_virtual_mode(void) end_pfn = PFN_UP(end); if (end_pfn <= max_low_pfn_mapped || (end_pfn > (1UL << (32 - PAGE_SHIFT)) - && end_pfn <= max_pfn_mapped)) { + && end_pfn <= max_pfn_mapped)) va = __va(md->phys_addr); - - if (!(md->attribute & EFI_MEMORY_WB)) - efi_memory_uc((u64)(unsigned long)va, size); - } else - va = efi_ioremap(md->phys_addr, size, - md->type, md->attribute); + else + va = efi_ioremap(md->phys_addr, size, md->type); md->virt_addr = (u64) (unsigned long) va; @@ -908,6 +892,13 @@ void __init efi_enter_virtual_mode(void) continue; } + if (!(md->attribute & EFI_MEMORY_WB)) { + addr = md->virt_addr; + npages = md->num_pages; + memrange_efi_to_native(&addr, &npages); + set_memory_uc(addr, npages); + } + systab = (u64) (unsigned long) efi_phys.systab; if (md->phys_addr <= systab && systab < end) { systab += md->virt_addr - md->phys_addr; diff --git a/trunk/arch/x86/platform/efi/efi_64.c b/trunk/arch/x86/platform/efi/efi_64.c index 95fd505dfeb6..ac3aa54e2654 100644 --- a/trunk/arch/x86/platform/efi/efi_64.c +++ b/trunk/arch/x86/platform/efi/efi_64.c @@ -82,7 +82,7 @@ void __init efi_call_phys_epilog(void) } void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size, - u32 type, u64 attribute) + u32 type) { unsigned long last_map_pfn; @@ -92,11 +92,8 @@ void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size, last_map_pfn = init_memory_mapping(phys_addr, phys_addr + size); if ((last_map_pfn << PAGE_SHIFT) < phys_addr + size) { unsigned long top = last_map_pfn << PAGE_SHIFT; - efi_ioremap(top, size - (top - phys_addr), type, attribute); + efi_ioremap(top, size - (top - phys_addr), type); } - if (!(attribute & EFI_MEMORY_WB)) - efi_memory_uc((u64)(unsigned long)__va(phys_addr), size); - return (void __iomem *)__va(phys_addr); } diff --git a/trunk/arch/x86/xen/enlighten.c b/trunk/arch/x86/xen/enlighten.c index 586d83812b67..e3497f240eab 100644 --- a/trunk/arch/x86/xen/enlighten.c +++ b/trunk/arch/x86/xen/enlighten.c @@ -81,6 +81,8 @@ #include "smp.h" #include "multicalls.h" +#include + EXPORT_SYMBOL_GPL(hypercall_page); DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu); diff --git a/trunk/arch/x86/xen/mmu.c b/trunk/arch/x86/xen/mmu.c index dcf5f2dd91ec..6226c99729b9 100644 --- a/trunk/arch/x86/xen/mmu.c +++ b/trunk/arch/x86/xen/mmu.c @@ -1288,25 +1288,6 @@ unsigned long xen_read_cr2_direct(void) return this_cpu_read(xen_vcpu_info.arch.cr2); } -void xen_flush_tlb_all(void) -{ - struct mmuext_op *op; - struct multicall_space mcs; - - trace_xen_mmu_flush_tlb_all(0); - - preempt_disable(); - - mcs = xen_mc_entry(sizeof(*op)); - - op = mcs.args; - op->cmd = MMUEXT_TLB_FLUSH_ALL; - MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); - - xen_mc_issue(PARAVIRT_LAZY_MMU); - - preempt_enable(); -} static void xen_flush_tlb(void) { struct mmuext_op *op; @@ -2537,7 +2518,7 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma, err = 0; out: - xen_flush_tlb_all(); + flush_tlb_all(); return err; } diff --git a/trunk/arch/xtensa/Kconfig b/trunk/arch/xtensa/Kconfig index 0d1f36a22c98..cdcb48adee4c 100644 --- a/trunk/arch/xtensa/Kconfig +++ b/trunk/arch/xtensa/Kconfig @@ -13,8 +13,6 @@ config XTENSA select GENERIC_CPU_DEVICES select MODULES_USE_ELF_RELA select GENERIC_PCI_IOMAP - select GENERIC_KERNEL_THREAD - select GENERIC_KERNEL_EXECVE select ARCH_WANT_OPTIONAL_GPIOLIB help Xtensa processors are 32-bit RISC machines designed by Tensilica diff --git a/trunk/arch/xtensa/include/asm/io.h b/trunk/arch/xtensa/include/asm/io.h index 700c2e6f2d25..e6be5b9091c2 100644 --- a/trunk/arch/xtensa/include/asm/io.h +++ b/trunk/arch/xtensa/include/asm/io.h @@ -62,10 +62,6 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size) static inline void iounmap(volatile void __iomem *addr) { } - -#define virt_to_bus virt_to_phys -#define bus_to_virt phys_to_virt - #endif /* CONFIG_MMU */ /* diff --git a/trunk/arch/xtensa/include/asm/processor.h b/trunk/arch/xtensa/include/asm/processor.h index 2d630e7399ca..5c371d8d4528 100644 --- a/trunk/arch/xtensa/include/asm/processor.h +++ b/trunk/arch/xtensa/include/asm/processor.h @@ -152,7 +152,6 @@ struct thread_struct { /* Clearing a0 terminates the backtrace. */ #define start_thread(regs, new_pc, new_sp) \ - memset(regs, 0, sizeof(*regs)); \ regs->pc = new_pc; \ regs->ps = USER_PS_VALUE; \ regs->areg[1] = new_sp; \ @@ -169,6 +168,9 @@ struct mm_struct; /* Free all resources held by a thread. */ #define release_thread(thread) do { } while(0) +/* Create a kernel thread without removing it from tasklists */ +extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); + /* Copy and release all segment info associated with a VM */ #define copy_segments(p, mm) do { } while(0) #define release_segments(mm) do { } while(0) diff --git a/trunk/arch/xtensa/include/asm/syscall.h b/trunk/arch/xtensa/include/asm/syscall.h index 124aeee0d381..c1dacca312f3 100644 --- a/trunk/arch/xtensa/include/asm/syscall.h +++ b/trunk/arch/xtensa/include/asm/syscall.h @@ -10,7 +10,7 @@ struct pt_regs; struct sigaction; -asmlinkage long sys_execve(char*, char**, char**, struct pt_regs*); +asmlinkage long xtensa_execve(char*, char**, char**, struct pt_regs*); asmlinkage long xtensa_clone(unsigned long, unsigned long, struct pt_regs*); asmlinkage long xtensa_ptrace(long, long, long, long); asmlinkage long xtensa_sigreturn(struct pt_regs*); diff --git a/trunk/arch/xtensa/include/asm/unistd.h b/trunk/arch/xtensa/include/asm/unistd.h index f4e6eaa40d1c..9ef1c31d2c83 100644 --- a/trunk/arch/xtensa/include/asm/unistd.h +++ b/trunk/arch/xtensa/include/asm/unistd.h @@ -1,9 +1,16 @@ -#ifndef _XTENSA_UNISTD_H -#define _XTENSA_UNISTD_H +/* + * include/asm-xtensa/unistd.h + * + * 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 + * for more details. + * + * Copyright (C) 2001 - 2005 Tensilica Inc. + */ -#define __ARCH_WANT_SYS_EXECVE #include + /* * "Conditional" syscalls * @@ -30,5 +37,3 @@ #define __IGNORE_mmap /* use mmap2 */ #define __IGNORE_vfork /* use clone */ #define __IGNORE_fadvise64 /* use fadvise64_64 */ - -#endif /* _XTENSA_UNISTD_H */ diff --git a/trunk/arch/xtensa/include/uapi/asm/unistd.h b/trunk/arch/xtensa/include/uapi/asm/unistd.h index 9f36d0e3e0ac..479abaea5aae 100644 --- a/trunk/arch/xtensa/include/uapi/asm/unistd.h +++ b/trunk/arch/xtensa/include/uapi/asm/unistd.h @@ -1,4 +1,14 @@ -#if !defined(_UAPI_XTENSA_UNISTD_H) || defined(__SYSCALL) +/* + * include/asm-xtensa/unistd.h + * + * 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 + * for more details. + * + * Copyright (C) 2001 - 2012 Tensilica Inc. + */ + +#ifndef _UAPI_XTENSA_UNISTD_H #define _UAPI_XTENSA_UNISTD_H #ifndef __SYSCALL @@ -262,7 +272,7 @@ __SYSCALL(115, sys_sendmmsg, 4) #define __NR_clone 116 __SYSCALL(116, xtensa_clone, 5) #define __NR_execve 117 -__SYSCALL(117, sys_execve, 3) +__SYSCALL(117, xtensa_execve, 3) #define __NR_exit 118 __SYSCALL(118, sys_exit, 1) #define __NR_exit_group 119 @@ -749,6 +759,4 @@ __SYSCALL(331, sys_kcmp, 5) #define SYS_XTENSA_COUNT 5 /* count */ -#undef __SYSCALL - #endif /* _UAPI_XTENSA_UNISTD_H */ diff --git a/trunk/arch/xtensa/kernel/entry.S b/trunk/arch/xtensa/kernel/entry.S index 90bfc1dbc13d..18453067c258 100644 --- a/trunk/arch/xtensa/kernel/entry.S +++ b/trunk/arch/xtensa/kernel/entry.S @@ -1832,6 +1832,50 @@ ENTRY(system_call) retw +/* + * Create a kernel thread + * + * int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) + * a2 a2 a3 a4 + */ + +ENTRY(kernel_thread) + entry a1, 16 + + mov a5, a2 # preserve fn over syscall + mov a7, a3 # preserve args over syscall + + movi a3, _CLONE_VM | _CLONE_UNTRACED + movi a2, __NR_clone + or a6, a4, a3 # arg0: flags + mov a3, a1 # arg1: sp + syscall + + beq a3, a1, 1f # branch if parent + mov a6, a7 # args + callx4 a5 # fn(args) + + movi a2, __NR_exit + syscall # return value of fn(args) still in a6 + +1: retw + +/* + * Do a system call from kernel instead of calling sys_execve, so we end up + * with proper pt_regs. + * + * int kernel_execve(const char *fname, char *const argv[], charg *const envp[]) + * a2 a2 a3 a4 + */ + +ENTRY(kernel_execve) + entry a1, 16 + mov a6, a2 # arg0 is in a6 + movi a2, __NR_execve + syscall + + retw + /* * Task switch. * @@ -1914,16 +1958,3 @@ ENTRY(ret_from_fork) j common_exception_return -/* - * Kernel thread creation helper - * On entry, set up by copy_thread: a2 = thread_fn, a3 = thread_fn arg - * left from _switch_to: a6 = prev - */ -ENTRY(ret_from_kernel_thread) - - call4 schedule_tail - mov a6, a3 - callx4 a2 - j common_exception_return - -ENDPROC(ret_from_kernel_thread) diff --git a/trunk/arch/xtensa/kernel/process.c b/trunk/arch/xtensa/kernel/process.c index 09ae7bfab9a7..1908f6642d31 100644 --- a/trunk/arch/xtensa/kernel/process.c +++ b/trunk/arch/xtensa/kernel/process.c @@ -45,7 +45,6 @@ #include extern void ret_from_fork(void); -extern void ret_from_kernel_thread(void); struct task_struct *current_set[NR_CPUS] = {&init_task, }; @@ -159,30 +158,18 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) /* * Copy thread. * - * There are two modes in which this function is called: - * 1) Userspace thread creation, - * regs != NULL, usp_thread_fn is userspace stack pointer. - * It is expected to copy parent regs (in case CLONE_VM is not set - * in the clone_flags) and set up passed usp in the childregs. - * 2) Kernel thread creation, - * regs == NULL, usp_thread_fn is the function to run in the new thread - * and thread_fn_arg is its parameter. - * childregs are not used for the kernel threads. - * * The stack layout for the new thread looks like this: * - * +------------------------+ + * +------------------------+ <- sp in childregs (= tos) * | childregs | * +------------------------+ <- thread.sp = sp in dummy-frame * | dummy-frame | (saved in dummy-frame spill-area) * +------------------------+ * - * We create a dummy frame to return to either ret_from_fork or - * ret_from_kernel_thread: - * a0 points to ret_from_fork/ret_from_kernel_thread (simulating a call4) + * We create a dummy frame to return to ret_from_fork: + * a0 points to ret_from_fork (simulating a call4) * sp points to itself (thread.sp) - * a2, a3 are unused for userspace threads, - * a2 points to thread_fn, a3 holds thread_fn arg for kernel threads. + * a2, a3 are unused. * * Note: This is a pristine frame, so we don't need any spill region on top of * childregs. @@ -198,63 +185,43 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) * involved. Much simpler to just not copy those live frames across. */ -int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn, - unsigned long thread_fn_arg, - struct task_struct *p, struct pt_regs *unused) +int copy_thread(unsigned long clone_flags, unsigned long usp, + unsigned long unused, + struct task_struct * p, struct pt_regs * regs) { - struct pt_regs *childregs = task_pt_regs(p); + struct pt_regs *childregs; + unsigned long tos; + int user_mode = user_mode(regs); #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) struct thread_info *ti; #endif + /* Set up new TSS. */ + tos = (unsigned long)task_stack_page(p) + THREAD_SIZE; + if (user_mode) + childregs = (struct pt_regs*)(tos - PT_USER_SIZE); + else + childregs = (struct pt_regs*)tos - 1; + + /* This does not copy all the regs. In a bout of brilliance or madness, + ARs beyond a0-a15 exist past the end of the struct. */ + *childregs = *regs; + /* Create a call4 dummy-frame: a0 = 0, a1 = childregs. */ *((int*)childregs - 3) = (unsigned long)childregs; *((int*)childregs - 4) = 0; + childregs->areg[2] = 0; + p->set_child_tid = p->clear_child_tid = NULL; + p->thread.ra = MAKE_RA_FOR_CALL((unsigned long)ret_from_fork, 0x1); p->thread.sp = (unsigned long)childregs; - if (!(p->flags & PF_KTHREAD)) { - struct pt_regs *regs = current_pt_regs(); - unsigned long usp = usp_thread_fn ? - usp_thread_fn : regs->areg[1]; + if (user_mode(regs)) { - p->thread.ra = MAKE_RA_FOR_CALL( - (unsigned long)ret_from_fork, 0x1); - - /* This does not copy all the regs. - * In a bout of brilliance or madness, - * ARs beyond a0-a15 exist past the end of the struct. - */ - *childregs = *regs; childregs->areg[1] = usp; - childregs->areg[2] = 0; - - /* When sharing memory with the parent thread, the child - usually starts on a pristine stack, so we have to reset - windowbase, windowstart and wmask. - (Note that such a new thread is required to always create - an initial call4 frame) - The exception is vfork, where the new thread continues to - run on the parent's stack until it calls execve. This could - be a call8 or call12, which requires a legal stack frame - of the previous caller for the overflow handlers to work. - (Note that it's always legal to overflow live registers). - In this case, ensure to spill at least the stack pointer - of that frame. */ - if (clone_flags & CLONE_VM) { - /* check that caller window is live and same stack */ - int len = childregs->wmask & ~0xf; - if (regs->areg[1] == usp && len != 0) { - int callinc = (regs->areg[0] >> 30) & 3; - int caller_ars = XCHAL_NUM_AREGS - callinc * 4; - put_user(regs->areg[caller_ars+1], - (unsigned __user*)(usp - 12)); - } - childregs->wmask = 1; - childregs->windowstart = 1; - childregs->windowbase = 0; + childregs->wmask = 1; /* can't share live windows */ } else { int len = childregs->wmask & ~0xf; memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4], @@ -263,19 +230,11 @@ int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn, // FIXME: we need to set THREADPTR in thread_info... if (clone_flags & CLONE_SETTLS) childregs->areg[2] = childregs->areg[6]; + } else { - p->thread.ra = MAKE_RA_FOR_CALL( - (unsigned long)ret_from_kernel_thread, 1); - - /* pass parameters to ret_from_kernel_thread: - * a2 = thread_fn, a3 = thread_fn arg - */ - *((int *)childregs - 1) = thread_fn_arg; - *((int *)childregs - 2) = usp_thread_fn; - - /* Childregs are only used when we're going to userspace - * in which case start_thread will set them up. - */ + /* In kernel space, we start a new thread with a new stack. */ + childregs->wmask = 1; + childregs->areg[1] = tos; } #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) @@ -371,5 +330,32 @@ long xtensa_clone(unsigned long clone_flags, unsigned long newsp, void __user *child_tid, long a5, struct pt_regs *regs) { + if (!newsp) + newsp = regs->areg[1]; return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); } + +/* + * xtensa_execve() executes a new program. + */ + +asmlinkage +long xtensa_execve(const char __user *name, + const char __user *const __user *argv, + const char __user *const __user *envp, + long a3, long a4, long a5, + struct pt_regs *regs) +{ + long error; + struct filename *filename; + + filename = getname(name); + error = PTR_ERR(filename); + if (IS_ERR(filename)) + goto out; + error = do_execve(filename->name, argv, envp, regs); + putname(filename); +out: + return error; +} + diff --git a/trunk/arch/xtensa/kernel/syscall.c b/trunk/arch/xtensa/kernel/syscall.c index 5702065f472a..a5c01e74d5d5 100644 --- a/trunk/arch/xtensa/kernel/syscall.c +++ b/trunk/arch/xtensa/kernel/syscall.c @@ -32,8 +32,10 @@ typedef void (*syscall_t)(void); syscall_t sys_call_table[__NR_syscall_count] /* FIXME __cacheline_aligned */= { [0 ... __NR_syscall_count - 1] = (syscall_t)&sys_ni_syscall, +#undef __SYSCALL #define __SYSCALL(nr,symbol,nargs) [ nr ] = (syscall_t)symbol, -#include +#undef __KERNEL_SYSCALLS__ +#include }; asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) @@ -47,8 +49,7 @@ asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) return (long)ret; } -asmlinkage long xtensa_fadvise64_64(int fd, int advice, - unsigned long long offset, unsigned long long len) +asmlinkage long xtensa_fadvise64_64(int fd, int advice, unsigned long long offset, unsigned long long len) { return sys_fadvise64_64(fd, offset, len, advice); } diff --git a/trunk/arch/xtensa/kernel/xtensa_ksyms.c b/trunk/arch/xtensa/kernel/xtensa_ksyms.c index afe058b24e6e..a8b9f1fd1e17 100644 --- a/trunk/arch/xtensa/kernel/xtensa_ksyms.c +++ b/trunk/arch/xtensa/kernel/xtensa_ksyms.c @@ -43,6 +43,7 @@ EXPORT_SYMBOL(__strncpy_user); EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(copy_page); +EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(empty_zero_page); /* diff --git a/trunk/block/Kconfig b/trunk/block/Kconfig index a7e40a7c8214..09acf1b39905 100644 --- a/trunk/block/Kconfig +++ b/trunk/block/Kconfig @@ -89,7 +89,7 @@ config BLK_DEV_INTEGRITY config BLK_DEV_THROTTLING bool "Block layer bio throttling support" - depends on BLK_CGROUP=y + depends on BLK_CGROUP=y && EXPERIMENTAL default n ---help--- Block layer bio throttling support. It can be used to limit diff --git a/trunk/block/blk-cgroup.c b/trunk/block/blk-cgroup.c index d0b770391ad4..cafcd7431189 100644 --- a/trunk/block/blk-cgroup.c +++ b/trunk/block/blk-cgroup.c @@ -285,13 +285,6 @@ static void blkg_destroy_all(struct request_queue *q) blkg_destroy(blkg); spin_unlock(&blkcg->lock); } - - /* - * root blkg is destroyed. Just clear the pointer since - * root_rl does not take reference on root blkg. - */ - q->root_blkg = NULL; - q->root_rl.blkg = NULL; } static void blkg_rcu_free(struct rcu_head *rcu_head) @@ -333,9 +326,6 @@ struct request_list *__blk_queue_next_rl(struct request_list *rl, */ if (rl == &q->root_rl) { ent = &q->blkg_list; - /* There are no more block groups, hence no request lists */ - if (list_empty(ent)) - return NULL; } else { blkg = container_of(rl, struct blkcg_gq, rl); ent = &blkg->q_node; diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index 3c95c4d6e31a..a33870b1847b 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -2868,8 +2868,7 @@ static int plug_rq_cmp(void *priv, struct list_head *a, struct list_head *b) struct request *rqa = container_of(a, struct request, queuelist); struct request *rqb = container_of(b, struct request, queuelist); - return !(rqa->q < rqb->q || - (rqa->q == rqb->q && blk_rq_pos(rqa) < blk_rq_pos(rqb))); + return !(rqa->q <= rqb->q); } /* diff --git a/trunk/block/blk-exec.c b/trunk/block/blk-exec.c index f71eac35c1b9..8b6dc5bd4dd0 100644 --- a/trunk/block/blk-exec.c +++ b/trunk/block/blk-exec.c @@ -52,17 +52,11 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, rq_end_io_fn *done) { int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK; - bool is_pm_resume; WARN_ON(irqs_disabled()); rq->rq_disk = bd_disk; rq->end_io = done; - /* - * need to check this before __blk_run_queue(), because rq can - * be freed before that returns. - */ - is_pm_resume = rq->cmd_type == REQ_TYPE_PM_RESUME; spin_lock_irq(q->queue_lock); @@ -77,7 +71,7 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, __elv_add_request(q, rq, where); __blk_run_queue(q); /* the queue is stopped so it won't be run */ - if (is_pm_resume) + if (rq->cmd_type == REQ_TYPE_PM_RESUME) q->request_fn(q); spin_unlock_irq(q->queue_lock); } diff --git a/trunk/crypto/cryptd.c b/trunk/crypto/cryptd.c index 7bdd61b867c8..671d4d6d14df 100644 --- a/trunk/crypto/cryptd.c +++ b/trunk/crypto/cryptd.c @@ -137,18 +137,13 @@ static void cryptd_queue_worker(struct work_struct *work) struct crypto_async_request *req, *backlog; cpu_queue = container_of(work, struct cryptd_cpu_queue, work); - /* - * Only handle one request at a time to avoid hogging crypto workqueue. - * preempt_disable/enable is used to prevent being preempted by - * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent - * cryptd_enqueue_request() being accessed from software interrupts. - */ - local_bh_disable(); + /* Only handle one request at a time to avoid hogging crypto + * workqueue. preempt_disable/enable is used to prevent + * being preempted by cryptd_enqueue_request() */ preempt_disable(); backlog = crypto_get_backlog(&cpu_queue->queue); req = crypto_dequeue_request(&cpu_queue->queue); preempt_enable(); - local_bh_enable(); if (!req) return; diff --git a/trunk/drivers/acpi/glue.c b/trunk/drivers/acpi/glue.c index 08373086cd7e..d1a2d74033e9 100644 --- a/trunk/drivers/acpi/glue.c +++ b/trunk/drivers/acpi/glue.c @@ -159,7 +159,6 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) if (physical_node->node_id >= ACPI_MAX_PHYSICAL_NODE) { retval = -ENOSPC; mutex_unlock(&acpi_dev->physical_node_lock); - kfree(physical_node); goto err; } diff --git a/trunk/drivers/acpi/processor_driver.c b/trunk/drivers/acpi/processor_driver.c index bd4e5dca3ff7..e78c2a52ea46 100644 --- a/trunk/drivers/acpi/processor_driver.c +++ b/trunk/drivers/acpi/processor_driver.c @@ -409,7 +409,6 @@ static void acpi_processor_notify(struct acpi_device *device, u32 event) acpi_bus_generate_proc_event(device, event, 0); acpi_bus_generate_netlink_event(device->pnp.device_class, dev_name(&device->dev), event, 0); - break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported event [0x%x]\n", event)); diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index 0230cb6cbb3a..f94d4c818fc7 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -1345,15 +1345,12 @@ static int acpi_video_bus_get_devices(struct acpi_video_bus *video, struct acpi_device *device) { - int status = 0; + int status; struct acpi_device *dev; - /* - * There are systems where video module known to work fine regardless - * of broken _DOD and ignoring returned value here doesn't cause - * any issues later. - */ - acpi_video_device_enumerate(video); + status = acpi_video_device_enumerate(video); + if (status) + return status; list_for_each_entry(dev, &device->children, node) { diff --git a/trunk/drivers/ata/ahci_platform.c b/trunk/drivers/ata/ahci_platform.c index b7078afddb74..b1ae48054dc5 100644 --- a/trunk/drivers/ata/ahci_platform.c +++ b/trunk/drivers/ata/ahci_platform.c @@ -238,7 +238,7 @@ static int __devexit ahci_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM static int ahci_suspend(struct device *dev) { struct ahci_platform_data *pdata = dev_get_platdata(dev); diff --git a/trunk/drivers/ata/libata-acpi.c b/trunk/drivers/ata/libata-acpi.c index 5b0ba3f20edc..fd9ecf74e631 100644 --- a/trunk/drivers/ata/libata-acpi.c +++ b/trunk/drivers/ata/libata-acpi.c @@ -1105,15 +1105,10 @@ static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev, struct acpi_device *acpi_dev; struct acpi_device_power_state *states; - if (ap->flags & ATA_FLAG_ACPI_SATA) { - if (!sata_pmp_attached(ap)) - ata_dev = &ap->link.device[sdev->id]; - else - ata_dev = &ap->pmp_link[sdev->channel].device[sdev->id]; - } - else { + if (ap->flags & ATA_FLAG_ACPI_SATA) + ata_dev = &ap->link.device[sdev->channel]; + else ata_dev = &ap->link.device[sdev->id]; - } *handle = ata_dev_acpi_handle(ata_dev); diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index f46fbd3bd3fb..3cc7096cfda7 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -2942,10 +2942,6 @@ const struct ata_timing *ata_timing_find_mode(u8 xfer_mode) if (xfer_mode == t->mode) return t; - - WARN_ONCE(true, "%s: unable to find timing for xfer_mode 0x%x\n", - __func__, xfer_mode); - return NULL; } diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c index a6df6a351d6e..e3bda074fa12 100644 --- a/trunk/drivers/ata/libata-scsi.c +++ b/trunk/drivers/ata/libata-scsi.c @@ -1052,8 +1052,6 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev) { sdev->use_10_for_rw = 1; sdev->use_10_for_ms = 1; - sdev->no_report_opcodes = 1; - sdev->no_write_same = 1; /* Schedule policy is determined by ->qc_defer() callback and * it needs to see every deferred qc. Set dev_blocked to 1 to diff --git a/trunk/drivers/ata/pata_arasan_cf.c b/trunk/drivers/ata/pata_arasan_cf.c index 371fd2c698b7..26201ebef3ca 100644 --- a/trunk/drivers/ata/pata_arasan_cf.c +++ b/trunk/drivers/ata/pata_arasan_cf.c @@ -317,12 +317,6 @@ static int cf_init(struct arasan_cf_dev *acdev) return ret; } - ret = clk_set_rate(acdev->clk, 166000000); - if (ret) { - dev_warn(acdev->host->dev, "clock set rate failed"); - return ret; - } - spin_lock_irqsave(&acdev->host->lock, flags); /* configure CF interface clock */ writel((pdata->cf_if_clk <= CF_IF_CLK_200M) ? pdata->cf_if_clk : @@ -914,7 +908,7 @@ static int __devexit arasan_cf_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM static int arasan_cf_suspend(struct device *dev) { struct ata_host *host = dev_get_drvdata(dev); diff --git a/trunk/drivers/ata/sata_highbank.c b/trunk/drivers/ata/sata_highbank.c index 400bf1c3e982..0d7c4c2cd26f 100644 --- a/trunk/drivers/ata/sata_highbank.c +++ b/trunk/drivers/ata/sata_highbank.c @@ -260,7 +260,7 @@ static const struct of_device_id ahci_of_match[] = { }; MODULE_DEVICE_TABLE(of, ahci_of_match); -static int __devinit ahci_highbank_probe(struct platform_device *pdev) +static int __init ahci_highbank_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ahci_host_priv *hpriv; @@ -378,7 +378,7 @@ static int __devexit ahci_highbank_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM static int ahci_highbank_suspend(struct device *dev) { struct ata_host *host = dev_get_drvdata(dev); diff --git a/trunk/drivers/ata/sata_svw.c b/trunk/drivers/ata/sata_svw.c index 08608de87e4e..44a4256533e1 100644 --- a/trunk/drivers/ata/sata_svw.c +++ b/trunk/drivers/ata/sata_svw.c @@ -142,39 +142,6 @@ static int k2_sata_scr_write(struct ata_link *link, return 0; } -static int k2_sata_softreset(struct ata_link *link, - unsigned int *class, unsigned long deadline) -{ - u8 dmactl; - void __iomem *mmio = link->ap->ioaddr.bmdma_addr; - - dmactl = readb(mmio + ATA_DMA_CMD); - - /* Clear the start bit */ - if (dmactl & ATA_DMA_START) { - dmactl &= ~ATA_DMA_START; - writeb(dmactl, mmio + ATA_DMA_CMD); - } - - return ata_sff_softreset(link, class, deadline); -} - -static int k2_sata_hardreset(struct ata_link *link, - unsigned int *class, unsigned long deadline) -{ - u8 dmactl; - void __iomem *mmio = link->ap->ioaddr.bmdma_addr; - - dmactl = readb(mmio + ATA_DMA_CMD); - - /* Clear the start bit */ - if (dmactl & ATA_DMA_START) { - dmactl &= ~ATA_DMA_START; - writeb(dmactl, mmio + ATA_DMA_CMD); - } - - return sata_sff_hardreset(link, class, deadline); -} static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) { @@ -379,8 +346,6 @@ static struct scsi_host_template k2_sata_sht = { static struct ata_port_operations k2_sata_ops = { .inherits = &ata_bmdma_port_ops, - .softreset = k2_sata_softreset, - .hardreset = k2_sata_hardreset, .sff_tf_load = k2_sata_tf_load, .sff_tf_read = k2_sata_tf_read, .sff_check_status = k2_stat_check_status, diff --git a/trunk/drivers/atm/ambassador.c b/trunk/drivers/atm/ambassador.c index ff7bb8a42ed6..89b30f32ba68 100644 --- a/trunk/drivers/atm/ambassador.c +++ b/trunk/drivers/atm/ambassador.c @@ -1961,7 +1961,6 @@ static int __devinit ucode_init (loader_block * lb, amb_dev * dev) { res = loader_verify(lb, dev, rec); if (res) break; - rec = ihex_next_binrec(rec); } release_firmware(fw); if (!res) diff --git a/trunk/drivers/base/Kconfig b/trunk/drivers/base/Kconfig index b34b5cda5ae1..08b4c5209384 100644 --- a/trunk/drivers/base/Kconfig +++ b/trunk/drivers/base/Kconfig @@ -236,7 +236,7 @@ config CMA_SIZE_PERCENTAGE choice prompt "Selected region size" - default CMA_SIZE_SEL_MBYTES + default CMA_SIZE_SEL_ABSOLUTE config CMA_SIZE_SEL_MBYTES bool "Use mega bytes value only" diff --git a/trunk/drivers/base/dma-coherent.c b/trunk/drivers/base/dma-coherent.c index bc256b641027..560a7173f810 100644 --- a/trunk/drivers/base/dma-coherent.c +++ b/trunk/drivers/base/dma-coherent.c @@ -191,8 +191,9 @@ EXPORT_SYMBOL(dma_release_from_coherent); * This checks whether the memory was allocated from the per-device * coherent memory pool and if so, maps that memory to the provided vma. * - * Returns 1 if we correctly mapped the memory, or 0 if the caller should - * proceed with mapping memory from generic pools. + * Returns 1 if we correctly mapped the memory, or 0 if + * dma_release_coherent() should proceed with mapping memory from + * generic pools. */ int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma, void *vaddr, size_t size, int *ret) diff --git a/trunk/drivers/base/dma-contiguous.c b/trunk/drivers/base/dma-contiguous.c index 0ca54421ce97..9a1469474f55 100644 --- a/trunk/drivers/base/dma-contiguous.c +++ b/trunk/drivers/base/dma-contiguous.c @@ -27,12 +27,15 @@ #include #include #include -#include #include #include #include #include +#ifndef SZ_1M +#define SZ_1M (1 << 20) +#endif + struct cma { unsigned long base_pfn; unsigned long count; @@ -57,8 +60,8 @@ struct cma *dma_contiguous_default_area; * Users, who want to set the size of global CMA area for their system * should use cma= kernel parameter. */ -static const phys_addr_t size_bytes = CMA_SIZE_MBYTES * SZ_1M; -static phys_addr_t size_cmdline = -1; +static const unsigned long size_bytes = CMA_SIZE_MBYTES * SZ_1M; +static long size_cmdline = -1; static int __init early_cma(char *p) { @@ -70,7 +73,7 @@ early_param("cma", early_cma); #ifdef CONFIG_CMA_SIZE_PERCENTAGE -static phys_addr_t __init __maybe_unused cma_early_percent_memory(void) +static unsigned long __init __maybe_unused cma_early_percent_memory(void) { struct memblock_region *reg; unsigned long total_pages = 0; @@ -88,7 +91,7 @@ static phys_addr_t __init __maybe_unused cma_early_percent_memory(void) #else -static inline __maybe_unused phys_addr_t cma_early_percent_memory(void) +static inline __maybe_unused unsigned long cma_early_percent_memory(void) { return 0; } @@ -106,7 +109,7 @@ static inline __maybe_unused phys_addr_t cma_early_percent_memory(void) */ void __init dma_contiguous_reserve(phys_addr_t limit) { - phys_addr_t selected_size = 0; + unsigned long selected_size = 0; pr_debug("%s(limit %08lx)\n", __func__, (unsigned long)limit); @@ -126,7 +129,7 @@ void __init dma_contiguous_reserve(phys_addr_t limit) if (selected_size) { pr_debug("%s: reserving %ld MiB for global area\n", __func__, - (unsigned long)selected_size / SZ_1M); + selected_size / SZ_1M); dma_declare_contiguous(NULL, selected_size, 0, limit); } @@ -227,11 +230,11 @@ core_initcall(cma_init_reserved_areas); * called by board specific code when early allocator (memblock or bootmem) * is still activate. */ -int __init dma_declare_contiguous(struct device *dev, phys_addr_t size, +int __init dma_declare_contiguous(struct device *dev, unsigned long size, phys_addr_t base, phys_addr_t limit) { struct cma_reserved *r = &cma_reserved[cma_reserved_count]; - phys_addr_t alignment; + unsigned long alignment; pr_debug("%s(size %lx, base %08lx, limit %08lx)\n", __func__, (unsigned long)size, (unsigned long)base, @@ -268,6 +271,10 @@ int __init dma_declare_contiguous(struct device *dev, phys_addr_t size, if (!addr) { base = -ENOMEM; goto err; + } else if (addr + size > ~(unsigned long)0) { + memblock_free(addr, size); + base = -EINVAL; + goto err; } else { base = addr; } @@ -281,14 +288,14 @@ int __init dma_declare_contiguous(struct device *dev, phys_addr_t size, r->size = size; r->dev = dev; cma_reserved_count++; - pr_info("CMA: reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M, + pr_info("CMA: reserved %ld MiB at %08lx\n", size / SZ_1M, (unsigned long)base); /* Architecture specific contiguous memory fixup. */ dma_contiguous_early_fixup(base, size); return 0; err: - pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M); + pr_err("CMA: failed to reserve %ld MiB\n", size / SZ_1M); return base; } diff --git a/trunk/drivers/base/firmware_class.c b/trunk/drivers/base/firmware_class.c index 8945f4e489ed..81541452887b 100644 --- a/trunk/drivers/base/firmware_class.c +++ b/trunk/drivers/base/firmware_class.c @@ -36,6 +36,68 @@ MODULE_AUTHOR("Manuel Estrada Sainz"); MODULE_DESCRIPTION("Multi purpose firmware loading support"); MODULE_LICENSE("GPL"); +static const char *fw_path[] = { + "/lib/firmware/updates/" UTS_RELEASE, + "/lib/firmware/updates", + "/lib/firmware/" UTS_RELEASE, + "/lib/firmware" +}; + +/* Don't inline this: 'struct kstat' is biggish */ +static noinline long fw_file_size(struct file *file) +{ + struct kstat st; + if (vfs_getattr(file->f_path.mnt, file->f_path.dentry, &st)) + return -1; + if (!S_ISREG(st.mode)) + return -1; + if (st.size != (long)st.size) + return -1; + return st.size; +} + +static bool fw_read_file_contents(struct file *file, struct firmware *fw) +{ + long size; + char *buf; + + size = fw_file_size(file); + if (size < 0) + return false; + buf = vmalloc(size); + if (!buf) + return false; + if (kernel_read(file, 0, buf, size) != size) { + vfree(buf); + return false; + } + fw->data = buf; + fw->size = size; + return true; +} + +static bool fw_get_filesystem_firmware(struct firmware *fw, const char *name) +{ + int i; + bool success = false; + char *path = __getname(); + + for (i = 0; i < ARRAY_SIZE(fw_path); i++) { + struct file *file; + snprintf(path, PATH_MAX, "%s/%s", fw_path[i], name); + + file = filp_open(path, O_RDONLY, 0); + if (IS_ERR(file)) + continue; + success = fw_read_file_contents(file, fw); + fput(file); + if (success) + break; + } + __putname(path); + return success; +} + /* Builtin firmware support */ #ifdef CONFIG_FW_LOADER @@ -88,11 +150,6 @@ enum { FW_STATUS_ABORT, }; -enum fw_buf_fmt { - VMALLOC_BUF, /* used in direct loading */ - PAGE_BUF, /* used in loading via userspace */ -}; - static int loading_timeout = 60; /* In seconds */ static inline long firmware_loading_timeout(void) @@ -116,6 +173,8 @@ struct firmware_cache { spinlock_t name_lock; struct list_head fw_names; + wait_queue_head_t wait_queue; + int cnt; struct delayed_work work; struct notifier_block pm_notify; @@ -128,7 +187,6 @@ struct firmware_buf { struct completion completion; struct firmware_cache *fwc; unsigned long status; - enum fw_buf_fmt fmt; void *data; size_t size; struct page **pages; @@ -182,7 +240,6 @@ static struct firmware_buf *__allocate_fw_buf(const char *fw_name, strcpy(buf->fw_id, fw_name); buf->fwc = fwc; init_completion(&buf->completion); - buf->fmt = VMALLOC_BUF; pr_debug("%s: fw-%s buf=%p\n", __func__, fw_name, buf); @@ -250,14 +307,10 @@ static void __fw_free_buf(struct kref *ref) list_del(&buf->list); spin_unlock(&fwc->lock); - - if (buf->fmt == PAGE_BUF) { - vunmap(buf->data); - for (i = 0; i < buf->nr_pages; i++) - __free_page(buf->pages[i]); - kfree(buf->pages); - } else - vfree(buf->data); + vunmap(buf->data); + for (i = 0; i < buf->nr_pages; i++) + __free_page(buf->pages[i]); + kfree(buf->pages); kfree(buf); } @@ -266,69 +319,6 @@ static void fw_free_buf(struct firmware_buf *buf) kref_put(&buf->ref, __fw_free_buf); } -/* direct firmware loading support */ -static const char *fw_path[] = { - "/lib/firmware/updates/" UTS_RELEASE, - "/lib/firmware/updates", - "/lib/firmware/" UTS_RELEASE, - "/lib/firmware" -}; - -/* Don't inline this: 'struct kstat' is biggish */ -static noinline long fw_file_size(struct file *file) -{ - struct kstat st; - if (vfs_getattr(file->f_path.mnt, file->f_path.dentry, &st)) - return -1; - if (!S_ISREG(st.mode)) - return -1; - if (st.size != (long)st.size) - return -1; - return st.size; -} - -static bool fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf) -{ - long size; - char *buf; - - size = fw_file_size(file); - if (size < 0) - return false; - buf = vmalloc(size); - if (!buf) - return false; - if (kernel_read(file, 0, buf, size) != size) { - vfree(buf); - return false; - } - fw_buf->data = buf; - fw_buf->size = size; - return true; -} - -static bool fw_get_filesystem_firmware(struct firmware_buf *buf) -{ - int i; - bool success = false; - char *path = __getname(); - - for (i = 0; i < ARRAY_SIZE(fw_path); i++) { - struct file *file; - snprintf(path, PATH_MAX, "%s/%s", fw_path[i], buf->fw_id); - - file = filp_open(path, O_RDONLY, 0); - if (IS_ERR(file)) - continue; - success = fw_read_file_contents(file, buf); - fput(file); - if (success) - break; - } - __putname(path); - return success; -} - static struct firmware_priv *to_firmware_priv(struct device *dev) { return container_of(dev, struct firmware_priv, dev); @@ -433,21 +423,6 @@ static void firmware_free_data(const struct firmware *fw) #ifndef PAGE_KERNEL_RO #define PAGE_KERNEL_RO PAGE_KERNEL #endif - -/* one pages buffer should be mapped/unmapped only once */ -static int fw_map_pages_buf(struct firmware_buf *buf) -{ - if (buf->fmt != PAGE_BUF) - return 0; - - if (buf->data) - vunmap(buf->data); - buf->data = vmap(buf->pages, buf->nr_pages, 0, PAGE_KERNEL_RO); - if (!buf->data) - return -ENOMEM; - return 0; -} - /** * firmware_loading_store - set value in the 'loading' control file * @dev: device pointer @@ -492,14 +467,6 @@ static ssize_t firmware_loading_store(struct device *dev, if (test_bit(FW_STATUS_LOADING, &fw_buf->status)) { set_bit(FW_STATUS_DONE, &fw_buf->status); clear_bit(FW_STATUS_LOADING, &fw_buf->status); - - /* - * Several loading requests may be pending on - * one same firmware buf, so let all requests - * see the mapped 'buf->data' once the loading - * is completed. - * */ - fw_map_pages_buf(fw_buf); complete_all(&fw_buf->completion); break; } @@ -703,6 +670,15 @@ fw_create_instance(struct firmware *firmware, const char *fw_name, return fw_priv; } +/* one pages buffer is mapped/unmapped only once */ +static int fw_map_pages_buf(struct firmware_buf *buf) +{ + buf->data = vmap(buf->pages, buf->nr_pages, 0, PAGE_KERNEL_RO); + if (!buf->data) + return -ENOMEM; + return 0; +} + /* store the pages buffer info firmware from buf */ static void fw_set_page_data(struct firmware_buf *buf, struct firmware *fw) { @@ -802,6 +778,11 @@ _request_firmware_prepare(const struct firmware **firmware_p, const char *name, return NULL; } + if (fw_get_filesystem_firmware(firmware, name)) { + dev_dbg(device, "firmware: direct-loading firmware %s\n", name); + return NULL; + } + ret = fw_lookup_and_allocate_buf(name, &fw_cache, &buf); if (!ret) fw_priv = fw_create_instance(firmware, name, device, @@ -851,21 +832,6 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, struct device *f_dev = &fw_priv->dev; struct firmware_buf *buf = fw_priv->buf; struct firmware_cache *fwc = &fw_cache; - int direct_load = 0; - - /* try direct loading from fs first */ - if (fw_get_filesystem_firmware(buf)) { - dev_dbg(f_dev->parent, "firmware: direct-loading" - " firmware %s\n", buf->fw_id); - - set_bit(FW_STATUS_DONE, &buf->status); - complete_all(&buf->completion); - direct_load = 1; - goto handle_fw; - } - - /* fall back on userspace loading */ - buf->fmt = PAGE_BUF; dev_set_uevent_suppress(f_dev, true); @@ -904,7 +870,6 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, del_timer_sync(&fw_priv->timeout); -handle_fw: mutex_lock(&fw_lock); if (!buf->size || test_bit(FW_STATUS_ABORT, &buf->status)) retval = -ENOENT; @@ -919,6 +884,9 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, if (!retval && f_dev->parent) fw_add_devm_name(f_dev->parent, buf->fw_id); + if (!retval) + retval = fw_map_pages_buf(buf); + /* * After caching firmware image is started, let it piggyback * on request firmware. @@ -934,9 +902,6 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, fw_priv->buf = NULL; mutex_unlock(&fw_lock); - if (direct_load) - goto err_put_dev; - device_remove_file(f_dev, &dev_attr_loading); err_del_bin_attr: device_remove_bin_file(f_dev, &firmware_attr_data); @@ -1164,8 +1129,6 @@ int uncache_firmware(const char *fw_name) } #ifdef CONFIG_PM_SLEEP -static ASYNC_DOMAIN_EXCLUSIVE(fw_cache_domain); - static struct fw_cache_entry *alloc_fw_cache_entry(const char *name) { struct fw_cache_entry *fce; @@ -1179,18 +1142,6 @@ static struct fw_cache_entry *alloc_fw_cache_entry(const char *name) return fce; } -static int __fw_entry_found(const char *name) -{ - struct firmware_cache *fwc = &fw_cache; - struct fw_cache_entry *fce; - - list_for_each_entry(fce, &fwc->fw_names, list) { - if (!strcmp(fce->name, name)) - return 1; - } - return 0; -} - static int fw_cache_piggyback_on_request(const char *name) { struct firmware_cache *fwc = &fw_cache; @@ -1198,8 +1149,10 @@ static int fw_cache_piggyback_on_request(const char *name) int ret = 0; spin_lock(&fwc->name_lock); - if (__fw_entry_found(name)) - goto found; + list_for_each_entry(fce, &fwc->fw_names, list) { + if (!strcmp(fce->name, name)) + goto found; + } fce = alloc_fw_cache_entry(name); if (fce) { @@ -1232,6 +1185,12 @@ static void __async_dev_cache_fw_image(void *fw_entry, free_fw_cache_entry(fce); } + + spin_lock(&fwc->name_lock); + fwc->cnt--; + spin_unlock(&fwc->name_lock); + + wake_up(&fwc->wait_queue); } /* called with dev->devres_lock held */ @@ -1270,19 +1229,11 @@ static void dev_cache_fw_image(struct device *dev, void *data) list_del(&fce->list); spin_lock(&fwc->name_lock); - /* only one cache entry for one firmware */ - if (!__fw_entry_found(fce->name)) { - list_add(&fce->list, &fwc->fw_names); - } else { - free_fw_cache_entry(fce); - fce = NULL; - } + fwc->cnt++; + list_add(&fce->list, &fwc->fw_names); spin_unlock(&fwc->name_lock); - if (fce) - async_schedule_domain(__async_dev_cache_fw_image, - (void *)fce, - &fw_cache_domain); + async_schedule(__async_dev_cache_fw_image, (void *)fce); } } @@ -1324,9 +1275,6 @@ static void device_cache_fw_images(void) pr_debug("%s\n", __func__); - /* cancel uncache work */ - cancel_delayed_work_sync(&fwc->work); - /* * use small loading timeout for caching devices' firmware * because all these firmware images have been loaded @@ -1344,7 +1292,21 @@ static void device_cache_fw_images(void) mutex_unlock(&fw_lock); /* wait for completion of caching firmware for all devices */ - async_synchronize_full_domain(&fw_cache_domain); + spin_lock(&fwc->name_lock); + for (;;) { + prepare_to_wait(&fwc->wait_queue, &wait, + TASK_UNINTERRUPTIBLE); + if (!fwc->cnt) + break; + + spin_unlock(&fwc->name_lock); + + schedule(); + + spin_lock(&fwc->name_lock); + } + spin_unlock(&fwc->name_lock); + finish_wait(&fwc->wait_queue, &wait); loading_timeout = old_timeout; } @@ -1432,7 +1394,9 @@ static void __init fw_cache_init(void) #ifdef CONFIG_PM_SLEEP spin_lock_init(&fw_cache.name_lock); INIT_LIST_HEAD(&fw_cache.fw_names); + fw_cache.cnt = 0; + init_waitqueue_head(&fw_cache.wait_queue); INIT_DELAYED_WORK(&fw_cache.work, device_uncache_fw_images_work); diff --git a/trunk/drivers/base/platform.c b/trunk/drivers/base/platform.c index 72c776f2a1f5..8727e9c5eea4 100644 --- a/trunk/drivers/base/platform.c +++ b/trunk/drivers/base/platform.c @@ -83,16 +83,9 @@ EXPORT_SYMBOL_GPL(platform_get_resource); */ int platform_get_irq(struct platform_device *dev, unsigned int num) { -#ifdef CONFIG_SPARC - /* sparc does not have irqs represented as IORESOURCE_IRQ resources */ - if (!dev || num >= dev->archdata.num_irqs) - return -ENXIO; - return dev->archdata.irqs[num]; -#else struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); return r ? r->start : -ENXIO; -#endif } EXPORT_SYMBOL_GPL(platform_get_irq); diff --git a/trunk/drivers/base/power/domain.c b/trunk/drivers/base/power/domain.c index 96b71b6536d6..c22b869245d9 100644 --- a/trunk/drivers/base/power/domain.c +++ b/trunk/drivers/base/power/domain.c @@ -1862,7 +1862,7 @@ int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state) cpuidle_drv = cpuidle_driver_ref(); if (!cpuidle_drv) { ret = -ENODEV; - goto err_drv; + goto out; } if (cpuidle_drv->state_count <= state) { ret = -EINVAL; @@ -1884,9 +1884,6 @@ int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state) err: cpuidle_driver_unref(); - - err_drv: - kfree(cpu_data); goto out; } diff --git a/trunk/drivers/base/power/qos.c b/trunk/drivers/base/power/qos.c index fbbd4ed2edf2..74a67e0019a2 100644 --- a/trunk/drivers/base/power/qos.c +++ b/trunk/drivers/base/power/qos.c @@ -451,7 +451,7 @@ int dev_pm_qos_add_ancestor_request(struct device *dev, if (ancestor) error = dev_pm_qos_add_request(ancestor, req, value); - if (error < 0) + if (error) req->dev = NULL; return error; diff --git a/trunk/drivers/base/regmap/Kconfig b/trunk/drivers/base/regmap/Kconfig index f0d30543fcce..6be390bd8bd1 100644 --- a/trunk/drivers/base/regmap/Kconfig +++ b/trunk/drivers/base/regmap/Kconfig @@ -3,7 +3,7 @@ # subsystems should select the appropriate symbols. config REGMAP - default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_MMIO || REGMAP_IRQ) + default y if (REGMAP_I2C || REGMAP_SPI) select LZO_COMPRESS select LZO_DECOMPRESS select IRQ_DOMAIN if REGMAP_IRQ diff --git a/trunk/drivers/bcma/main.c b/trunk/drivers/bcma/main.c index d865470bc951..432aeeedfd5e 100644 --- a/trunk/drivers/bcma/main.c +++ b/trunk/drivers/bcma/main.c @@ -158,10 +158,9 @@ static int bcma_register_cores(struct bcma_bus *bus) static void bcma_unregister_cores(struct bcma_bus *bus) { - struct bcma_device *core, *tmp; + struct bcma_device *core; - list_for_each_entry_safe(core, tmp, &bus->cores, list) { - list_del(&core->list); + list_for_each_entry(core, &bus->cores, list) { if (core->dev_registered) device_unregister(&core->dev); } diff --git a/trunk/drivers/block/Kconfig b/trunk/drivers/block/Kconfig index 824e09c4d0d7..f529407db93f 100644 --- a/trunk/drivers/block/Kconfig +++ b/trunk/drivers/block/Kconfig @@ -131,7 +131,6 @@ config BLK_CPQ_DA config BLK_CPQ_CISS_DA tristate "Compaq Smart Array 5xxx support" depends on PCI - select CHECK_SIGNATURE help This is the driver for Compaq Smart Array 5xxx controllers. Everyone using these boards should say Y here. @@ -167,8 +166,8 @@ config BLK_DEV_DAC960 module will be called DAC960. config BLK_DEV_UMEM - tristate "Micro Memory MM5415 Battery Backed RAM support" - depends on PCI + tristate "Micro Memory MM5415 Battery Backed RAM support (EXPERIMENTAL)" + depends on PCI && EXPERIMENTAL ---help--- Saying Y here will include support for the MM5415 family of battery backed (Non-volatile) RAM cards. @@ -431,8 +430,8 @@ config CDROM_PKTCDVD_BUFFERS a disc is opened for writing. config CDROM_PKTCDVD_WCACHE - bool "Enable write caching" - depends on CDROM_PKTCDVD + bool "Enable write caching (EXPERIMENTAL)" + depends on CDROM_PKTCDVD && EXPERIMENTAL help If enabled, write caching will be set for the CD-R/W device. For now this option is dangerous unless the CD-RW media is known good, as we @@ -509,8 +508,8 @@ config XEN_BLKDEV_BACKEND config VIRTIO_BLK - tristate "Virtio block driver" - depends on VIRTIO + tristate "Virtio block driver (EXPERIMENTAL)" + depends on EXPERIMENTAL && VIRTIO ---help--- This is the virtual block driver for virtio. It can be used with lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. @@ -529,7 +528,7 @@ config BLK_DEV_HD config BLK_DEV_RBD tristate "Rados block device (RBD)" - depends on INET && BLOCK + depends on INET && EXPERIMENTAL && BLOCK select CEPH_LIB select LIBCRC32C select CRYPTO_AES diff --git a/trunk/drivers/block/aoe/aoecmd.c b/trunk/drivers/block/aoe/aoecmd.c index 9fe4f1865558..3804a0af3ef1 100644 --- a/trunk/drivers/block/aoe/aoecmd.c +++ b/trunk/drivers/block/aoe/aoecmd.c @@ -935,7 +935,7 @@ aoe_end_request(struct aoedev *d, struct request *rq, int fastfail) /* cf. http://lkml.org/lkml/2006/10/31/28 */ if (!fastfail) - __blk_run_queue(q); + q->request_fn(q); } static void diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index ca83f96756ad..b0f553b26d0f 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -5205,6 +5205,7 @@ static void cciss_shutdown(struct pci_dev *pdev) return; } /* write all data in the battery backed cache to disk */ + memset(flush_buf, 0, 4); return_code = sendcmd_withirq(h, CCISS_CACHE_FLUSH, flush_buf, 4, 0, CTLR_LUNID, TYPE_CMD); kfree(flush_buf); diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index 2ddd64a9ffde..17c675c52295 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -4109,19 +4109,12 @@ static struct platform_driver floppy_driver = { static struct platform_device floppy_device[N_DRIVE]; -static bool floppy_available(int drive) -{ - if (!(allowed_drive_mask & (1 << drive))) - return false; - if (fdc_state[FDC(drive)].version == FDC_NONE) - return false; - return true; -} - static struct kobject *floppy_find(dev_t dev, int *part, void *data) { int drive = (*part & 3) | ((*part & 0x80) >> 5); - if (drive >= N_DRIVE || !floppy_available(drive)) + if (drive >= N_DRIVE || + !(allowed_drive_mask & (1 << drive)) || + fdc_state[FDC(drive)].version == FDC_NONE) return NULL; if (((*part >> 2) & 0x1f) >= ARRAY_SIZE(floppy_type)) return NULL; @@ -4131,7 +4124,8 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data) static int __init do_floppy_init(void) { - int i, unit, drive, err; + int i, unit, drive; + int err, dr; set_debugt(); interruptjiffies = resultjiffies = jiffies; @@ -4143,32 +4137,34 @@ static int __init do_floppy_init(void) raw_cmd = NULL; - floppy_wq = alloc_ordered_workqueue("floppy", 0); - if (!floppy_wq) - return -ENOMEM; - - for (drive = 0; drive < N_DRIVE; drive++) { - disks[drive] = alloc_disk(1); - if (!disks[drive]) { + for (dr = 0; dr < N_DRIVE; dr++) { + disks[dr] = alloc_disk(1); + if (!disks[dr]) { err = -ENOMEM; goto out_put_disk; } - disks[drive]->queue = blk_init_queue(do_fd_request, &floppy_lock); - if (!disks[drive]->queue) { + floppy_wq = alloc_ordered_workqueue("floppy", 0); + if (!floppy_wq) { err = -ENOMEM; goto out_put_disk; } - blk_queue_max_hw_sectors(disks[drive]->queue, 64); - disks[drive]->major = FLOPPY_MAJOR; - disks[drive]->first_minor = TOMINOR(drive); - disks[drive]->fops = &floppy_fops; - sprintf(disks[drive]->disk_name, "fd%d", drive); + disks[dr]->queue = blk_init_queue(do_fd_request, &floppy_lock); + if (!disks[dr]->queue) { + err = -ENOMEM; + goto out_destroy_workq; + } + + blk_queue_max_hw_sectors(disks[dr]->queue, 64); + disks[dr]->major = FLOPPY_MAJOR; + disks[dr]->first_minor = TOMINOR(dr); + disks[dr]->fops = &floppy_fops; + sprintf(disks[dr]->disk_name, "fd%d", dr); - init_timer(&motor_off_timer[drive]); - motor_off_timer[drive].data = drive; - motor_off_timer[drive].function = motor_off_callback; + init_timer(&motor_off_timer[dr]); + motor_off_timer[dr].data = dr; + motor_off_timer[dr].function = motor_off_callback; } err = register_blkdev(FLOPPY_MAJOR, "fd"); @@ -4286,7 +4282,9 @@ static int __init do_floppy_init(void) } for (drive = 0; drive < N_DRIVE; drive++) { - if (!floppy_available(drive)) + if (!(allowed_drive_mask & (1 << drive))) + continue; + if (fdc_state[FDC(drive)].version == FDC_NONE) continue; floppy_device[drive].name = floppy_device_name; @@ -4295,7 +4293,7 @@ static int __init do_floppy_init(void) err = platform_device_register(&floppy_device[drive]); if (err) - goto out_remove_drives; + goto out_release_dma; err = device_create_file(&floppy_device[drive].dev, &dev_attr_cmos); @@ -4313,33 +4311,28 @@ static int __init do_floppy_init(void) out_unreg_platform_dev: platform_device_unregister(&floppy_device[drive]); -out_remove_drives: - while (drive--) { - if (floppy_available(drive)) { - del_gendisk(disks[drive]); - device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos); - platform_device_unregister(&floppy_device[drive]); - } - } out_release_dma: if (atomic_read(&usage_count)) floppy_release_irq_and_dma(); out_unreg_region: blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); platform_driver_unregister(&floppy_driver); +out_destroy_workq: + destroy_workqueue(floppy_wq); out_unreg_blkdev: unregister_blkdev(FLOPPY_MAJOR, "fd"); out_put_disk: - destroy_workqueue(floppy_wq); - for (drive = 0; drive < N_DRIVE; drive++) { - if (!disks[drive]) - break; - if (disks[drive]->queue) { - del_timer_sync(&motor_off_timer[drive]); - blk_cleanup_queue(disks[drive]->queue); - disks[drive]->queue = NULL; + while (dr--) { + del_timer_sync(&motor_off_timer[dr]); + if (disks[dr]->queue) { + blk_cleanup_queue(disks[dr]->queue); + /* + * put_disk() is not paired with add_disk() and + * will put queue reference one extra time. fix it. + */ + disks[dr]->queue = NULL; } - put_disk(disks[drive]); + put_disk(disks[dr]); } return err; } @@ -4555,12 +4548,11 @@ static void __exit floppy_module_exit(void) unregister_blkdev(FLOPPY_MAJOR, "fd"); platform_driver_unregister(&floppy_driver); - destroy_workqueue(floppy_wq); - for (drive = 0; drive < N_DRIVE; drive++) { del_timer_sync(&motor_off_timer[drive]); - if (floppy_available(drive)) { + if ((allowed_drive_mask & (1 << drive)) && + fdc_state[FDC(drive)].version != FDC_NONE) { del_gendisk(disks[drive]); device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos); platform_device_unregister(&floppy_device[drive]); @@ -4580,6 +4572,7 @@ static void __exit floppy_module_exit(void) cancel_delayed_work_sync(&fd_timeout); cancel_delayed_work_sync(&fd_timer); + destroy_workqueue(floppy_wq); if (atomic_read(&usage_count)) floppy_release_irq_and_dma(); diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c index 54046e51160a..e9d594fd12cb 100644 --- a/trunk/drivers/block/loop.c +++ b/trunk/drivers/block/loop.c @@ -976,21 +976,8 @@ static int loop_clr_fd(struct loop_device *lo) if (lo->lo_state != Lo_bound) return -ENXIO; - /* - * If we've explicitly asked to tear down the loop device, - * and it has an elevated reference count, set it for auto-teardown when - * the last reference goes away. This stops $!~#$@ udev from - * preventing teardown because it decided that it needs to run blkid on - * the loopback device whenever they appear. xfstests is notorious for - * failing tests because blkid via udev races with a losetup - * /do something like mkfs/losetup -d causing the losetup -d - * command to fail with EBUSY. - */ - if (lo->lo_refcnt > 1) { - lo->lo_flags |= LO_FLAGS_AUTOCLEAR; - mutex_unlock(&lo->lo_ctl_mutex); - return 0; - } + if (lo->lo_refcnt > 1) /* we needed one fd for the ioctl */ + return -EBUSY; if (filp == NULL) return -EINVAL; diff --git a/trunk/drivers/block/mtip32xx/mtip32xx.c b/trunk/drivers/block/mtip32xx/mtip32xx.c index 9694dd99bbbc..f946d31d6917 100644 --- a/trunk/drivers/block/mtip32xx/mtip32xx.c +++ b/trunk/drivers/block/mtip32xx/mtip32xx.c @@ -559,7 +559,7 @@ static void mtip_timeout_function(unsigned long int data) struct mtip_cmd *command; int tag, cmdto_cnt = 0; unsigned int bit, group; - unsigned int num_command_slots; + unsigned int num_command_slots = port->dd->slot_groups * 32; unsigned long to, tagaccum[SLOTBITS_IN_LONGS]; if (unlikely(!port)) @@ -572,7 +572,6 @@ static void mtip_timeout_function(unsigned long int data) } /* clear the tag accumulator */ memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); - num_command_slots = port->dd->slot_groups * 32; for (tag = 0; tag < num_command_slots; tag++) { /* @@ -2036,9 +2035,8 @@ static unsigned int implicit_sector(unsigned char command, } return rv; } -static void mtip_set_timeout(struct driver_data *dd, - struct host_to_dev_fis *fis, - unsigned int *timeout, u8 erasemode) + +static void mtip_set_timeout(struct host_to_dev_fis *fis, unsigned int *timeout) { switch (fis->command) { case ATA_CMD_DOWNLOAD_MICRO: @@ -2046,10 +2044,7 @@ static void mtip_set_timeout(struct driver_data *dd, break; case ATA_CMD_SEC_ERASE_UNIT: case 0xFC: - if (erasemode) - *timeout = ((*(dd->port->identify + 90) * 2) * 60000); - else - *timeout = ((*(dd->port->identify + 89) * 2) * 60000); + *timeout = 240000; /* 4 minutes */ break; case ATA_CMD_STANDBYNOW1: *timeout = 120000; /* 2 minutes */ @@ -2092,7 +2087,6 @@ static int exec_drive_taskfile(struct driver_data *dd, unsigned int transfer_size; unsigned long task_file_data; int intotal = outtotal + req_task->out_size; - int erasemode = 0; taskout = req_task->out_size; taskin = req_task->in_size; @@ -2218,13 +2212,7 @@ static int exec_drive_taskfile(struct driver_data *dd, fis.lba_hi, fis.device); - /* check for erase mode support during secure erase.*/ - if ((fis.command == ATA_CMD_SEC_ERASE_UNIT) && outbuf && - (outbuf[0] & MTIP_SEC_ERASE_MODE)) { - erasemode = 1; - } - - mtip_set_timeout(dd, &fis, &timeout, erasemode); + mtip_set_timeout(&fis, &timeout); /* Determine the correct transfer size.*/ if (force_single_sector) @@ -2440,7 +2428,7 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd, * return value * None */ -static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector, +static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, int nsect, int nents, int tag, void *callback, void *data, int dir) { @@ -2448,7 +2436,6 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector, struct mtip_port *port = dd->port; struct mtip_cmd *command = &port->commands[tag]; int dma_dir = (dir == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; - u64 start = sector; /* Map the scatter list for DMA access */ nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir); @@ -2467,12 +2454,8 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector, fis->opts = 1 << 7; fis->command = (dir == READ ? ATA_CMD_FPDMA_READ : ATA_CMD_FPDMA_WRITE); - fis->lba_low = start & 0xFF; - fis->lba_mid = (start >> 8) & 0xFF; - fis->lba_hi = (start >> 16) & 0xFF; - fis->lba_low_ex = (start >> 24) & 0xFF; - fis->lba_mid_ex = (start >> 32) & 0xFF; - fis->lba_hi_ex = (start >> 40) & 0xFF; + *((unsigned int *) &fis->lba_low) = (start & 0xFFFFFF); + *((unsigned int *) &fis->lba_low_ex) = ((start >> 24) & 0xFFFFFF); fis->device = 1 << 6; fis->features = nsect & 0xFF; fis->features_ex = (nsect >> 8) & 0xFF; diff --git a/trunk/drivers/block/mtip32xx/mtip32xx.h b/trunk/drivers/block/mtip32xx/mtip32xx.h index b1742640556a..18627a1d04c5 100644 --- a/trunk/drivers/block/mtip32xx/mtip32xx.h +++ b/trunk/drivers/block/mtip32xx/mtip32xx.h @@ -33,9 +33,6 @@ /* offset of Device Control register in PCIe extended capabilites space */ #define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET 0x48 -/* check for erase mode support during secure erase */ -#define MTIP_SEC_ERASE_MODE 0x2 - /* # of times to retry timed out/failed IOs */ #define MTIP_MAX_RETRIES 2 @@ -155,14 +152,14 @@ enum { MTIP_DDF_REBUILD_FAILED_BIT = 8, }; -struct smart_attr { +__packed struct smart_attr{ u8 attr_id; u16 flags; u8 cur; u8 worst; u32 data; u8 res[3]; -} __packed; +}; /* Register Frame Information Structure (FIS), host to device. */ struct host_to_dev_fis { diff --git a/trunk/drivers/block/xen-blkback/common.h b/trunk/drivers/block/xen-blkback/common.h index 9a54623e52d7..9ad3b5ec1dc1 100644 --- a/trunk/drivers/block/xen-blkback/common.h +++ b/trunk/drivers/block/xen-blkback/common.h @@ -158,8 +158,8 @@ struct xen_vbd { struct block_device *bdev; /* Cached size parameter. */ sector_t size; - unsigned int flush_support:1; - unsigned int discard_secure:1; + bool flush_support; + bool discard_secure; }; struct backend_info; diff --git a/trunk/drivers/block/xen-blkback/xenbus.c b/trunk/drivers/block/xen-blkback/xenbus.c index f58434c2617c..4f66171c6683 100644 --- a/trunk/drivers/block/xen-blkback/xenbus.c +++ b/trunk/drivers/block/xen-blkback/xenbus.c @@ -105,10 +105,11 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid) { struct xen_blkif *blkif; - blkif = kmem_cache_zalloc(xen_blkif_cachep, GFP_KERNEL); + blkif = kmem_cache_alloc(xen_blkif_cachep, GFP_KERNEL); if (!blkif) return ERR_PTR(-ENOMEM); + memset(blkif, 0, sizeof(*blkif)); blkif->domid = domid; spin_lock_init(&blkif->blk_ring_lock); atomic_set(&blkif->refcnt, 1); @@ -195,7 +196,7 @@ static void xen_blkif_disconnect(struct xen_blkif *blkif) } } -static void xen_blkif_free(struct xen_blkif *blkif) +void xen_blkif_free(struct xen_blkif *blkif) { if (!atomic_dec_and_test(&blkif->refcnt)) BUG(); @@ -256,7 +257,7 @@ static struct attribute_group xen_vbdstat_group = { VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor); VBD_SHOW(mode, "%s\n", be->mode); -static int xenvbd_sysfs_addif(struct xenbus_device *dev) +int xenvbd_sysfs_addif(struct xenbus_device *dev) { int error; @@ -280,7 +281,7 @@ fail1: device_remove_file(&dev->dev, &dev_attr_physical_device); return error; } -static void xenvbd_sysfs_delif(struct xenbus_device *dev) +void xenvbd_sysfs_delif(struct xenbus_device *dev) { sysfs_remove_group(&dev->dev.kobj, &xen_vbdstat_group); device_remove_file(&dev->dev, &dev_attr_mode); diff --git a/trunk/drivers/bluetooth/ath3k.c b/trunk/drivers/bluetooth/ath3k.c index b00000e8aef6..fc2de5528dcc 100644 --- a/trunk/drivers/bluetooth/ath3k.c +++ b/trunk/drivers/bluetooth/ath3k.c @@ -67,7 +67,6 @@ static struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x13d3, 0x3304) }, { USB_DEVICE(0x0930, 0x0215) }, { USB_DEVICE(0x0489, 0xE03D) }, - { USB_DEVICE(0x0489, 0xE027) }, /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03F0, 0x311D) }, diff --git a/trunk/drivers/bluetooth/btusb.c b/trunk/drivers/bluetooth/btusb.c index ee82f2fb65f0..debda27df9b0 100644 --- a/trunk/drivers/bluetooth/btusb.c +++ b/trunk/drivers/bluetooth/btusb.c @@ -124,7 +124,6 @@ static struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, - { USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE }, /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, diff --git a/trunk/drivers/bus/omap-ocp2scp.c b/trunk/drivers/bus/omap-ocp2scp.c index 0c48b0e05ed6..ff63560b8467 100644 --- a/trunk/drivers/bus/omap-ocp2scp.c +++ b/trunk/drivers/bus/omap-ocp2scp.c @@ -22,26 +22,6 @@ #include #include #include -#include - -/** - * _count_resources - count for the number of resources - * @res: struct resource * - * - * Count and return the number of resources populated for the device that is - * connected to ocp2scp. - */ -static unsigned _count_resources(struct resource *res) -{ - int cnt = 0; - - while (res->start != res->end) { - cnt++; - res++; - } - - return cnt; -} static int ocp2scp_remove_devices(struct device *dev, void *c) { @@ -54,62 +34,20 @@ static int ocp2scp_remove_devices(struct device *dev, void *c) static int __devinit omap_ocp2scp_probe(struct platform_device *pdev) { - int ret; - unsigned res_cnt, i; - struct device_node *np = pdev->dev.of_node; - struct platform_device *pdev_child; - struct omap_ocp2scp_platform_data *pdata = pdev->dev.platform_data; - struct omap_ocp2scp_dev *dev; + int ret; + struct device_node *np = pdev->dev.of_node; if (np) { ret = of_platform_populate(np, NULL, NULL, &pdev->dev); if (ret) { - dev_err(&pdev->dev, - "failed to add resources for ocp2scp child\n"); + dev_err(&pdev->dev, "failed to add resources for ocp2scp child\n"); goto err0; } - } else if (pdata) { - for (i = 0, dev = *pdata->devices; i < pdata->dev_cnt; i++, - dev++) { - res_cnt = _count_resources(dev->res); - - pdev_child = platform_device_alloc(dev->drv_name, - PLATFORM_DEVID_AUTO); - if (!pdev_child) { - dev_err(&pdev->dev, - "failed to allocate mem for ocp2scp child\n"); - goto err0; - } - - ret = platform_device_add_resources(pdev_child, - dev->res, res_cnt); - if (ret) { - dev_err(&pdev->dev, - "failed to add resources for ocp2scp child\n"); - goto err1; - } - - pdev_child->dev.parent = &pdev->dev; - - ret = platform_device_add(pdev_child); - if (ret) { - dev_err(&pdev->dev, - "failed to register ocp2scp child device\n"); - goto err1; - } - } - } else { - dev_err(&pdev->dev, "OCP2SCP initialized without plat data\n"); - return -EINVAL; } - pm_runtime_enable(&pdev->dev); return 0; -err1: - platform_device_put(pdev_child); - err0: device_for_each_child(&pdev->dev, NULL, ocp2scp_remove_devices); diff --git a/trunk/drivers/char/hw_random/Kconfig b/trunk/drivers/char/hw_random/Kconfig index c58ea9b80b1a..fbd9b2b850ef 100644 --- a/trunk/drivers/char/hw_random/Kconfig +++ b/trunk/drivers/char/hw_random/Kconfig @@ -127,12 +127,12 @@ config HW_RANDOM_VIA If unsure, say Y. config HW_RANDOM_IXP4XX - tristate "Intel IXP4xx NPU HW Pseudo-Random Number Generator support" + tristate "Intel IXP4xx NPU HW Random Number Generator support" depends on HW_RANDOM && ARCH_IXP4XX default HW_RANDOM ---help--- - This driver provides kernel-side support for the Pseudo-Random - Number Generator hardware found on the Intel IXP45x/46x NPU. + This driver provides kernel-side support for the Random + Number Generator hardware found on the Intel IXP4xx NPU. To compile this driver as a module, choose M here: the module will be called ixp4xx-rng. diff --git a/trunk/drivers/char/hw_random/ixp4xx-rng.c b/trunk/drivers/char/hw_random/ixp4xx-rng.c index beec1627db3c..263567f5f392 100644 --- a/trunk/drivers/char/hw_random/ixp4xx-rng.c +++ b/trunk/drivers/char/hw_random/ixp4xx-rng.c @@ -45,9 +45,6 @@ static int __init ixp4xx_rng_init(void) void __iomem * rng_base; int err; - if (!cpu_is_ixp46x()) /* includes IXP455 */ - return -ENOSYS; - rng_base = ioremap(0x70002100, 4); if (!rng_base) return -ENOMEM; @@ -71,5 +68,5 @@ module_init(ixp4xx_rng_init); module_exit(ixp4xx_rng_exit); MODULE_AUTHOR("Deepak Saxena "); -MODULE_DESCRIPTION("H/W Pseudo-Random Number Generator (RNG) driver for IXP45x/46x"); +MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver for IXP4xx"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/char/raw.c b/trunk/drivers/char/raw.c index 54a3a6d09819..0bb207eaef2f 100644 --- a/trunk/drivers/char/raw.c +++ b/trunk/drivers/char/raw.c @@ -285,7 +285,7 @@ static long raw_ctl_compat_ioctl(struct file *file, unsigned int cmd, static const struct file_operations raw_fops = { .read = do_sync_read, - .aio_read = generic_file_aio_read, + .aio_read = blkdev_aio_read, .write = do_sync_write, .aio_write = blkdev_aio_write, .fsync = blkdev_fsync, diff --git a/trunk/drivers/char/sonypi.c b/trunk/drivers/char/sonypi.c index 9b4f0116ff21..320debbe32fa 100644 --- a/trunk/drivers/char/sonypi.c +++ b/trunk/drivers/char/sonypi.c @@ -1456,7 +1456,7 @@ static int __devexit sonypi_remove(struct platform_device *dev) return 0; } -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM static int old_camera_power; static int sonypi_suspend(struct device *dev) diff --git a/trunk/drivers/clk/Kconfig b/trunk/drivers/clk/Kconfig index 823f62d900ba..bace9e98f75d 100644 --- a/trunk/drivers/clk/Kconfig +++ b/trunk/drivers/clk/Kconfig @@ -42,12 +42,10 @@ config COMMON_CLK_WM831X config COMMON_CLK_VERSATILE bool "Clock driver for ARM Reference designs" - depends on ARCH_INTEGRATOR || ARCH_REALVIEW || ARCH_VEXPRESS + depends on ARCH_INTEGRATOR || ARCH_REALVIEW ---help--- - Supports clocking on ARM Reference designs: - - Integrator/AP and Integrator/CP - - RealView PB1176, EB, PB11MP and PBX - - Versatile Express + Supports clocking on ARM Reference designs Integrator/AP, + Integrator/CP, RealView PB1176, EB, PB11MP and PBX. config COMMON_CLK_MAX77686 tristate "Clock driver for Maxim 77686 MFD" @@ -55,12 +53,4 @@ config COMMON_CLK_MAX77686 ---help--- This driver supports Maxim 77686 crystal oscillator clock. -config CLK_TWL6040 - tristate "External McPDM functional clock from twl6040" - depends on TWL6040_CORE - ---help--- - Enable the external functional clock support on OMAP4+ platforms for - McPDM. McPDM module is using the external bit clock on the McPDM bus - as functional clock. - endmenu diff --git a/trunk/drivers/clk/Makefile b/trunk/drivers/clk/Makefile index 2701235d5757..71a25b91de00 100644 --- a/trunk/drivers/clk/Makefile +++ b/trunk/drivers/clk/Makefile @@ -23,4 +23,3 @@ obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o # Chip specific obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o -obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o diff --git a/trunk/drivers/clk/clk-bcm2835.c b/trunk/drivers/clk/clk-bcm2835.c index b61ee2c5af84..67ad16b20b81 100644 --- a/trunk/drivers/clk/clk-bcm2835.c +++ b/trunk/drivers/clk/clk-bcm2835.c @@ -33,17 +33,17 @@ void __init bcm2835_init_clocks(void) clk = clk_register_fixed_rate(NULL, "sys_pclk", NULL, CLK_IS_ROOT, 250000000); - if (IS_ERR(clk)) + if (!clk) pr_err("sys_pclk not registered\n"); clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 126000000); - if (IS_ERR(clk)) + if (!clk) pr_err("apb_pclk not registered\n"); clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, CLK_IS_ROOT, 3000000); - if (IS_ERR(clk)) + if (!clk) pr_err("uart0_pclk not registered\n"); ret = clk_register_clkdev(clk, NULL, "20201000.uart"); if (ret) @@ -51,7 +51,7 @@ void __init bcm2835_init_clocks(void) clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, CLK_IS_ROOT, 125000000); - if (IS_ERR(clk)) + if (!clk) pr_err("uart1_pclk not registered\n"); ret = clk_register_clkdev(clk, NULL, "20215000.uart"); if (ret) diff --git a/trunk/drivers/clk/clk-fixed-rate.c b/trunk/drivers/clk/clk-fixed-rate.c index af78ed6b67ef..f5ec0eebd4d7 100644 --- a/trunk/drivers/clk/clk-fixed-rate.c +++ b/trunk/drivers/clk/clk-fixed-rate.c @@ -97,7 +97,7 @@ void __init of_fixed_clk_setup(struct device_node *node) of_property_read_string(node, "clock-output-names", &clk_name); clk = clk_register_fixed_rate(NULL, clk_name, NULL, CLK_IS_ROOT, rate); - if (!IS_ERR(clk)) + if (clk) of_clk_add_provider(node, of_clk_src_simple_get, clk); } EXPORT_SYMBOL_GPL(of_fixed_clk_setup); diff --git a/trunk/drivers/clk/clk-prima2.c b/trunk/drivers/clk/clk-prima2.c index a203ecccdc4f..517874fa6858 100644 --- a/trunk/drivers/clk/clk-prima2.c +++ b/trunk/drivers/clk/clk-prima2.c @@ -1054,118 +1054,118 @@ void __init sirfsoc_of_clk_init(void) /* These are always available (RTC and 26MHz OSC)*/ clk = clk_register_fixed_rate(NULL, "rtc", NULL, CLK_IS_ROOT, 32768); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk = clk_register_fixed_rate(NULL, "osc", NULL, CLK_IS_ROOT, 26000000); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk = clk_register(NULL, &clk_pll1.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk = clk_register(NULL, &clk_pll2.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk = clk_register(NULL, &clk_pll3.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk = clk_register(NULL, &clk_mem.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk = clk_register(NULL, &clk_sys.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk = clk_register(NULL, &clk_security.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b8030000.security"); clk = clk_register(NULL, &clk_dsp.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk = clk_register(NULL, &clk_gps.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "a8010000.gps"); clk = clk_register(NULL, &clk_mf.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk = clk_register(NULL, &clk_io.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "io"); clk = clk_register(NULL, &clk_cpu.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "cpu"); clk = clk_register(NULL, &clk_uart0.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b0050000.uart"); clk = clk_register(NULL, &clk_uart1.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b0060000.uart"); clk = clk_register(NULL, &clk_uart2.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b0070000.uart"); clk = clk_register(NULL, &clk_tsc.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b0110000.tsc"); clk = clk_register(NULL, &clk_i2c0.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b00e0000.i2c"); clk = clk_register(NULL, &clk_i2c1.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b00f0000.i2c"); clk = clk_register(NULL, &clk_spi0.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b00d0000.spi"); clk = clk_register(NULL, &clk_spi1.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b0170000.spi"); clk = clk_register(NULL, &clk_pwmc.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b0130000.pwm"); clk = clk_register(NULL, &clk_efuse.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b0140000.efusesys"); clk = clk_register(NULL, &clk_pulse.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b0150000.pulsec"); clk = clk_register(NULL, &clk_dmac0.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b00b0000.dma-controller"); clk = clk_register(NULL, &clk_dmac1.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b0160000.dma-controller"); clk = clk_register(NULL, &clk_nand.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b0030000.nand"); clk = clk_register(NULL, &clk_audio.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b0040000.audio"); clk = clk_register(NULL, &clk_usp0.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b0080000.usp"); clk = clk_register(NULL, &clk_usp1.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b0090000.usp"); clk = clk_register(NULL, &clk_usp2.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b00a0000.usp"); clk = clk_register(NULL, &clk_vip.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b00c0000.vip"); clk = clk_register(NULL, &clk_gfx.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "98000000.graphics"); clk = clk_register(NULL, &clk_mm.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "a0000000.multimedia"); clk = clk_register(NULL, &clk_lcd.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "90010000.display"); clk = clk_register(NULL, &clk_vpp.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "90020000.vpp"); clk = clk_register(NULL, &clk_mmc01.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk = clk_register(NULL, &clk_mmc23.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk = clk_register(NULL, &clk_mmc45.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk = clk_register(NULL, &usb_pll_clk_hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk = clk_register(NULL, &clk_usb0.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b00e0000.usb"); clk = clk_register(NULL, &clk_usb1.hw); - BUG_ON(IS_ERR(clk)); + BUG_ON(!clk); clk_register_clkdev(clk, NULL, "b00f0000.usb"); } diff --git a/trunk/drivers/clk/clk-twl6040.c b/trunk/drivers/clk/clk-twl6040.c deleted file mode 100644 index bc1e713e7b9c..000000000000 --- a/trunk/drivers/clk/clk-twl6040.c +++ /dev/null @@ -1,126 +0,0 @@ -/* -* TWL6040 clock module driver for OMAP4 McPDM functional clock -* -* Copyright (C) 2012 Texas Instruments Inc. -* Peter Ujfalusi -* -* 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 License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -* 02110-1301 USA -* -*/ - -#include -#include -#include -#include -#include -#include - -struct twl6040_clk { - struct twl6040 *twl6040; - struct device *dev; - struct clk_hw mcpdm_fclk; - struct clk *clk; - int enabled; -}; - -static int twl6040_bitclk_is_enabled(struct clk_hw *hw) -{ - struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk, - mcpdm_fclk); - return twl6040_clk->enabled; -} - -static int twl6040_bitclk_prepare(struct clk_hw *hw) -{ - struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk, - mcpdm_fclk); - int ret; - - ret = twl6040_power(twl6040_clk->twl6040, 1); - if (!ret) - twl6040_clk->enabled = 1; - - return ret; -} - -static void twl6040_bitclk_unprepare(struct clk_hw *hw) -{ - struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk, - mcpdm_fclk); - int ret; - - ret = twl6040_power(twl6040_clk->twl6040, 0); - if (!ret) - twl6040_clk->enabled = 0; -} - -static const struct clk_ops twl6040_mcpdm_ops = { - .is_enabled = twl6040_bitclk_is_enabled, - .prepare = twl6040_bitclk_prepare, - .unprepare = twl6040_bitclk_unprepare, -}; - -static struct clk_init_data wm831x_clkout_init = { - .name = "mcpdm_fclk", - .ops = &twl6040_mcpdm_ops, - .flags = CLK_IS_ROOT, -}; - -static int __devinit twl6040_clk_probe(struct platform_device *pdev) -{ - struct twl6040 *twl6040 = dev_get_drvdata(pdev->dev.parent); - struct twl6040_clk *clkdata; - - clkdata = devm_kzalloc(&pdev->dev, sizeof(*clkdata), GFP_KERNEL); - if (!clkdata) - return -ENOMEM; - - clkdata->dev = &pdev->dev; - clkdata->twl6040 = twl6040; - - clkdata->mcpdm_fclk.init = &wm831x_clkout_init; - clkdata->clk = clk_register(&pdev->dev, &clkdata->mcpdm_fclk); - if (IS_ERR(clkdata->clk)) - return PTR_ERR(clkdata->clk); - - dev_set_drvdata(&pdev->dev, clkdata); - - return 0; -} - -static int __devexit twl6040_clk_remove(struct platform_device *pdev) -{ - struct twl6040_clk *clkdata = dev_get_drvdata(&pdev->dev); - - clk_unregister(clkdata->clk); - - return 0; -} - -static struct platform_driver twl6040_clk_driver = { - .driver = { - .name = "twl6040-clk", - .owner = THIS_MODULE, - }, - .probe = twl6040_clk_probe, - .remove = __devexit_p(twl6040_clk_remove), -}; - -module_platform_driver(twl6040_clk_driver); - -MODULE_DESCRIPTION("TWL6040 clock driver for McPDM functional clock"); -MODULE_AUTHOR("Peter Ujfalusi "); -MODULE_ALIAS("platform:twl6040-clk"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/clk/clk-vt8500.c b/trunk/drivers/clk/clk-vt8500.c index fe25570874d6..a885600f5270 100644 --- a/trunk/drivers/clk/clk-vt8500.c +++ b/trunk/drivers/clk/clk-vt8500.c @@ -120,17 +120,8 @@ static unsigned long vt8500_dclk_recalc_rate(struct clk_hw *hw, static long vt8500_dclk_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) { - struct clk_device *cdev = to_clk_device(hw); u32 divisor = *prate / rate; - /* - * If this is a request for SDMMC we have to adjust the divisor - * when >31 to use the fixed predivisor - */ - if ((cdev->div_mask == 0x3F) && (divisor > 31)) { - divisor = 64 * ((divisor / 64) + 1); - } - return *prate / divisor; } @@ -144,15 +135,6 @@ static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate, if (divisor == cdev->div_mask + 1) divisor = 0; - /* SDMMC mask may need to be corrected before testing if its valid */ - if ((cdev->div_mask == 0x3F) && (divisor > 31)) { - /* - * Bit 5 is a fixed /64 predivisor. If the requested divisor - * is >31 then correct for the fixed divisor being required. - */ - divisor = 0x20 + (divisor / 64); - } - if (divisor > cdev->div_mask) { pr_err("%s: invalid divisor for clock\n", __func__); return -EINVAL; diff --git a/trunk/drivers/clk/clk-wm831x.c b/trunk/drivers/clk/clk-wm831x.c index db4fbf20ffd7..e7b7765e85f3 100644 --- a/trunk/drivers/clk/clk-wm831x.c +++ b/trunk/drivers/clk/clk-wm831x.c @@ -370,27 +370,43 @@ static __devinit int wm831x_clk_probe(struct platform_device *pdev) clkdata->xtal_ena = ret & WM831X_XTAL_ENA; clkdata->xtal_hw.init = &wm831x_xtal_init; - clkdata->xtal = devm_clk_register(&pdev->dev, &clkdata->xtal_hw); - if (IS_ERR(clkdata->xtal)) - return PTR_ERR(clkdata->xtal); + clkdata->xtal = clk_register(&pdev->dev, &clkdata->xtal_hw); + if (!clkdata->xtal) + return -EINVAL; clkdata->fll_hw.init = &wm831x_fll_init; - clkdata->fll = devm_clk_register(&pdev->dev, &clkdata->fll_hw); - if (IS_ERR(clkdata->fll)) - return PTR_ERR(clkdata->fll); + clkdata->fll = clk_register(&pdev->dev, &clkdata->fll_hw); + if (!clkdata->fll) { + ret = -EINVAL; + goto err_xtal; + } clkdata->clkout_hw.init = &wm831x_clkout_init; - clkdata->clkout = devm_clk_register(&pdev->dev, &clkdata->clkout_hw); - if (IS_ERR(clkdata->clkout)) - return PTR_ERR(clkdata->clkout); + clkdata->clkout = clk_register(&pdev->dev, &clkdata->clkout_hw); + if (!clkdata->clkout) { + ret = -EINVAL; + goto err_fll; + } dev_set_drvdata(&pdev->dev, clkdata); return 0; + +err_fll: + clk_unregister(clkdata->fll); +err_xtal: + clk_unregister(clkdata->xtal); + return ret; } static int __devexit wm831x_clk_remove(struct platform_device *pdev) { + struct wm831x_clk *clkdata = dev_get_drvdata(&pdev->dev); + + clk_unregister(clkdata->clkout); + clk_unregister(clkdata->fll); + clk_unregister(clkdata->xtal); + return 0; } diff --git a/trunk/drivers/clk/clk.c b/trunk/drivers/clk/clk.c index 251e45d6024d..56e4495ebeb1 100644 --- a/trunk/drivers/clk/clk.c +++ b/trunk/drivers/clk/clk.c @@ -17,7 +17,6 @@ #include #include #include -#include static DEFINE_SPINLOCK(enable_lock); static DEFINE_MUTEX(prepare_lock); @@ -219,17 +218,8 @@ static void clk_disable_unused_subtree(struct clk *clk) if (clk->flags & CLK_IGNORE_UNUSED) goto unlock_out; - /* - * some gate clocks have special needs during the disable-unused - * sequence. call .disable_unused if available, otherwise fall - * back to .disable - */ - if (__clk_is_enabled(clk)) { - if (clk->ops->disable_unused) - clk->ops->disable_unused(clk->hw); - else if (clk->ops->disable) - clk->ops->disable(clk->hw); - } + if (__clk_is_enabled(clk) && clk->ops->disable) + clk->ops->disable(clk->hw); unlock_out: spin_unlock_irqrestore(&enable_lock, flags); @@ -271,7 +261,7 @@ inline struct clk_hw *__clk_get_hw(struct clk *clk) inline u8 __clk_get_num_parents(struct clk *clk) { - return !clk ? 0 : clk->num_parents; + return !clk ? -EINVAL : clk->num_parents; } inline struct clk *__clk_get_parent(struct clk *clk) @@ -279,14 +269,14 @@ inline struct clk *__clk_get_parent(struct clk *clk) return !clk ? NULL : clk->parent; } -inline unsigned int __clk_get_enable_count(struct clk *clk) +inline int __clk_get_enable_count(struct clk *clk) { - return !clk ? 0 : clk->enable_count; + return !clk ? -EINVAL : clk->enable_count; } -inline unsigned int __clk_get_prepare_count(struct clk *clk) +inline int __clk_get_prepare_count(struct clk *clk) { - return !clk ? 0 : clk->prepare_count; + return !clk ? -EINVAL : clk->prepare_count; } unsigned long __clk_get_rate(struct clk *clk) @@ -312,15 +302,15 @@ unsigned long __clk_get_rate(struct clk *clk) inline unsigned long __clk_get_flags(struct clk *clk) { - return !clk ? 0 : clk->flags; + return !clk ? -EINVAL : clk->flags; } -bool __clk_is_enabled(struct clk *clk) +int __clk_is_enabled(struct clk *clk) { int ret; if (!clk) - return false; + return -EINVAL; /* * .is_enabled is only mandatory for clocks that gate @@ -333,7 +323,7 @@ bool __clk_is_enabled(struct clk *clk) ret = clk->ops->is_enabled(clk->hw); out: - return !!ret; + return ret; } static struct clk *__clk_lookup_subtree(const char *name, struct clk *clk) @@ -578,7 +568,7 @@ unsigned long __clk_round_rate(struct clk *clk, unsigned long rate) unsigned long parent_rate = 0; if (!clk) - return 0; + return -EINVAL; if (!clk->ops->round_rate) { if (clk->flags & CLK_SET_RATE_PARENT) @@ -1307,20 +1297,12 @@ int __clk_init(struct device *dev, struct clk *clk) * walk the list of orphan clocks and reparent any that are children of * this clock */ - hlist_for_each_entry_safe(orphan, tmp, tmp2, &clk_orphan_list, child_node) { - if (orphan->ops->get_parent) { - i = orphan->ops->get_parent(orphan->hw); - if (!strcmp(clk->name, orphan->parent_names[i])) - __clk_reparent(orphan, clk); - continue; - } - + hlist_for_each_entry_safe(orphan, tmp, tmp2, &clk_orphan_list, child_node) for (i = 0; i < orphan->num_parents; i++) if (!strcmp(clk->name, orphan->parent_names[i])) { __clk_reparent(orphan, clk); break; } - } /* * optional platform-specific magic @@ -1379,9 +1361,28 @@ struct clk *__clk_register(struct device *dev, struct clk_hw *hw) } EXPORT_SYMBOL_GPL(__clk_register); -static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) +/** + * clk_register - allocate a new clock, register it and return an opaque cookie + * @dev: device that is registering this clock + * @hw: link to hardware-specific clock data + * + * clk_register is the primary interface for populating the clock tree with new + * clock nodes. It returns a pointer to the newly allocated struct clk which + * cannot be dereferenced by driver code but may be used in conjuction with the + * rest of the clock API. In the event of an error clk_register will return an + * error code; drivers must test for an error code after calling clk_register. + */ +struct clk *clk_register(struct device *dev, struct clk_hw *hw) { int i, ret; + struct clk *clk; + + clk = kzalloc(sizeof(*clk), GFP_KERNEL); + if (!clk) { + pr_err("%s: could not allocate clk\n", __func__); + ret = -ENOMEM; + goto fail_out; + } clk->name = kstrdup(hw->init->name, GFP_KERNEL); if (!clk->name) { @@ -1419,7 +1420,7 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) ret = __clk_init(dev, clk); if (!ret) - return 0; + return clk; fail_parent_names_copy: while (--i >= 0) @@ -1428,36 +1429,6 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) fail_parent_names: kfree(clk->name); fail_name: - return ret; -} - -/** - * clk_register - allocate a new clock, register it and return an opaque cookie - * @dev: device that is registering this clock - * @hw: link to hardware-specific clock data - * - * clk_register is the primary interface for populating the clock tree with new - * clock nodes. It returns a pointer to the newly allocated struct clk which - * cannot be dereferenced by driver code but may be used in conjuction with the - * rest of the clock API. In the event of an error clk_register will return an - * error code; drivers must test for an error code after calling clk_register. - */ -struct clk *clk_register(struct device *dev, struct clk_hw *hw) -{ - int ret; - struct clk *clk; - - clk = kzalloc(sizeof(*clk), GFP_KERNEL); - if (!clk) { - pr_err("%s: could not allocate clk\n", __func__); - ret = -ENOMEM; - goto fail_out; - } - - ret = _clk_register(dev, hw, clk); - if (!ret) - return clk; - kfree(clk); fail_out: return ERR_PTR(ret); @@ -1473,63 +1444,6 @@ EXPORT_SYMBOL_GPL(clk_register); void clk_unregister(struct clk *clk) {} EXPORT_SYMBOL_GPL(clk_unregister); -static void devm_clk_release(struct device *dev, void *res) -{ - clk_unregister(res); -} - -/** - * devm_clk_register - resource managed clk_register() - * @dev: device that is registering this clock - * @hw: link to hardware-specific clock data - * - * Managed clk_register(). Clocks returned from this function are - * automatically clk_unregister()ed on driver detach. See clk_register() for - * more information. - */ -struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw) -{ - struct clk *clk; - int ret; - - clk = devres_alloc(devm_clk_release, sizeof(*clk), GFP_KERNEL); - if (!clk) - return ERR_PTR(-ENOMEM); - - ret = _clk_register(dev, hw, clk); - if (!ret) { - devres_add(dev, clk); - } else { - devres_free(clk); - clk = ERR_PTR(ret); - } - - return clk; -} -EXPORT_SYMBOL_GPL(devm_clk_register); - -static int devm_clk_match(struct device *dev, void *res, void *data) -{ - struct clk *c = res; - if (WARN_ON(!c)) - return 0; - return c == data; -} - -/** - * devm_clk_unregister - resource managed clk_unregister() - * @clk: clock to unregister - * - * Deallocate a clock allocated with devm_clk_register(). Normally - * this function will not need to be called and the resource management - * code will ensure that the resource is freed. - */ -void devm_clk_unregister(struct device *dev, struct clk *clk) -{ - WARN_ON(devres_release(dev, devm_clk_release, devm_clk_match, clk)); -} -EXPORT_SYMBOL_GPL(devm_clk_unregister); - /*** clk rate change notifiers ***/ /** diff --git a/trunk/drivers/clk/mxs/clk-imx23.c b/trunk/drivers/clk/mxs/clk-imx23.c index 8dd476e2a9c5..f00dffb9ad60 100644 --- a/trunk/drivers/clk/mxs/clk-imx23.c +++ b/trunk/drivers/clk/mxs/clk-imx23.c @@ -85,7 +85,7 @@ enum imx23_clk { cpu_xtal, hbus, xbus, lcdif_div, ssp_div, gpmi_div, emi_pll, emi_xtal, etm_div, saif_div, clk32k_div, rtc, adc, spdif_div, clk32k, dri, pwm, filt, uart, ssp, gpmi, spdif, emi, saif, - lcdif, etm, usb, usb_phy, + lcdif, etm, usb, usb_pwr, clk_max }; @@ -143,8 +143,8 @@ int __init mx23_clocks_init(void) clks[saif] = mxs_clk_gate("saif", "saif_div", SAIF, 31); clks[lcdif] = mxs_clk_gate("lcdif", "lcdif_div", PIX, 31); clks[etm] = mxs_clk_gate("etm", "etm_div", ETM, 31); - clks[usb] = mxs_clk_gate("usb", "usb_phy", DIGCTRL, 2); - clks[usb_phy] = clk_register_gate(NULL, "usb_phy", "pll", 0, PLLCTRL0, 18, 0, &mxs_lock); + clks[usb] = mxs_clk_gate("usb", "usb_pwr", DIGCTRL, 2); + clks[usb_pwr] = clk_register_gate(NULL, "usb_pwr", "pll", 0, PLLCTRL0, 18, 0, &mxs_lock); for (i = 0; i < ARRAY_SIZE(clks); i++) if (IS_ERR(clks[i])) { diff --git a/trunk/drivers/clk/mxs/clk-imx28.c b/trunk/drivers/clk/mxs/clk-imx28.c index db3af0874121..42978f1b4bd2 100644 --- a/trunk/drivers/clk/mxs/clk-imx28.c +++ b/trunk/drivers/clk/mxs/clk-imx28.c @@ -140,7 +140,7 @@ enum imx28_clk { emi_xtal, lcdif_div, etm_div, ptp, saif0_div, saif1_div, clk32k_div, rtc, lradc, spdif_div, clk32k, pwm, uart, ssp0, ssp1, ssp2, ssp3, gpmi, spdif, emi, saif0, saif1, lcdif, etm, - fec, can0, can1, usb0, usb1, usb0_phy, usb1_phy, enet_out, + fec, can0, can1, usb0, usb1, usb0_pwr, usb1_pwr, enet_out, clk_max }; @@ -218,10 +218,10 @@ int __init mx28_clocks_init(void) clks[fec] = mxs_clk_gate("fec", "hbus", ENET, 30); clks[can0] = mxs_clk_gate("can0", "ref_xtal", FLEXCAN, 30); clks[can1] = mxs_clk_gate("can1", "ref_xtal", FLEXCAN, 28); - clks[usb0] = mxs_clk_gate("usb0", "usb0_phy", DIGCTRL, 2); - clks[usb1] = mxs_clk_gate("usb1", "usb1_phy", DIGCTRL, 16); - clks[usb0_phy] = clk_register_gate(NULL, "usb0_phy", "pll0", 0, PLL0CTRL0, 18, 0, &mxs_lock); - clks[usb1_phy] = clk_register_gate(NULL, "usb1_phy", "pll1", 0, PLL1CTRL0, 18, 0, &mxs_lock); + clks[usb0] = mxs_clk_gate("usb0", "usb0_pwr", DIGCTRL, 2); + clks[usb1] = mxs_clk_gate("usb1", "usb1_pwr", DIGCTRL, 16); + clks[usb0_pwr] = clk_register_gate(NULL, "usb0_pwr", "pll0", 0, PLL0CTRL0, 18, 0, &mxs_lock); + clks[usb1_pwr] = clk_register_gate(NULL, "usb1_pwr", "pll1", 0, PLL1CTRL0, 18, 0, &mxs_lock); clks[enet_out] = clk_register_gate(NULL, "enet_out", "pll2", 0, ENET, 18, 0, &mxs_lock); for (i = 0; i < ARRAY_SIZE(clks); i++) diff --git a/trunk/drivers/clk/spear/clk-aux-synth.c b/trunk/drivers/clk/spear/clk-aux-synth.c index bdfb4421c643..6756e7c3bc07 100644 --- a/trunk/drivers/clk/spear/clk-aux-synth.c +++ b/trunk/drivers/clk/spear/clk-aux-synth.c @@ -179,8 +179,7 @@ struct clk *clk_register_aux(const char *aux_name, const char *gate_name, if (gate_name) { struct clk *tgate_clk; - tgate_clk = clk_register_gate(NULL, gate_name, aux_name, - CLK_SET_RATE_PARENT, reg, + tgate_clk = clk_register_gate(NULL, gate_name, aux_name, 0, reg, aux->masks->enable_bit, 0, lock); if (IS_ERR_OR_NULL(tgate_clk)) goto free_aux; diff --git a/trunk/drivers/clk/spear/clk-vco-pll.c b/trunk/drivers/clk/spear/clk-vco-pll.c index 1b9b65bca51e..5f1b6badeb15 100644 --- a/trunk/drivers/clk/spear/clk-vco-pll.c +++ b/trunk/drivers/clk/spear/clk-vco-pll.c @@ -147,7 +147,7 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long drate, struct clk_pll *pll = to_clk_pll(hw); struct pll_rate_tbl *rtbl = pll->vco->rtbl; unsigned long flags = 0, val; - int uninitialized_var(i); + int i; clk_pll_round_rate_index(hw, drate, NULL, &i); diff --git a/trunk/drivers/clk/spear/clk.c b/trunk/drivers/clk/spear/clk.c index 628b6d5ed3d9..7cd63788d546 100644 --- a/trunk/drivers/clk/spear/clk.c +++ b/trunk/drivers/clk/spear/clk.c @@ -32,8 +32,5 @@ long clk_round_rate_index(struct clk_hw *hw, unsigned long drate, } } - if ((*index) == rtbl_cnt) - (*index)--; - return rate; } diff --git a/trunk/drivers/clk/spear/spear1310_clock.c b/trunk/drivers/clk/spear/spear1310_clock.c index 147e25f00405..0fcec2aae19c 100644 --- a/trunk/drivers/clk/spear/spear1310_clock.c +++ b/trunk/drivers/clk/spear/spear1310_clock.c @@ -313,20 +313,6 @@ static struct aux_clk_masks i2s_sclk_masks = { /* i2s prs1 aux rate configuration table, in ascending order of rates */ static struct aux_rate_tbl i2s_prs1_rtbl[] = { /* For parent clk = 49.152 MHz */ - {.xscale = 1, .yscale = 12, .eq = 0}, /* 2.048 MHz, smp freq = 8Khz */ - {.xscale = 11, .yscale = 96, .eq = 0}, /* 2.816 MHz, smp freq = 11Khz */ - {.xscale = 1, .yscale = 6, .eq = 0}, /* 4.096 MHz, smp freq = 16Khz */ - {.xscale = 11, .yscale = 48, .eq = 0}, /* 5.632 MHz, smp freq = 22Khz */ - - /* - * with parent clk = 49.152, freq gen is 8.192 MHz, smp freq = 32Khz - * with parent clk = 12.288, freq gen is 2.048 MHz, smp freq = 8Khz - */ - {.xscale = 1, .yscale = 3, .eq = 0}, - - /* For parent clk = 49.152 MHz */ - {.xscale = 17, .yscale = 37, .eq = 0}, /* 11.289 MHz, smp freq = 44Khz*/ - {.xscale = 1, .yscale = 2, .eq = 0}, /* 12.288 MHz */ }; @@ -388,6 +374,9 @@ void __init spear1310_clk_init(void) { struct clk *clk, *clk1; + clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0); + clk_register_clkdev(clk, "apb_pclk", NULL); + clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT, 32000); clk_register_clkdev(clk, "osc_32k_clk", NULL); @@ -412,7 +401,7 @@ void __init spear1310_clk_init(void) clk = clk_register_gate(NULL, "rtc-spear", "osc_32k_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_RTC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e0580000.rtc"); + clk_register_clkdev(clk, NULL, "fc900000.rtc"); /* clock derived from 24 or 25 MHz osc clk */ /* vco-pll */ @@ -494,18 +483,13 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk, "ddr_clk", NULL); /* clock derived from pll1 clk */ - clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk", - CLK_SET_RATE_PARENT, 1, 2); + clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk", 0, 1, 2); clk_register_clkdev(clk, "cpu_clk", NULL); clk = clk_register_fixed_factor(NULL, "wdt_clk", "cpu_clk", 0, 1, 2); clk_register_clkdev(clk, NULL, "ec800620.wdt"); - clk = clk_register_fixed_factor(NULL, "smp_twd_clk", "cpu_clk", 0, 1, - 2); - clk_register_clkdev(clk, NULL, "smp_twd"); - clk = clk_register_fixed_factor(NULL, "ahb_clk", "pll1_clk", 0, 1, 6); clk_register_clkdev(clk, "ahb_clk", NULL); @@ -563,14 +547,14 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk1, "uart_syn_gclk", NULL); clk = clk_register_mux(NULL, "uart0_mclk", uart0_parents, - ARRAY_SIZE(uart0_parents), CLK_SET_RATE_PARENT, - SPEAR1310_PERIP_CLK_CFG, SPEAR1310_UART_CLK_SHIFT, - SPEAR1310_UART_CLK_MASK, 0, &_lock); + ARRAY_SIZE(uart0_parents), 0, SPEAR1310_PERIP_CLK_CFG, + SPEAR1310_UART_CLK_SHIFT, SPEAR1310_UART_CLK_MASK, 0, + &_lock); clk_register_clkdev(clk, "uart0_mclk", NULL); - clk = clk_register_gate(NULL, "uart0_clk", "uart0_mclk", - CLK_SET_RATE_PARENT, SPEAR1310_PERIP1_CLK_ENB, - SPEAR1310_UART_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "uart0_clk", "uart0_mclk", 0, + SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_UART_CLK_ENB, 0, + &_lock); clk_register_clkdev(clk, NULL, "e0000000.serial"); clk = clk_register_aux("sdhci_syn_clk", "sdhci_syn_gclk", @@ -579,9 +563,9 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk, "sdhci_syn_clk", NULL); clk_register_clkdev(clk1, "sdhci_syn_gclk", NULL); - clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_syn_gclk", - CLK_SET_RATE_PARENT, SPEAR1310_PERIP1_CLK_ENB, - SPEAR1310_SDHCI_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_syn_gclk", 0, + SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_SDHCI_CLK_ENB, 0, + &_lock); clk_register_clkdev(clk, NULL, "b3000000.sdhci"); clk = clk_register_aux("cfxd_syn_clk", "cfxd_syn_gclk", "vco1div2_clk", @@ -590,9 +574,9 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk, "cfxd_syn_clk", NULL); clk_register_clkdev(clk1, "cfxd_syn_gclk", NULL); - clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_syn_gclk", - CLK_SET_RATE_PARENT, SPEAR1310_PERIP1_CLK_ENB, - SPEAR1310_CFXD_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_syn_gclk", 0, + SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_CFXD_CLK_ENB, 0, + &_lock); clk_register_clkdev(clk, NULL, "b2800000.cf"); clk_register_clkdev(clk, NULL, "arasan_xd"); @@ -603,9 +587,9 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk1, "c3_syn_gclk", NULL); clk = clk_register_mux(NULL, "c3_mclk", c3_parents, - ARRAY_SIZE(c3_parents), CLK_SET_RATE_PARENT, - SPEAR1310_PERIP_CLK_CFG, SPEAR1310_C3_CLK_SHIFT, - SPEAR1310_C3_CLK_MASK, 0, &_lock); + ARRAY_SIZE(c3_parents), 0, SPEAR1310_PERIP_CLK_CFG, + SPEAR1310_C3_CLK_SHIFT, SPEAR1310_C3_CLK_MASK, 0, + &_lock); clk_register_clkdev(clk, "c3_mclk", NULL); clk = clk_register_gate(NULL, "c3_clk", "c3_mclk", 0, @@ -631,7 +615,7 @@ void __init spear1310_clk_init(void) ARRAY_SIZE(gmac_phy_parents), 0, SPEAR1310_PERIP_CLK_CFG, SPEAR1310_GMAC_PHY_CLK_SHIFT, SPEAR1310_GMAC_PHY_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "stmmacphy.0", NULL); + clk_register_clkdev(clk, NULL, "stmmacphy.0"); /* clcd */ clk = clk_register_mux(NULL, "clcd_syn_mclk", clcd_synth_parents, @@ -646,22 +630,22 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk, "clcd_syn_clk", NULL); clk = clk_register_mux(NULL, "clcd_pixel_mclk", clcd_pixel_parents, - ARRAY_SIZE(clcd_pixel_parents), CLK_SET_RATE_PARENT, + ARRAY_SIZE(clcd_pixel_parents), 0, SPEAR1310_PERIP_CLK_CFG, SPEAR1310_CLCD_CLK_SHIFT, SPEAR1310_CLCD_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "clcd_pixel_mclk", NULL); + clk_register_clkdev(clk, "clcd_pixel_clk", NULL); clk = clk_register_gate(NULL, "clcd_clk", "clcd_pixel_mclk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_CLCD_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e1000000.clcd"); + clk_register_clkdev(clk, "clcd_clk", NULL); /* i2s */ clk = clk_register_mux(NULL, "i2s_src_mclk", i2s_src_parents, ARRAY_SIZE(i2s_src_parents), 0, SPEAR1310_I2S_CLK_CFG, SPEAR1310_I2S_SRC_CLK_SHIFT, SPEAR1310_I2S_SRC_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "i2s_src_mclk", NULL); + clk_register_clkdev(clk, "i2s_src_clk", NULL); clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mclk", 0, SPEAR1310_I2S_CLK_CFG, &i2s_prs1_masks, i2s_prs1_rtbl, @@ -669,10 +653,10 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk, "i2s_prs1_clk", NULL); clk = clk_register_mux(NULL, "i2s_ref_mclk", i2s_ref_parents, - ARRAY_SIZE(i2s_ref_parents), CLK_SET_RATE_PARENT, - SPEAR1310_I2S_CLK_CFG, SPEAR1310_I2S_REF_SHIFT, - SPEAR1310_I2S_REF_SEL_MASK, 0, &_lock); - clk_register_clkdev(clk, "i2s_ref_mclk", NULL); + ARRAY_SIZE(i2s_ref_parents), 0, SPEAR1310_I2S_CLK_CFG, + SPEAR1310_I2S_REF_SHIFT, SPEAR1310_I2S_REF_SEL_MASK, 0, + &_lock); + clk_register_clkdev(clk, "i2s_ref_clk", NULL); clk = clk_register_gate(NULL, "i2s_ref_pad_clk", "i2s_ref_mclk", 0, SPEAR1310_PERIP2_CLK_ENB, SPEAR1310_I2S_REF_PAD_CLK_ENB, @@ -680,7 +664,7 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk, "i2s_ref_pad_clk", NULL); clk = clk_register_aux("i2s_sclk_clk", "i2s_sclk_gclk", - "i2s_ref_mclk", 0, SPEAR1310_I2S_CLK_CFG, + "i2s_ref_pad_clk", 0, SPEAR1310_I2S_CLK_CFG, &i2s_sclk_masks, i2s_sclk_rtbl, ARRAY_SIZE(i2s_sclk_rtbl), &_lock, &clk1); clk_register_clkdev(clk, "i2s_sclk_clk", NULL); @@ -721,37 +705,35 @@ void __init spear1310_clk_init(void) clk = clk_register_gate(NULL, "usbh0_clk", "ahb_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_UHC0_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e4000000.ohci"); - clk_register_clkdev(clk, NULL, "e4800000.ehci"); + clk_register_clkdev(clk, "usbh.0_clk", NULL); clk = clk_register_gate(NULL, "usbh1_clk", "ahb_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_UHC1_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e5000000.ohci"); - clk_register_clkdev(clk, NULL, "e5800000.ehci"); + clk_register_clkdev(clk, "usbh.1_clk", NULL); clk = clk_register_gate(NULL, "uoc_clk", "ahb_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_UOC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e3800000.otg"); + clk_register_clkdev(clk, NULL, "uoc"); clk = clk_register_gate(NULL, "pcie_sata_0_clk", "ahb_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_0_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "dw_pcie.0"); - clk_register_clkdev(clk, NULL, "b1000000.ahci"); + clk_register_clkdev(clk, NULL, "ahci.0"); clk = clk_register_gate(NULL, "pcie_sata_1_clk", "ahb_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_1_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "dw_pcie.1"); - clk_register_clkdev(clk, NULL, "b1800000.ahci"); + clk_register_clkdev(clk, NULL, "ahci.1"); clk = clk_register_gate(NULL, "pcie_sata_2_clk", "ahb_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_2_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "dw_pcie.2"); - clk_register_clkdev(clk, NULL, "b4000000.ahci"); + clk_register_clkdev(clk, NULL, "ahci.2"); clk = clk_register_gate(NULL, "sysram0_clk", "ahb_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_SYSRAM0_CLK_ENB, 0, @@ -769,10 +751,10 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk, "adc_syn_clk", NULL); clk_register_clkdev(clk1, "adc_syn_gclk", NULL); - clk = clk_register_gate(NULL, "adc_clk", "adc_syn_gclk", - CLK_SET_RATE_PARENT, SPEAR1310_PERIP1_CLK_ENB, - SPEAR1310_ADC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e0080000.adc"); + clk = clk_register_gate(NULL, "adc_clk", "adc_syn_gclk", 0, + SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_ADC_CLK_ENB, 0, + &_lock); + clk_register_clkdev(clk, NULL, "adc_clk"); /* clock derived from apb clk */ clk = clk_register_gate(NULL, "ssp0_clk", "apb_clk", 0, @@ -934,15 +916,15 @@ void __init spear1310_clk_init(void) SPEAR1310_RAS_CTRL_REG1, SPEAR1310_SMII_RGMII_PHY_CLK_SHIFT, SPEAR1310_PHY_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "stmmacphy.1", NULL); - clk_register_clkdev(clk, "stmmacphy.2", NULL); - clk_register_clkdev(clk, "stmmacphy.4", NULL); + clk_register_clkdev(clk, NULL, "stmmacphy.1"); + clk_register_clkdev(clk, NULL, "stmmacphy.2"); + clk_register_clkdev(clk, NULL, "stmmacphy.4"); clk = clk_register_mux(NULL, "rmii_phy_mclk", rmii_phy_parents, ARRAY_SIZE(rmii_phy_parents), 0, SPEAR1310_RAS_CTRL_REG1, SPEAR1310_RMII_PHY_CLK_SHIFT, SPEAR1310_PHY_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "stmmacphy.3", NULL); + clk_register_clkdev(clk, NULL, "stmmacphy.3"); clk = clk_register_mux(NULL, "uart1_mclk", uart_parents, ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0, diff --git a/trunk/drivers/clk/spear/spear1340_clock.c b/trunk/drivers/clk/spear/spear1340_clock.c index 82abea366b78..2352cee7f645 100644 --- a/trunk/drivers/clk/spear/spear1340_clock.c +++ b/trunk/drivers/clk/spear/spear1340_clock.c @@ -190,7 +190,6 @@ static struct pll_rate_tbl pll4_rtbl[] = { * different values of vco1div2 */ static struct frac_rate_tbl amba_synth_rtbl[] = { - {.div = 0x073A8}, /* for vco1div2 = 600 MHz */ {.div = 0x06062}, /* for vco1div2 = 500 MHz */ {.div = 0x04D1B}, /* for vco1div2 = 400 MHz */ {.div = 0x04000}, /* for vco1div2 = 332 MHz */ @@ -221,12 +220,6 @@ static struct frac_rate_tbl amba_synth_rtbl[] = { * 500 400 200 0x02800 * 500 500 250 0x02000 * -------------------------------------------------------------------- - * 600 200 100 0x06000 - * 600 250 125 0x04CCE - * 600 332 166 0x039D5 - * 600 400 200 0x03000 - * 600 500 250 0x02666 - * -------------------------------------------------------------------- * 664 200 100 0x06a38 * 664 250 125 0x054FD * 664 332 166 0x04000 @@ -245,50 +238,28 @@ static struct frac_rate_tbl sys_synth_rtbl[] = { {.div = 0x08000}, {.div = 0x06a38}, {.div = 0x06666}, - {.div = 0x06000}, {.div = 0x054FD}, {.div = 0x05000}, {.div = 0x04D18}, - {.div = 0x04CCE}, {.div = 0x04000}, - {.div = 0x039D5}, {.div = 0x0351E}, {.div = 0x03333}, {.div = 0x03031}, - {.div = 0x03000}, {.div = 0x02A7E}, {.div = 0x02800}, {.div = 0x0268D}, - {.div = 0x02666}, {.div = 0x02000}, }; /* aux rate configuration table, in ascending order of rates */ static struct aux_rate_tbl aux_rtbl[] = { - /* 12.29MHz for vic1div2=600MHz and 10.24MHz for VCO1div2=500MHz */ - {.xscale = 5, .yscale = 122, .eq = 0}, - /* 14.70MHz for vic1div2=600MHz and 12.29MHz for VCO1div2=500MHz */ - {.xscale = 10, .yscale = 204, .eq = 0}, - /* 48MHz for vic1div2=600MHz and 40 MHz for VCO1div2=500MHz */ - {.xscale = 4, .yscale = 25, .eq = 0}, - /* 57.14MHz for vic1div2=600MHz and 48 MHz for VCO1div2=500MHz */ - {.xscale = 4, .yscale = 21, .eq = 0}, - /* 83.33MHz for vic1div2=600MHz and 69.44MHz for VCO1div2=500MHz */ - {.xscale = 5, .yscale = 18, .eq = 0}, - /* 100MHz for vic1div2=600MHz and 83.33 MHz for VCO1div2=500MHz */ - {.xscale = 2, .yscale = 6, .eq = 0}, - /* 125MHz for vic1div2=600MHz and 104.1MHz for VCO1div2=500MHz */ - {.xscale = 5, .yscale = 12, .eq = 0}, - /* 150MHz for vic1div2=600MHz and 125MHz for VCO1div2=500MHz */ - {.xscale = 2, .yscale = 4, .eq = 0}, - /* 166MHz for vic1div2=600MHz and 138.88MHz for VCO1div2=500MHz */ - {.xscale = 5, .yscale = 18, .eq = 1}, - /* 200MHz for vic1div2=600MHz and 166MHz for VCO1div2=500MHz */ - {.xscale = 1, .yscale = 3, .eq = 1}, - /* 250MHz for vic1div2=600MHz and 208.33MHz for VCO1div2=500MHz */ - {.xscale = 5, .yscale = 12, .eq = 1}, - /* 300MHz for vic1div2=600MHz and 250MHz for VCO1div2=500MHz */ - {.xscale = 1, .yscale = 2, .eq = 1}, + /* For VCO1div2 = 500 MHz */ + {.xscale = 10, .yscale = 204, .eq = 0}, /* 12.29 MHz */ + {.xscale = 4, .yscale = 21, .eq = 0}, /* 48 MHz */ + {.xscale = 2, .yscale = 6, .eq = 0}, /* 83 MHz */ + {.xscale = 2, .yscale = 4, .eq = 0}, /* 125 MHz */ + {.xscale = 1, .yscale = 3, .eq = 1}, /* 166 MHz */ + {.xscale = 1, .yscale = 2, .eq = 1}, /* 250 MHz */ }; /* gmac rate configuration table, in ascending order of rates */ @@ -302,23 +273,16 @@ static struct aux_rate_tbl gmac_rtbl[] = { /* clcd rate configuration table, in ascending order of rates */ static struct frac_rate_tbl clcd_rtbl[] = { - {.div = 0x18000}, /* 25 Mhz , for vc01div4 = 300 MHz*/ - {.div = 0x1638E}, /* 27 Mhz , for vc01div4 = 300 MHz*/ {.div = 0x14000}, /* 25 Mhz , for vc01div4 = 250 MHz*/ {.div = 0x1284B}, /* 27 Mhz , for vc01div4 = 250 MHz*/ {.div = 0x0D8D3}, /* 58 Mhz , for vco1div4 = 393 MHz */ {.div = 0x0B72C}, /* 58 Mhz , for vco1div4 = 332 MHz */ - {.div = 0x0A584}, /* 58 Mhz , for vco1div4 = 300 MHz */ - {.div = 0x093B1}, /* 65 Mhz , for vc01div4 = 300 MHz*/ {.div = 0x089EE}, /* 58 Mhz , for vc01div4 = 250 MHz*/ - {.div = 0x081BA}, /* 74 Mhz , for vc01div4 = 300 MHz*/ {.div = 0x07BA0}, /* 65 Mhz , for vc01div4 = 250 MHz*/ {.div = 0x06f1C}, /* 72 Mhz , for vc01div4 = 250 MHz*/ {.div = 0x06E58}, /* 58 Mhz , for vco1div4 = 200 MHz */ {.div = 0x06c1B}, /* 74 Mhz , for vc01div4 = 250 MHz*/ - {.div = 0x058E3}, /* 108 Mhz , for vc01div4 = 300 MHz*/ {.div = 0x04A12}, /* 108 Mhz , for vc01div4 = 250 MHz*/ - {.div = 0x040A5}, /* 148.5 Mhz , for vc01div4 = 300 MHz*/ {.div = 0x0378E}, /* 144 Mhz , for vc01div4 = 250 MHz*/ {.div = 0x0360D}, /* 148 Mhz , for vc01div4 = 250 MHz*/ {.div = 0x035E0}, /* 148.5 MHz, for vc01div4 = 250 MHz*/ @@ -387,37 +351,26 @@ static struct aux_rate_tbl adc_rtbl[] = { /* General synth rate configuration table, in ascending order of rates */ static struct frac_rate_tbl gen_rtbl[] = { - {.div = 0x1A92B}, /* 22.5792 MHz for vco1div4=300 MHz*/ - {.div = 0x186A0}, /* 24.576 MHz for vco1div4=300 MHz*/ - {.div = 0x18000}, /* 25 MHz for vco1div4=300 MHz*/ - {.div = 0x1624E}, /* 22.5792 MHz for vco1div4=250 MHz*/ - {.div = 0x14585}, /* 24.576 MHz for vco1div4=250 MHz*/ - {.div = 0x14000}, /* 25 MHz for vco1div4=250 MHz*/ - {.div = 0x0D495}, /* 45.1584 MHz for vco1div4=300 MHz*/ - {.div = 0x0C000}, /* 50 MHz for vco1div4=300 MHz*/ - {.div = 0x0B127}, /* 45.1584 MHz for vco1div4=250 MHz*/ - {.div = 0x0A000}, /* 50 MHz for vco1div4=250 MHz*/ - {.div = 0x07530}, /* 81.92 MHz for vco1div4=300 MHz*/ - {.div = 0x061A8}, /* 81.92 MHz for vco1div4=250 MHz*/ - {.div = 0x06000}, /* 100 MHz for vco1div4=300 MHz*/ - {.div = 0x05000}, /* 100 MHz for vco1div4=250 MHz*/ - {.div = 0x03000}, /* 200 MHz for vco1div4=300 MHz*/ - {.div = 0x02DB6}, /* 210 MHz for vco1div4=300 MHz*/ - {.div = 0x02BA2}, /* 220 MHz for vco1div4=300 MHz*/ - {.div = 0x029BD}, /* 230 MHz for vco1div4=300 MHz*/ - {.div = 0x02800}, /* 200 MHz for vco1div4=250 MHz*/ - {.div = 0x02666}, /* 250 MHz for vco1div4=300 MHz*/ - {.div = 0x02620}, /* 210 MHz for vco1div4=250 MHz*/ - {.div = 0x02460}, /* 220 MHz for vco1div4=250 MHz*/ - {.div = 0x022C0}, /* 230 MHz for vco1div4=250 MHz*/ - {.div = 0x02160}, /* 240 MHz for vco1div4=250 MHz*/ - {.div = 0x02000}, /* 250 MHz for vco1div4=250 MHz*/ + /* For vco1div4 = 250 MHz */ + {.div = 0x1624E}, /* 22.5792 MHz */ + {.div = 0x14585}, /* 24.576 MHz */ + {.div = 0x14000}, /* 25 MHz */ + {.div = 0x0B127}, /* 45.1584 MHz */ + {.div = 0x0A000}, /* 50 MHz */ + {.div = 0x061A8}, /* 81.92 MHz */ + {.div = 0x05000}, /* 100 MHz */ + {.div = 0x02800}, /* 200 MHz */ + {.div = 0x02620}, /* 210 MHz */ + {.div = 0x02460}, /* 220 MHz */ + {.div = 0x022C0}, /* 230 MHz */ + {.div = 0x02160}, /* 240 MHz */ + {.div = 0x02000}, /* 250 MHz */ }; /* clock parents */ static const char *vco_parents[] = { "osc_24m_clk", "osc_25m_clk", }; static const char *sys_parents[] = { "pll1_clk", "pll1_clk", "pll1_clk", - "pll1_clk", "sys_syn_clk", "sys_syn_clk", "pll2_clk", "pll3_clk", }; + "pll1_clk", "sys_synth_clk", "sys_synth_clk", "pll2_clk", "pll3_clk", }; static const char *ahb_parents[] = { "cpu_div3_clk", "amba_syn_clk", }; static const char *gpt_parents[] = { "osc_24m_clk", "apb_clk", }; static const char *uart0_parents[] = { "pll5_clk", "osc_24m_clk", @@ -438,13 +391,16 @@ static const char *spdif_in_parents[] = { "pll2_clk", "gen_syn3_clk", }; static const char *gen_synth0_1_parents[] = { "vco1div4_clk", "vco3div2_clk", "pll3_clk", }; -static const char *gen_synth2_3_parents[] = { "vco1div4_clk", "vco2div2_clk", +static const char *gen_synth2_3_parents[] = { "vco1div4_clk", "vco3div2_clk", "pll2_clk", }; void __init spear1340_clk_init(void) { struct clk *clk, *clk1; + clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0); + clk_register_clkdev(clk, "apb_pclk", NULL); + clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT, 32000); clk_register_clkdev(clk, "osc_32k_clk", NULL); @@ -469,7 +425,7 @@ void __init spear1340_clk_init(void) clk = clk_register_gate(NULL, "rtc-spear", "osc_32k_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_RTC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e0580000.rtc"); + clk_register_clkdev(clk, NULL, "fc900000.rtc"); /* clock derived from 24 or 25 MHz osc clk */ /* vco-pll */ @@ -543,7 +499,7 @@ void __init spear1340_clk_init(void) clk = clk_register_gate(NULL, "thermal_gclk", "thermal_clk", 0, SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_THSENS_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e07008c4.thermal"); + clk_register_clkdev(clk, NULL, "spear_thermal"); /* clock derived from pll4 clk */ clk = clk_register_fixed_factor(NULL, "ddr_clk", "pll4_clk", 0, 1, @@ -565,7 +521,7 @@ void __init spear1340_clk_init(void) ARRAY_SIZE(sys_parents), 0, SPEAR1340_SYS_CLK_CTRL, SPEAR1340_SCLK_SRC_SEL_SHIFT, SPEAR1340_SCLK_SRC_SEL_MASK, 0, &_lock); - clk_register_clkdev(clk, "sys_mclk", NULL); + clk_register_clkdev(clk, "sys_clk", NULL); clk = clk_register_fixed_factor(NULL, "cpu_clk", "sys_mclk", 0, 1, 2); @@ -579,10 +535,6 @@ void __init spear1340_clk_init(void) 2); clk_register_clkdev(clk, NULL, "ec800620.wdt"); - clk = clk_register_fixed_factor(NULL, "smp_twd_clk", "cpu_clk", 0, 1, - 2); - clk_register_clkdev(clk, NULL, "smp_twd"); - clk = clk_register_mux(NULL, "ahb_clk", ahb_parents, ARRAY_SIZE(ahb_parents), 0, SPEAR1340_SYS_CLK_CTRL, SPEAR1340_HCLK_SRC_SEL_SHIFT, @@ -642,14 +594,14 @@ void __init spear1340_clk_init(void) clk_register_clkdev(clk1, "uart0_syn_gclk", NULL); clk = clk_register_mux(NULL, "uart0_mclk", uart0_parents, - ARRAY_SIZE(uart0_parents), CLK_SET_RATE_PARENT, - SPEAR1340_PERIP_CLK_CFG, SPEAR1340_UART0_CLK_SHIFT, - SPEAR1340_UART_CLK_MASK, 0, &_lock); + ARRAY_SIZE(uart0_parents), 0, SPEAR1340_PERIP_CLK_CFG, + SPEAR1340_UART0_CLK_SHIFT, SPEAR1340_UART_CLK_MASK, 0, + &_lock); clk_register_clkdev(clk, "uart0_mclk", NULL); - clk = clk_register_gate(NULL, "uart0_clk", "uart0_mclk", - CLK_SET_RATE_PARENT, SPEAR1340_PERIP1_CLK_ENB, - SPEAR1340_UART0_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "uart0_clk", "uart0_mclk", 0, + SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_UART0_CLK_ENB, 0, + &_lock); clk_register_clkdev(clk, NULL, "e0000000.serial"); clk = clk_register_aux("uart1_syn_clk", "uart1_syn_gclk", @@ -675,9 +627,9 @@ void __init spear1340_clk_init(void) clk_register_clkdev(clk, "sdhci_syn_clk", NULL); clk_register_clkdev(clk1, "sdhci_syn_gclk", NULL); - clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_syn_gclk", - CLK_SET_RATE_PARENT, SPEAR1340_PERIP1_CLK_ENB, - SPEAR1340_SDHCI_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_syn_gclk", 0, + SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_SDHCI_CLK_ENB, 0, + &_lock); clk_register_clkdev(clk, NULL, "b3000000.sdhci"); clk = clk_register_aux("cfxd_syn_clk", "cfxd_syn_gclk", "vco1div2_clk", @@ -686,9 +638,9 @@ void __init spear1340_clk_init(void) clk_register_clkdev(clk, "cfxd_syn_clk", NULL); clk_register_clkdev(clk1, "cfxd_syn_gclk", NULL); - clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_syn_gclk", - CLK_SET_RATE_PARENT, SPEAR1340_PERIP1_CLK_ENB, - SPEAR1340_CFXD_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_syn_gclk", 0, + SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_CFXD_CLK_ENB, 0, + &_lock); clk_register_clkdev(clk, NULL, "b2800000.cf"); clk_register_clkdev(clk, NULL, "arasan_xd"); @@ -699,15 +651,15 @@ void __init spear1340_clk_init(void) clk_register_clkdev(clk1, "c3_syn_gclk", NULL); clk = clk_register_mux(NULL, "c3_mclk", c3_parents, - ARRAY_SIZE(c3_parents), CLK_SET_RATE_PARENT, - SPEAR1340_PERIP_CLK_CFG, SPEAR1340_C3_CLK_SHIFT, - SPEAR1340_C3_CLK_MASK, 0, &_lock); + ARRAY_SIZE(c3_parents), 0, SPEAR1340_PERIP_CLK_CFG, + SPEAR1340_C3_CLK_SHIFT, SPEAR1340_C3_CLK_MASK, 0, + &_lock); clk_register_clkdev(clk, "c3_mclk", NULL); - clk = clk_register_gate(NULL, "c3_clk", "c3_mclk", CLK_SET_RATE_PARENT, + clk = clk_register_gate(NULL, "c3_clk", "c3_mclk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_C3_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e1800000.c3"); + clk_register_clkdev(clk, NULL, "c3"); /* gmac */ clk = clk_register_mux(NULL, "phy_input_mclk", gmac_phy_input_parents, @@ -727,7 +679,7 @@ void __init spear1340_clk_init(void) ARRAY_SIZE(gmac_phy_parents), 0, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_GMAC_PHY_CLK_SHIFT, SPEAR1340_GMAC_PHY_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "stmmacphy.0", NULL); + clk_register_clkdev(clk, NULL, "stmmacphy.0"); /* clcd */ clk = clk_register_mux(NULL, "clcd_syn_mclk", clcd_synth_parents, @@ -742,34 +694,33 @@ void __init spear1340_clk_init(void) clk_register_clkdev(clk, "clcd_syn_clk", NULL); clk = clk_register_mux(NULL, "clcd_pixel_mclk", clcd_pixel_parents, - ARRAY_SIZE(clcd_pixel_parents), CLK_SET_RATE_PARENT, + ARRAY_SIZE(clcd_pixel_parents), 0, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_CLCD_CLK_SHIFT, SPEAR1340_CLCD_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "clcd_pixel_mclk", NULL); + clk_register_clkdev(clk, "clcd_pixel_clk", NULL); clk = clk_register_gate(NULL, "clcd_clk", "clcd_pixel_mclk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_CLCD_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e1000000.clcd"); + clk_register_clkdev(clk, "clcd_clk", NULL); /* i2s */ clk = clk_register_mux(NULL, "i2s_src_mclk", i2s_src_parents, ARRAY_SIZE(i2s_src_parents), 0, SPEAR1340_I2S_CLK_CFG, SPEAR1340_I2S_SRC_CLK_SHIFT, SPEAR1340_I2S_SRC_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "i2s_src_mclk", NULL); + clk_register_clkdev(clk, "i2s_src_clk", NULL); - clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mclk", - CLK_SET_RATE_PARENT, SPEAR1340_I2S_CLK_CFG, - &i2s_prs1_masks, i2s_prs1_rtbl, + clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mclk", 0, + SPEAR1340_I2S_CLK_CFG, &i2s_prs1_masks, i2s_prs1_rtbl, ARRAY_SIZE(i2s_prs1_rtbl), &_lock, NULL); clk_register_clkdev(clk, "i2s_prs1_clk", NULL); clk = clk_register_mux(NULL, "i2s_ref_mclk", i2s_ref_parents, - ARRAY_SIZE(i2s_ref_parents), CLK_SET_RATE_PARENT, - SPEAR1340_I2S_CLK_CFG, SPEAR1340_I2S_REF_SHIFT, - SPEAR1340_I2S_REF_SEL_MASK, 0, &_lock); - clk_register_clkdev(clk, "i2s_ref_mclk", NULL); + ARRAY_SIZE(i2s_ref_parents), 0, SPEAR1340_I2S_CLK_CFG, + SPEAR1340_I2S_REF_SHIFT, SPEAR1340_I2S_REF_SEL_MASK, 0, + &_lock); + clk_register_clkdev(clk, "i2s_ref_clk", NULL); clk = clk_register_gate(NULL, "i2s_ref_pad_clk", "i2s_ref_mclk", 0, SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_I2S_REF_PAD_CLK_ENB, @@ -818,25 +769,23 @@ void __init spear1340_clk_init(void) clk = clk_register_gate(NULL, "usbh0_clk", "ahb_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_UHC0_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e4000000.ohci"); - clk_register_clkdev(clk, NULL, "e4800000.ehci"); + clk_register_clkdev(clk, "usbh.0_clk", NULL); clk = clk_register_gate(NULL, "usbh1_clk", "ahb_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_UHC1_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e5000000.ohci"); - clk_register_clkdev(clk, NULL, "e5800000.ehci"); + clk_register_clkdev(clk, "usbh.1_clk", NULL); clk = clk_register_gate(NULL, "uoc_clk", "ahb_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_UOC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e3800000.otg"); + clk_register_clkdev(clk, NULL, "uoc"); clk = clk_register_gate(NULL, "pcie_sata_clk", "ahb_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_PCIE_SATA_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "dw_pcie"); - clk_register_clkdev(clk, NULL, "b1000000.ahci"); + clk_register_clkdev(clk, NULL, "ahci"); clk = clk_register_gate(NULL, "sysram0_clk", "ahb_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_SYSRAM0_CLK_ENB, 0, @@ -854,10 +803,10 @@ void __init spear1340_clk_init(void) clk_register_clkdev(clk, "adc_syn_clk", NULL); clk_register_clkdev(clk1, "adc_syn_gclk", NULL); - clk = clk_register_gate(NULL, "adc_clk", "adc_syn_gclk", - CLK_SET_RATE_PARENT, SPEAR1340_PERIP1_CLK_ENB, - SPEAR1340_ADC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e0080000.adc"); + clk = clk_register_gate(NULL, "adc_clk", "adc_syn_gclk", 0, + SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_ADC_CLK_ENB, 0, + &_lock); + clk_register_clkdev(clk, NULL, "adc_clk"); /* clock derived from apb clk */ clk = clk_register_gate(NULL, "ssp_clk", "apb_clk", 0, @@ -878,12 +827,12 @@ void __init spear1340_clk_init(void) clk = clk_register_gate(NULL, "i2s_play_clk", "apb_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_I2S_PLAY_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "b2400000.i2s-play"); + clk_register_clkdev(clk, NULL, "b2400000.i2s"); clk = clk_register_gate(NULL, "i2s_rec_clk", "apb_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_I2S_REC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "b2000000.i2s-rec"); + clk_register_clkdev(clk, NULL, "b2000000.i2s"); clk = clk_register_gate(NULL, "kbd_clk", "apb_clk", 0, SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_KBD_CLK_ENB, 0, @@ -895,37 +844,37 @@ void __init spear1340_clk_init(void) ARRAY_SIZE(gen_synth0_1_parents), 0, SPEAR1340_PLL_CFG, SPEAR1340_GEN_SYNT0_1_CLK_SHIFT, SPEAR1340_GEN_SYNT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gen_syn0_1_mclk", NULL); + clk_register_clkdev(clk, "gen_syn0_1_clk", NULL); clk = clk_register_mux(NULL, "gen_syn2_3_mclk", gen_synth2_3_parents, ARRAY_SIZE(gen_synth2_3_parents), 0, SPEAR1340_PLL_CFG, SPEAR1340_GEN_SYNT2_3_CLK_SHIFT, SPEAR1340_GEN_SYNT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gen_syn2_3_mclk", NULL); + clk_register_clkdev(clk, "gen_syn2_3_clk", NULL); - clk = clk_register_frac("gen_syn0_clk", "gen_syn0_1_mclk", 0, + clk = clk_register_frac("gen_syn0_clk", "gen_syn0_1_clk", 0, SPEAR1340_GEN_CLK_SYNT0, gen_rtbl, ARRAY_SIZE(gen_rtbl), &_lock); clk_register_clkdev(clk, "gen_syn0_clk", NULL); - clk = clk_register_frac("gen_syn1_clk", "gen_syn0_1_mclk", 0, + clk = clk_register_frac("gen_syn1_clk", "gen_syn0_1_clk", 0, SPEAR1340_GEN_CLK_SYNT1, gen_rtbl, ARRAY_SIZE(gen_rtbl), &_lock); clk_register_clkdev(clk, "gen_syn1_clk", NULL); - clk = clk_register_frac("gen_syn2_clk", "gen_syn2_3_mclk", 0, + clk = clk_register_frac("gen_syn2_clk", "gen_syn2_3_clk", 0, SPEAR1340_GEN_CLK_SYNT2, gen_rtbl, ARRAY_SIZE(gen_rtbl), &_lock); clk_register_clkdev(clk, "gen_syn2_clk", NULL); - clk = clk_register_frac("gen_syn3_clk", "gen_syn2_3_mclk", 0, + clk = clk_register_frac("gen_syn3_clk", "gen_syn2_3_clk", 0, SPEAR1340_GEN_CLK_SYNT3, gen_rtbl, ARRAY_SIZE(gen_rtbl), &_lock); clk_register_clkdev(clk, "gen_syn3_clk", NULL); - clk = clk_register_gate(NULL, "mali_clk", "gen_syn3_clk", - CLK_SET_RATE_PARENT, SPEAR1340_PERIP3_CLK_ENB, - SPEAR1340_MALI_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "mali_clk", "gen_syn3_clk", 0, + SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_MALI_CLK_ENB, 0, + &_lock); clk_register_clkdev(clk, NULL, "mali"); clk = clk_register_gate(NULL, "cec0_clk", "ahb_clk", 0, @@ -939,26 +888,26 @@ void __init spear1340_clk_init(void) clk_register_clkdev(clk, NULL, "spear_cec.1"); clk = clk_register_mux(NULL, "spdif_out_mclk", spdif_out_parents, - ARRAY_SIZE(spdif_out_parents), CLK_SET_RATE_PARENT, + ARRAY_SIZE(spdif_out_parents), 0, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_SPDIF_OUT_CLK_SHIFT, SPEAR1340_SPDIF_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "spdif_out_mclk", NULL); - clk = clk_register_gate(NULL, "spdif_out_clk", "spdif_out_mclk", - CLK_SET_RATE_PARENT, SPEAR1340_PERIP3_CLK_ENB, - SPEAR1340_SPDIF_OUT_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "d0000000.spdif-out"); + clk = clk_register_gate(NULL, "spdif_out_clk", "spdif_out_mclk", 0, + SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_SPDIF_OUT_CLK_ENB, + 0, &_lock); + clk_register_clkdev(clk, NULL, "spdif-out"); clk = clk_register_mux(NULL, "spdif_in_mclk", spdif_in_parents, - ARRAY_SIZE(spdif_in_parents), CLK_SET_RATE_PARENT, + ARRAY_SIZE(spdif_in_parents), 0, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_SPDIF_IN_CLK_SHIFT, SPEAR1340_SPDIF_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "spdif_in_mclk", NULL); - clk = clk_register_gate(NULL, "spdif_in_clk", "spdif_in_mclk", - CLK_SET_RATE_PARENT, SPEAR1340_PERIP3_CLK_ENB, - SPEAR1340_SPDIF_IN_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "d0100000.spdif-in"); + clk = clk_register_gate(NULL, "spdif_in_clk", "spdif_in_mclk", 0, + SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_SPDIF_IN_CLK_ENB, 0, + &_lock); + clk_register_clkdev(clk, NULL, "spdif-in"); clk = clk_register_gate(NULL, "acp_clk", "acp_mclk", 0, SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_ACP_CLK_ENB, 0, @@ -968,7 +917,7 @@ void __init spear1340_clk_init(void) clk = clk_register_gate(NULL, "plgpio_clk", "plgpio_mclk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_PLGPIO_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e2800000.gpio"); + clk_register_clkdev(clk, NULL, "plgpio"); clk = clk_register_gate(NULL, "video_dec_clk", "video_dec_mclk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_DEC_CLK_ENB, @@ -988,25 +937,25 @@ void __init spear1340_clk_init(void) clk = clk_register_gate(NULL, "cam0_clk", "cam0_mclk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM0_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "d0200000.cam0"); + clk_register_clkdev(clk, NULL, "spear_camif.0"); clk = clk_register_gate(NULL, "cam1_clk", "cam1_mclk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM1_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "d0300000.cam1"); + clk_register_clkdev(clk, NULL, "spear_camif.1"); clk = clk_register_gate(NULL, "cam2_clk", "cam2_mclk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM2_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "d0400000.cam2"); + clk_register_clkdev(clk, NULL, "spear_camif.2"); clk = clk_register_gate(NULL, "cam3_clk", "cam3_mclk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM3_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "d0500000.cam3"); + clk_register_clkdev(clk, NULL, "spear_camif.3"); - clk = clk_register_gate(NULL, "pwm_clk", "ahb_clk", 0, + clk = clk_register_gate(NULL, "pwm_clk", "pwm_mclk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_PWM_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e0180000.pwm"); + clk_register_clkdev(clk, NULL, "pwm"); } diff --git a/trunk/drivers/clk/spear/spear3xx_clock.c b/trunk/drivers/clk/spear/spear3xx_clock.c index 33d3ac588da7..c3157454bb3f 100644 --- a/trunk/drivers/clk/spear/spear3xx_clock.c +++ b/trunk/drivers/clk/spear/spear3xx_clock.c @@ -107,12 +107,6 @@ static struct pll_rate_tbl pll_rtbl[] = { /* aux rate configuration table, in ascending order of rates */ static struct aux_rate_tbl aux_rtbl[] = { /* For PLL1 = 332 MHz */ - {.xscale = 1, .yscale = 81, .eq = 0}, /* 2.049 MHz */ - {.xscale = 1, .yscale = 59, .eq = 0}, /* 2.822 MHz */ - {.xscale = 2, .yscale = 81, .eq = 0}, /* 4.098 MHz */ - {.xscale = 3, .yscale = 89, .eq = 0}, /* 5.644 MHz */ - {.xscale = 4, .yscale = 81, .eq = 0}, /* 8.197 MHz */ - {.xscale = 4, .yscale = 59, .eq = 0}, /* 11.254 MHz */ {.xscale = 2, .yscale = 27, .eq = 0}, /* 12.296 MHz */ {.xscale = 2, .yscale = 8, .eq = 0}, /* 41.5 MHz */ {.xscale = 2, .yscale = 4, .eq = 0}, /* 83 MHz */ @@ -163,8 +157,6 @@ static void __init spear300_clk_init(void) 1); clk_register_clkdev(clk, NULL, "a0000000.kbd"); } -#else -static inline void spear300_clk_init(void) { } #endif /* array of all spear 310 clock lookups */ @@ -205,8 +197,6 @@ static void __init spear310_clk_init(void) 1); clk_register_clkdev(clk, NULL, "b2200000.serial"); } -#else -static inline void spear310_clk_init(void) { } #endif /* array of all spear 320 clock lookups */ @@ -261,7 +251,7 @@ static void __init spear320_clk_init(void) clk = clk_register_fixed_factor(NULL, "pwm_clk", "ras_ahb_clk", 0, 1, 1); - clk_register_clkdev(clk, NULL, "a8000000.pwm"); + clk_register_clkdev(clk, "pwm", NULL); clk = clk_register_fixed_factor(NULL, "ssp1_clk", "ras_ahb_clk", 0, 1, 1); @@ -281,37 +271,26 @@ static void __init spear320_clk_init(void) clk = clk_register_fixed_factor(NULL, "i2s_clk", "ras_apb_clk", 0, 1, 1); - clk_register_clkdev(clk, NULL, "a9400000.i2s"); + clk_register_clkdev(clk, NULL, "i2s"); clk = clk_register_mux(NULL, "i2s_ref_clk", i2s_ref_parents, - ARRAY_SIZE(i2s_ref_parents), CLK_SET_RATE_PARENT, - SPEAR320_CONTROL_REG, I2S_REF_PCLK_SHIFT, - I2S_REF_PCLK_MASK, 0, &_lock); + ARRAY_SIZE(i2s_ref_parents), 0, SPEAR320_CONTROL_REG, + I2S_REF_PCLK_SHIFT, I2S_REF_PCLK_MASK, 0, &_lock); clk_register_clkdev(clk, "i2s_ref_clk", NULL); - clk = clk_register_fixed_factor(NULL, "i2s_sclk", "i2s_ref_clk", - CLK_SET_RATE_PARENT, 1, + clk = clk_register_fixed_factor(NULL, "i2s_sclk", "i2s_ref_clk", 0, 1, 4); clk_register_clkdev(clk, "i2s_sclk", NULL); - clk = clk_register_fixed_factor(NULL, "macb1_clk", "ras_apb_clk", 0, 1, - 1); - clk_register_clkdev(clk, "hclk", "aa000000.eth"); - - clk = clk_register_fixed_factor(NULL, "macb2_clk", "ras_apb_clk", 0, 1, - 1); - clk_register_clkdev(clk, "hclk", "ab000000.eth"); - clk = clk_register_mux(NULL, "rs485_clk", uartx_parents, - ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT, - SPEAR320_EXT_CTRL_REG, SPEAR320_RS485_PCLK_SHIFT, - SPEAR320_UARTX_PCLK_MASK, 0, &_lock); + ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG, + SPEAR320_RS485_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0, + &_lock); clk_register_clkdev(clk, NULL, "a9300000.serial"); clk = clk_register_mux(NULL, "sdhci_clk", sdhci_parents, - ARRAY_SIZE(sdhci_parents), CLK_SET_RATE_PARENT, - SPEAR320_CONTROL_REG, SDHCI_PCLK_SHIFT, SDHCI_PCLK_MASK, - 0, &_lock); + ARRAY_SIZE(sdhci_parents), 0, SPEAR320_CONTROL_REG, + SDHCI_PCLK_SHIFT, SDHCI_PCLK_MASK, 0, &_lock); clk_register_clkdev(clk, NULL, "70000000.sdhci"); clk = clk_register_mux(NULL, "smii_pclk", smii0_parents, @@ -323,49 +302,49 @@ static void __init spear320_clk_init(void) clk_register_clkdev(clk, NULL, "smii"); clk = clk_register_mux(NULL, "uart1_clk", uartx_parents, - ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT, - SPEAR320_CONTROL_REG, UART1_PCLK_SHIFT, UART1_PCLK_MASK, - 0, &_lock); + ARRAY_SIZE(uartx_parents), 0, SPEAR320_CONTROL_REG, + UART1_PCLK_SHIFT, UART1_PCLK_MASK, 0, &_lock); clk_register_clkdev(clk, NULL, "a3000000.serial"); clk = clk_register_mux(NULL, "uart2_clk", uartx_parents, - ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT, - SPEAR320_EXT_CTRL_REG, SPEAR320_UART2_PCLK_SHIFT, - SPEAR320_UARTX_PCLK_MASK, 0, &_lock); + ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG, + SPEAR320_UART2_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0, + &_lock); clk_register_clkdev(clk, NULL, "a4000000.serial"); clk = clk_register_mux(NULL, "uart3_clk", uartx_parents, - ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT, - SPEAR320_EXT_CTRL_REG, SPEAR320_UART3_PCLK_SHIFT, - SPEAR320_UARTX_PCLK_MASK, 0, &_lock); + ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG, + SPEAR320_UART3_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0, + &_lock); clk_register_clkdev(clk, NULL, "a9100000.serial"); clk = clk_register_mux(NULL, "uart4_clk", uartx_parents, - ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT, - SPEAR320_EXT_CTRL_REG, SPEAR320_UART4_PCLK_SHIFT, - SPEAR320_UARTX_PCLK_MASK, 0, &_lock); + ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG, + SPEAR320_UART4_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0, + &_lock); clk_register_clkdev(clk, NULL, "a9200000.serial"); clk = clk_register_mux(NULL, "uart5_clk", uartx_parents, - ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT, - SPEAR320_EXT_CTRL_REG, SPEAR320_UART5_PCLK_SHIFT, - SPEAR320_UARTX_PCLK_MASK, 0, &_lock); + ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG, + SPEAR320_UART5_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0, + &_lock); clk_register_clkdev(clk, NULL, "60000000.serial"); clk = clk_register_mux(NULL, "uart6_clk", uartx_parents, - ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT, - SPEAR320_EXT_CTRL_REG, SPEAR320_UART6_PCLK_SHIFT, - SPEAR320_UARTX_PCLK_MASK, 0, &_lock); + ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG, + SPEAR320_UART6_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0, + &_lock); clk_register_clkdev(clk, NULL, "60100000.serial"); } -#else -static inline void spear320_clk_init(void) { } #endif void __init spear3xx_clk_init(void) { struct clk *clk, *clk1; + clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0); + clk_register_clkdev(clk, "apb_pclk", NULL); + clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT, 32000); clk_register_clkdev(clk, "osc_32k_clk", NULL); @@ -401,8 +380,7 @@ void __init spear3xx_clk_init(void) clk_register_clkdev(clk1, "pll2_clk", NULL); /* clock derived from pll1 clk */ - clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk", - CLK_SET_RATE_PARENT, 1, 1); + clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk", 0, 1, 1); clk_register_clkdev(clk, "cpu_clk", NULL); clk = clk_register_divider(NULL, "ahb_clk", "pll1_clk", @@ -417,14 +395,12 @@ void __init spear3xx_clk_init(void) clk_register_clkdev(clk1, "uart_syn_gclk", NULL); clk = clk_register_mux(NULL, "uart0_mclk", uart0_parents, - ARRAY_SIZE(uart0_parents), CLK_SET_RATE_PARENT, - PERIP_CLK_CFG, UART_CLK_SHIFT, UART_CLK_MASK, 0, - &_lock); + ARRAY_SIZE(uart0_parents), 0, PERIP_CLK_CFG, + UART_CLK_SHIFT, UART_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "uart0_mclk", NULL); - clk = clk_register_gate(NULL, "uart0", "uart0_mclk", - CLK_SET_RATE_PARENT, PERIP1_CLK_ENB, UART_CLK_ENB, 0, - &_lock); + clk = clk_register_gate(NULL, "uart0", "uart0_mclk", 0, PERIP1_CLK_ENB, + UART_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "d0000000.serial"); clk = clk_register_aux("firda_syn_clk", "firda_syn_gclk", "pll1_clk", 0, @@ -434,44 +410,40 @@ void __init spear3xx_clk_init(void) clk_register_clkdev(clk1, "firda_syn_gclk", NULL); clk = clk_register_mux(NULL, "firda_mclk", firda_parents, - ARRAY_SIZE(firda_parents), CLK_SET_RATE_PARENT, - PERIP_CLK_CFG, FIRDA_CLK_SHIFT, FIRDA_CLK_MASK, 0, - &_lock); + ARRAY_SIZE(firda_parents), 0, PERIP_CLK_CFG, + FIRDA_CLK_SHIFT, FIRDA_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "firda_mclk", NULL); - clk = clk_register_gate(NULL, "firda_clk", "firda_mclk", - CLK_SET_RATE_PARENT, PERIP1_CLK_ENB, FIRDA_CLK_ENB, 0, - &_lock); + clk = clk_register_gate(NULL, "firda_clk", "firda_mclk", 0, + PERIP1_CLK_ENB, FIRDA_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "firda"); /* gpt clocks */ clk_register_gpt("gpt0_syn_clk", "pll1_clk", 0, PRSC0_CLK_CFG, gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); clk = clk_register_mux(NULL, "gpt0_clk", gpt0_parents, - ARRAY_SIZE(gpt0_parents), CLK_SET_RATE_PARENT, - PERIP_CLK_CFG, GPT0_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); + ARRAY_SIZE(gpt0_parents), 0, PERIP_CLK_CFG, + GPT0_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, NULL, "gpt0"); clk_register_gpt("gpt1_syn_clk", "pll1_clk", 0, PRSC1_CLK_CFG, gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); clk = clk_register_mux(NULL, "gpt1_mclk", gpt1_parents, - ARRAY_SIZE(gpt1_parents), CLK_SET_RATE_PARENT, - PERIP_CLK_CFG, GPT1_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); + ARRAY_SIZE(gpt1_parents), 0, PERIP_CLK_CFG, + GPT1_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "gpt1_mclk", NULL); - clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mclk", - CLK_SET_RATE_PARENT, PERIP1_CLK_ENB, GPT1_CLK_ENB, 0, - &_lock); + clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mclk", 0, + PERIP1_CLK_ENB, GPT1_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "gpt1"); clk_register_gpt("gpt2_syn_clk", "pll1_clk", 0, PRSC2_CLK_CFG, gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); clk = clk_register_mux(NULL, "gpt2_mclk", gpt2_parents, - ARRAY_SIZE(gpt2_parents), CLK_SET_RATE_PARENT, - PERIP_CLK_CFG, GPT2_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); + ARRAY_SIZE(gpt2_parents), 0, PERIP_CLK_CFG, + GPT2_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "gpt2_mclk", NULL); - clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mclk", - CLK_SET_RATE_PARENT, PERIP1_CLK_ENB, GPT2_CLK_ENB, 0, - &_lock); + clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mclk", 0, + PERIP1_CLK_ENB, GPT2_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "gpt2"); /* general synths clocks */ @@ -508,9 +480,7 @@ void __init spear3xx_clk_init(void) /* clock derived from pll3 clk */ clk = clk_register_gate(NULL, "usbh_clk", "pll3_clk", 0, PERIP1_CLK_ENB, USBH_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e1800000.ehci"); - clk_register_clkdev(clk, NULL, "e1900000.ohci"); - clk_register_clkdev(clk, NULL, "e2100000.ohci"); + clk_register_clkdev(clk, "usbh_clk", NULL); clk = clk_register_fixed_factor(NULL, "usbh.0_clk", "usbh_clk", 0, 1, 1); @@ -522,7 +492,7 @@ void __init spear3xx_clk_init(void) clk = clk_register_gate(NULL, "usbd_clk", "pll3_clk", 0, PERIP1_CLK_ENB, USBD_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e1100000.usbd"); + clk_register_clkdev(clk, NULL, "designware_udc"); /* clock derived from ahb clk */ clk = clk_register_fixed_factor(NULL, "ahbmult2_clk", "ahb_clk", 0, 2, @@ -570,7 +540,7 @@ void __init spear3xx_clk_init(void) /* clock derived from apb clk */ clk = clk_register_gate(NULL, "adc_clk", "apb_clk", 0, PERIP1_CLK_ENB, ADC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "d0080000.adc"); + clk_register_clkdev(clk, NULL, "adc"); clk = clk_register_gate(NULL, "gpio0_clk", "apb_clk", 0, PERIP1_CLK_ENB, GPIO_CLK_ENB, 0, &_lock); @@ -609,24 +579,20 @@ void __init spear3xx_clk_init(void) RAS_CLK_ENB, RAS_48M_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, "ras_pll3_clk", NULL); - clk = clk_register_gate(NULL, "ras_syn0_gclk", "gen0_syn_gclk", - CLK_SET_RATE_PARENT, RAS_CLK_ENB, RAS_SYNT0_CLK_ENB, 0, - &_lock); + clk = clk_register_gate(NULL, "ras_syn0_gclk", "gen0_syn_gclk", 0, + RAS_CLK_ENB, RAS_SYNT0_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, "ras_syn0_gclk", NULL); - clk = clk_register_gate(NULL, "ras_syn1_gclk", "gen1_syn_gclk", - CLK_SET_RATE_PARENT, RAS_CLK_ENB, RAS_SYNT1_CLK_ENB, 0, - &_lock); + clk = clk_register_gate(NULL, "ras_syn1_gclk", "gen1_syn_gclk", 0, + RAS_CLK_ENB, RAS_SYNT1_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, "ras_syn1_gclk", NULL); - clk = clk_register_gate(NULL, "ras_syn2_gclk", "gen2_syn_gclk", - CLK_SET_RATE_PARENT, RAS_CLK_ENB, RAS_SYNT2_CLK_ENB, 0, - &_lock); + clk = clk_register_gate(NULL, "ras_syn2_gclk", "gen2_syn_gclk", 0, + RAS_CLK_ENB, RAS_SYNT2_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, "ras_syn2_gclk", NULL); - clk = clk_register_gate(NULL, "ras_syn3_gclk", "gen3_syn_gclk", - CLK_SET_RATE_PARENT, RAS_CLK_ENB, RAS_SYNT3_CLK_ENB, 0, - &_lock); + clk = clk_register_gate(NULL, "ras_syn3_gclk", "gen3_syn_gclk", 0, + RAS_CLK_ENB, RAS_SYNT3_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, "ras_syn3_gclk", NULL); if (of_machine_is_compatible("st,spear300")) diff --git a/trunk/drivers/clk/spear/spear6xx_clock.c b/trunk/drivers/clk/spear/spear6xx_clock.c index e862a333ad30..a98d0866f541 100644 --- a/trunk/drivers/clk/spear/spear6xx_clock.c +++ b/trunk/drivers/clk/spear/spear6xx_clock.c @@ -92,7 +92,6 @@ static struct pll_rate_tbl pll_rtbl[] = { /* aux rate configuration table, in ascending order of rates */ static struct aux_rate_tbl aux_rtbl[] = { /* For PLL1 = 332 MHz */ - {.xscale = 2, .yscale = 27, .eq = 0}, /* 12.296 MHz */ {.xscale = 2, .yscale = 8, .eq = 0}, /* 41.5 MHz */ {.xscale = 2, .yscale = 4, .eq = 0}, /* 83 MHz */ {.xscale = 1, .yscale = 2, .eq = 1}, /* 166 MHz */ @@ -119,6 +118,9 @@ void __init spear6xx_clk_init(void) { struct clk *clk, *clk1; + clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0); + clk_register_clkdev(clk, "apb_pclk", NULL); + clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT, 32000); clk_register_clkdev(clk, "osc_32k_clk", NULL); @@ -154,8 +156,7 @@ void __init spear6xx_clk_init(void) clk_register_clkdev(clk, NULL, "wdt"); /* clock derived from pll1 clk */ - clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk", - CLK_SET_RATE_PARENT, 1, 1); + clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk", 0, 1, 1); clk_register_clkdev(clk, "cpu_clk", NULL); clk = clk_register_divider(NULL, "ahb_clk", "pll1_clk", @@ -260,13 +261,11 @@ void __init spear6xx_clk_init(void) /* clock derived from pll3 clk */ clk = clk_register_gate(NULL, "usbh0_clk", "pll3_clk", 0, PERIP1_CLK_ENB, USBH0_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e1800000.ehci"); - clk_register_clkdev(clk, NULL, "e1900000.ohci"); + clk_register_clkdev(clk, NULL, "usbh.0_clk"); clk = clk_register_gate(NULL, "usbh1_clk", "pll3_clk", 0, PERIP1_CLK_ENB, USBH1_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "e2000000.ehci"); - clk_register_clkdev(clk, NULL, "e2100000.ohci"); + clk_register_clkdev(clk, NULL, "usbh.1_clk"); clk = clk_register_gate(NULL, "usbd_clk", "pll3_clk", 0, PERIP1_CLK_ENB, USBD_CLK_ENB, 0, &_lock); diff --git a/trunk/drivers/clk/ux500/Makefile b/trunk/drivers/clk/ux500/Makefile index bcc0c11a507c..858fbfe66281 100644 --- a/trunk/drivers/clk/ux500/Makefile +++ b/trunk/drivers/clk/ux500/Makefile @@ -10,6 +10,3 @@ obj-y += clk-prcmu.o obj-y += u8500_clk.o obj-y += u9540_clk.o obj-y += u8540_clk.o - -# ABX500 clock driver -obj-y += abx500-clk.o diff --git a/trunk/drivers/clk/ux500/abx500-clk.c b/trunk/drivers/clk/ux500/abx500-clk.c deleted file mode 100644 index e27c52317ffe..000000000000 --- a/trunk/drivers/clk/ux500/abx500-clk.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * abx500 clock implementation for ux500 platform. - * - * Copyright (C) 2012 ST-Ericsson SA - * Author: Ulf Hansson - * - * License terms: GNU General Public License (GPL) version 2 - */ - -#include -#include -#include -#include -#include - -/* TODO: Add clock implementations here */ - - -/* Clock definitions for ab8500 */ -static int ab8500_reg_clks(struct device *dev) -{ - return 0; -} - -/* Clock definitions for ab8540 */ -static int ab8540_reg_clks(struct device *dev) -{ - return 0; -} - -/* Clock definitions for ab9540 */ -static int ab9540_reg_clks(struct device *dev) -{ - return 0; -} - -static int __devinit abx500_clk_probe(struct platform_device *pdev) -{ - struct ab8500 *parent = dev_get_drvdata(pdev->dev.parent); - int ret; - - if (is_ab8500(parent) || is_ab8505(parent)) { - ret = ab8500_reg_clks(&pdev->dev); - } else if (is_ab8540(parent)) { - ret = ab8540_reg_clks(&pdev->dev); - } else if (is_ab9540(parent)) { - ret = ab9540_reg_clks(&pdev->dev); - } else { - dev_err(&pdev->dev, "non supported plf id\n"); - return -ENODEV; - } - - return ret; -} - -static struct platform_driver abx500_clk_driver = { - .driver = { - .name = "abx500-clk", - .owner = THIS_MODULE, - }, - .probe = abx500_clk_probe, -}; - -static int __init abx500_clk_init(void) -{ - return platform_driver_register(&abx500_clk_driver); -} - -arch_initcall(abx500_clk_init); - -MODULE_AUTHOR("Ulf Hansson init->name); } -static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw) -{ - int err; - struct clk_prcmu *clk = to_clk_prcmu(hw); - - err = prcmu_request_ape_opp_100_voltage(true); - if (err) { - pr_err("clk_prcmu: %s failed to request APE OPP VOLT for %s.\n", - __func__, hw->init->name); - return err; - } - - err = prcmu_request_clock(clk->cg_sel, true); - if (err) - prcmu_request_ape_opp_100_voltage(false); - - return err; -} - -static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw) -{ - struct clk_prcmu *clk = to_clk_prcmu(hw); - - if (prcmu_request_clock(clk->cg_sel, false)) - goto out_error; - if (prcmu_request_ape_opp_100_voltage(false)) - goto out_error; - return; - -out_error: - pr_err("clk_prcmu: %s failed to disable %s.\n", __func__, - hw->init->name); -} - static struct clk_ops clk_prcmu_scalable_ops = { .prepare = clk_prcmu_prepare, .unprepare = clk_prcmu_unprepare, @@ -187,13 +153,6 @@ static struct clk_ops clk_prcmu_gate_ops = { .recalc_rate = clk_prcmu_recalc_rate, }; -static struct clk_ops clk_prcmu_scalable_rate_ops = { - .is_enabled = clk_prcmu_is_enabled, - .recalc_rate = clk_prcmu_recalc_rate, - .round_rate = clk_prcmu_round_rate, - .set_rate = clk_prcmu_set_rate, -}; - static struct clk_ops clk_prcmu_rate_ops = { .is_enabled = clk_prcmu_is_enabled, .recalc_rate = clk_prcmu_recalc_rate, @@ -208,17 +167,6 @@ static struct clk_ops clk_prcmu_opp_gate_ops = { .recalc_rate = clk_prcmu_recalc_rate, }; -static struct clk_ops clk_prcmu_opp_volt_scalable_ops = { - .prepare = clk_prcmu_opp_volt_prepare, - .unprepare = clk_prcmu_opp_volt_unprepare, - .enable = clk_prcmu_enable, - .disable = clk_prcmu_disable, - .is_enabled = clk_prcmu_is_enabled, - .recalc_rate = clk_prcmu_recalc_rate, - .round_rate = clk_prcmu_round_rate, - .set_rate = clk_prcmu_set_rate, -}; - static struct clk *clk_reg_prcmu(const char *name, const char *parent_name, u8 cg_sel, @@ -285,16 +233,6 @@ struct clk *clk_reg_prcmu_gate(const char *name, &clk_prcmu_gate_ops); } -struct clk *clk_reg_prcmu_scalable_rate(const char *name, - const char *parent_name, - u8 cg_sel, - unsigned long rate, - unsigned long flags) -{ - return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags, - &clk_prcmu_scalable_rate_ops); -} - struct clk *clk_reg_prcmu_rate(const char *name, const char *parent_name, u8 cg_sel, @@ -312,13 +250,3 @@ struct clk *clk_reg_prcmu_opp_gate(const char *name, return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags, &clk_prcmu_opp_gate_ops); } - -struct clk *clk_reg_prcmu_opp_volt_scalable(const char *name, - const char *parent_name, - u8 cg_sel, - unsigned long rate, - unsigned long flags) -{ - return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags, - &clk_prcmu_opp_volt_scalable_ops); -} diff --git a/trunk/drivers/clk/ux500/clk.h b/trunk/drivers/clk/ux500/clk.h index c3e449169a83..836d7d16751e 100644 --- a/trunk/drivers/clk/ux500/clk.h +++ b/trunk/drivers/clk/ux500/clk.h @@ -35,12 +35,6 @@ struct clk *clk_reg_prcmu_gate(const char *name, u8 cg_sel, unsigned long flags); -struct clk *clk_reg_prcmu_scalable_rate(const char *name, - const char *parent_name, - u8 cg_sel, - unsigned long rate, - unsigned long flags); - struct clk *clk_reg_prcmu_rate(const char *name, const char *parent_name, u8 cg_sel, @@ -51,10 +45,4 @@ struct clk *clk_reg_prcmu_opp_gate(const char *name, u8 cg_sel, unsigned long flags); -struct clk *clk_reg_prcmu_opp_volt_scalable(const char *name, - const char *parent_name, - u8 cg_sel, - unsigned long rate, - unsigned long flags); - #endif /* __UX500_CLK_H */ diff --git a/trunk/drivers/clk/ux500/u8500_clk.c b/trunk/drivers/clk/ux500/u8500_clk.c index 7d0e0258f204..ca4a25ed844c 100644 --- a/trunk/drivers/clk/ux500/u8500_clk.c +++ b/trunk/drivers/clk/ux500/u8500_clk.c @@ -40,7 +40,7 @@ void u8500_clk_init(void) CLK_IS_ROOT|CLK_IGNORE_UNUSED, 32768); clk_register_clkdev(clk, "clk32k", NULL); - clk_register_clkdev(clk, "apb_pclk", "rtc-pl031"); + clk_register_clkdev(clk, NULL, "rtc-pl031"); /* PRCMU clocks */ fw_version = prcmu_get_fw_version(); @@ -170,11 +170,10 @@ void u8500_clk_init(void) clk_register_clkdev(clk, NULL, "mtu0"); clk_register_clkdev(clk, NULL, "mtu1"); - clk = clk_reg_prcmu_opp_volt_scalable("sdmmcclk", NULL, PRCMU_SDMMCCLK, - 100000000, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + clk = clk_reg_prcmu_gate("sdmmcclk", NULL, PRCMU_SDMMCCLK, CLK_IS_ROOT); clk_register_clkdev(clk, NULL, "sdmmc"); + clk = clk_reg_prcmu_scalable("dsi_pll", "hdmiclk", PRCMU_PLLDSI, 0, CLK_SET_RATE_GATE); clk_register_clkdev(clk, "dsihs2", "mcde"); @@ -206,18 +205,16 @@ void u8500_clk_init(void) clk_register_clkdev(clk, "dsilp2", "dsilink.2"); clk_register_clkdev(clk, "dsilp2", "mcde"); - clk = clk_reg_prcmu_scalable_rate("armss", NULL, - PRCMU_ARMSS, 0, CLK_IS_ROOT|CLK_IGNORE_UNUSED); - clk_register_clkdev(clk, "armss", NULL); - - clk = clk_register_fixed_factor(NULL, "smp_twd", "armss", - CLK_IGNORE_UNUSED, 1, 2); + clk = clk_reg_prcmu_rate("smp_twd", NULL, PRCMU_ARMSS, + CLK_IS_ROOT|CLK_GET_RATE_NOCACHE| + CLK_IGNORE_UNUSED); clk_register_clkdev(clk, NULL, "smp_twd"); /* * FIXME: Add special handled PRCMU clocks here: - * 1. clkout0yuv, use PRCMU as parent + need regulator + pinctrl. - * 2. ab9540_clkout1yuv, see clkout0yuv + * 1. clk_arm, use PRCMU_ARMCLK. + * 2. clkout0yuv, use PRCMU as parent + need regulator + pinctrl. + * 3. ab9540_clkout1yuv, see clkout0yuv */ /* PRCC P-clocks */ @@ -231,17 +228,10 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", U8500_CLKRST1_BASE, BIT(2), 0); - clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.1"); - clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE, BIT(3), 0); - clk_register_clkdev(clk, "apb_pclk", "msp0"); - clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.0"); - clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE, BIT(4), 0); - clk_register_clkdev(clk, "apb_pclk", "msp1"); - clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.1"); clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", U8500_CLKRST1_BASE, BIT(5), 0); @@ -249,7 +239,6 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", U8500_CLKRST1_BASE, BIT(6), 0); - clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.2"); clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", U8500_CLKRST1_BASE, BIT(7), 0); @@ -257,7 +246,6 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", U8500_CLKRST1_BASE, BIT(8), 0); - clk_register_clkdev(clk, "apb_pclk", "slimbus0"); clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", U8500_CLKRST1_BASE, BIT(9), 0); @@ -267,16 +255,11 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", U8500_CLKRST1_BASE, BIT(10), 0); - clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.4"); - clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE, BIT(11), 0); - clk_register_clkdev(clk, "apb_pclk", "msp3"); - clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.3"); clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE, BIT(0), 0); - clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.3"); clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", U8500_CLKRST2_BASE, BIT(1), 0); @@ -296,13 +279,12 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", U8500_CLKRST2_BASE, BIT(5), 0); - clk_register_clkdev(clk, "apb_pclk", "msp2"); - clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.2"); clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", U8500_CLKRST2_BASE, BIT(6), 0); clk_register_clkdev(clk, "apb_pclk", "sdi1"); + clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", U8500_CLKRST2_BASE, BIT(7), 0); clk_register_clkdev(clk, "apb_pclk", "sdi3"); @@ -326,7 +308,7 @@ void u8500_clk_init(void) clk_register_clkdev(clk, NULL, "gpioblock1"); clk = clk_reg_prcc_pclk("p2_pclk12", "per2clk", U8500_CLKRST2_BASE, - BIT(12), 0); + BIT(11), 0); clk = clk_reg_prcc_pclk("p3_pclk0", "per3clk", U8500_CLKRST3_BASE, BIT(0), 0); @@ -334,15 +316,10 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", U8500_CLKRST3_BASE, BIT(1), 0); - clk_register_clkdev(clk, "apb_pclk", "ssp0"); - clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE, BIT(2), 0); - clk_register_clkdev(clk, "apb_pclk", "ssp1"); - clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE, BIT(3), 0); - clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.0"); clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", U8500_CLKRST3_BASE, BIT(4), 0); @@ -350,8 +327,6 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p3_pclk5", "per3clk", U8500_CLKRST3_BASE, BIT(5), 0); - clk_register_clkdev(clk, "apb_pclk", "ske"); - clk_register_clkdev(clk, "apb_pclk", "nmk-ske-keypad"); clk = clk_reg_prcc_pclk("p3_pclk6", "per3clk", U8500_CLKRST3_BASE, BIT(6), 0); @@ -380,7 +355,6 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p6_pclk0", "per6clk", U8500_CLKRST6_BASE, BIT(0), 0); - clk_register_clkdev(clk, "apb_pclk", "rng"); clk = clk_reg_prcc_pclk("p6_pclk1", "per6clk", U8500_CLKRST6_BASE, BIT(1), 0); @@ -427,17 +401,10 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(2), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "nmk-i2c.1"); - clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk", U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "msp0"); - clk_register_clkdev(clk, NULL, "ux500-msp-i2s.0"); - clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk", U8500_CLKRST1_BASE, BIT(4), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "msp1"); - clk_register_clkdev(clk, NULL, "ux500-msp-i2s.1"); clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmcclk", U8500_CLKRST1_BASE, BIT(5), CLK_SET_RATE_GATE); @@ -445,25 +412,17 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(6), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "nmk-i2c.2"); - clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk", - U8500_CLKRST1_BASE, BIT(8), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "slimbus0"); - + U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); + /* FIXME: Redefinition of BIT(3). */ clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "nmk-i2c.4"); - clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk", U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "msp3"); - clk_register_clkdev(clk, NULL, "ux500-msp-i2s.3"); /* Periph2 */ clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk", U8500_CLKRST2_BASE, BIT(0), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "nmk-i2c.3"); clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmcclk", U8500_CLKRST2_BASE, BIT(2), CLK_SET_RATE_GATE); @@ -471,8 +430,6 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk", U8500_CLKRST2_BASE, BIT(3), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "msp2"); - clk_register_clkdev(clk, NULL, "ux500-msp-i2s.2"); clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmcclk", U8500_CLKRST2_BASE, BIT(4), CLK_SET_RATE_GATE); @@ -493,15 +450,10 @@ void u8500_clk_init(void) /* Periph3 */ clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk", U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "ssp0"); - clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk", U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "ssp1"); - clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk", U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "nmk-i2c.0"); clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmcclk", U8500_CLKRST3_BASE, BIT(4), CLK_SET_RATE_GATE); @@ -509,8 +461,6 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p3_ske_kclk", "rtc32k", U8500_CLKRST3_BASE, BIT(5), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "ske"); - clk_register_clkdev(clk, NULL, "nmk-ske-keypad"); clk = clk_reg_prcc_kclk("p3_uart2_kclk", "uartclk", U8500_CLKRST3_BASE, BIT(6), CLK_SET_RATE_GATE); @@ -523,5 +473,5 @@ void u8500_clk_init(void) /* Periph6 */ clk = clk_reg_prcc_kclk("p3_rng_kclk", "rngclk", U8500_CLKRST6_BASE, BIT(0), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "rng"); + } diff --git a/trunk/drivers/clk/versatile/Makefile b/trunk/drivers/clk/versatile/Makefile index ec3b88fe3e6d..c0a0f6478798 100644 --- a/trunk/drivers/clk/versatile/Makefile +++ b/trunk/drivers/clk/versatile/Makefile @@ -1,7 +1,4 @@ # Makefile for Versatile-specific clocks obj-$(CONFIG_ICST) += clk-icst.o obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o -obj-$(CONFIG_INTEGRATOR_IMPD1) += clk-impd1.o obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o -obj-$(CONFIG_ARCH_VEXPRESS) += clk-vexpress.o -obj-$(CONFIG_VEXPRESS_CONFIG) += clk-vexpress-osc.o diff --git a/trunk/drivers/clk/versatile/clk-icst.c b/trunk/drivers/clk/versatile/clk-icst.c index 67ccf4aa7277..f555b50a5fa5 100644 --- a/trunk/drivers/clk/versatile/clk-icst.c +++ b/trunk/drivers/clk/versatile/clk-icst.c @@ -3,12 +3,6 @@ * We wrap the custom interface from into the generic * clock framework. * - * Copyright (C) 2012 Linus Walleij - * - * 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. - * * TODO: when all ARM reference designs are migrated to generic clocks, the * ICST clock code from the ARM tree should probably be merged into this * file. @@ -17,74 +11,33 @@ #include #include #include -#include #include "clk-icst.h" /** * struct clk_icst - ICST VCO clock wrapper * @hw: corresponding clock hardware entry - * @vcoreg: VCO register address - * @lockreg: VCO lock register address * @params: parameters for this ICST instance * @rate: current rate + * @setvco: function to commit ICST settings to hardware */ struct clk_icst { struct clk_hw hw; - void __iomem *vcoreg; - void __iomem *lockreg; const struct icst_params *params; unsigned long rate; + struct icst_vco (*getvco)(void); + void (*setvco)(struct icst_vco); }; #define to_icst(_hw) container_of(_hw, struct clk_icst, hw) -/** - * vco_get() - get ICST VCO settings from a certain register - * @vcoreg: register containing the VCO settings - */ -static struct icst_vco vco_get(void __iomem *vcoreg) -{ - u32 val; - struct icst_vco vco; - - val = readl(vcoreg); - vco.v = val & 0x1ff; - vco.r = (val >> 9) & 0x7f; - vco.s = (val >> 16) & 03; - return vco; -} - -/** - * vco_set() - commit changes to an ICST VCO - * @locreg: register to poke to unlock the VCO for writing - * @vcoreg: register containing the VCO settings - * @vco: ICST VCO parameters to commit - */ -static void vco_set(void __iomem *lockreg, - void __iomem *vcoreg, - struct icst_vco vco) -{ - u32 val; - - val = readl(vcoreg) & ~0x7ffff; - val |= vco.v | (vco.r << 9) | (vco.s << 16); - - /* This magic unlocks the VCO so it can be controlled */ - writel(0xa05f, lockreg); - writel(val, vcoreg); - /* This locks the VCO again */ - writel(0, lockreg); -} - - static unsigned long icst_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct clk_icst *icst = to_icst(hw); struct icst_vco vco; - vco = vco_get(icst->vcoreg); + vco = icst->getvco(); icst->rate = icst_hz(icst->params, vco); return icst->rate; } @@ -107,7 +60,7 @@ static int icst_set_rate(struct clk_hw *hw, unsigned long rate, vco = icst_hz_to_vco(icst->params, rate); icst->rate = icst_hz(icst->params, vco); - vco_set(icst->vcoreg, icst->lockreg, vco); + icst->setvco(vco); return 0; } @@ -117,9 +70,8 @@ static const struct clk_ops icst_ops = { .set_rate = icst_set_rate, }; -struct clk *icst_clk_register(struct device *dev, - const struct clk_icst_desc *desc, - void __iomem *base) +struct clk * __init icst_clk_register(struct device *dev, + const struct clk_icst_desc *desc) { struct clk *clk; struct clk_icst *icst; @@ -137,8 +89,8 @@ struct clk *icst_clk_register(struct device *dev, init.num_parents = 0; icst->hw.init = &init; icst->params = desc->params; - icst->vcoreg = base + desc->vco_offset; - icst->lockreg = base + desc->lock_offset; + icst->getvco = desc->getvco; + icst->setvco = desc->setvco; clk = clk_register(dev, &icst->hw); if (IS_ERR(clk)) diff --git a/trunk/drivers/clk/versatile/clk-icst.h b/trunk/drivers/clk/versatile/clk-icst.h index dad51b6ffd00..71b4c56c1410 100644 --- a/trunk/drivers/clk/versatile/clk-icst.h +++ b/trunk/drivers/clk/versatile/clk-icst.h @@ -1,18 +1,10 @@ #include -/** - * struct clk_icst_desc - descriptor for the ICST VCO - * @params: ICST parameters - * @vco_offset: offset to the ICST VCO from the provided memory base - * @lock_offset: offset to the ICST VCO locking register from the provided - * memory base - */ struct clk_icst_desc { const struct icst_params *params; - u32 vco_offset; - u32 lock_offset; + struct icst_vco (*getvco)(void); + void (*setvco)(struct icst_vco); }; struct clk *icst_clk_register(struct device *dev, - const struct clk_icst_desc *desc, - void __iomem *base); + const struct clk_icst_desc *desc); diff --git a/trunk/drivers/clk/versatile/clk-impd1.c b/trunk/drivers/clk/versatile/clk-impd1.c deleted file mode 100644 index 369139af2a3b..000000000000 --- a/trunk/drivers/clk/versatile/clk-impd1.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Clock driver for the ARM Integrator/IM-PD1 board - * Copyright (C) 2012 Linus Walleij - * - * 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. - */ -#include -#include -#include -#include -#include -#include - -#include - -#include "clk-icst.h" - -struct impd1_clk { - struct clk *vcoclk; - struct clk *uartclk; - struct clk_lookup *clks[3]; -}; - -static struct impd1_clk impd1_clks[4]; - -/* - * There are two VCO's on the IM-PD1 but only one is used by the - * kernel, that is why we are only implementing the control of - * IMPD1_OSC1 here. - */ - -static const struct icst_params impd1_vco_params = { - .ref = 24000000, /* 24 MHz */ - .vco_max = ICST525_VCO_MAX_3V, - .vco_min = ICST525_VCO_MIN, - .vd_min = 12, - .vd_max = 519, - .rd_min = 3, - .rd_max = 120, - .s2div = icst525_s2div, - .idx2s = icst525_idx2s, -}; - -static const struct clk_icst_desc impd1_icst1_desc = { - .params = &impd1_vco_params, - .vco_offset = IMPD1_OSC1, - .lock_offset = IMPD1_LOCK, -}; - -/** - * integrator_impd1_clk_init() - set up the integrator clock tree - * @base: base address of the logic module (LM) - * @id: the ID of this LM - */ -void integrator_impd1_clk_init(void __iomem *base, unsigned int id) -{ - struct impd1_clk *imc; - struct clk *clk; - int i; - - if (id > 3) { - pr_crit("no more than 4 LMs can be attached\n"); - return; - } - imc = &impd1_clks[id]; - - clk = icst_clk_register(NULL, &impd1_icst1_desc, base); - imc->vcoclk = clk; - imc->clks[0] = clkdev_alloc(clk, NULL, "lm%x:01000", id); - - /* UART reference clock */ - clk = clk_register_fixed_rate(NULL, "uartclk", NULL, CLK_IS_ROOT, - 14745600); - imc->uartclk = clk; - imc->clks[1] = clkdev_alloc(clk, NULL, "lm%x:00100", id); - imc->clks[2] = clkdev_alloc(clk, NULL, "lm%x:00200", id); - - for (i = 0; i < ARRAY_SIZE(imc->clks); i++) - clkdev_add(imc->clks[i]); -} - -void integrator_impd1_clk_exit(unsigned int id) -{ - int i; - struct impd1_clk *imc; - - if (id > 3) - return; - imc = &impd1_clks[id]; - - for (i = 0; i < ARRAY_SIZE(imc->clks); i++) - clkdev_drop(imc->clks[i]); - clk_unregister(imc->uartclk); - clk_unregister(imc->vcoclk); -} diff --git a/trunk/drivers/clk/versatile/clk-integrator.c b/trunk/drivers/clk/versatile/clk-integrator.c index 08593b4ee2c9..a5053921bf7f 100644 --- a/trunk/drivers/clk/versatile/clk-integrator.c +++ b/trunk/drivers/clk/versatile/clk-integrator.c @@ -1,16 +1,8 @@ -/* - * Clock driver for the ARM Integrator/AP and Integrator/CP boards - * Copyright (C) 2012 Linus Walleij - * - * 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. - */ -#include #include #include #include -#include +#include +#include #include #include @@ -22,6 +14,42 @@ * Inspired by portions of: * plat-versatile/clock.c and plat-versatile/include/plat/clock.h */ +#define CM_LOCK (__io_address(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET) +#define CM_AUXOSC (__io_address(INTEGRATOR_HDR_BASE)+0x1c) + +/** + * cp_auxvco_get() - get ICST VCO settings for the Integrator/CP + * @vco: ICST VCO parameters to update with hardware status + */ +static struct icst_vco cp_auxvco_get(void) +{ + u32 val; + struct icst_vco vco; + + val = readl(CM_AUXOSC); + vco.v = val & 0x1ff; + vco.r = (val >> 9) & 0x7f; + vco.s = (val >> 16) & 03; + return vco; +} + +/** + * cp_auxvco_set() - commit changes to Integrator/CP ICST VCO + * @vco: ICST VCO parameters to commit + */ +static void cp_auxvco_set(struct icst_vco vco) +{ + u32 val; + + val = readl(CM_AUXOSC) & ~0x7ffff; + val |= vco.v | (vco.r << 9) | (vco.s << 16); + + /* This magic unlocks the CM VCO so it can be controlled */ + writel(0xa05f, CM_LOCK); + writel(val, CM_AUXOSC); + /* This locks the CM again */ + writel(0, CM_LOCK); +} static const struct icst_params cp_auxvco_params = { .ref = 24000000, @@ -37,8 +65,8 @@ static const struct icst_params cp_auxvco_params = { static const struct clk_icst_desc __initdata cp_icst_desc = { .params = &cp_auxvco_params, - .vco_offset = 0x1c, - .lock_offset = INTEGRATOR_HDR_LOCK_OFFSET, + .getvco = cp_auxvco_get, + .setvco = cp_auxvco_set, }; /* @@ -78,7 +106,6 @@ void __init integrator_clk_init(bool is_cp) clk_register_clkdev(clk, NULL, "sp804"); /* ICST VCO clock used on the Integrator/CP CLCD */ - clk = icst_clk_register(NULL, &cp_icst_desc, - __io_address(INTEGRATOR_HDR_BASE)); + clk = icst_clk_register(NULL, &cp_icst_desc); clk_register_clkdev(clk, NULL, "clcd"); } diff --git a/trunk/drivers/clk/versatile/clk-realview.c b/trunk/drivers/clk/versatile/clk-realview.c index cda07e70a408..e21a99cef378 100644 --- a/trunk/drivers/clk/versatile/clk-realview.c +++ b/trunk/drivers/clk/versatile/clk-realview.c @@ -1,11 +1,3 @@ -/* - * Clock driver for the ARM RealView boards - * Copyright (C) 2012 Linus Walleij - * - * 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. - */ #include #include #include @@ -21,6 +13,38 @@ * Implementation of the ARM RealView clock trees. */ +static void __iomem *sys_lock; +static void __iomem *sys_vcoreg; + +/** + * realview_oscvco_get() - get ICST OSC settings for the RealView + */ +static struct icst_vco realview_oscvco_get(void) +{ + u32 val; + struct icst_vco vco; + + val = readl(sys_vcoreg); + vco.v = val & 0x1ff; + vco.r = (val >> 9) & 0x7f; + vco.s = (val >> 16) & 03; + return vco; +} + +static void realview_oscvco_set(struct icst_vco vco) +{ + u32 val; + + val = readl(sys_vcoreg) & ~0x7ffff; + val |= vco.v | (vco.r << 9) | (vco.s << 16); + + /* This magic unlocks the CM VCO so it can be controlled */ + writel(0xa05f, sys_lock); + writel(val, sys_vcoreg); + /* This locks the CM again */ + writel(0, sys_lock); +} + static const struct icst_params realview_oscvco_params = { .ref = 24000000, .vco_max = ICST307_VCO_MAX, @@ -33,16 +57,10 @@ static const struct icst_params realview_oscvco_params = { .idx2s = icst307_idx2s, }; -static const struct clk_icst_desc __initdata realview_osc0_desc = { - .params = &realview_oscvco_params, - .vco_offset = REALVIEW_SYS_OSC0_OFFSET, - .lock_offset = REALVIEW_SYS_LOCK_OFFSET, -}; - -static const struct clk_icst_desc __initdata realview_osc4_desc = { +static const struct clk_icst_desc __initdata realview_icst_desc = { .params = &realview_oscvco_params, - .vco_offset = REALVIEW_SYS_OSC4_OFFSET, - .lock_offset = REALVIEW_SYS_LOCK_OFFSET, + .getvco = realview_oscvco_get, + .setvco = realview_oscvco_set, }; /* @@ -52,6 +70,13 @@ void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176) { struct clk *clk; + sys_lock = sysbase + REALVIEW_SYS_LOCK_OFFSET; + if (is_pb1176) + sys_vcoreg = sysbase + REALVIEW_SYS_OSC0_OFFSET; + else + sys_vcoreg = sysbase + REALVIEW_SYS_OSC4_OFFSET; + + /* APB clock dummy */ clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0); clk_register_clkdev(clk, "apb_pclk", NULL); @@ -83,11 +108,7 @@ void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176) clk_register_clkdev(clk, NULL, "sp804"); /* ICST VCO clock */ - if (is_pb1176) - clk = icst_clk_register(NULL, &realview_osc0_desc, sysbase); - else - clk = icst_clk_register(NULL, &realview_osc4_desc, sysbase); - + clk = icst_clk_register(NULL, &realview_icst_desc); clk_register_clkdev(clk, NULL, "dev:clcd"); clk_register_clkdev(clk, NULL, "issp:clcd"); } diff --git a/trunk/drivers/clk/versatile/clk-vexpress-osc.c b/trunk/drivers/clk/versatile/clk-vexpress-osc.c deleted file mode 100644 index dcb6ae0a0425..000000000000 --- a/trunk/drivers/clk/versatile/clk-vexpress-osc.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * 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. - * - * Copyright (C) 2012 ARM Limited - */ - -#define pr_fmt(fmt) "vexpress-osc: " fmt - -#include -#include -#include -#include -#include -#include -#include - -struct vexpress_osc { - struct vexpress_config_func *func; - struct clk_hw hw; - unsigned long rate_min; - unsigned long rate_max; -}; - -#define to_vexpress_osc(osc) container_of(osc, struct vexpress_osc, hw) - -static unsigned long vexpress_osc_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct vexpress_osc *osc = to_vexpress_osc(hw); - u32 rate; - - vexpress_config_read(osc->func, 0, &rate); - - return rate; -} - -static long vexpress_osc_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - struct vexpress_osc *osc = to_vexpress_osc(hw); - - if (WARN_ON(osc->rate_min && rate < osc->rate_min)) - rate = osc->rate_min; - - if (WARN_ON(osc->rate_max && rate > osc->rate_max)) - rate = osc->rate_max; - - return rate; -} - -static int vexpress_osc_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct vexpress_osc *osc = to_vexpress_osc(hw); - - return vexpress_config_write(osc->func, 0, rate); -} - -static struct clk_ops vexpress_osc_ops = { - .recalc_rate = vexpress_osc_recalc_rate, - .round_rate = vexpress_osc_round_rate, - .set_rate = vexpress_osc_set_rate, -}; - - -struct clk * __init vexpress_osc_setup(struct device *dev) -{ - struct clk_init_data init; - struct vexpress_osc *osc = kzalloc(sizeof(*osc), GFP_KERNEL); - - if (!osc) - return NULL; - - osc->func = vexpress_config_func_get_by_dev(dev); - if (!osc->func) { - kfree(osc); - return NULL; - } - - init.name = dev_name(dev); - init.ops = &vexpress_osc_ops; - init.flags = CLK_IS_ROOT; - init.num_parents = 0; - osc->hw.init = &init; - - return clk_register(NULL, &osc->hw); -} - -void __init vexpress_osc_of_setup(struct device_node *node) -{ - struct clk_init_data init; - struct vexpress_osc *osc; - struct clk *clk; - u32 range[2]; - - osc = kzalloc(sizeof(*osc), GFP_KERNEL); - if (!osc) - goto error; - - osc->func = vexpress_config_func_get_by_node(node); - if (!osc->func) { - pr_err("Failed to obtain config func for node '%s'!\n", - node->name); - goto error; - } - - if (of_property_read_u32_array(node, "freq-range", range, - ARRAY_SIZE(range)) == 0) { - osc->rate_min = range[0]; - osc->rate_max = range[1]; - } - - of_property_read_string(node, "clock-output-names", &init.name); - if (!init.name) - init.name = node->name; - - init.ops = &vexpress_osc_ops; - init.flags = CLK_IS_ROOT; - init.num_parents = 0; - - osc->hw.init = &init; - - clk = clk_register(NULL, &osc->hw); - if (IS_ERR(clk)) { - pr_err("Failed to register clock '%s'!\n", init.name); - goto error; - } - - of_clk_add_provider(node, of_clk_src_simple_get, clk); - - pr_debug("Registered clock '%s'\n", init.name); - - return; - -error: - if (osc->func) - vexpress_config_func_put(osc->func); - kfree(osc); -} diff --git a/trunk/drivers/clk/versatile/clk-vexpress.c b/trunk/drivers/clk/versatile/clk-vexpress.c deleted file mode 100644 index c742ac7c60bb..000000000000 --- a/trunk/drivers/clk/versatile/clk-vexpress.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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. - * - * Copyright (C) 2012 ARM Limited - */ - -#include -#include -#include -#include -#include -#include - -#include - -static struct clk *vexpress_sp810_timerclken[4]; -static DEFINE_SPINLOCK(vexpress_sp810_lock); - -static void __init vexpress_sp810_init(void __iomem *base) -{ - int i; - - if (WARN_ON(!base)) - return; - - for (i = 0; i < ARRAY_SIZE(vexpress_sp810_timerclken); i++) { - char name[12]; - const char *parents[] = { - "v2m:refclk32khz", /* REFCLK */ - "v2m:refclk1mhz" /* TIMCLK */ - }; - - snprintf(name, ARRAY_SIZE(name), "timerclken%d", i); - - vexpress_sp810_timerclken[i] = clk_register_mux(NULL, name, - parents, 2, 0, base + SCCTRL, - SCCTRL_TIMERENnSEL_SHIFT(i), 1, - 0, &vexpress_sp810_lock); - - if (WARN_ON(IS_ERR(vexpress_sp810_timerclken[i]))) - break; - } -} - - -static const char * const vexpress_clk_24mhz_periphs[] __initconst = { - "mb:uart0", "mb:uart1", "mb:uart2", "mb:uart3", - "mb:mmci", "mb:kmi0", "mb:kmi1" -}; - -void __init vexpress_clk_init(void __iomem *sp810_base) -{ - struct clk *clk; - int i; - - clk = clk_register_fixed_rate(NULL, "dummy_apb_pclk", NULL, - CLK_IS_ROOT, 0); - WARN_ON(clk_register_clkdev(clk, "apb_pclk", NULL)); - - clk = clk_register_fixed_rate(NULL, "v2m:clk_24mhz", NULL, - CLK_IS_ROOT, 24000000); - for (i = 0; i < ARRAY_SIZE(vexpress_clk_24mhz_periphs); i++) - WARN_ON(clk_register_clkdev(clk, NULL, - vexpress_clk_24mhz_periphs[i])); - - clk = clk_register_fixed_rate(NULL, "v2m:refclk32khz", NULL, - CLK_IS_ROOT, 32768); - WARN_ON(clk_register_clkdev(clk, NULL, "v2m:wdt")); - - clk = clk_register_fixed_rate(NULL, "v2m:refclk1mhz", NULL, - CLK_IS_ROOT, 1000000); - - vexpress_sp810_init(sp810_base); - - for (i = 0; i < ARRAY_SIZE(vexpress_sp810_timerclken); i++) - WARN_ON(clk_set_parent(vexpress_sp810_timerclken[i], clk)); - - WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[0], - "v2m-timer0", "sp804")); - WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[1], - "v2m-timer1", "sp804")); -} - -#if defined(CONFIG_OF) - -struct clk *vexpress_sp810_of_get(struct of_phandle_args *clkspec, void *data) -{ - if (WARN_ON(clkspec->args_count != 1 || clkspec->args[0] > - ARRAY_SIZE(vexpress_sp810_timerclken))) - return NULL; - - return vexpress_sp810_timerclken[clkspec->args[0]]; -} - -static const __initconst struct of_device_id vexpress_fixed_clk_match[] = { - { .compatible = "fixed-clock", .data = of_fixed_clk_setup, }, - { .compatible = "arm,vexpress-osc", .data = vexpress_osc_of_setup, }, - {} -}; - -void __init vexpress_clk_of_init(void) -{ - struct device_node *node; - struct clk *clk; - struct clk *refclk, *timclk; - - of_clk_init(vexpress_fixed_clk_match); - - node = of_find_compatible_node(NULL, NULL, "arm,sp810"); - vexpress_sp810_init(of_iomap(node, 0)); - of_clk_add_provider(node, vexpress_sp810_of_get, NULL); - - /* Select "better" (faster) parent for SP804 timers */ - refclk = of_clk_get_by_name(node, "refclk"); - timclk = of_clk_get_by_name(node, "timclk"); - if (!WARN_ON(IS_ERR(refclk) || IS_ERR(timclk))) { - int i = 0; - - if (clk_get_rate(refclk) > clk_get_rate(timclk)) - clk = refclk; - else - clk = timclk; - - for (i = 0; i < ARRAY_SIZE(vexpress_sp810_timerclken); i++) - WARN_ON(clk_set_parent(vexpress_sp810_timerclken[i], - clk)); - } - - WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[0], - "v2m-timer0", "sp804")); - WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[1], - "v2m-timer1", "sp804")); -} - -#endif diff --git a/trunk/drivers/cpufreq/cpufreq_stats.c b/trunk/drivers/cpufreq/cpufreq_stats.c index 399831690fed..b40ee1403be9 100644 --- a/trunk/drivers/cpufreq/cpufreq_stats.c +++ b/trunk/drivers/cpufreq/cpufreq_stats.c @@ -328,7 +328,6 @@ static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb, cpufreq_update_policy(cpu); break; case CPU_DOWN_PREPARE: - case CPU_DOWN_PREPARE_FROZEN: cpufreq_stats_free_sysfs(cpu); break; case CPU_DEAD: diff --git a/trunk/drivers/cpufreq/db8500-cpufreq.c b/trunk/drivers/cpufreq/db8500-cpufreq.c index 4f154bc0ebe4..74b830b635a6 100644 --- a/trunk/drivers/cpufreq/db8500-cpufreq.c +++ b/trunk/drivers/cpufreq/db8500-cpufreq.c @@ -8,17 +8,43 @@ * Author: Jonas Aaberg * */ -#include #include #include #include #include -#include -#include +#include #include -static struct cpufreq_frequency_table *freq_table; -static struct clk *armss_clk; +static struct cpufreq_frequency_table freq_table[] = { + [0] = { + .index = 0, + .frequency = 200000, + }, + [1] = { + .index = 1, + .frequency = 400000, + }, + [2] = { + .index = 2, + .frequency = 800000, + }, + [3] = { + /* Used for MAX_OPP, if available */ + .index = 3, + .frequency = CPUFREQ_TABLE_END, + }, + [4] = { + .index = 4, + .frequency = CPUFREQ_TABLE_END, + }, +}; + +static enum arm_opp idx2opp[] = { + ARM_EXTCLK, + ARM_50_OPP, + ARM_100_OPP, + ARM_MAX_OPP +}; static struct freq_attr *db8500_cpufreq_attr[] = { &cpufreq_freq_attr_scaling_available_freqs, @@ -59,9 +85,9 @@ static int db8500_cpufreq_target(struct cpufreq_policy *policy, for_each_cpu(freqs.cpu, policy->cpus) cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - /* update armss clk frequency */ - if (clk_set_rate(armss_clk, freq_table[idx].frequency * 1000)) { - pr_err("db8500-cpufreq: Failed to update armss clk\n"); + /* request the PRCM unit for opp change */ + if (prcmu_set_arm_opp(idx2opp[idx])) { + pr_err("db8500-cpufreq: Failed to set OPP level\n"); return -EINVAL; } @@ -74,36 +100,25 @@ static int db8500_cpufreq_target(struct cpufreq_policy *policy, static unsigned int db8500_cpufreq_getspeed(unsigned int cpu) { - int i = 0; - unsigned long freq = clk_get_rate(armss_clk) / 1000; - - while (freq_table[i].frequency != CPUFREQ_TABLE_END) { - if (freq <= freq_table[i].frequency) - return freq_table[i].frequency; - i++; - } - - /* We could not find a corresponding frequency. */ - pr_err("db8500-cpufreq: Failed to find cpufreq speed\n"); - return 0; + int i; + /* request the prcm to get the current ARM opp */ + for (i = 0; prcmu_get_arm_opp() != idx2opp[i]; i++) + ; + return freq_table[i].frequency; } static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy) { - int i = 0; - int res; + int i, res; - armss_clk = clk_get(NULL, "armss"); - if (IS_ERR(armss_clk)) { - pr_err("db8500-cpufreq : Failed to get armss clk\n"); - return PTR_ERR(armss_clk); - } + BUILD_BUG_ON(ARRAY_SIZE(idx2opp) + 1 != ARRAY_SIZE(freq_table)); + + if (prcmu_has_arm_maxopp()) + freq_table[3].frequency = 1000000; pr_info("db8500-cpufreq : Available frequencies:\n"); - while (freq_table[i].frequency != CPUFREQ_TABLE_END) { + for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) pr_info(" %d Mhz\n", freq_table[i].frequency/1000); - i++; - } /* get policy fields based on the table */ res = cpufreq_frequency_table_cpuinfo(policy, freq_table); @@ -111,7 +126,6 @@ static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy) cpufreq_frequency_table_get_attr(freq_table, policy->cpu); else { pr_err("db8500-cpufreq : Failed to read policy table\n"); - clk_put(armss_clk); return res; } @@ -145,35 +159,12 @@ static struct cpufreq_driver db8500_cpufreq_driver = { .attr = db8500_cpufreq_attr, }; -static int db8500_cpufreq_probe(struct platform_device *pdev) -{ - freq_table = dev_get_platdata(&pdev->dev); - - if (!freq_table) { - pr_err("db8500-cpufreq: Failed to fetch cpufreq table\n"); - return -ENODEV; - } - - return cpufreq_register_driver(&db8500_cpufreq_driver); -} - -static struct platform_driver db8500_cpufreq_plat_driver = { - .driver = { - .name = "cpufreq-u8500", - .owner = THIS_MODULE, - }, - .probe = db8500_cpufreq_probe, -}; - static int __init db8500_cpufreq_register(void) { if (!cpu_is_u8500_family()) return -ENODEV; pr_info("cpufreq for DB8500 started\n"); - return platform_driver_register(&db8500_cpufreq_plat_driver); + return cpufreq_register_driver(&db8500_cpufreq_driver); } device_initcall(db8500_cpufreq_register); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("cpufreq driver for DB8500"); diff --git a/trunk/drivers/cpufreq/powernow-k8.c b/trunk/drivers/cpufreq/powernow-k8.c index e3ebb4fa2c3e..129e80bfff22 100644 --- a/trunk/drivers/cpufreq/powernow-k8.c +++ b/trunk/drivers/cpufreq/powernow-k8.c @@ -5,7 +5,7 @@ * http://www.gnu.org/licenses/gpl.html * * Maintainer: - * Andreas Herrmann + * Andreas Herrmann * * Based on the powernow-k7.c module written by Dave Jones. * (C) 2003 Dave Jones on behalf of SuSE Labs @@ -1052,7 +1052,14 @@ static int powernowk8_target(struct cpufreq_policy *pol, struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq, .relation = relation }; - return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); + /* + * Must run on @pol->cpu. cpufreq core is responsible for ensuring + * that we're bound to the current CPU and pol->cpu stays online. + */ + if (smp_processor_id() == pol->cpu) + return powernowk8_target_fn(&pta); + else + return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); } /* Driver entry point to verify the policy and range of frequencies */ diff --git a/trunk/drivers/crypto/Kconfig b/trunk/drivers/crypto/Kconfig index f6644f59fd9d..308c7fb92a60 100644 --- a/trunk/drivers/crypto/Kconfig +++ b/trunk/drivers/crypto/Kconfig @@ -224,7 +224,7 @@ config CRYPTO_DEV_TALITOS config CRYPTO_DEV_IXP4XX tristate "Driver for IXP4xx crypto hardware acceleration" - depends on ARCH_IXP4XX && IXP4XX_QMGR && IXP4XX_NPE + depends on ARCH_IXP4XX select CRYPTO_DES select CRYPTO_ALGAPI select CRYPTO_AUTHENC diff --git a/trunk/drivers/crypto/ixp4xx_crypto.c b/trunk/drivers/crypto/ixp4xx_crypto.c index 21180d6cad6e..8f3f74ce8c7f 100644 --- a/trunk/drivers/crypto/ixp4xx_crypto.c +++ b/trunk/drivers/crypto/ixp4xx_crypto.c @@ -750,12 +750,12 @@ static int setup_cipher(struct crypto_tfm *tfm, int encrypt, } if (cipher_cfg & MOD_AES) { switch (key_len) { - case 16: keylen_cfg = MOD_AES128; break; - case 24: keylen_cfg = MOD_AES192; break; - case 32: keylen_cfg = MOD_AES256; break; - default: - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; - return -EINVAL; + case 16: keylen_cfg = MOD_AES128 | KEYLEN_128; break; + case 24: keylen_cfg = MOD_AES192 | KEYLEN_192; break; + case 32: keylen_cfg = MOD_AES256 | KEYLEN_256; break; + default: + *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; } cipher_cfg |= keylen_cfg; } else if (cipher_cfg & MOD_3DES) { diff --git a/trunk/drivers/dma/Kconfig b/trunk/drivers/dma/Kconfig index d4c12180c654..677cd6e4e1a1 100644 --- a/trunk/drivers/dma/Kconfig +++ b/trunk/drivers/dma/Kconfig @@ -90,17 +90,6 @@ config DW_DMAC Support the Synopsys DesignWare AHB DMA controller. This can be integrated in chips such as the Atmel AT32ap7000. -config DW_DMAC_BIG_ENDIAN_IO - bool "Use big endian I/O register access" - default y if AVR32 - depends on DW_DMAC - help - Say yes here to use big endian I/O access when reading and writing - to the DMA controller registers. This is needed on some platforms, - like the Atmel AVR32 architecture. - - If unsure, use the default setting. - config AT_HDMAC tristate "Atmel AHB DMA support" depends on ARCH_AT91 diff --git a/trunk/drivers/dma/dw_dmac_regs.h b/trunk/drivers/dma/dw_dmac_regs.h index 88965597b7d0..ff39fa6cd2bc 100644 --- a/trunk/drivers/dma/dw_dmac_regs.h +++ b/trunk/drivers/dma/dw_dmac_regs.h @@ -98,17 +98,9 @@ struct dw_dma_regs { u32 DW_PARAMS; }; -#ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO -#define dma_readl_native ioread32be -#define dma_writel_native iowrite32be -#else -#define dma_readl_native readl -#define dma_writel_native writel -#endif - /* To access the registers in early stage of probe */ #define dma_read_byaddr(addr, name) \ - dma_readl_native((addr) + offsetof(struct dw_dma_regs, name)) + readl((addr) + offsetof(struct dw_dma_regs, name)) /* Bitfields in DW_PARAMS */ #define DW_PARAMS_NR_CHAN 8 /* number of channels */ @@ -224,9 +216,9 @@ __dwc_regs(struct dw_dma_chan *dwc) } #define channel_readl(dwc, name) \ - dma_readl_native(&(__dwc_regs(dwc)->name)) + readl(&(__dwc_regs(dwc)->name)) #define channel_writel(dwc, name, val) \ - dma_writel_native((val), &(__dwc_regs(dwc)->name)) + writel((val), &(__dwc_regs(dwc)->name)) static inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan) { @@ -254,9 +246,9 @@ static inline struct dw_dma_regs __iomem *__dw_regs(struct dw_dma *dw) } #define dma_readl(dw, name) \ - dma_readl_native(&(__dw_regs(dw)->name)) + readl(&(__dw_regs(dw)->name)) #define dma_writel(dw, name, val) \ - dma_writel_native((val), &(__dw_regs(dw)->name)) + writel((val), &(__dw_regs(dw)->name)) #define channel_set_bit(dw, reg, mask) \ dma_writel(dw, reg, ((mask) << 8) | (mask)) diff --git a/trunk/drivers/dma/imx-dma.c b/trunk/drivers/dma/imx-dma.c index 7d9554cc4976..f11b5b2b1a1c 100644 --- a/trunk/drivers/dma/imx-dma.c +++ b/trunk/drivers/dma/imx-dma.c @@ -474,10 +474,8 @@ static int imxdma_xfer_desc(struct imxdma_desc *d) slot = i; break; } - if (slot < 0) { - spin_unlock_irqrestore(&imxdma->lock, flags); + if (slot < 0) return -EBUSY; - } imxdma->slots_2d[slot].xsr = d->x; imxdma->slots_2d[slot].ysr = d->y; diff --git a/trunk/drivers/dma/sirf-dma.c b/trunk/drivers/dma/sirf-dma.c index d451caace806..64385cde044b 100644 --- a/trunk/drivers/dma/sirf-dma.c +++ b/trunk/drivers/dma/sirf-dma.c @@ -109,7 +109,7 @@ static void sirfsoc_dma_execute(struct sirfsoc_dma_chan *schan) sdesc = list_first_entry(&schan->queued, struct sirfsoc_dma_desc, node); /* Move the first queued descriptor to active list */ - list_move_tail(&sdesc->node, &schan->active); + list_move_tail(&schan->queued, &schan->active); /* Start the DMA transfer */ writel_relaxed(sdesc->width, sdma->base + SIRFSOC_DMA_WIDTH_0 + @@ -428,7 +428,7 @@ static struct dma_async_tx_descriptor *sirfsoc_dma_prep_interleaved( unsigned long iflags; int ret; - if ((xt->dir != DMA_MEM_TO_DEV) && (xt->dir != DMA_DEV_TO_MEM)) { + if ((xt->dir != DMA_MEM_TO_DEV) || (xt->dir != DMA_DEV_TO_MEM)) { ret = -EINVAL; goto err_dir; } diff --git a/trunk/drivers/edac/Kconfig b/trunk/drivers/edac/Kconfig index bb82d6be793c..409b92b8d346 100644 --- a/trunk/drivers/edac/Kconfig +++ b/trunk/drivers/edac/Kconfig @@ -42,10 +42,10 @@ config EDAC_LEGACY_SYSFS config EDAC_DEBUG bool "Debugging" help - This turns on debugging information for the entire EDAC subsystem. - You do so by inserting edac_module with "edac_debug_level=x." Valid - levels are 0-4 (from low to high) and by default it is set to 2. - Usually you should select 'N' here. + This turns on debugging information for the entire EDAC + sub-system. You can insert module with "debug_level=x", current + there're four debug levels (x=0,1,2,3 from low to high). + Usually you should select 'N'. config EDAC_DECODE_MCE tristate "Decode MCEs in human-readable form (only on AMD for now)" diff --git a/trunk/drivers/edac/amd64_edac.c b/trunk/drivers/edac/amd64_edac.c index f74a684269ff..5a297a26211d 100644 --- a/trunk/drivers/edac/amd64_edac.c +++ b/trunk/drivers/edac/amd64_edac.c @@ -60,8 +60,8 @@ struct scrubrate { { 0x00, 0UL}, /* scrubbing off */ }; -int __amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset, - u32 *val, const char *func) +static int __amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset, + u32 *val, const char *func) { int err = 0; @@ -170,11 +170,8 @@ static int __amd64_set_scrub_rate(struct pci_dev *ctl, u32 new_bw, u32 min_rate) * memory controller and apply to register. Search for the first * bandwidth entry that is greater or equal than the setting requested * and program that. If at last entry, turn off DRAM scrubbing. - * - * If no suitable bandwidth is found, turn off DRAM scrubbing entirely - * by falling back to the last element in scrubrates[]. */ - for (i = 0; i < ARRAY_SIZE(scrubrates) - 1; i++) { + for (i = 0; i < ARRAY_SIZE(scrubrates); i++) { /* * skip scrub rates which aren't recommended * (see F10 BKDG, F3x58) @@ -184,6 +181,12 @@ static int __amd64_set_scrub_rate(struct pci_dev *ctl, u32 new_bw, u32 min_rate) if (scrubrates[i].bandwidth <= new_bw) break; + + /* + * if no suitable bandwidth found, turn off DRAM scrubbing + * entirely by falling back to the last element in the + * scrubrates array. + */ } scrubval = scrubrates[i].scrubval; @@ -423,6 +426,7 @@ int amd64_get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base, u64 *hole_offset, u64 *hole_size) { struct amd64_pvt *pvt = mci->pvt_info; + u64 base; /* only revE and later have the DRAM Hole Address Register */ if (boot_cpu_data.x86 == 0xf && pvt->ext_model < K8_REV_E) { @@ -461,8 +465,10 @@ int amd64_get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base, * addresses in the hole so that they start at 0x100000000. */ - *hole_base = dhar_base(pvt); - *hole_size = (1ULL << 32) - *hole_base; + base = dhar_base(pvt); + + *hole_base = base; + *hole_size = (0x1ull << 32) - base; if (boot_cpu_data.x86 > 0xf) *hole_offset = f10_dhar_offset(pvt); @@ -510,15 +516,15 @@ static u64 sys_addr_to_dram_addr(struct mem_ctl_info *mci, u64 sys_addr) { struct amd64_pvt *pvt = mci->pvt_info; u64 dram_base, hole_base, hole_offset, hole_size, dram_addr; - int ret; + int ret = 0; dram_base = get_dram_base(pvt, pvt->mc_node_id); ret = amd64_get_dram_hole_info(mci, &hole_base, &hole_offset, &hole_size); if (!ret) { - if ((sys_addr >= (1ULL << 32)) && - (sys_addr < ((1ULL << 32) + hole_size))) { + if ((sys_addr >= (1ull << 32)) && + (sys_addr < ((1ull << 32) + hole_size))) { /* use DHAR to translate SysAddr to DramAddr */ dram_addr = sys_addr - hole_offset; @@ -709,10 +715,10 @@ static inline u64 input_addr_to_sys_addr(struct mem_ctl_info *mci, /* Map the Error address to a PAGE and PAGE OFFSET. */ static inline void error_address_to_page_and_offset(u64 error_address, - struct err_info *err) + u32 *page, u32 *offset) { - err->page = (u32) (error_address >> PAGE_SHIFT); - err->offset = ((u32) error_address) & ~PAGE_MASK; + *page = (u32) (error_address >> PAGE_SHIFT); + *offset = ((u32) error_address) & ~PAGE_MASK; } /* @@ -1023,44 +1029,59 @@ static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range) } static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr, - struct err_info *err) + u16 syndrome) { + struct mem_ctl_info *src_mci; struct amd64_pvt *pvt = mci->pvt_info; + int channel, csrow; + u32 page, offset; - error_address_to_page_and_offset(sys_addr, err); + error_address_to_page_and_offset(sys_addr, &page, &offset); /* * Find out which node the error address belongs to. This may be * different from the node that detected the error. */ - err->src_mci = find_mc_by_sys_addr(mci, sys_addr); - if (!err->src_mci) { + src_mci = find_mc_by_sys_addr(mci, sys_addr); + if (!src_mci) { amd64_mc_err(mci, "failed to map error addr 0x%lx to a node\n", (unsigned long)sys_addr); - err->err_code = ERR_NODE; + edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, + page, offset, syndrome, + -1, -1, -1, + "failed to map error addr to a node", + ""); return; } /* Now map the sys_addr to a CSROW */ - err->csrow = sys_addr_to_csrow(err->src_mci, sys_addr); - if (err->csrow < 0) { - err->err_code = ERR_CSROW; + csrow = sys_addr_to_csrow(src_mci, sys_addr); + if (csrow < 0) { + edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, + page, offset, syndrome, + -1, -1, -1, + "failed to map error addr to a csrow", + ""); return; } /* CHIPKILL enabled */ if (pvt->nbcfg & NBCFG_CHIPKILL) { - err->channel = get_channel_from_ecc_syndrome(mci, err->syndrome); - if (err->channel < 0) { + channel = get_channel_from_ecc_syndrome(mci, syndrome); + if (channel < 0) { /* * Syndrome didn't map, so we don't know which of the * 2 DIMMs is in error. So we need to ID 'both' of them * as suspect. */ - amd64_mc_warn(err->src_mci, "unknown syndrome 0x%04x - " + amd64_mc_warn(src_mci, "unknown syndrome 0x%04x - " "possible error reporting race\n", - err->syndrome); - err->err_code = ERR_CHANNEL; + syndrome); + edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, + page, offset, syndrome, + csrow, -1, -1, + "unknown syndrome - possible error reporting race", + ""); return; } } else { @@ -1072,8 +1093,13 @@ static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr, * was obtained from email communication with someone at AMD. * (Wish the email was placed in this comment - norsk) */ - err->channel = ((sys_addr & BIT(3)) != 0); + channel = ((sys_addr & BIT(3)) != 0); } + + edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, src_mci, 1, + page, offset, syndrome, + csrow, channel, -1, + "", ""); } static int ddr2_cs_size(unsigned i, bool dct_width) @@ -1459,7 +1485,7 @@ static u64 f1x_swap_interleaved_region(struct amd64_pvt *pvt, u64 sys_addr) /* For a given @dram_range, check if @sys_addr falls within it. */ static int f1x_match_to_this_node(struct amd64_pvt *pvt, unsigned range, - u64 sys_addr, int *chan_sel) + u64 sys_addr, int *nid, int *chan_sel) { int cs_found = -EINVAL; u64 chan_addr; @@ -1532,14 +1558,15 @@ static int f1x_match_to_this_node(struct amd64_pvt *pvt, unsigned range, cs_found = f1x_lookup_addr_in_dct(chan_addr, node_id, channel); - if (cs_found >= 0) + if (cs_found >= 0) { + *nid = node_id; *chan_sel = channel; - + } return cs_found; } static int f1x_translate_sysaddr_to_cs(struct amd64_pvt *pvt, u64 sys_addr, - int *chan_sel) + int *node, int *chan_sel) { int cs_found = -EINVAL; unsigned range; @@ -1553,7 +1580,8 @@ static int f1x_translate_sysaddr_to_cs(struct amd64_pvt *pvt, u64 sys_addr, (get_dram_limit(pvt, range) >= sys_addr)) { cs_found = f1x_match_to_this_node(pvt, range, - sys_addr, chan_sel); + sys_addr, node, + chan_sel); if (cs_found >= 0) break; } @@ -1569,15 +1597,22 @@ static int f1x_translate_sysaddr_to_cs(struct amd64_pvt *pvt, u64 sys_addr, * (MCX_ADDR). */ static void f1x_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr, - struct err_info *err) + u16 syndrome) { struct amd64_pvt *pvt = mci->pvt_info; + u32 page, offset; + int nid, csrow, chan = 0; - error_address_to_page_and_offset(sys_addr, err); + error_address_to_page_and_offset(sys_addr, &page, &offset); - err->csrow = f1x_translate_sysaddr_to_cs(pvt, sys_addr, &err->channel); - if (err->csrow < 0) { - err->err_code = ERR_CSROW; + csrow = f1x_translate_sysaddr_to_cs(pvt, sys_addr, &nid, &chan); + + if (csrow < 0) { + edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, + page, offset, syndrome, + -1, -1, -1, + "failed to map error addr to a csrow", + ""); return; } @@ -1587,7 +1622,12 @@ static void f1x_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr, * this point. */ if (dct_ganging_enabled(pvt)) - err->channel = get_channel_from_ecc_syndrome(mci, err->syndrome); + chan = get_channel_from_ecc_syndrome(mci, syndrome); + + edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, + page, offset, syndrome, + csrow, chan, -1, + "", ""); } /* @@ -1596,11 +1636,14 @@ static void f1x_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr, */ static void amd64_debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl) { - int dimm, size0, size1; + int dimm, size0, size1, factor = 0; u32 *dcsb = ctrl ? pvt->csels[1].csbases : pvt->csels[0].csbases; u32 dbam = ctrl ? pvt->dbam1 : pvt->dbam0; if (boot_cpu_data.x86 == 0xf) { + if (pvt->dclr0 & WIDTH_128) + factor = 1; + /* K8 families < revF not supported yet */ if (pvt->ext_model < K8_REV_F) return; @@ -1631,8 +1674,8 @@ static void amd64_debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl) DBAM_DIMM(dimm, dbam)); amd64_info(EDAC_MC ": %d: %5dMB %d: %5dMB\n", - dimm * 2, size0, - dimm * 2 + 1, size1); + dimm * 2, size0 << factor, + dimm * 2 + 1, size1 << factor); } } @@ -1853,56 +1896,101 @@ static int get_channel_from_ecc_syndrome(struct mem_ctl_info *mci, u16 syndrome) return map_err_sym_to_channel(err_sym, pvt->ecc_sym_sz); } -static void __log_bus_error(struct mem_ctl_info *mci, struct err_info *err, - u8 ecc_type) +/* + * Handle any Correctable Errors (CEs) that have occurred. Check for valid ERROR + * ADDRESS and process. + */ +static void amd64_handle_ce(struct mem_ctl_info *mci, struct mce *m) { - enum hw_event_mc_err_type err_type; - const char *string; + struct amd64_pvt *pvt = mci->pvt_info; + u64 sys_addr; + u16 syndrome; + + /* Ensure that the Error Address is VALID */ + if (!(m->status & MCI_STATUS_ADDRV)) { + amd64_mc_err(mci, "HW has no ERROR_ADDRESS available\n"); + edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, + 0, 0, 0, + -1, -1, -1, + "HW has no ERROR_ADDRESS available", + ""); + return; + } - if (ecc_type == 2) - err_type = HW_EVENT_ERR_CORRECTED; - else if (ecc_type == 1) - err_type = HW_EVENT_ERR_UNCORRECTED; - else { - WARN(1, "Something is rotten in the state of Denmark.\n"); + sys_addr = get_error_address(m); + syndrome = extract_syndrome(m->status); + + amd64_mc_err(mci, "CE ERROR_ADDRESS= 0x%llx\n", sys_addr); + + pvt->ops->map_sysaddr_to_csrow(mci, sys_addr, syndrome); +} + +/* Handle any Un-correctable Errors (UEs) */ +static void amd64_handle_ue(struct mem_ctl_info *mci, struct mce *m) +{ + struct mem_ctl_info *log_mci, *src_mci = NULL; + int csrow; + u64 sys_addr; + u32 page, offset; + + log_mci = mci; + + if (!(m->status & MCI_STATUS_ADDRV)) { + amd64_mc_err(mci, "HW has no ERROR_ADDRESS available\n"); + edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, + 0, 0, 0, + -1, -1, -1, + "HW has no ERROR_ADDRESS available", + ""); return; } - switch (err->err_code) { - case DECODE_OK: - string = ""; - break; - case ERR_NODE: - string = "Failed to map error addr to a node"; - break; - case ERR_CSROW: - string = "Failed to map error addr to a csrow"; - break; - case ERR_CHANNEL: - string = "unknown syndrome - possible error reporting race"; - break; - default: - string = "WTF error"; - break; + sys_addr = get_error_address(m); + error_address_to_page_and_offset(sys_addr, &page, &offset); + + /* + * Find out which node the error address belongs to. This may be + * different from the node that detected the error. + */ + src_mci = find_mc_by_sys_addr(mci, sys_addr); + if (!src_mci) { + amd64_mc_err(mci, "ERROR ADDRESS (0x%lx) NOT mapped to a MC\n", + (unsigned long)sys_addr); + edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, + page, offset, 0, + -1, -1, -1, + "ERROR ADDRESS NOT mapped to a MC", + ""); + return; } - edac_mc_handle_error(err_type, mci, 1, - err->page, err->offset, err->syndrome, - err->csrow, err->channel, -1, - string, ""); + log_mci = src_mci; + + csrow = sys_addr_to_csrow(log_mci, sys_addr); + if (csrow < 0) { + amd64_mc_err(mci, "ERROR_ADDRESS (0x%lx) NOT mapped to CS\n", + (unsigned long)sys_addr); + edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, + page, offset, 0, + -1, -1, -1, + "ERROR ADDRESS NOT mapped to CS", + ""); + } else { + edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, + page, offset, 0, + csrow, -1, -1, + "", ""); + } } static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci, struct mce *m) { - struct amd64_pvt *pvt = mci->pvt_info; - u8 ecc_type = (m->status >> 45) & 0x3; - u8 xec = XEC(m->status, 0x1f); u16 ec = EC(m->status); - u64 sys_addr; - struct err_info err; + u8 xec = XEC(m->status, 0x1f); + u8 ecc_type = (m->status >> 45) & 0x3; - /* Bail out early if this was an 'observed' error */ + /* Bail early out if this was an 'observed' error */ if (PP(ec) == NBSL_PP_OBS) return; @@ -1910,16 +1998,10 @@ static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci, if (xec && xec != F10_NBSL_EXT_ERR_ECC) return; - memset(&err, 0, sizeof(err)); - - sys_addr = get_error_address(m); - if (ecc_type == 2) - err.syndrome = extract_syndrome(m->status); - - pvt->ops->map_sysaddr_to_csrow(mci, sys_addr, &err); - - __log_bus_error(mci, &err, ecc_type); + amd64_handle_ce(mci, m); + else if (ecc_type == 1) + amd64_handle_ue(mci, m); } void amd64_decode_bus_error(int node_id, struct mce *m) @@ -2087,7 +2169,6 @@ static u32 amd64_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr) u32 cs_mode, nr_pages; u32 dbam = dct ? pvt->dbam1 : pvt->dbam0; - /* * The math on this doesn't look right on the surface because x/2*4 can * be simplified to x*2 but this expression makes use of the fact that @@ -2095,13 +2176,13 @@ static u32 amd64_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr) * number of bits to shift the DBAM register to extract the proper CSROW * field. */ - cs_mode = DBAM_DIMM(csrow_nr / 2, dbam); + cs_mode = (dbam >> ((csrow_nr / 2) * 4)) & 0xF; nr_pages = pvt->ops->dbam_to_cs(pvt, dct, cs_mode) << (20 - PAGE_SHIFT); - edac_dbg(0, "csrow: %d, channel: %d, DBAM idx: %d\n", - csrow_nr, dct, cs_mode); - edac_dbg(0, "nr_pages/channel: %u\n", nr_pages); + edac_dbg(0, " (csrow=%d) DBAM map index= %d\n", csrow_nr, cs_mode); + edac_dbg(0, " nr_pages/channel= %u channel-count = %d\n", + nr_pages, pvt->channel_count); return nr_pages; } @@ -2112,14 +2193,15 @@ static u32 amd64_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr) */ static int init_csrows(struct mem_ctl_info *mci) { - struct amd64_pvt *pvt = mci->pvt_info; struct csrow_info *csrow; struct dimm_info *dimm; - enum edac_type edac_mode; - enum mem_type mtype; + struct amd64_pvt *pvt = mci->pvt_info; + u64 base, mask; + u32 val; int i, j, empty = 1; + enum mem_type mtype; + enum edac_type edac_mode; int nr_pages = 0; - u32 val; amd64_read_pci_cfg(pvt->F3, NBCFG, &val); @@ -2129,35 +2211,29 @@ static int init_csrows(struct mem_ctl_info *mci) pvt->mc_node_id, val, !!(val & NBCFG_CHIPKILL), !!(val & NBCFG_ECC_ENABLE)); - /* - * We iterate over DCT0 here but we look at DCT1 in parallel, if needed. - */ for_each_chip_select(i, 0, pvt) { - bool row_dct0 = !!csrow_enabled(i, 0, pvt); - bool row_dct1 = false; - - if (boot_cpu_data.x86 != 0xf) - row_dct1 = !!csrow_enabled(i, 1, pvt); + csrow = mci->csrows[i]; - if (!row_dct0 && !row_dct1) + if (!csrow_enabled(i, 0, pvt) && !csrow_enabled(i, 1, pvt)) { + edac_dbg(1, "----CSROW %d VALID for MC node %d\n", + i, pvt->mc_node_id); continue; + } - csrow = mci->csrows[i]; empty = 0; - - edac_dbg(1, "MC node: %d, csrow: %d\n", - pvt->mc_node_id, i); - - if (row_dct0) + if (csrow_enabled(i, 0, pvt)) nr_pages = amd64_csrow_nr_pages(pvt, 0, i); - - /* K8 has only one DCT */ - if (boot_cpu_data.x86 != 0xf && row_dct1) + if (csrow_enabled(i, 1, pvt)) nr_pages += amd64_csrow_nr_pages(pvt, 1, i); + get_cs_base_and_mask(pvt, i, 0, &base, &mask); + /* 8 bytes of resolution */ + mtype = amd64_determine_memory_type(pvt, i); - edac_dbg(1, "Total csrow%d pages: %u\n", i, nr_pages); + edac_dbg(1, " for MC node %d csrow %d:\n", pvt->mc_node_id, i); + edac_dbg(1, " nr_pages: %u\n", + nr_pages * pvt->channel_count); /* * determine whether CHIPKILL or JUST ECC or NO ECC is operating @@ -2174,7 +2250,6 @@ static int init_csrows(struct mem_ctl_info *mci) dimm->edac_mode = edac_mode; dimm->nr_pages = nr_pages; } - csrow->nr_pages = nr_pages; } return empty; @@ -2519,7 +2594,6 @@ static int amd64_init_one_instance(struct pci_dev *F2) mci->pvt_info = pvt; mci->pdev = &pvt->F2->dev; - mci->csbased = 1; setup_mci_misc_attrs(mci, fam_type); diff --git a/trunk/drivers/edac/amd64_edac.h b/trunk/drivers/edac/amd64_edac.h index e864f407806c..8d4804732bac 100644 --- a/trunk/drivers/edac/amd64_edac.h +++ b/trunk/drivers/edac/amd64_edac.h @@ -33,7 +33,7 @@ * detection. The mods to Rev F required more family * information detection. * - * Changes/Fixes by Borislav Petkov : + * Changes/Fixes by Borislav Petkov : * - misc fixes and code cleanups * * This module is based on the following documents @@ -219,7 +219,7 @@ #define DBAM1 0x180 /* Extract the DIMM 'type' on the i'th DIMM from the DBAM reg value passed */ -#define DBAM_DIMM(i, reg) ((((reg) >> (4*(i)))) & 0xF) +#define DBAM_DIMM(i, reg) ((((reg) >> (4*i))) & 0xF) #define DBAM_MAX_VALUE 11 @@ -267,20 +267,18 @@ #define online_spare_bad_dramcs(pvt, c) (((pvt)->online_spare >> (4 + 4 * (c))) & 0x7) #define F10_NB_ARRAY_ADDR 0xB8 -#define F10_NB_ARRAY_DRAM BIT(31) +#define F10_NB_ARRAY_DRAM_ECC BIT(31) /* Bits [2:1] are used to select 16-byte section within a 64-byte cacheline */ -#define SET_NB_ARRAY_ADDR(section) (((section) & 0x3) << 1) +#define SET_NB_ARRAY_ADDRESS(section) (((section) & 0x3) << 1) #define F10_NB_ARRAY_DATA 0xBC -#define F10_NB_ARR_ECC_WR_REQ BIT(17) -#define SET_NB_DRAM_INJECTION_WRITE(inj) \ - (BIT(((inj.word) & 0xF) + 20) | \ - F10_NB_ARR_ECC_WR_REQ | inj.bit_map) -#define SET_NB_DRAM_INJECTION_READ(inj) \ - (BIT(((inj.word) & 0xF) + 20) | \ - BIT(16) | inj.bit_map) - +#define SET_NB_DRAM_INJECTION_WRITE(word, bits) \ + (BIT(((word) & 0xF) + 20) | \ + BIT(17) | bits) +#define SET_NB_DRAM_INJECTION_READ(word, bits) \ + (BIT(((word) & 0xF) + 20) | \ + BIT(16) | bits) #define NBCAP 0xE8 #define NBCAP_CHIPKILL BIT(4) @@ -307,9 +305,9 @@ enum amd_families { /* Error injection control structure */ struct error_injection { - u32 section; - u32 word; - u32 bit_map; + u32 section; + u32 word; + u32 bit_map; }; /* low and high part of PCI config space regs */ @@ -376,23 +374,6 @@ struct amd64_pvt { struct error_injection injection; }; -enum err_codes { - DECODE_OK = 0, - ERR_NODE = -1, - ERR_CSROW = -2, - ERR_CHANNEL = -3, -}; - -struct err_info { - int err_code; - struct mem_ctl_info *src_mci; - int csrow; - int channel; - u16 syndrome; - u32 page; - u32 offset; -}; - static inline u64 get_dram_base(struct amd64_pvt *pvt, unsigned i) { u64 addr = ((u64)pvt->ranges[i].base.lo & 0xffff0000) << 8; @@ -466,7 +447,7 @@ static inline void amd64_remove_sysfs_inject_files(struct mem_ctl_info *mci) struct low_ops { int (*early_channel_count) (struct amd64_pvt *pvt); void (*map_sysaddr_to_csrow) (struct mem_ctl_info *mci, u64 sys_addr, - struct err_info *); + u16 syndrome); int (*dbam_to_cs) (struct amd64_pvt *pvt, u8 dct, unsigned cs_mode); int (*read_dct_pci_cfg) (struct amd64_pvt *pvt, int offset, u32 *val, const char *func); @@ -478,8 +459,6 @@ struct amd64_family_type { struct low_ops ops; }; -int __amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset, - u32 *val, const char *func); int __amd64_write_pci_cfg_dword(struct pci_dev *pdev, int offset, u32 val, const char *func); @@ -496,15 +475,3 @@ int amd64_get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base, u64 *hole_offset, u64 *hole_size); #define to_mci(k) container_of(k, struct mem_ctl_info, dev) - -/* Injection helpers */ -static inline void disable_caches(void *dummy) -{ - write_cr0(read_cr0() | X86_CR0_CD); - wbinvd(); -} - -static inline void enable_caches(void *dummy) -{ - write_cr0(read_cr0() & ~X86_CR0_CD); -} diff --git a/trunk/drivers/edac/amd64_edac_inj.c b/trunk/drivers/edac/amd64_edac_inj.c index 8c171fa1cb9b..53d972e00dfb 100644 --- a/trunk/drivers/edac/amd64_edac_inj.c +++ b/trunk/drivers/edac/amd64_edac_inj.c @@ -22,19 +22,20 @@ static ssize_t amd64_inject_section_store(struct device *dev, struct mem_ctl_info *mci = to_mci(dev); struct amd64_pvt *pvt = mci->pvt_info; unsigned long value; - int ret; + int ret = 0; ret = strict_strtoul(data, 10, &value); - if (ret < 0) - return ret; + if (ret != -EINVAL) { - if (value > 3) { - amd64_warn("%s: invalid section 0x%lx\n", __func__, value); - return -EINVAL; - } + if (value > 3) { + amd64_warn("%s: invalid section 0x%lx\n", __func__, value); + return -EINVAL; + } - pvt->injection.section = (u32) value; - return count; + pvt->injection.section = (u32) value; + return count; + } + return ret; } static ssize_t amd64_inject_word_show(struct device *dev, @@ -59,19 +60,20 @@ static ssize_t amd64_inject_word_store(struct device *dev, struct mem_ctl_info *mci = to_mci(dev); struct amd64_pvt *pvt = mci->pvt_info; unsigned long value; - int ret; + int ret = 0; ret = strict_strtoul(data, 10, &value); - if (ret < 0) - return ret; + if (ret != -EINVAL) { - if (value > 8) { - amd64_warn("%s: invalid word 0x%lx\n", __func__, value); - return -EINVAL; - } + if (value > 8) { + amd64_warn("%s: invalid word 0x%lx\n", __func__, value); + return -EINVAL; + } - pvt->injection.word = (u32) value; - return count; + pvt->injection.word = (u32) value; + return count; + } + return ret; } static ssize_t amd64_inject_ecc_vector_show(struct device *dev, @@ -95,19 +97,21 @@ static ssize_t amd64_inject_ecc_vector_store(struct device *dev, struct mem_ctl_info *mci = to_mci(dev); struct amd64_pvt *pvt = mci->pvt_info; unsigned long value; - int ret; + int ret = 0; ret = strict_strtoul(data, 16, &value); - if (ret < 0) - return ret; + if (ret != -EINVAL) { - if (value & 0xFFFF0000) { - amd64_warn("%s: invalid EccVector: 0x%lx\n", __func__, value); - return -EINVAL; - } + if (value & 0xFFFF0000) { + amd64_warn("%s: invalid EccVector: 0x%lx\n", + __func__, value); + return -EINVAL; + } - pvt->injection.bit_map = (u32) value; - return count; + pvt->injection.bit_map = (u32) value; + return count; + } + return ret; } /* @@ -122,25 +126,28 @@ static ssize_t amd64_inject_read_store(struct device *dev, struct amd64_pvt *pvt = mci->pvt_info; unsigned long value; u32 section, word_bits; - int ret; + int ret = 0; ret = strict_strtoul(data, 10, &value); - if (ret < 0) - return ret; - - /* Form value to choose 16-byte section of cacheline */ - section = F10_NB_ARRAY_DRAM | SET_NB_ARRAY_ADDR(pvt->injection.section); + if (ret != -EINVAL) { - amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section); + /* Form value to choose 16-byte section of cacheline */ + section = F10_NB_ARRAY_DRAM_ECC | + SET_NB_ARRAY_ADDRESS(pvt->injection.section); + amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section); - word_bits = SET_NB_DRAM_INJECTION_READ(pvt->injection); + word_bits = SET_NB_DRAM_INJECTION_READ(pvt->injection.word, + pvt->injection.bit_map); - /* Issue 'word' and 'bit' along with the READ request */ - amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits); + /* Issue 'word' and 'bit' along with the READ request */ + amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits); - edac_dbg(0, "section=0x%x word_bits=0x%x\n", section, word_bits); + edac_dbg(0, "section=0x%x word_bits=0x%x\n", + section, word_bits); - return count; + return count; + } + return ret; } /* @@ -153,43 +160,30 @@ static ssize_t amd64_inject_write_store(struct device *dev, { struct mem_ctl_info *mci = to_mci(dev); struct amd64_pvt *pvt = mci->pvt_info; - u32 section, word_bits, tmp; unsigned long value; - int ret; + u32 section, word_bits; + int ret = 0; ret = strict_strtoul(data, 10, &value); - if (ret < 0) - return ret; - - /* Form value to choose 16-byte section of cacheline */ - section = F10_NB_ARRAY_DRAM | SET_NB_ARRAY_ADDR(pvt->injection.section); - - amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section); + if (ret != -EINVAL) { - word_bits = SET_NB_DRAM_INJECTION_WRITE(pvt->injection); + /* Form value to choose 16-byte section of cacheline */ + section = F10_NB_ARRAY_DRAM_ECC | + SET_NB_ARRAY_ADDRESS(pvt->injection.section); + amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section); - pr_notice_once("Don't forget to decrease MCE polling interval in\n" - "/sys/bus/machinecheck/devices/machinecheck/check_interval\n" - "so that you can get the error report faster.\n"); + word_bits = SET_NB_DRAM_INJECTION_WRITE(pvt->injection.word, + pvt->injection.bit_map); - on_each_cpu(disable_caches, NULL, 1); + /* Issue 'word' and 'bit' along with the READ request */ + amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits); - /* Issue 'word' and 'bit' along with the READ request */ - amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits); + edac_dbg(0, "section=0x%x word_bits=0x%x\n", + section, word_bits); - retry: - /* wait until injection happens */ - amd64_read_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, &tmp); - if (tmp & F10_NB_ARR_ECC_WR_REQ) { - cpu_relax(); - goto retry; + return count; } - - on_each_cpu(enable_caches, NULL, 1); - - edac_dbg(0, "section=0x%x word_bits=0x%x\n", section, word_bits); - - return count; + return ret; } /* diff --git a/trunk/drivers/edac/edac_mc.c b/trunk/drivers/edac/edac_mc.c index 281f566a5513..90f0b730e9bb 100644 --- a/trunk/drivers/edac/edac_mc.c +++ b/trunk/drivers/edac/edac_mc.c @@ -416,18 +416,10 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num, dimm->cschannel = chn; /* Increment csrow location */ - if (layers[0].is_virt_csrow) { + row++; + if (row == tot_csrows) { + row = 0; chn++; - if (chn == tot_channels) { - chn = 0; - row++; - } - } else { - row++; - if (row == tot_csrows) { - row = 0; - chn++; - } } /* Increment dimm location */ @@ -974,22 +966,20 @@ static void edac_ce_error(struct mem_ctl_info *mci, long grain) { unsigned long remapped_page; - char *msg_aux = ""; - - if (*msg) - msg_aux = " "; if (edac_mc_get_log_ce()) { if (other_detail && *other_detail) edac_mc_printk(mci, KERN_WARNING, - "%d CE %s%son %s (%s %s - %s)\n", - error_count, msg, msg_aux, label, - location, detail, other_detail); + "%d CE %s on %s (%s %s - %s)\n", + error_count, + msg, label, location, + detail, other_detail); else edac_mc_printk(mci, KERN_WARNING, - "%d CE %s%son %s (%s %s)\n", - error_count, msg, msg_aux, label, - location, detail); + "%d CE %s on %s (%s %s)\n", + error_count, + msg, label, location, + detail); } edac_inc_ce_error(mci, enable_per_layer_report, pos, error_count); @@ -1024,31 +1014,27 @@ static void edac_ue_error(struct mem_ctl_info *mci, const char *other_detail, const bool enable_per_layer_report) { - char *msg_aux = ""; - - if (*msg) - msg_aux = " "; - if (edac_mc_get_log_ue()) { if (other_detail && *other_detail) edac_mc_printk(mci, KERN_WARNING, - "%d UE %s%son %s (%s %s - %s)\n", - error_count, msg, msg_aux, label, - location, detail, other_detail); + "%d UE %s on %s (%s %s - %s)\n", + error_count, + msg, label, location, detail, + other_detail); else edac_mc_printk(mci, KERN_WARNING, - "%d UE %s%son %s (%s %s)\n", - error_count, msg, msg_aux, label, - location, detail); + "%d UE %s on %s (%s %s)\n", + error_count, + msg, label, location, detail); } if (edac_mc_get_panic_on_ue()) { if (other_detail && *other_detail) - panic("UE %s%son %s (%s%s - %s)\n", - msg, msg_aux, label, location, detail, other_detail); + panic("UE %s on %s (%s%s - %s)\n", + msg, label, location, detail, other_detail); else - panic("UE %s%son %s (%s%s)\n", - msg, msg_aux, label, location, detail); + panic("UE %s on %s (%s%s)\n", + msg, label, location, detail); } edac_inc_ue_error(mci, enable_per_layer_report, pos, error_count); @@ -1107,6 +1093,10 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type, */ for (i = 0; i < mci->n_layers; i++) { if (pos[i] >= (int)mci->layers[i].size) { + if (type == HW_EVENT_ERR_CORRECTED) + p = "CE"; + else + p = "UE"; edac_mc_printk(mci, KERN_ERR, "INTERNAL ERROR: %s value is out of range (%d >= %d)\n", @@ -1138,7 +1128,6 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type, grain = 0; p = label; *p = '\0'; - for (i = 0; i < mci->tot_dimms; i++) { struct dimm_info *dimm = mci->dimms[i]; @@ -1206,7 +1195,6 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type, /* Fill the RAM location data */ p = location; - for (i = 0; i < mci->n_layers; i++) { if (pos[i] < 0) continue; @@ -1219,6 +1207,7 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type, *(p - 1) = '\0'; /* Report the error via the trace interface */ + grain_bits = fls_long(grain) + 1; trace_mc_event(type, msg, label, error_count, mci->mc_idx, top_layer, mid_layer, low_layer, diff --git a/trunk/drivers/edac/edac_mc_sysfs.c b/trunk/drivers/edac/edac_mc_sysfs.c index de2df92f9c77..ed0bc07b8503 100644 --- a/trunk/drivers/edac/edac_mc_sysfs.c +++ b/trunk/drivers/edac/edac_mc_sysfs.c @@ -180,9 +180,6 @@ static ssize_t csrow_size_show(struct device *dev, int i; u32 nr_pages = 0; - if (csrow->mci->csbased) - return sprintf(data, "%u\n", PAGES_TO_MiB(csrow->nr_pages)); - for (i = 0; i < csrow->nr_channels; i++) nr_pages += csrow->channels[i]->dimm->nr_pages; return sprintf(data, "%u\n", PAGES_TO_MiB(nr_pages)); @@ -376,7 +373,6 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci, csrow->dev.bus = &mci->bus; device_initialize(&csrow->dev); csrow->dev.parent = &mci->dev; - csrow->mci = mci; dev_set_name(&csrow->dev, "csrow%d", index); dev_set_drvdata(&csrow->dev, csrow); @@ -781,14 +777,10 @@ static ssize_t mci_size_mb_show(struct device *dev, for (csrow_idx = 0; csrow_idx < mci->nr_csrows; csrow_idx++) { struct csrow_info *csrow = mci->csrows[csrow_idx]; - if (csrow->mci->csbased) { - total_pages += csrow->nr_pages; - } else { - for (j = 0; j < csrow->nr_channels; j++) { - struct dimm_info *dimm = csrow->channels[j]->dimm; + for (j = 0; j < csrow->nr_channels; j++) { + struct dimm_info *dimm = csrow->channels[j]->dimm; - total_pages += dimm->nr_pages; - } + total_pages += dimm->nr_pages; } } @@ -846,8 +838,14 @@ static ssize_t edac_fake_inject_write(struct file *file, return count; } +static int debugfs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static const struct file_operations debug_fake_inject_fops = { - .open = simple_open, + .open = debugfs_open, .write = edac_fake_inject_write, .llseek = generic_file_llseek, }; @@ -1126,15 +1124,10 @@ int __init edac_mc_sysfs_init(void) edac_subsys = edac_get_sysfs_subsys(); if (edac_subsys == NULL) { edac_dbg(1, "no edac_subsys\n"); - err = -EINVAL; - goto out; + return -EINVAL; } mci_pdev = kzalloc(sizeof(*mci_pdev), GFP_KERNEL); - if (!mci_pdev) { - err = -ENOMEM; - goto out_put_sysfs; - } mci_pdev->bus = edac_subsys; mci_pdev->type = &mc_attr_type; @@ -1143,18 +1136,11 @@ int __init edac_mc_sysfs_init(void) err = device_add(mci_pdev); if (err < 0) - goto out_dev_free; + return err; edac_dbg(0, "device %s created\n", dev_name(mci_pdev)); return 0; - - out_dev_free: - kfree(mci_pdev); - out_put_sysfs: - edac_put_sysfs_subsys(); - out: - return err; } void __exit edac_mc_sysfs_exit(void) @@ -1162,5 +1148,4 @@ void __exit edac_mc_sysfs_exit(void) put_device(mci_pdev); device_del(mci_pdev); edac_put_sysfs_subsys(); - kfree(mci_pdev); } diff --git a/trunk/drivers/edac/edac_module.c b/trunk/drivers/edac/edac_module.c index 12c951a2c33d..58a28d838f37 100644 --- a/trunk/drivers/edac/edac_module.c +++ b/trunk/drivers/edac/edac_module.c @@ -18,29 +18,9 @@ #define EDAC_VERSION "Ver: 3.0.0" #ifdef CONFIG_EDAC_DEBUG - -static int edac_set_debug_level(const char *buf, struct kernel_param *kp) -{ - unsigned long val; - int ret; - - ret = kstrtoul(buf, 0, &val); - if (ret) - return ret; - - if (val < 0 || val > 4) - return -EINVAL; - - return param_set_int(buf, kp); -} - /* Values of 0 to 4 will generate output */ int edac_debug_level = 2; EXPORT_SYMBOL_GPL(edac_debug_level); - -module_param_call(edac_debug_level, edac_set_debug_level, param_get_int, - &edac_debug_level, 0644); -MODULE_PARM_DESC(edac_debug_level, "EDAC debug level: [0-4], default: 2"); #endif /* scope is to module level only */ @@ -152,3 +132,10 @@ module_exit(edac_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Doug Thompson www.softwarebitmaker.com, et al"); MODULE_DESCRIPTION("Core library routines for EDAC reporting"); + +/* refer to *_sysfs.c files for parameters that are exported via sysfs */ + +#ifdef CONFIG_EDAC_DEBUG +module_param(edac_debug_level, int, 0644); +MODULE_PARM_DESC(edac_debug_level, "Debug level"); +#endif diff --git a/trunk/drivers/edac/edac_pci.c b/trunk/drivers/edac/edac_pci.c index dd370f92ace3..ee87ef972ead 100644 --- a/trunk/drivers/edac/edac_pci.c +++ b/trunk/drivers/edac/edac_pci.c @@ -470,8 +470,7 @@ struct edac_pci_ctl_info *edac_pci_create_generic_ctl(struct device *dev, pci->mod_name = mod_name; pci->ctl_name = EDAC_PCI_GENCTL_NAME; - if (edac_op_state == EDAC_OPSTATE_POLL) - pci->edac_check = edac_pci_generic_check; + pci->edac_check = edac_pci_generic_check; pdata->edac_idx = edac_pci_idx++; diff --git a/trunk/drivers/edac/edac_pci_sysfs.c b/trunk/drivers/edac/edac_pci_sysfs.c index dc6e905ee1a5..e164c555a337 100644 --- a/trunk/drivers/edac/edac_pci_sysfs.c +++ b/trunk/drivers/edac/edac_pci_sysfs.c @@ -645,16 +645,20 @@ typedef void (*pci_parity_check_fn_t) (struct pci_dev *dev); /* * pci_dev parity list iterator - * - * Scan the PCI device list looking for SERRORs, Master Parity ERRORS or - * Parity ERRORs on primary or secondary devices. + * Scan the PCI device list for one pass, looking for SERRORs + * Master Parity ERRORS or Parity ERRORs on primary or secondary devices */ static inline void edac_pci_dev_parity_iterator(pci_parity_check_fn_t fn) { struct pci_dev *dev = NULL; - for_each_pci_dev(dev) + /* request for kernel access to the next PCI device, if any, + * and while we are looking at it have its reference count + * bumped until we are done with it + */ + while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { fn(dev); + } } /* diff --git a/trunk/drivers/edac/edac_stub.c b/trunk/drivers/edac/edac_stub.c index 351945fa2ecd..6c86f6e54558 100644 --- a/trunk/drivers/edac/edac_stub.c +++ b/trunk/drivers/edac/edac_stub.c @@ -5,7 +5,7 @@ * * 2007 (c) MontaVista Software, Inc. * 2010 (c) Advanced Micro Devices Inc. - * Borislav Petkov + * Borislav Petkov * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/drivers/edac/highbank_mc_edac.c b/trunk/drivers/edac/highbank_mc_edac.c index 7ea4cc2e8bd2..c769f477fd22 100644 --- a/trunk/drivers/edac/highbank_mc_edac.c +++ b/trunk/drivers/edac/highbank_mc_edac.c @@ -113,8 +113,14 @@ static ssize_t highbank_mc_err_inject_write(struct file *file, return count; } +static int debugfs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static const struct file_operations highbank_mc_debug_inject_fops = { - .open = simple_open, + .open = debugfs_open, .write = highbank_mc_err_inject_write, .llseek = generic_file_llseek, }; diff --git a/trunk/drivers/edac/i7300_edac.c b/trunk/drivers/edac/i7300_edac.c index 9d669cd43618..a09d0667f72a 100644 --- a/trunk/drivers/edac/i7300_edac.c +++ b/trunk/drivers/edac/i7300_edac.c @@ -197,8 +197,8 @@ static const char *ferr_fat_fbd_name[] = { [0] = "Memory Write error on non-redundant retry or " "FBD configuration Write error on retry", }; -#define GET_FBD_FAT_IDX(fbderr) (((fbderr) >> 28) & 3) -#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 22)) +#define GET_FBD_FAT_IDX(fbderr) (fbderr & (3 << 28)) +#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)) #define FERR_NF_FBD 0xa0 static const char *ferr_nf_fbd_name[] = { @@ -225,7 +225,7 @@ static const char *ferr_nf_fbd_name[] = { [1] = "Aliased Uncorrectable Non-Mirrored Demand Data ECC", [0] = "Uncorrectable Data ECC on Replay", }; -#define GET_FBD_NF_IDX(fbderr) (((fbderr) >> 28) & 3) +#define GET_FBD_NF_IDX(fbderr) (fbderr & (3 << 28)) #define FERR_NF_FBD_ERR_MASK ((1 << 24) | (1 << 23) | (1 << 22) | (1 << 21) |\ (1 << 18) | (1 << 17) | (1 << 16) | (1 << 15) |\ (1 << 14) | (1 << 13) | (1 << 11) | (1 << 10) |\ @@ -464,7 +464,7 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci) errnum = find_first_bit(&errors, ARRAY_SIZE(ferr_nf_fbd_name)); specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum); - branch = (GET_FBD_NF_IDX(error_reg) == 2) ? 1 : 0; + branch = (GET_FBD_FAT_IDX(error_reg) == 2) ? 1 : 0; pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, REDMEMA, &syndrome); diff --git a/trunk/drivers/edac/i7core_edac.c b/trunk/drivers/edac/i7core_edac.c index 10c8c00d6469..3672101023bd 100644 --- a/trunk/drivers/edac/i7core_edac.c +++ b/trunk/drivers/edac/i7core_edac.c @@ -816,7 +816,7 @@ static ssize_t i7core_inject_store_##param( \ struct device_attribute *mattr, \ const char *data, size_t count) \ { \ - struct mem_ctl_info *mci = dev_get_drvdata(dev); \ + struct mem_ctl_info *mci = to_mci(dev); \ struct i7core_pvt *pvt; \ long value; \ int rc; \ @@ -845,7 +845,7 @@ static ssize_t i7core_inject_show_##param( \ struct device_attribute *mattr, \ char *data) \ { \ - struct mem_ctl_info *mci = dev_get_drvdata(dev); \ + struct mem_ctl_info *mci = to_mci(dev); \ struct i7core_pvt *pvt; \ \ pvt = mci->pvt_info; \ @@ -1052,7 +1052,7 @@ static ssize_t i7core_show_counter_##param( \ struct device_attribute *mattr, \ char *data) \ { \ - struct mem_ctl_info *mci = dev_get_drvdata(dev); \ + struct mem_ctl_info *mci = to_mci(dev); \ struct i7core_pvt *pvt = mci->pvt_info; \ \ edac_dbg(1, "\n"); \ diff --git a/trunk/drivers/edac/i82975x_edac.c b/trunk/drivers/edac/i82975x_edac.c index a98020409fa9..069e26c11c4f 100644 --- a/trunk/drivers/edac/i82975x_edac.c +++ b/trunk/drivers/edac/i82975x_edac.c @@ -370,6 +370,10 @@ static enum dev_type i82975x_dram_type(void __iomem *mch_window, int rank) static void i82975x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev, void __iomem *mch_window) { + static const char *labels[4] = { + "DIMM A1", "DIMM A2", + "DIMM B1", "DIMM B2" + }; struct csrow_info *csrow; unsigned long last_cumul_size; u8 value; @@ -419,10 +423,9 @@ static void i82975x_init_csrows(struct mem_ctl_info *mci, dimm = mci->csrows[index]->channels[chan]->dimm; dimm->nr_pages = nr_pages / csrow->nr_channels; - - snprintf(csrow->channels[chan]->dimm->label, EDAC_MC_LABEL_LEN, "DIMM %c%d", - (chan == 0) ? 'A' : 'B', - index); + strncpy(csrow->channels[chan]->dimm->label, + labels[(index >> 1) + (chan * 2)], + EDAC_MC_LABEL_LEN); dimm->grain = 1 << 7; /* 128Byte cache-line resolution */ dimm->dtype = i82975x_dram_type(mch_window, index); dimm->mtype = MEM_DDR2; /* I82975x supports only DDR2 */ diff --git a/trunk/drivers/edac/mce_amd.c b/trunk/drivers/edac/mce_amd.c index ad637572d8c7..d0c372e30de4 100644 --- a/trunk/drivers/edac/mce_amd.c +++ b/trunk/drivers/edac/mce_amd.c @@ -64,7 +64,7 @@ EXPORT_SYMBOL_GPL(to_msgs); const char * const ii_msgs[] = { "MEM", "RESV", "IO", "GEN" }; EXPORT_SYMBOL_GPL(ii_msgs); -static const char * const f15h_mc1_mce_desc[] = { +static const char * const f15h_ic_mce_desc[] = { "UC during a demand linefill from L2", "Parity error during data load from IC", "Parity error for IC valid bit", @@ -84,7 +84,7 @@ static const char * const f15h_mc1_mce_desc[] = { "fetch address FIFO" }; -static const char * const f15h_mc2_mce_desc[] = { +static const char * const f15h_cu_mce_desc[] = { "Fill ECC error on data fills", /* xec = 0x4 */ "Fill parity error on insn fills", "Prefetcher request FIFO parity error", @@ -101,7 +101,7 @@ static const char * const f15h_mc2_mce_desc[] = { "PRB address parity error" }; -static const char * const mc4_mce_desc[] = { +static const char * const nb_mce_desc[] = { "DRAM ECC error detected on the NB", "CRC error detected on HT link", "Link-defined sync error packets detected on HT link", @@ -123,7 +123,7 @@ static const char * const mc4_mce_desc[] = { "ECC Error in the Probe Filter directory" }; -static const char * const mc5_mce_desc[] = { +static const char * const fr_ex_mce_desc[] = { "CPU Watchdog timer expire", "Wakeup array dest tag", "AG payload array", @@ -139,7 +139,7 @@ static const char * const mc5_mce_desc[] = { "DE error occurred" }; -static bool f12h_mc0_mce(u16 ec, u8 xec) +static bool f12h_dc_mce(u16 ec, u8 xec) { bool ret = false; @@ -157,26 +157,26 @@ static bool f12h_mc0_mce(u16 ec, u8 xec) return ret; } -static bool f10h_mc0_mce(u16 ec, u8 xec) +static bool f10h_dc_mce(u16 ec, u8 xec) { if (R4(ec) == R4_GEN && LL(ec) == LL_L1) { pr_cont("during data scrub.\n"); return true; } - return f12h_mc0_mce(ec, xec); + return f12h_dc_mce(ec, xec); } -static bool k8_mc0_mce(u16 ec, u8 xec) +static bool k8_dc_mce(u16 ec, u8 xec) { if (BUS_ERROR(ec)) { pr_cont("during system linefill.\n"); return true; } - return f10h_mc0_mce(ec, xec); + return f10h_dc_mce(ec, xec); } -static bool f14h_mc0_mce(u16 ec, u8 xec) +static bool f14h_dc_mce(u16 ec, u8 xec) { u8 r4 = R4(ec); bool ret = true; @@ -228,7 +228,7 @@ static bool f14h_mc0_mce(u16 ec, u8 xec) return ret; } -static bool f15h_mc0_mce(u16 ec, u8 xec) +static bool f15h_dc_mce(u16 ec, u8 xec) { bool ret = true; @@ -275,12 +275,12 @@ static bool f15h_mc0_mce(u16 ec, u8 xec) return ret; } -static void decode_mc0_mce(struct mce *m) +static void amd_decode_dc_mce(struct mce *m) { u16 ec = EC(m->status); u8 xec = XEC(m->status, xec_mask); - pr_emerg(HW_ERR "MC0 Error: "); + pr_emerg(HW_ERR "Data Cache Error: "); /* TLB error signatures are the same across families */ if (TLB_ERROR(ec)) { @@ -290,13 +290,13 @@ static void decode_mc0_mce(struct mce *m) : (xec ? "multimatch" : "parity"))); return; } - } else if (fam_ops->mc0_mce(ec, xec)) + } else if (fam_ops->dc_mce(ec, xec)) ; else - pr_emerg(HW_ERR "Corrupted MC0 MCE info?\n"); + pr_emerg(HW_ERR "Corrupted DC MCE info?\n"); } -static bool k8_mc1_mce(u16 ec, u8 xec) +static bool k8_ic_mce(u16 ec, u8 xec) { u8 ll = LL(ec); bool ret = true; @@ -330,7 +330,7 @@ static bool k8_mc1_mce(u16 ec, u8 xec) return ret; } -static bool f14h_mc1_mce(u16 ec, u8 xec) +static bool f14h_ic_mce(u16 ec, u8 xec) { u8 r4 = R4(ec); bool ret = true; @@ -349,7 +349,7 @@ static bool f14h_mc1_mce(u16 ec, u8 xec) return ret; } -static bool f15h_mc1_mce(u16 ec, u8 xec) +static bool f15h_ic_mce(u16 ec, u8 xec) { bool ret = true; @@ -358,19 +358,19 @@ static bool f15h_mc1_mce(u16 ec, u8 xec) switch (xec) { case 0x0 ... 0xa: - pr_cont("%s.\n", f15h_mc1_mce_desc[xec]); + pr_cont("%s.\n", f15h_ic_mce_desc[xec]); break; case 0xd: - pr_cont("%s.\n", f15h_mc1_mce_desc[xec-2]); + pr_cont("%s.\n", f15h_ic_mce_desc[xec-2]); break; case 0x10: - pr_cont("%s.\n", f15h_mc1_mce_desc[xec-4]); + pr_cont("%s.\n", f15h_ic_mce_desc[xec-4]); break; case 0x11 ... 0x14: - pr_cont("Decoder %s parity error.\n", f15h_mc1_mce_desc[xec-4]); + pr_cont("Decoder %s parity error.\n", f15h_ic_mce_desc[xec-4]); break; default: @@ -379,12 +379,12 @@ static bool f15h_mc1_mce(u16 ec, u8 xec) return ret; } -static void decode_mc1_mce(struct mce *m) +static void amd_decode_ic_mce(struct mce *m) { u16 ec = EC(m->status); u8 xec = XEC(m->status, xec_mask); - pr_emerg(HW_ERR "MC1 Error: "); + pr_emerg(HW_ERR "Instruction Cache Error: "); if (TLB_ERROR(ec)) pr_cont("%s TLB %s.\n", LL_MSG(ec), @@ -393,18 +393,18 @@ static void decode_mc1_mce(struct mce *m) bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58))); pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read")); - } else if (fam_ops->mc1_mce(ec, xec)) + } else if (fam_ops->ic_mce(ec, xec)) ; else - pr_emerg(HW_ERR "Corrupted MC1 MCE info?\n"); + pr_emerg(HW_ERR "Corrupted IC MCE info?\n"); } -static void decode_mc2_mce(struct mce *m) +static void amd_decode_bu_mce(struct mce *m) { u16 ec = EC(m->status); u8 xec = XEC(m->status, xec_mask); - pr_emerg(HW_ERR "MC2 Error"); + pr_emerg(HW_ERR "Bus Unit Error"); if (xec == 0x1) pr_cont(" in the write data buffers.\n"); @@ -429,24 +429,24 @@ static void decode_mc2_mce(struct mce *m) pr_cont(": %s parity/ECC error during data " "access from L2.\n", R4_MSG(ec)); else - goto wrong_mc2_mce; + goto wrong_bu_mce; } else - goto wrong_mc2_mce; + goto wrong_bu_mce; } else - goto wrong_mc2_mce; + goto wrong_bu_mce; return; - wrong_mc2_mce: - pr_emerg(HW_ERR "Corrupted MC2 MCE info?\n"); +wrong_bu_mce: + pr_emerg(HW_ERR "Corrupted BU MCE info?\n"); } -static void decode_f15_mc2_mce(struct mce *m) +static void amd_decode_cu_mce(struct mce *m) { u16 ec = EC(m->status); u8 xec = XEC(m->status, xec_mask); - pr_emerg(HW_ERR "MC2 Error: "); + pr_emerg(HW_ERR "Combined Unit Error: "); if (TLB_ERROR(ec)) { if (xec == 0x0) @@ -454,63 +454,63 @@ static void decode_f15_mc2_mce(struct mce *m) else if (xec == 0x1) pr_cont("Poison data provided for TLB fill.\n"); else - goto wrong_f15_mc2_mce; + goto wrong_cu_mce; } else if (BUS_ERROR(ec)) { if (xec > 2) - goto wrong_f15_mc2_mce; + goto wrong_cu_mce; pr_cont("Error during attempted NB data read.\n"); } else if (MEM_ERROR(ec)) { switch (xec) { case 0x4 ... 0xc: - pr_cont("%s.\n", f15h_mc2_mce_desc[xec - 0x4]); + pr_cont("%s.\n", f15h_cu_mce_desc[xec - 0x4]); break; case 0x10 ... 0x14: - pr_cont("%s.\n", f15h_mc2_mce_desc[xec - 0x7]); + pr_cont("%s.\n", f15h_cu_mce_desc[xec - 0x7]); break; default: - goto wrong_f15_mc2_mce; + goto wrong_cu_mce; } } return; - wrong_f15_mc2_mce: - pr_emerg(HW_ERR "Corrupted MC2 MCE info?\n"); +wrong_cu_mce: + pr_emerg(HW_ERR "Corrupted CU MCE info?\n"); } -static void decode_mc3_mce(struct mce *m) +static void amd_decode_ls_mce(struct mce *m) { u16 ec = EC(m->status); u8 xec = XEC(m->status, xec_mask); if (boot_cpu_data.x86 >= 0x14) { - pr_emerg("You shouldn't be seeing MC3 MCE on this cpu family," + pr_emerg("You shouldn't be seeing an LS MCE on this cpu family," " please report on LKML.\n"); return; } - pr_emerg(HW_ERR "MC3 Error"); + pr_emerg(HW_ERR "Load Store Error"); if (xec == 0x0) { u8 r4 = R4(ec); if (!BUS_ERROR(ec) || (r4 != R4_DRD && r4 != R4_DWR)) - goto wrong_mc3_mce; + goto wrong_ls_mce; pr_cont(" during %s.\n", R4_MSG(ec)); } else - goto wrong_mc3_mce; + goto wrong_ls_mce; return; - wrong_mc3_mce: - pr_emerg(HW_ERR "Corrupted MC3 MCE info?\n"); +wrong_ls_mce: + pr_emerg(HW_ERR "Corrupted LS MCE info?\n"); } -static void decode_mc4_mce(struct mce *m) +void amd_decode_nb_mce(struct mce *m) { struct cpuinfo_x86 *c = &boot_cpu_data; int node_id = amd_get_nb_id(m->extcpu); @@ -518,7 +518,7 @@ static void decode_mc4_mce(struct mce *m) u8 xec = XEC(m->status, 0x1f); u8 offset = 0; - pr_emerg(HW_ERR "MC4 Error (node %d): ", node_id); + pr_emerg(HW_ERR "Northbridge Error (node %d): ", node_id); switch (xec) { case 0x0 ... 0xe: @@ -527,9 +527,9 @@ static void decode_mc4_mce(struct mce *m) if (xec == 0x0 || xec == 0x8) { /* no ECCs on F11h */ if (c->x86 == 0x11) - goto wrong_mc4_mce; + goto wrong_nb_mce; - pr_cont("%s.\n", mc4_mce_desc[xec]); + pr_cont("%s.\n", nb_mce_desc[xec]); if (nb_bus_decoder) nb_bus_decoder(node_id, m); @@ -543,14 +543,14 @@ static void decode_mc4_mce(struct mce *m) else if (BUS_ERROR(ec)) pr_cont("DMA Exclusion Vector Table Walk error.\n"); else - goto wrong_mc4_mce; + goto wrong_nb_mce; return; case 0x19: if (boot_cpu_data.x86 == 0x15) pr_cont("Compute Unit Data Error.\n"); else - goto wrong_mc4_mce; + goto wrong_nb_mce; return; case 0x1c ... 0x1f: @@ -558,44 +558,46 @@ static void decode_mc4_mce(struct mce *m) break; default: - goto wrong_mc4_mce; + goto wrong_nb_mce; } - pr_cont("%s.\n", mc4_mce_desc[xec - offset]); + pr_cont("%s.\n", nb_mce_desc[xec - offset]); return; - wrong_mc4_mce: - pr_emerg(HW_ERR "Corrupted MC4 MCE info?\n"); +wrong_nb_mce: + pr_emerg(HW_ERR "Corrupted NB MCE info?\n"); } +EXPORT_SYMBOL_GPL(amd_decode_nb_mce); -static void decode_mc5_mce(struct mce *m) +static void amd_decode_fr_mce(struct mce *m) { struct cpuinfo_x86 *c = &boot_cpu_data; u8 xec = XEC(m->status, xec_mask); if (c->x86 == 0xf || c->x86 == 0x11) - goto wrong_mc5_mce; + goto wrong_fr_mce; - pr_emerg(HW_ERR "MC5 Error: "); + pr_emerg(HW_ERR "%s Error: ", + (c->x86 == 0x15 ? "Execution Unit" : "FIROB")); if (xec == 0x0 || xec == 0xc) - pr_cont("%s.\n", mc5_mce_desc[xec]); + pr_cont("%s.\n", fr_ex_mce_desc[xec]); else if (xec < 0xd) - pr_cont("%s parity error.\n", mc5_mce_desc[xec]); + pr_cont("%s parity error.\n", fr_ex_mce_desc[xec]); else - goto wrong_mc5_mce; + goto wrong_fr_mce; return; - wrong_mc5_mce: - pr_emerg(HW_ERR "Corrupted MC5 MCE info?\n"); +wrong_fr_mce: + pr_emerg(HW_ERR "Corrupted FR MCE info?\n"); } -static void decode_mc6_mce(struct mce *m) +static void amd_decode_fp_mce(struct mce *m) { u8 xec = XEC(m->status, xec_mask); - pr_emerg(HW_ERR "MC6 Error: "); + pr_emerg(HW_ERR "Floating Point Unit Error: "); switch (xec) { case 0x1: @@ -619,7 +621,7 @@ static void decode_mc6_mce(struct mce *m) break; default: - goto wrong_mc6_mce; + goto wrong_fp_mce; break; } @@ -627,8 +629,8 @@ static void decode_mc6_mce(struct mce *m) return; - wrong_mc6_mce: - pr_emerg(HW_ERR "Corrupted MC6 MCE info?\n"); +wrong_fp_mce: + pr_emerg(HW_ERR "Corrupted FP MCE info?\n"); } static inline void amd_decode_err_code(u16 ec) @@ -667,94 +669,74 @@ static bool amd_filter_mce(struct mce *m) return false; } -static const char *decode_error_status(struct mce *m) -{ - if (m->status & MCI_STATUS_UC) { - if (m->status & MCI_STATUS_PCC) - return "System Fatal error."; - if (m->mcgstatus & MCG_STATUS_RIPV) - return "Uncorrected, software restartable error."; - return "Uncorrected, software containable error."; - } - - if (m->status & MCI_STATUS_DEFERRED) - return "Deferred error."; - - return "Corrected error, no action required."; -} - int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data) { struct mce *m = (struct mce *)data; - struct cpuinfo_x86 *c = &cpu_data(m->extcpu); + struct cpuinfo_x86 *c = &boot_cpu_data; int ecc; if (amd_filter_mce(m)) return NOTIFY_STOP; + pr_emerg(HW_ERR "CPU:%d\tMC%d_STATUS[%s|%s|%s|%s|%s", + m->extcpu, m->bank, + ((m->status & MCI_STATUS_OVER) ? "Over" : "-"), + ((m->status & MCI_STATUS_UC) ? "UE" : "CE"), + ((m->status & MCI_STATUS_MISCV) ? "MiscV" : "-"), + ((m->status & MCI_STATUS_PCC) ? "PCC" : "-"), + ((m->status & MCI_STATUS_ADDRV) ? "AddrV" : "-")); + + if (c->x86 == 0x15) + pr_cont("|%s|%s", + ((m->status & BIT_64(44)) ? "Deferred" : "-"), + ((m->status & BIT_64(43)) ? "Poison" : "-")); + + /* do the two bits[14:13] together */ + ecc = (m->status >> 45) & 0x3; + if (ecc) + pr_cont("|%sECC", ((ecc == 2) ? "C" : "U")); + + pr_cont("]: 0x%016llx\n", m->status); + + if (m->status & MCI_STATUS_ADDRV) + pr_emerg(HW_ERR "\tMC%d_ADDR: 0x%016llx\n", m->bank, m->addr); + switch (m->bank) { case 0: - decode_mc0_mce(m); + amd_decode_dc_mce(m); break; case 1: - decode_mc1_mce(m); + amd_decode_ic_mce(m); break; case 2: if (c->x86 == 0x15) - decode_f15_mc2_mce(m); + amd_decode_cu_mce(m); else - decode_mc2_mce(m); + amd_decode_bu_mce(m); break; case 3: - decode_mc3_mce(m); + amd_decode_ls_mce(m); break; case 4: - decode_mc4_mce(m); + amd_decode_nb_mce(m); break; case 5: - decode_mc5_mce(m); + amd_decode_fr_mce(m); break; case 6: - decode_mc6_mce(m); + amd_decode_fp_mce(m); break; default: break; } - pr_emerg(HW_ERR "Error Status: %s\n", decode_error_status(m)); - - pr_emerg(HW_ERR "CPU:%d (%x:%x:%x) MC%d_STATUS[%s|%s|%s|%s|%s", - m->extcpu, - c->x86, c->x86_model, c->x86_mask, - m->bank, - ((m->status & MCI_STATUS_OVER) ? "Over" : "-"), - ((m->status & MCI_STATUS_UC) ? "UE" : "CE"), - ((m->status & MCI_STATUS_MISCV) ? "MiscV" : "-"), - ((m->status & MCI_STATUS_PCC) ? "PCC" : "-"), - ((m->status & MCI_STATUS_ADDRV) ? "AddrV" : "-")); - - if (c->x86 == 0x15) - pr_cont("|%s|%s", - ((m->status & MCI_STATUS_DEFERRED) ? "Deferred" : "-"), - ((m->status & MCI_STATUS_POISON) ? "Poison" : "-")); - - /* do the two bits[14:13] together */ - ecc = (m->status >> 45) & 0x3; - if (ecc) - pr_cont("|%sECC", ((ecc == 2) ? "C" : "U")); - - pr_cont("]: 0x%016llx\n", m->status); - - if (m->status & MCI_STATUS_ADDRV) - pr_emerg(HW_ERR "MC%d_ADDR: 0x%016llx\n", m->bank, m->addr); - amd_decode_err_code(m->status & 0xffff); return NOTIFY_STOP; @@ -781,35 +763,35 @@ static int __init mce_amd_init(void) switch (c->x86) { case 0xf: - fam_ops->mc0_mce = k8_mc0_mce; - fam_ops->mc1_mce = k8_mc1_mce; + fam_ops->dc_mce = k8_dc_mce; + fam_ops->ic_mce = k8_ic_mce; break; case 0x10: - fam_ops->mc0_mce = f10h_mc0_mce; - fam_ops->mc1_mce = k8_mc1_mce; + fam_ops->dc_mce = f10h_dc_mce; + fam_ops->ic_mce = k8_ic_mce; break; case 0x11: - fam_ops->mc0_mce = k8_mc0_mce; - fam_ops->mc1_mce = k8_mc1_mce; + fam_ops->dc_mce = k8_dc_mce; + fam_ops->ic_mce = k8_ic_mce; break; case 0x12: - fam_ops->mc0_mce = f12h_mc0_mce; - fam_ops->mc1_mce = k8_mc1_mce; + fam_ops->dc_mce = f12h_dc_mce; + fam_ops->ic_mce = k8_ic_mce; break; case 0x14: nb_err_cpumask = 0x3; - fam_ops->mc0_mce = f14h_mc0_mce; - fam_ops->mc1_mce = f14h_mc1_mce; + fam_ops->dc_mce = f14h_dc_mce; + fam_ops->ic_mce = f14h_ic_mce; break; case 0x15: xec_mask = 0x1f; - fam_ops->mc0_mce = f15h_mc0_mce; - fam_ops->mc1_mce = f15h_mc1_mce; + fam_ops->dc_mce = f15h_dc_mce; + fam_ops->ic_mce = f15h_ic_mce; break; default: diff --git a/trunk/drivers/edac/mce_amd.h b/trunk/drivers/edac/mce_amd.h index 679679951e23..8c87a5e87057 100644 --- a/trunk/drivers/edac/mce_amd.h +++ b/trunk/drivers/edac/mce_amd.h @@ -29,8 +29,10 @@ #define R4(x) (((x) >> 4) & 0xf) #define R4_MSG(x) ((R4(x) < 9) ? rrrr_msgs[R4(x)] : "Wrong R4!") -#define MCI_STATUS_DEFERRED BIT_64(44) -#define MCI_STATUS_POISON BIT_64(43) +/* + * F3x4C bits (MCi_STATUS' high half) + */ +#define NBSH_ERR_CPU_VAL BIT(24) enum tt_ids { TT_INSTR = 0, @@ -76,13 +78,14 @@ extern const char * const ii_msgs[]; * per-family decoder ops */ struct amd_decoder_ops { - bool (*mc0_mce)(u16, u8); - bool (*mc1_mce)(u16, u8); + bool (*dc_mce)(u16, u8); + bool (*ic_mce)(u16, u8); }; void amd_report_gart_errors(bool); void amd_register_ecc_decoder(void (*f)(int, struct mce *)); void amd_unregister_ecc_decoder(void (*f)(int, struct mce *)); +void amd_decode_nb_mce(struct mce *); int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data); #endif /* _EDAC_MCE_AMD_H */ diff --git a/trunk/drivers/edac/mce_amd_inj.c b/trunk/drivers/edac/mce_amd_inj.c index 2ae78f20cc28..66b5151c1080 100644 --- a/trunk/drivers/edac/mce_amd_inj.c +++ b/trunk/drivers/edac/mce_amd_inj.c @@ -6,7 +6,7 @@ * This file may be distributed under the terms of the GNU General Public * License version 2. * - * Copyright (c) 2010: Borislav Petkov + * Copyright (c) 2010: Borislav Petkov * Advanced Micro Devices Inc. */ @@ -168,6 +168,6 @@ module_init(edac_init_mce_inject); module_exit(edac_exit_mce_inject); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Borislav Petkov "); +MODULE_AUTHOR("Borislav Petkov "); MODULE_AUTHOR("AMD Inc."); MODULE_DESCRIPTION("MCE injection facility for testing MCE decoding"); diff --git a/trunk/drivers/extcon/extcon-adc-jack.c b/trunk/drivers/extcon/extcon-adc-jack.c index e87196f6d2d2..725eb5aa8d8c 100644 --- a/trunk/drivers/extcon/extcon-adc-jack.c +++ b/trunk/drivers/extcon/extcon-adc-jack.c @@ -14,7 +14,6 @@ * */ -#include #include #include #include @@ -162,12 +161,13 @@ static int __devinit adc_jack_probe(struct platform_device *pdev) err = request_any_context_irq(data->irq, adc_jack_irq_thread, pdata->irq_flags, pdata->name, data); - if (err < 0) { + if (err) { dev_err(&pdev->dev, "error: irq %d\n", data->irq); + err = -EINVAL; goto err_irq; } - return 0; + goto out; err_irq: extcon_dev_unregister(&data->edev); @@ -196,7 +196,3 @@ static struct platform_driver adc_jack_driver = { }; module_platform_driver(adc_jack_driver); - -MODULE_AUTHOR("MyungJoo Ham "); -MODULE_DESCRIPTION("ADC Jack extcon driver"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/extcon/extcon-class.c b/trunk/drivers/extcon/extcon-class.c index d398821097f3..946a3188b2b7 100644 --- a/trunk/drivers/extcon/extcon-class.c +++ b/trunk/drivers/extcon/extcon-class.c @@ -41,7 +41,7 @@ * every single port-type of the following cable names. Please choose cable * names that are actually used in your extcon device. */ -const char extcon_cable_name[][CABLE_NAME_MAX + 1] = { +const char *extcon_cable_name[] = { [EXTCON_USB] = "USB", [EXTCON_USB_HOST] = "USB-Host", [EXTCON_TA] = "TA", @@ -62,6 +62,8 @@ const char extcon_cable_name[][CABLE_NAME_MAX + 1] = { [EXTCON_VIDEO_IN] = "Video-in", [EXTCON_VIDEO_OUT] = "Video-out", [EXTCON_MECHANICAL] = "Mechanical", + + NULL, }; static struct class *extcon_class; @@ -89,13 +91,17 @@ static int check_mutually_exclusive(struct extcon_dev *edev, u32 new_state) return 0; for (i = 0; edev->mutually_exclusive[i]; i++) { - int weight; + int count = 0, j; u32 correspondants = new_state & edev->mutually_exclusive[i]; - - /* calculate the total number of bits set */ - weight = hweight32(correspondants); - if (weight > 1) - return i + 1; + u32 exp = 1; + + for (j = 0; j < 32; j++) { + if (exp & correspondants) + count++; + if (count > 1) + return i + 1; + exp <<= 1; + } } return 0; @@ -356,7 +362,7 @@ int extcon_get_cable_state(struct extcon_dev *edev, const char *cable_name) EXPORT_SYMBOL_GPL(extcon_get_cable_state); /** - * extcon_set_cable_state_() - Set the status of a specific cable. + * extcon_get_cable_state_() - Set the status of a specific cable. * @edev: the extcon device that has the cable. * @index: cable index that can be retrieved by extcon_find_cable_index(). * @cable_state: the new cable status. The default semantics is @@ -376,7 +382,7 @@ int extcon_set_cable_state_(struct extcon_dev *edev, EXPORT_SYMBOL_GPL(extcon_set_cable_state_); /** - * extcon_set_cable_state() - Set the status of a specific cable. + * extcon_get_cable_state() - Set the status of a specific cable. * @edev: the extcon device that has the cable. * @cable_name: cable name. * @cable_state: the new cable status. The default semantics is @@ -441,8 +447,6 @@ static int _call_per_cable(struct notifier_block *nb, unsigned long val, * extcon device. * @obj: an empty extcon_specific_cable_nb object to be returned. * @extcon_name: the name of extcon device. - * if NULL, extcon_register_interest will register - * every cable with the target cable_name given. * @cable_name: the target cable name. * @nb: the notifier block to get notified. * @@ -462,44 +466,22 @@ int extcon_register_interest(struct extcon_specific_cable_nb *obj, const char *extcon_name, const char *cable_name, struct notifier_block *nb) { - if (!obj || !cable_name || !nb) + if (!obj || !extcon_name || !cable_name || !nb) return -EINVAL; - if (extcon_name) { - obj->edev = extcon_get_extcon_dev(extcon_name); - if (!obj->edev) - return -ENODEV; - - obj->cable_index = extcon_find_cable_index(obj->edev, cable_name); - if (obj->cable_index < 0) - return -ENODEV; + obj->edev = extcon_get_extcon_dev(extcon_name); + if (!obj->edev) + return -ENODEV; - obj->user_nb = nb; + obj->cable_index = extcon_find_cable_index(obj->edev, cable_name); + if (obj->cable_index < 0) + return -ENODEV; - obj->internal_nb.notifier_call = _call_per_cable; + obj->user_nb = nb; - return raw_notifier_chain_register(&obj->edev->nh, &obj->internal_nb); - } else { - struct class_dev_iter iter; - struct extcon_dev *extd; - struct device *dev; - - if (!extcon_class) - return -ENODEV; - class_dev_iter_init(&iter, extcon_class, NULL, NULL); - while ((dev = class_dev_iter_next(&iter))) { - extd = (struct extcon_dev *)dev_get_drvdata(dev); - - if (extcon_find_cable_index(extd, cable_name) < 0) - continue; - - class_dev_iter_exit(&iter); - return extcon_register_interest(obj, extd->name, - cable_name, nb); - } + obj->internal_nb.notifier_call = _call_per_cable; - return -ENODEV; - } + return raw_notifier_chain_register(&obj->edev->nh, &obj->internal_nb); } /** @@ -569,9 +551,43 @@ static int create_extcon_class(void) return 0; } +static void extcon_cleanup(struct extcon_dev *edev, bool skip) +{ + mutex_lock(&extcon_dev_list_lock); + list_del(&edev->entry); + mutex_unlock(&extcon_dev_list_lock); + + if (!skip && get_device(edev->dev)) { + int index; + + if (edev->mutually_exclusive && edev->max_supported) { + for (index = 0; edev->mutually_exclusive[index]; + index++) + kfree(edev->d_attrs_muex[index].attr.name); + kfree(edev->d_attrs_muex); + kfree(edev->attrs_muex); + } + + for (index = 0; index < edev->max_supported; index++) + kfree(edev->cables[index].attr_g.name); + + if (edev->max_supported) { + kfree(edev->extcon_dev_type.groups); + kfree(edev->cables); + } + + device_unregister(edev->dev); + put_device(edev->dev); + } + + kfree(edev->dev); +} + static void extcon_dev_release(struct device *dev) { - kfree(dev); + struct extcon_dev *edev = (struct extcon_dev *) dev_get_drvdata(dev); + + extcon_cleanup(edev, true); } static const char *muex_name = "mutually_exclusive"; @@ -797,40 +813,7 @@ EXPORT_SYMBOL_GPL(extcon_dev_register); */ void extcon_dev_unregister(struct extcon_dev *edev) { - int index; - - mutex_lock(&extcon_dev_list_lock); - list_del(&edev->entry); - mutex_unlock(&extcon_dev_list_lock); - - if (IS_ERR_OR_NULL(get_device(edev->dev))) { - dev_err(edev->dev, "Failed to unregister extcon_dev (%s)\n", - dev_name(edev->dev)); - return; - } - - if (edev->mutually_exclusive && edev->max_supported) { - for (index = 0; edev->mutually_exclusive[index]; - index++) - kfree(edev->d_attrs_muex[index].attr.name); - kfree(edev->d_attrs_muex); - kfree(edev->attrs_muex); - } - - for (index = 0; index < edev->max_supported; index++) - kfree(edev->cables[index].attr_g.name); - - if (edev->max_supported) { - kfree(edev->extcon_dev_type.groups); - kfree(edev->cables); - } - -#if defined(CONFIG_ANDROID) - if (switch_class) - class_compat_remove_link(switch_class, edev->dev, NULL); -#endif - device_unregister(edev->dev); - put_device(edev->dev); + extcon_cleanup(edev, false); } EXPORT_SYMBOL_GPL(extcon_dev_unregister); @@ -842,9 +825,6 @@ module_init(extcon_class_init); static void __exit extcon_class_exit(void) { -#if defined(CONFIG_ANDROID) - class_compat_unregister(switch_class); -#endif class_destroy(extcon_class); } module_exit(extcon_class_exit); diff --git a/trunk/drivers/extcon/extcon-gpio.c b/trunk/drivers/extcon/extcon-gpio.c index 71d3ab7b3d8d..3cc152e690b0 100644 --- a/trunk/drivers/extcon/extcon-gpio.c +++ b/trunk/drivers/extcon/extcon-gpio.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/extcon/extcon-max77693.c b/trunk/drivers/extcon/extcon-max77693.c index a17d0d91ada2..e21387e2da5c 100644 --- a/trunk/drivers/extcon/extcon-max77693.c +++ b/trunk/drivers/extcon/extcon-max77693.c @@ -239,19 +239,25 @@ const char *max77693_extcon_cable[] = { static int max77693_muic_set_debounce_time(struct max77693_muic_info *info, enum max77693_muic_adc_debounce_time time) { - int ret; + int ret = 0; + u8 ctrl3; switch (time) { case ADC_DEBOUNCE_TIME_5MS: case ADC_DEBOUNCE_TIME_10MS: case ADC_DEBOUNCE_TIME_25MS: case ADC_DEBOUNCE_TIME_38_62MS: - ret = max77693_update_reg(info->max77693->regmap_muic, - MAX77693_MUIC_REG_CTRL3, - time << CONTROL3_ADCDBSET_SHIFT, - CONTROL3_ADCDBSET_MASK); - if (ret) + ret = max77693_read_reg(info->max77693->regmap_muic, + MAX77693_MUIC_REG_CTRL3, &ctrl3); + ctrl3 &= ~CONTROL3_ADCDBSET_MASK; + ctrl3 |= (time << CONTROL3_ADCDBSET_SHIFT); + + ret = max77693_write_reg(info->max77693->regmap_muic, + MAX77693_MUIC_REG_CTRL3, ctrl3); + if (ret) { dev_err(info->dev, "failed to set ADC debounce time\n"); + ret = -EINVAL; + } break; default: dev_err(info->dev, "invalid ADC debounce time\n"); @@ -651,8 +657,6 @@ static int max77693_muic_detect_accessory(struct max77693_muic_info *info) static int __devinit max77693_muic_probe(struct platform_device *pdev) { struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent); - struct max77693_platform_data *pdata = dev_get_platdata(max77693->dev); - struct max77693_muic_platform_data *muic_pdata = pdata->muic_data; struct max77693_muic_info *info; int ret, i; u8 id; @@ -723,31 +727,6 @@ static int __devinit max77693_muic_probe(struct platform_device *pdev) goto err_extcon; } - /* Initialize MUIC register by using platform data */ - for (i = 0 ; i < muic_pdata->num_init_data ; i++) { - enum max77693_irq_source irq_src = MAX77693_IRQ_GROUP_NR; - - max77693_write_reg(info->max77693->regmap_muic, - muic_pdata->init_data[i].addr, - muic_pdata->init_data[i].data); - - switch (muic_pdata->init_data[i].addr) { - case MAX77693_MUIC_REG_INTMASK1: - irq_src = MUIC_INT1; - break; - case MAX77693_MUIC_REG_INTMASK2: - irq_src = MUIC_INT2; - break; - case MAX77693_MUIC_REG_INTMASK3: - irq_src = MUIC_INT3; - break; - } - - if (irq_src < MAX77693_IRQ_GROUP_NR) - info->max77693->irq_masks_cur[irq_src] - = muic_pdata->init_data[i].data; - } - /* Check revision number of MUIC device*/ ret = max77693_read_reg(info->max77693->regmap_muic, MAX77693_MUIC_REG_ID, &id); @@ -783,7 +762,6 @@ static int __devexit max77693_muic_remove(struct platform_device *pdev) free_irq(muic_irqs[i].virq, info); cancel_work_sync(&info->irq_work); extcon_dev_unregister(info->edev); - kfree(info->edev); kfree(info); return 0; diff --git a/trunk/drivers/extcon/extcon-max8997.c b/trunk/drivers/extcon/extcon-max8997.c index 77b66b0cc8f5..ef9090a4271d 100644 --- a/trunk/drivers/extcon/extcon-max8997.c +++ b/trunk/drivers/extcon/extcon-max8997.c @@ -271,6 +271,8 @@ static int max8997_muic_handle_adc(struct max8997_muic_info *info, int adc) static int max8997_muic_handle_charger_type_detach( struct max8997_muic_info *info) { + int ret = 0; + switch (info->pre_charger_type) { case MAX8997_CHARGER_TYPE_USB: extcon_set_cable_state(info->edev, "USB", false); @@ -288,11 +290,11 @@ static int max8997_muic_handle_charger_type_detach( extcon_set_cable_state(info->edev, "Fast-charger", false); break; default: - return -EINVAL; + ret = -EINVAL; break; } - return 0; + return ret; } static int max8997_muic_handle_charger_type(struct max8997_muic_info *info, diff --git a/trunk/drivers/firewire/sbp2.c b/trunk/drivers/firewire/sbp2.c index bb1b392f5cda..1162d6b3bf85 100644 --- a/trunk/drivers/firewire/sbp2.c +++ b/trunk/drivers/firewire/sbp2.c @@ -1546,8 +1546,6 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) struct sbp2_logical_unit *lu = sdev->hostdata; sdev->use_10_for_rw = 1; - sdev->no_report_opcodes = 1; - sdev->no_write_same = 1; if (sbp2_param_exclusive_login) sdev->manage_start_stop = 1; diff --git a/trunk/drivers/gpio/Kconfig b/trunk/drivers/gpio/Kconfig index 47150f5ded04..d055cee36942 100644 --- a/trunk/drivers/gpio/Kconfig +++ b/trunk/drivers/gpio/Kconfig @@ -47,7 +47,7 @@ if GPIOLIB config OF_GPIO def_bool y - depends on OF + depends on OF && !SPARC config DEBUG_GPIO bool "Debug GPIO calls" @@ -466,7 +466,7 @@ config GPIO_ADP5588_IRQ config GPIO_ADNP tristate "Avionic Design N-bit GPIO expander" - depends on I2C && OF_GPIO + depends on I2C && OF help This option enables support for N GPIOs found on Avionic Design I2C GPIO expanders. The register space will be extended by powers diff --git a/trunk/drivers/gpio/gpio-74x164.c b/trunk/drivers/gpio/gpio-74x164.c index f05e54258ffb..ed3e55161bdc 100644 --- a/trunk/drivers/gpio/gpio-74x164.c +++ b/trunk/drivers/gpio/gpio-74x164.c @@ -153,7 +153,7 @@ static int __devinit gen_74x164_probe(struct spi_device *spi) } chip->gpio_chip.ngpio = GEN_74X164_NUMBER_GPIOS * chip->registers; - chip->buffer = devm_kzalloc(&spi->dev, chip->registers, GFP_KERNEL); + chip->buffer = devm_kzalloc(&spi->dev, chip->gpio_chip.ngpio, GFP_KERNEL); if (!chip->buffer) { ret = -ENOMEM; goto exit_destroy; diff --git a/trunk/drivers/gpio/gpio-mcp23s08.c b/trunk/drivers/gpio/gpio-mcp23s08.c index ce1c84760076..0f425189de11 100644 --- a/trunk/drivers/gpio/gpio-mcp23s08.c +++ b/trunk/drivers/gpio/gpio-mcp23s08.c @@ -77,7 +77,7 @@ struct mcp23s08_driver_data { /*----------------------------------------------------------------------*/ -#if IS_ENABLED(CONFIG_I2C) +#ifdef CONFIG_I2C static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg) { @@ -399,7 +399,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, break; #endif /* CONFIG_SPI_MASTER */ -#if IS_ENABLED(CONFIG_I2C) +#ifdef CONFIG_I2C case MCP_TYPE_008: mcp->ops = &mcp23008_ops; mcp->chip.ngpio = 8; @@ -473,7 +473,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, /*----------------------------------------------------------------------*/ -#if IS_ENABLED(CONFIG_I2C) +#ifdef CONFIG_I2C static int __devinit mcp230xx_probe(struct i2c_client *client, const struct i2c_device_id *id) diff --git a/trunk/drivers/gpio/gpio-mvebu.c b/trunk/drivers/gpio/gpio-mvebu.c index be65c0451ad5..7a874129e5d8 100644 --- a/trunk/drivers/gpio/gpio-mvebu.c +++ b/trunk/drivers/gpio/gpio-mvebu.c @@ -92,11 +92,6 @@ static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip) return mvchip->membase + GPIO_OUT_OFF; } -static inline void __iomem *mvebu_gpioreg_blink(struct mvebu_gpio_chip *mvchip) -{ - return mvchip->membase + GPIO_BLINK_EN_OFF; -} - static inline void __iomem *mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip) { return mvchip->membase + GPIO_IO_CONF_OFF; @@ -211,23 +206,6 @@ static int mvebu_gpio_get(struct gpio_chip *chip, unsigned pin) return (u >> pin) & 1; } -static void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value) -{ - struct mvebu_gpio_chip *mvchip = - container_of(chip, struct mvebu_gpio_chip, chip); - unsigned long flags; - u32 u; - - spin_lock_irqsave(&mvchip->lock, flags); - u = readl_relaxed(mvebu_gpioreg_blink(mvchip)); - if (value) - u |= 1 << pin; - else - u &= ~(1 << pin); - writel_relaxed(u, mvebu_gpioreg_blink(mvchip)); - spin_unlock_irqrestore(&mvchip->lock, flags); -} - static int mvebu_gpio_direction_input(struct gpio_chip *chip, unsigned pin) { struct mvebu_gpio_chip *mvchip = @@ -266,9 +244,6 @@ static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin, if (ret) return ret; - mvebu_gpio_blink(chip, pin, 0); - mvebu_gpio_set(chip, pin, value); - spin_lock_irqsave(&mvchip->lock, flags); u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip)); u &= ~(1 << pin); @@ -669,7 +644,7 @@ static int __devinit mvebu_gpio_probe(struct platform_device *pdev) ct->handler = handle_edge_irq; ct->chip.name = mvchip->chip.label; - irq_setup_generic_chip(gc, IRQ_MSK(ngpios), 0, + irq_setup_generic_chip(gc, IRQ_MSK(ngpios), IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); /* Setup irq domain on top of the generic chip. */ diff --git a/trunk/drivers/gpio/gpio-omap.c b/trunk/drivers/gpio/gpio-omap.c index d335af1d4d85..94cbc842fbc3 100644 --- a/trunk/drivers/gpio/gpio-omap.c +++ b/trunk/drivers/gpio/gpio-omap.c @@ -251,40 +251,6 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio, } } -/** - * _clear_gpio_debounce - clear debounce settings for a gpio - * @bank: the gpio bank we're acting upon - * @gpio: the gpio number on this @gpio - * - * If a gpio is using debounce, then clear the debounce enable bit and if - * this is the only gpio in this bank using debounce, then clear the debounce - * time too. The debounce clock will also be disabled when calling this function - * if this is the only gpio in the bank using debounce. - */ -static void _clear_gpio_debounce(struct gpio_bank *bank, unsigned gpio) -{ - u32 gpio_bit = GPIO_BIT(bank, gpio); - - if (!bank->dbck_flag) - return; - - if (!(bank->dbck_enable_mask & gpio_bit)) - return; - - bank->dbck_enable_mask &= ~gpio_bit; - bank->context.debounce_en &= ~gpio_bit; - __raw_writel(bank->context.debounce_en, - bank->base + bank->regs->debounce_en); - - if (!bank->dbck_enable_mask) { - bank->context.debounce = 0; - __raw_writel(bank->context.debounce, bank->base + - bank->regs->debounce); - clk_disable(bank->dbck); - bank->dbck_enabled = false; - } -} - static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio, unsigned trigger) { @@ -573,7 +539,6 @@ static void _reset_gpio(struct gpio_bank *bank, int gpio) _set_gpio_irqenable(bank, gpio, 0); _clear_gpio_irqstatus(bank, gpio); _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE); - _clear_gpio_debounce(bank, gpio); } /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ diff --git a/trunk/drivers/gpio/gpio-timberdale.c b/trunk/drivers/gpio/gpio-timberdale.c index 1a3e2b9b4772..031c6adf5b65 100644 --- a/trunk/drivers/gpio/gpio-timberdale.c +++ b/trunk/drivers/gpio/gpio-timberdale.c @@ -116,7 +116,7 @@ static void timbgpio_irq_disable(struct irq_data *d) unsigned long flags; spin_lock_irqsave(&tgpio->lock, flags); - tgpio->last_ier &= ~(1UL << offset); + tgpio->last_ier &= ~(1 << offset); iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); spin_unlock_irqrestore(&tgpio->lock, flags); } @@ -128,7 +128,7 @@ static void timbgpio_irq_enable(struct irq_data *d) unsigned long flags; spin_lock_irqsave(&tgpio->lock, flags); - tgpio->last_ier |= 1UL << offset; + tgpio->last_ier |= 1 << offset; iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); spin_unlock_irqrestore(&tgpio->lock, flags); } diff --git a/trunk/drivers/gpio/gpiolib-of.c b/trunk/drivers/gpio/gpiolib-of.c index d542a141811a..f1a45997aea8 100644 --- a/trunk/drivers/gpio/gpiolib-of.c +++ b/trunk/drivers/gpio/gpiolib-of.c @@ -19,7 +19,6 @@ #include #include #include -#include #include /* Private data structure for of_gpiochip_find_and_xlate */ @@ -217,54 +216,6 @@ int of_mm_gpiochip_add(struct device_node *np, } EXPORT_SYMBOL(of_mm_gpiochip_add); -#ifdef CONFIG_PINCTRL -static void of_gpiochip_add_pin_range(struct gpio_chip *chip) -{ - struct device_node *np = chip->of_node; - struct of_phandle_args pinspec; - struct pinctrl_dev *pctldev; - int index = 0, ret; - - if (!np) - return; - - do { - ret = of_parse_phandle_with_args(np, "gpio-ranges", - "#gpio-range-cells", index, &pinspec); - if (ret) - break; - - pctldev = of_pinctrl_get(pinspec.np); - if (!pctldev) - break; - - /* - * This assumes that the n GPIO pins are consecutive in the - * GPIO number space, and that the pins are also consecutive - * in their local number space. Currently it is not possible - * to add different ranges for one and the same GPIO chip, - * as the code assumes that we have one consecutive range - * on both, mapping 1-to-1. - * - * TODO: make the OF bindings handle multiple sparse ranges - * on the same GPIO chip. - */ - ret = gpiochip_add_pin_range(chip, - pinctrl_dev_get_name(pctldev), - 0, /* offset in gpiochip */ - pinspec.args[0], - pinspec.args[1]); - - if (ret) - break; - - } while (index++); -} - -#else -static void of_gpiochip_add_pin_range(struct gpio_chip *chip) {} -#endif - void of_gpiochip_add(struct gpio_chip *chip) { if ((!chip->of_node) && (chip->dev)) @@ -278,14 +229,11 @@ void of_gpiochip_add(struct gpio_chip *chip) chip->of_xlate = of_gpio_simple_xlate; } - of_gpiochip_add_pin_range(chip); of_node_get(chip->of_node); } void of_gpiochip_remove(struct gpio_chip *chip) { - gpiochip_remove_pin_ranges(chip); - if (chip->of_node) of_node_put(chip->of_node); } diff --git a/trunk/drivers/gpio/gpiolib.c b/trunk/drivers/gpio/gpiolib.c index 58b9838801c0..5d6c71edc739 100644 --- a/trunk/drivers/gpio/gpiolib.c +++ b/trunk/drivers/gpio/gpiolib.c @@ -623,11 +623,9 @@ static ssize_t export_store(struct class *class, */ status = gpio_request(gpio, "sysfs"); - if (status < 0) { - if (status == -EPROBE_DEFER) - status = -ENODEV; + if (status < 0) goto done; - } + status = gpio_export(gpio, true); if (status < 0) gpio_free(gpio); @@ -1083,10 +1081,6 @@ int gpiochip_add(struct gpio_chip *chip) } } -#ifdef CONFIG_PINCTRL - INIT_LIST_HEAD(&chip->pin_ranges); -#endif - of_gpiochip_add(chip); unlock: @@ -1127,7 +1121,6 @@ int gpiochip_remove(struct gpio_chip *chip) spin_lock_irqsave(&gpio_lock, flags); - gpiochip_remove_pin_ranges(chip); of_gpiochip_remove(chip); for (id = chip->base; id < chip->base + chip->ngpio; id++) { @@ -1185,77 +1178,6 @@ struct gpio_chip *gpiochip_find(void *data, } EXPORT_SYMBOL_GPL(gpiochip_find); -#ifdef CONFIG_PINCTRL - -/** - * gpiochip_add_pin_range() - add a range for GPIO <-> pin mapping - * @chip: the gpiochip to add the range for - * @pinctrl_name: the dev_name() of the pin controller to map to - * @gpio_offset: the start offset in the current gpio_chip number space - * @pin_offset: the start offset in the pin controller number space - * @npins: the number of pins from the offset of each pin space (GPIO and - * pin controller) to accumulate in this range - */ -int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int gpio_offset, unsigned int pin_offset, - unsigned int npins) -{ - struct gpio_pin_range *pin_range; - int ret; - - pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL); - if (!pin_range) { - pr_err("%s: GPIO chip: failed to allocate pin ranges\n", - chip->label); - return -ENOMEM; - } - - /* Use local offset as range ID */ - pin_range->range.id = gpio_offset; - pin_range->range.gc = chip; - pin_range->range.name = chip->label; - pin_range->range.base = chip->base + gpio_offset; - pin_range->range.pin_base = pin_offset; - pin_range->range.npins = npins; - pin_range->pctldev = pinctrl_find_and_add_gpio_range(pinctl_name, - &pin_range->range); - if (IS_ERR(pin_range->pctldev)) { - ret = PTR_ERR(pin_range->pctldev); - pr_err("%s: GPIO chip: could not create pin range\n", - chip->label); - kfree(pin_range); - return ret; - } - pr_debug("GPIO chip %s: created GPIO range %d->%d ==> %s PIN %d->%d\n", - chip->label, gpio_offset, gpio_offset + npins - 1, - pinctl_name, - pin_offset, pin_offset + npins - 1); - - list_add_tail(&pin_range->node, &chip->pin_ranges); - - return 0; -} -EXPORT_SYMBOL_GPL(gpiochip_add_pin_range); - -/** - * gpiochip_remove_pin_ranges() - remove all the GPIO <-> pin mappings - * @chip: the chip to remove all the mappings for - */ -void gpiochip_remove_pin_ranges(struct gpio_chip *chip) -{ - struct gpio_pin_range *pin_range, *tmp; - - list_for_each_entry_safe(pin_range, tmp, &chip->pin_ranges, node) { - list_del(&pin_range->node); - pinctrl_remove_gpio_range(pin_range->pctldev, - &pin_range->range); - kfree(pin_range); - } -} -EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges); - -#endif /* CONFIG_PINCTRL */ - /* These "optional" allocation calls help prevent drivers from stomping * on each other, and help provide better diagnostics in debugfs. * They're called even less than the "set direction" calls. @@ -1269,10 +1191,8 @@ int gpio_request(unsigned gpio, const char *label) spin_lock_irqsave(&gpio_lock, flags); - if (!gpio_is_valid(gpio)) { - status = -EINVAL; + if (!gpio_is_valid(gpio)) goto done; - } desc = &gpio_desc[gpio]; chip = desc->chip; if (chip == NULL) diff --git a/trunk/drivers/gpu/drm/drm_fb_cma_helper.c b/trunk/drivers/gpu/drm/drm_fb_cma_helper.c index fd9d0af4d536..09e11a5d921a 100644 --- a/trunk/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/trunk/drivers/gpu/drm/drm_fb_cma_helper.c @@ -206,7 +206,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, size_t size; int ret; - DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d)\n", + DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d\n", sizes->surface_width, sizes->surface_height, sizes->surface_bpp); @@ -220,7 +220,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, size = mode_cmd.pitches[0] * mode_cmd.height; obj = drm_gem_cma_create(dev, size); - if (IS_ERR(obj)) + if (!obj) return -ENOMEM; fbi = framebuffer_alloc(0, dev->dev); diff --git a/trunk/drivers/gpu/drm/drm_fops.c b/trunk/drivers/gpu/drm/drm_fops.c index 133b4132983e..7ef1b673e1be 100644 --- a/trunk/drivers/gpu/drm/drm_fops.c +++ b/trunk/drivers/gpu/drm/drm_fops.c @@ -121,8 +121,6 @@ int drm_open(struct inode *inode, struct file *filp) int minor_id = iminor(inode); struct drm_minor *minor; int retcode = 0; - int need_setup = 0; - struct address_space *old_mapping; minor = idr_find(&drm_minors_idr, minor_id); if (!minor) @@ -134,37 +132,23 @@ int drm_open(struct inode *inode, struct file *filp) if (drm_device_is_unplugged(dev)) return -ENODEV; - if (!dev->open_count++) - need_setup = 1; - mutex_lock(&dev->struct_mutex); - old_mapping = dev->dev_mapping; - if (old_mapping == NULL) - dev->dev_mapping = &inode->i_data; - /* ihold ensures nobody can remove inode with our i_data */ - ihold(container_of(dev->dev_mapping, struct inode, i_data)); - inode->i_mapping = dev->dev_mapping; - filp->f_mapping = dev->dev_mapping; - mutex_unlock(&dev->struct_mutex); - retcode = drm_open_helper(inode, filp, dev); - if (retcode) - goto err_undo; - atomic_inc(&dev->counts[_DRM_STAT_OPENS]); - if (need_setup) { - retcode = drm_setup(dev); - if (retcode) - goto err_undo; + if (!retcode) { + atomic_inc(&dev->counts[_DRM_STAT_OPENS]); + if (!dev->open_count++) + retcode = drm_setup(dev); + } + if (!retcode) { + mutex_lock(&dev->struct_mutex); + if (dev->dev_mapping == NULL) + dev->dev_mapping = &inode->i_data; + /* ihold ensures nobody can remove inode with our i_data */ + ihold(container_of(dev->dev_mapping, struct inode, i_data)); + inode->i_mapping = dev->dev_mapping; + filp->f_mapping = dev->dev_mapping; + mutex_unlock(&dev->struct_mutex); } - return 0; -err_undo: - mutex_lock(&dev->struct_mutex); - filp->f_mapping = old_mapping; - inode->i_mapping = old_mapping; - iput(container_of(dev->dev_mapping, struct inode, i_data)); - dev->dev_mapping = old_mapping; - mutex_unlock(&dev->struct_mutex); - dev->open_count--; return retcode; } EXPORT_SYMBOL(drm_open); diff --git a/trunk/drivers/gpu/drm/drm_info.c b/trunk/drivers/gpu/drm/drm_info.c index d4b20ceda3fb..441ebc1bdbef 100644 --- a/trunk/drivers/gpu/drm/drm_info.c +++ b/trunk/drivers/gpu/drm/drm_info.c @@ -205,6 +205,8 @@ static int drm_gem_one_name_info(int id, void *ptr, void *data) struct drm_gem_object *obj = ptr; struct seq_file *m = data; + seq_printf(m, "name %d size %zd\n", obj->name, obj->size); + seq_printf(m, "%6d %8zd %7d %8d\n", obj->name, obj->size, atomic_read(&obj->handle_count), diff --git a/trunk/drivers/gpu/drm/drm_platform.c b/trunk/drivers/gpu/drm/drm_platform.c index b8a282ea8751..aaeb6f8d69ce 100644 --- a/trunk/drivers/gpu/drm/drm_platform.c +++ b/trunk/drivers/gpu/drm/drm_platform.c @@ -64,6 +64,7 @@ int drm_get_platform_dev(struct platform_device *platdev, } if (drm_core_check_feature(dev, DRIVER_MODESET)) { + dev_set_drvdata(&platdev->dev, dev); ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); if (ret) goto err_g1; diff --git a/trunk/drivers/gpu/drm/exynos/Kconfig b/trunk/drivers/gpu/drm/exynos/Kconfig index fc345d4ebb03..59a26e577b57 100644 --- a/trunk/drivers/gpu/drm/exynos/Kconfig +++ b/trunk/drivers/gpu/drm/exynos/Kconfig @@ -1,6 +1,6 @@ config DRM_EXYNOS tristate "DRM Support for Samsung SoC EXYNOS Series" - depends on DRM && (PLAT_SAMSUNG || ARCH_MULTIPLATFORM) + depends on DRM && PLAT_SAMSUNG select DRM_KMS_HELPER select FB_CFB_FILLRECT select FB_CFB_COPYAREA diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c index 0f68a2872673..18c271862ca8 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c @@ -374,7 +374,6 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev, exynos_connector->encoder_id = encoder->base.id; exynos_connector->manager = manager; exynos_connector->dpms = DRM_MODE_DPMS_OFF; - connector->dpms = DRM_MODE_DPMS_OFF; connector->encoder = encoder; err = drm_mode_connector_attach_encoder(connector, encoder); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c index f2df06c603f7..e51503fbaf2b 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c @@ -43,14 +43,12 @@ * @manager: specific encoder has its own manager to control a hardware * appropriately and we can access a hardware drawing on this manager. * @dpms: store the encoder dpms value. - * @updated: indicate whether overlay data updating is needed or not. */ struct exynos_drm_encoder { struct drm_crtc *old_crtc; struct drm_encoder drm_encoder; struct exynos_drm_manager *manager; - int dpms; - bool updated; + int dpms; }; static void exynos_drm_connector_power(struct drm_encoder *encoder, int mode) @@ -87,9 +85,7 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) switch (mode) { case DRM_MODE_DPMS_ON: if (manager_ops && manager_ops->apply) - if (!exynos_encoder->updated) - manager_ops->apply(manager->dev); - + manager_ops->apply(manager->dev); exynos_drm_connector_power(encoder, mode); exynos_encoder->dpms = mode; break; @@ -98,7 +94,6 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) case DRM_MODE_DPMS_OFF: exynos_drm_connector_power(encoder, mode); exynos_encoder->dpms = mode; - exynos_encoder->updated = false; break; default: DRM_ERROR("unspecified mode %d\n", mode); @@ -210,28 +205,13 @@ static void exynos_drm_encoder_prepare(struct drm_encoder *encoder) static void exynos_drm_encoder_commit(struct drm_encoder *encoder) { - struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); - struct exynos_drm_manager *manager = exynos_encoder->manager; + struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); struct exynos_drm_manager_ops *manager_ops = manager->ops; DRM_DEBUG_KMS("%s\n", __FILE__); if (manager_ops && manager_ops->commit) manager_ops->commit(manager->dev); - - /* - * this will avoid one issue that overlay data is updated to - * real hardware two times. - * And this variable will be used to check if the data was - * already updated or not by exynos_drm_encoder_dpms function. - */ - exynos_encoder->updated = true; - - /* - * In case of setcrtc, there is no way to update encoder's dpms - * so update it here. - */ - exynos_encoder->dpms = DRM_MODE_DPMS_ON; } static void exynos_drm_encoder_disable(struct drm_encoder *encoder) @@ -420,6 +400,19 @@ void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data) if (manager_ops && manager_ops->dpms) manager_ops->dpms(manager->dev, mode); + /* + * set current mode to new one so that data aren't updated into + * registers by drm_helper_connector_dpms two times. + * + * in case that drm_crtc_helper_set_mode() is called, + * overlay_ops->commit() and manager_ops->commit() callbacks + * can be called two times, first at drm_crtc_helper_set_mode() + * and second at drm_helper_connector_dpms(). + * so with this setting, when drm_helper_connector_dpms() is called + * encoder->funcs->dpms() will be ignored. + */ + exynos_encoder->dpms = mode; + /* * if this condition is ok then it means that the crtc is already * detached from encoder and last function for detaching is properly @@ -513,6 +506,6 @@ void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data) * because the setting for disabling the overlay will be updated * at vsync. */ - if (overlay_ops && overlay_ops->wait_for_vblank) + if (overlay_ops->wait_for_vblank) overlay_ops->wait_for_vblank(manager->dev); } diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index e7466c4414cb..67eb6ba56edf 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -87,8 +87,7 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr; fbi->screen_base = buffer->kvaddr + offset; - fbi->fix.smem_start = (unsigned long)(page_to_phys(buffer->pages[0]) + - offset); + fbi->fix.smem_start = (unsigned long)(buffer->dma_addr + offset); fbi->screen_size = size; fbi->fix.smem_len = size; diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c index e08478f19f1a..130a2b510d4a 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -61,11 +61,11 @@ struct fimd_driver_data { unsigned int timing_base; }; -static struct fimd_driver_data exynos4_fimd_driver_data = { +struct fimd_driver_data exynos4_fimd_driver_data = { .timing_base = 0x0, }; -static struct fimd_driver_data exynos5_fimd_driver_data = { +struct fimd_driver_data exynos5_fimd_driver_data = { .timing_base = 0x20000, }; diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_plane.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_plane.c index 862ca1eb2102..60b877a388c2 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -204,6 +204,7 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, return ret; plane->crtc = crtc; + plane->fb = crtc->fb; exynos_plane_commit(plane); exynos_plane_dpms(plane, DRM_MODE_DPMS_ON); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_mixer.c b/trunk/drivers/gpu/drm/exynos/exynos_mixer.c index e7fbb823fd8e..614b2e9ac462 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_mixer.c @@ -1142,7 +1142,7 @@ static int __devinit mixer_probe(struct platform_device *pdev) const struct of_device_id *match; match = of_match_node(of_match_ptr(mixer_match_types), pdev->dev.of_node); - drv = (struct mixer_drv_data *)match->data; + drv = match->data; } else { drv = (struct mixer_drv_data *) platform_get_device_id(pdev)->driver_data; diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index 61ae104dca8c..c9bfd83dde64 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -1505,8 +1505,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto put_gmch; } - if (drm_core_check_feature(dev, DRIVER_MODESET)) - i915_kick_out_firmware_fb(dev_priv); + i915_kick_out_firmware_fb(dev_priv); pci_set_master(dev->pdev); diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index 6770ee6084b4..aac4e5e1a5b9 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -118,13 +118,6 @@ module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, int, 0600); MODULE_PARM_DESC(i915_enable_ppgtt, "Enable PPGTT (default: true)"); -unsigned int i915_preliminary_hw_support __read_mostly = 0; -module_param_named(preliminary_hw_support, i915_preliminary_hw_support, int, 0600); -MODULE_PARM_DESC(preliminary_hw_support, - "Enable preliminary hardware support. " - "Enable Haswell and ValleyView Support. " - "(default: false)"); - static struct drm_driver driver; extern int intel_agp_enabled; @@ -833,12 +826,6 @@ i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct intel_device_info *intel_info = (struct intel_device_info *) ent->driver_data; - if (intel_info->is_haswell || intel_info->is_valleyview) - if(!i915_preliminary_hw_support) { - DRM_ERROR("Preliminary hardware support disabled\n"); - return -ENODEV; - } - /* Only bind to function 0 of the device. Early generations * used function 1 as a placeholder for multi-head. This causes * us confusion instead, especially on the systems where both diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index f511fa2f4168..b84f7861e438 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -1217,7 +1217,6 @@ extern int i915_enable_rc6 __read_mostly; extern int i915_enable_fbc __read_mostly; extern bool i915_enable_hangcheck __read_mostly; extern int i915_enable_ppgtt __read_mostly; -extern unsigned int i915_preliminary_hw_support __read_mostly; extern int i915_suspend(struct drm_device *dev, pm_message_t state); extern int i915_resume(struct drm_device *dev); diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index 9b285da4449b..d33d02d13c96 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -1407,10 +1407,8 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) return VM_FAULT_NOPAGE; case -ENOMEM: return VM_FAULT_OOM; - case -ENOSPC: - return VM_FAULT_SIGBUS; default: - WARN_ONCE(ret, "unhandled error in i915_gem_fault: %i\n", ret); + WARN_ON_ONCE(ret); return VM_FAULT_SIGBUS; } } @@ -1796,7 +1794,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) */ mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; gfp = mapping_gfp_mask(mapping); - gfp |= __GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD; + gfp |= __GFP_NORETRY | __GFP_NOWARN; gfp &= ~(__GFP_IO | __GFP_WAIT); for_each_sg(st->sgl, sg, page_count, i) { page = shmem_read_mapping_page_gfp(mapping, i, gfp); @@ -1809,7 +1807,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) * our own buffer, now let the real VM do its job and * go down in flames if truly OOM. */ - gfp &= ~(__GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD); + gfp &= ~(__GFP_NORETRY | __GFP_NOWARN); gfp |= __GFP_IO | __GFP_WAIT; i915_gem_shrink_all(dev_priv); @@ -1817,18 +1815,17 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) if (IS_ERR(page)) goto err_pages; - gfp |= __GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD; + gfp |= __GFP_NORETRY | __GFP_NOWARN; gfp &= ~(__GFP_IO | __GFP_WAIT); } sg_set_page(sg, page, PAGE_SIZE, 0); } - obj->pages = st; - if (i915_gem_object_needs_bit17_swizzle(obj)) i915_gem_object_do_bit_17_swizzle(obj); + obj->pages = st; return 0; err_pages: diff --git a/trunk/drivers/gpu/drm/i915/intel_bios.c b/trunk/drivers/gpu/drm/i915/intel_bios.c index 56846ed5ee55..0ed6baff4b0c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_bios.c +++ b/trunk/drivers/gpu/drm/i915/intel_bios.c @@ -499,8 +499,12 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb) edp = find_section(bdb, BDB_EDP); if (!edp) { - if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support) - DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported.\n"); + if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support) { + DRM_DEBUG_KMS("No eDP BDB found but eDP panel " + "supported, assume %dbpp panel color " + "depth.\n", + dev_priv->edp.bpp); + } return; } @@ -653,6 +657,9 @@ init_vbt_defaults(struct drm_i915_private *dev_priv) dev_priv->lvds_use_ssc = 1; dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1); DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq); + + /* eDP data */ + dev_priv->edp.bpp = 18; } static int __init intel_no_opregion_vbt_callback(const struct dmi_system_id *id) diff --git a/trunk/drivers/gpu/drm/i915/intel_crt.c b/trunk/drivers/gpu/drm/i915/intel_crt.c index 6345878ae1e7..893f30164b7e 100644 --- a/trunk/drivers/gpu/drm/i915/intel_crt.c +++ b/trunk/drivers/gpu/drm/i915/intel_crt.c @@ -143,7 +143,7 @@ static void intel_crt_dpms(struct drm_connector *connector, int mode) int old_dpms; /* PCH platforms and VLV only support on/off. */ - if (INTEL_INFO(dev)->gen >= 5 && mode != DRM_MODE_DPMS_ON) + if (INTEL_INFO(dev)->gen < 5 && mode != DRM_MODE_DPMS_ON) mode = DRM_MODE_DPMS_OFF; if (mode == connector->dpms) @@ -219,7 +219,20 @@ static void intel_crt_mode_set(struct drm_encoder *encoder, intel_encoder_to_crt(to_intel_encoder(encoder)); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_i915_private *dev_priv = dev->dev_private; - u32 adpa; + int dpll_md_reg; + u32 adpa, dpll_md; + + dpll_md_reg = DPLL_MD(intel_crtc->pipe); + + /* + * Disable separate mode multiplier used when cloning SDVO to CRT + * XXX this needs to be adjusted when we really are cloning + */ + if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { + dpll_md = I915_READ(dpll_md_reg); + I915_WRITE(dpll_md_reg, + dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK); + } adpa = ADPA_HOTPLUG_BITS; if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) @@ -729,7 +742,7 @@ void intel_crt_init(struct drm_device *dev) crt->base.type = INTEL_OUTPUT_ANALOG; crt->base.cloneable = true; - if (IS_HASWELL(dev) || IS_I830(dev)) + if (IS_HASWELL(dev)) crt->base.crtc_mask = (1 << 0); else crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index b426d44a2b05..682bd3729baf 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -3841,17 +3841,6 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, } } - if (intel_encoder->type == INTEL_OUTPUT_EDP) { - /* Use VBT settings if we have an eDP panel */ - unsigned int edp_bpc = dev_priv->edp.bpp / 3; - - if (edp_bpc && edp_bpc < display_bpc) { - DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); - display_bpc = edp_bpc; - } - continue; - } - /* * HDMI is either 12 or 8, so if the display lets 10bpc sneak * through, clamp it down. (Note: >12bpc will be caught below.) @@ -7903,34 +7892,6 @@ struct intel_quirk { void (*hook)(struct drm_device *dev); }; -/* For systems that don't have a meaningful PCI subdevice/subvendor ID */ -struct intel_dmi_quirk { - void (*hook)(struct drm_device *dev); - const struct dmi_system_id (*dmi_id_list)[]; -}; - -static int intel_dmi_reverse_brightness(const struct dmi_system_id *id) -{ - DRM_INFO("Backlight polarity reversed on %s\n", id->ident); - return 1; -} - -static const struct intel_dmi_quirk intel_dmi_quirks[] = { - { - .dmi_id_list = &(const struct dmi_system_id[]) { - { - .callback = intel_dmi_reverse_brightness, - .ident = "NCR Corporation", - .matches = {DMI_MATCH(DMI_SYS_VENDOR, "NCR Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, ""), - }, - }, - { } /* terminating entry */ - }, - .hook = quirk_invert_brightness, - }, -}; - static struct intel_quirk intel_quirks[] = { /* HP Mini needs pipe A force quirk (LP: #322104) */ { 0x27ae, 0x103c, 0x361a, quirk_pipea_force }, @@ -7970,10 +7931,6 @@ static void intel_init_quirks(struct drm_device *dev) q->subsystem_device == PCI_ANY_ID)) q->hook(dev); } - for (i = 0; i < ARRAY_SIZE(intel_dmi_quirks); i++) { - if (dmi_check_system(*intel_dmi_quirks[i].dmi_id_list) != 0) - intel_dmi_quirks[i].hook(dev); - } } /* Disable the VGA plane that we never use */ diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c index 368ed8ef1600..1b727a5c9ee5 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ b/trunk/drivers/gpu/drm/i915/intel_dp.c @@ -1797,8 +1797,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) break; if (i == intel_dp->lane_count && voltage_tries == 5) { - ++loop_tries; - if (loop_tries == 5) { + if (++loop_tries == 5) { DRM_DEBUG_KMS("too many full retries, give up\n"); break; } @@ -1808,15 +1807,11 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) } /* Check to see if we've tried the same voltage 5 times */ - if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { - ++voltage_tries; - if (voltage_tries == 5) { - DRM_DEBUG_KMS("too many voltage retries, give up\n"); - break; - } - } else + if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) != voltage) { + voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; voltage_tries = 0; - voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; + } else + ++voltage_tries; /* Compute new intel_dp->train_set as requested by target */ intel_get_adjust_train(intel_dp, link_status); diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index edba93b3474b..e3166df55daa 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -777,14 +777,6 @@ static const struct dmi_system_id intel_no_lvds[] = { DMI_MATCH(DMI_BOARD_NAME, "D525TUD"), }, }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "Supermicro X7SPA-H", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"), - DMI_MATCH(DMI_PRODUCT_NAME, "X7SPA-H"), - }, - }, { } /* terminating entry */ }; diff --git a/trunk/drivers/gpu/drm/i915/intel_overlay.c b/trunk/drivers/gpu/drm/i915/intel_overlay.c index d7bc817f51a0..495625914e4a 100644 --- a/trunk/drivers/gpu/drm/i915/intel_overlay.c +++ b/trunk/drivers/gpu/drm/i915/intel_overlay.c @@ -341,17 +341,9 @@ static int intel_overlay_off(struct intel_overlay *overlay) intel_ring_emit(ring, flip_addr); intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); /* turn overlay off */ - if (IS_I830(dev)) { - /* Workaround: Don't disable the overlay fully, since otherwise - * it dies on the next OVERLAY_ON cmd. */ - intel_ring_emit(ring, MI_NOOP); - intel_ring_emit(ring, MI_NOOP); - intel_ring_emit(ring, MI_NOOP); - } else { - intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); - intel_ring_emit(ring, flip_addr); - intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); - } + intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); + intel_ring_emit(ring, flip_addr); + intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); intel_ring_advance(ring); return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail); diff --git a/trunk/drivers/gpu/drm/i915/intel_panel.c b/trunk/drivers/gpu/drm/i915/intel_panel.c index e2aacd329545..e019b2369861 100644 --- a/trunk/drivers/gpu/drm/i915/intel_panel.c +++ b/trunk/drivers/gpu/drm/i915/intel_panel.c @@ -435,7 +435,7 @@ int intel_panel_setup_backlight(struct drm_device *dev) props.type = BACKLIGHT_RAW; props.max_brightness = _intel_panel_get_max_backlight(dev); if (props.max_brightness == 0) { - DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n"); + DRM_ERROR("Failed to get maximum backlight value\n"); return -ENODEV; } dev_priv->backlight = diff --git a/trunk/drivers/gpu/drm/i915/intel_pm.c b/trunk/drivers/gpu/drm/i915/intel_pm.c index 442968f8b201..72f41aaa71ff 100644 --- a/trunk/drivers/gpu/drm/i915/intel_pm.c +++ b/trunk/drivers/gpu/drm/i915/intel_pm.c @@ -2373,9 +2373,15 @@ int intel_enable_rc6(const struct drm_device *dev) if (i915_enable_rc6 >= 0) return i915_enable_rc6; - /* Disable RC6 on Ironlake */ - if (INTEL_INFO(dev)->gen == 5) - return 0; + if (INTEL_INFO(dev)->gen == 5) { +#ifdef CONFIG_INTEL_IOMMU + /* Disable rc6 on ilk if VT-d is on. */ + if (intel_iommu_gfx_mapped) + return false; +#endif + DRM_DEBUG_DRIVER("Ironlake: only RC6 available\n"); + return INTEL_RC6_ENABLE; + } if (IS_HASWELL(dev)) { DRM_DEBUG_DRIVER("Haswell: only RC6 available\n"); diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo.c b/trunk/drivers/gpu/drm/i915/intel_sdvo.c index a6ac0b416964..0007a4d9bf6e 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo.c @@ -139,11 +139,6 @@ struct intel_sdvo { /* DDC bus used by this SDVO encoder */ uint8_t ddc_bus; - - /* - * the sdvo flag gets lost in round trip: dtd->adjusted_mode->dtd - */ - uint8_t dtd_sdvo_flags; }; struct intel_sdvo_connector { @@ -894,45 +889,6 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) } #endif -static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo, - unsigned if_index, uint8_t tx_rate, - uint8_t *data, unsigned length) -{ - uint8_t set_buf_index[2] = { if_index, 0 }; - uint8_t hbuf_size, tmp[8]; - int i; - - if (!intel_sdvo_set_value(intel_sdvo, - SDVO_CMD_SET_HBUF_INDEX, - set_buf_index, 2)) - return false; - - if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO, - &hbuf_size, 1)) - return false; - - /* Buffer size is 0 based, hooray! */ - hbuf_size++; - - DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n", - if_index, length, hbuf_size); - - for (i = 0; i < hbuf_size; i += 8) { - memset(tmp, 0, 8); - if (i < length) - memcpy(tmp, data + i, min_t(unsigned, 8, length - i)); - - if (!intel_sdvo_set_value(intel_sdvo, - SDVO_CMD_SET_HBUF_DATA, - tmp, 8)) - return false; - } - - return intel_sdvo_set_value(intel_sdvo, - SDVO_CMD_SET_HBUF_TXRATE, - &tx_rate, 1); -} - static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) { struct dip_infoframe avi_if = { @@ -940,7 +896,11 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) .ver = DIP_VERSION_AVI, .len = DIP_LEN_AVI, }; + uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; + uint8_t set_buf_index[2] = { 1, 0 }; uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; + uint64_t *data = (uint64_t *)sdvo_data; + unsigned i; intel_dip_infoframe_csum(&avi_if); @@ -950,9 +910,22 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) sdvo_data[3] = avi_if.checksum; memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); - return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, - SDVO_HBUF_TX_VSYNC, - sdvo_data, sizeof(sdvo_data)); + if (!intel_sdvo_set_value(intel_sdvo, + SDVO_CMD_SET_HBUF_INDEX, + set_buf_index, 2)) + return false; + + for (i = 0; i < sizeof(sdvo_data); i += 8) { + if (!intel_sdvo_set_value(intel_sdvo, + SDVO_CMD_SET_HBUF_DATA, + data, 8)) + return false; + data++; + } + + return intel_sdvo_set_value(intel_sdvo, + SDVO_CMD_SET_HBUF_TXRATE, + &tx_rate, 1); } static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) @@ -1011,7 +984,6 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo, return false; intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); - intel_sdvo->dtd_sdvo_flags = input_dtd.part2.sdvo_flags; return true; } @@ -1120,8 +1092,6 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, * adjusted_mode. */ intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); - if (intel_sdvo->is_tv || intel_sdvo->is_lvds) - input_dtd.part2.sdvo_flags = intel_sdvo->dtd_sdvo_flags; if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) DRM_INFO("Setting input timings on %s failed\n", SDVO_NAME(intel_sdvo)); @@ -2201,6 +2171,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; intel_sdvo->is_hdmi = true; } + intel_sdvo->base.cloneable = true; intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); if (intel_sdvo->is_hdmi) @@ -2231,6 +2202,7 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) intel_sdvo->is_tv = true; intel_sdvo->base.needs_tv_clock = true; + intel_sdvo->base.cloneable = false; intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); @@ -2273,6 +2245,8 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device) intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; } + intel_sdvo->base.cloneable = true; + intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); return true; @@ -2303,6 +2277,11 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; } + /* SDVO LVDS is cloneable because the SDVO encoder does the upscaling, + * as opposed to native LVDS, where we upscale with the panel-fitter + * (and hence only the native LVDS resolution could be cloned). */ + intel_sdvo->base.cloneable = true; + intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) goto err; @@ -2375,18 +2354,6 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) return true; } -static void intel_sdvo_output_cleanup(struct intel_sdvo *intel_sdvo) -{ - struct drm_device *dev = intel_sdvo->base.base.dev; - struct drm_connector *connector, *tmp; - - list_for_each_entry_safe(connector, tmp, - &dev->mode_config.connector_list, head) { - if (intel_attached_encoder(connector) == &intel_sdvo->base) - intel_sdvo_destroy(connector); - } -} - static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, struct intel_sdvo_connector *intel_sdvo_connector, int type) @@ -2710,20 +2677,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) intel_sdvo->caps.output_flags) != true) { DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", SDVO_NAME(intel_sdvo)); - /* Output_setup can leave behind connectors! */ - goto err_output; + goto err; } - /* - * Cloning SDVO with anything is often impossible, since the SDVO - * encoder can request a special input timing mode. And even if that's - * not the case we have evidence that cloning a plain unscaled mode with - * VGA doesn't really work. Furthermore the cloning flags are way too - * simplistic anyway to express such constraints, so just give up on - * cloning for SDVO encoders. - */ - intel_sdvo->base.cloneable = false; - /* Only enable the hotplug irq if we need it, to work around noisy * hotplug lines. */ @@ -2734,12 +2690,12 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) /* Set the input timing to the screen. Assume always input 0. */ if (!intel_sdvo_set_target_input(intel_sdvo)) - goto err_output; + goto err; if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, &intel_sdvo->pixel_clock_min, &intel_sdvo->pixel_clock_max)) - goto err_output; + goto err; DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " "clock range %dMHz - %dMHz, " @@ -2759,9 +2715,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); return true; -err_output: - intel_sdvo_output_cleanup(intel_sdvo); - err: drm_encoder_cleanup(&intel_encoder->base); i2c_del_adapter(&intel_sdvo->ddc); diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h b/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h index 770bdd6ecd9f..9d030142ee43 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h @@ -708,8 +708,6 @@ struct intel_sdvo_enhancements_arg { #define SDVO_CMD_SET_AUDIO_STAT 0x91 #define SDVO_CMD_GET_AUDIO_STAT 0x92 #define SDVO_CMD_SET_HBUF_INDEX 0x93 - #define SDVO_HBUF_INDEX_ELD 0 - #define SDVO_HBUF_INDEX_AVI_IF 1 #define SDVO_CMD_GET_HBUF_INDEX 0x94 #define SDVO_CMD_GET_HBUF_INFO 0x95 #define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 diff --git a/trunk/drivers/gpu/drm/nouveau/core/core/gpuobj.c b/trunk/drivers/gpu/drm/nouveau/core/core/gpuobj.c index 70586fde69cf..1f34549aff18 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/core/gpuobj.c +++ b/trunk/drivers/gpu/drm/nouveau/core/core/gpuobj.c @@ -39,11 +39,6 @@ nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj) nv_wo32(gpuobj, i, 0x00000000); } - if (gpuobj->node) { - nouveau_mm_free(&nv_gpuobj(gpuobj->parent)->heap, - &gpuobj->node); - } - if (gpuobj->heap.block_size) nouveau_mm_fini(&gpuobj->heap); diff --git a/trunk/drivers/gpu/drm/nouveau/core/core/mm.c b/trunk/drivers/gpu/drm/nouveau/core/core/mm.c index a6d3cd6490f7..bfddf87926dd 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/core/mm.c +++ b/trunk/drivers/gpu/drm/nouveau/core/core/mm.c @@ -218,16 +218,13 @@ nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block) node = kzalloc(sizeof(*node), GFP_KERNEL); if (!node) return -ENOMEM; - - if (length) { - node->offset = roundup(offset, mm->block_size); - node->length = rounddown(offset + length, mm->block_size); - node->length -= node->offset; - } + node->offset = roundup(offset, mm->block_size); + node->length = rounddown(offset + length, mm->block_size) - node->offset; list_add_tail(&node->nl_entry, &mm->nodes); list_add_tail(&node->fl_entry, &mm->free); mm->heap_nodes++; + mm->heap_size += length; return 0; } @@ -239,7 +236,7 @@ nouveau_mm_fini(struct nouveau_mm *mm) int nodes = 0; list_for_each_entry(node, &mm->nodes, nl_entry) { - if (WARN_ON(nodes++ == mm->heap_nodes)) + if (nodes++ == mm->heap_nodes) return -EBUSY; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 15b182c84ce8..16a9afb1060b 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -22,8 +22,6 @@ * Authors: Ben Skeggs */ -#include - #include #include @@ -39,7 +37,6 @@ nv50_disp_sclass[] = { static void nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) { - struct nouveau_bar *bar = nouveau_bar(priv); struct nouveau_disp *disp = &priv->base; struct nouveau_software_chan *chan, *temp; unsigned long flags; @@ -49,25 +46,19 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) if (chan->vblank.crtc != crtc) continue; - if (nv_device(priv)->chipset >= 0xc0) { - nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel); - bar->flush(bar); - nv_wr32(priv, 0x06000c, - upper_32_bits(chan->vblank.offset)); - nv_wr32(priv, 0x060010, - lower_32_bits(chan->vblank.offset)); - nv_wr32(priv, 0x060014, chan->vblank.value); + nv_wr32(priv, 0x001704, chan->vblank.channel); + nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); + + if (nv_device(priv)->chipset == 0x50) { + nv_wr32(priv, 0x001570, chan->vblank.offset); + nv_wr32(priv, 0x001574, chan->vblank.value); } else { - nv_wr32(priv, 0x001704, chan->vblank.channel); - nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); - bar->flush(bar); - if (nv_device(priv)->chipset == 0x50) { - nv_wr32(priv, 0x001570, chan->vblank.offset); - nv_wr32(priv, 0x001574, chan->vblank.value); - } else { - nv_wr32(priv, 0x060010, chan->vblank.offset); - nv_wr32(priv, 0x060014, chan->vblank.value); + if (nv_device(priv)->chipset >= 0xc0) { + nv_wr32(priv, 0x06000c, + upper_32_bits(chan->vblank.offset)); } + nv_wr32(priv, 0x060010, chan->vblank.offset); + nv_wr32(priv, 0x060014, chan->vblank.value); } list_del(&chan->vblank.head); diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c index 7bbb1e1b7a8d..e45035efb8ca 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c @@ -669,27 +669,21 @@ nv40_grctx_fill(struct nouveau_device *device, struct nouveau_gpuobj *mem) }); } -int +void nv40_grctx_init(struct nouveau_device *device, u32 *size) { - u32 *ctxprog = kmalloc(256 * 4, GFP_KERNEL), i; + u32 ctxprog[256], i; struct nouveau_grctx ctx = { .device = device, .mode = NOUVEAU_GRCTX_PROG, .data = ctxprog, - .ctxprog_max = 256, + .ctxprog_max = ARRAY_SIZE(ctxprog) }; - if (!ctxprog) - return -ENOMEM; - nv40_grctx_generate(&ctx); nv_wr32(device, 0x400324, 0); for (i = 0; i < ctx.ctxprog_len; i++) nv_wr32(device, 0x400328, ctxprog[i]); *size = ctx.ctxvals_pos * 4; - - kfree(ctxprog); - return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c index cc6574eeb80e..8d0021049ec0 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c @@ -156,8 +156,8 @@ nv40_graph_context_ctor(struct nouveau_object *parent, static int nv40_graph_context_fini(struct nouveau_object *object, bool suspend) { - struct nv40_graph_priv *priv = (void *)object->engine; - struct nv40_graph_chan *chan = (void *)object; + struct nv04_graph_priv *priv = (void *)object->engine; + struct nv04_graph_chan *chan = (void *)object; u32 inst = 0x01000000 | nv_gpuobj(chan)->addr >> 4; int ret = 0; @@ -346,9 +346,7 @@ nv40_graph_init(struct nouveau_object *object) return ret; /* generate and upload context program */ - ret = nv40_grctx_init(nv_device(priv), &priv->size); - if (ret) - return ret; + nv40_grctx_init(nv_device(priv), &priv->size); /* No context present currently */ nv_wr32(priv, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h index 7da35a4e7970..d2ac975afc2e 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h @@ -15,7 +15,7 @@ nv44_graph_class(void *priv) return !(0x0baf & (1 << (device->chipset & 0x0f))); } -int nv40_grctx_init(struct nouveau_device *, u32 *size); +void nv40_grctx_init(struct nouveau_device *, u32 *size); void nv40_grctx_fill(struct nouveau_device *, struct nouveau_gpuobj *); #endif diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c b/trunk/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c index f7c581ad1991..12418574efea 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c @@ -38,7 +38,7 @@ struct nv40_mpeg_priv { }; struct nv40_mpeg_chan { - struct nouveau_mpeg_chan base; + struct nouveau_mpeg base; }; /******************************************************************************* diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/core/mm.h b/trunk/drivers/gpu/drm/nouveau/core/include/core/mm.h index 975137ba34a6..9ee9bf4028ca 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/core/mm.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/core/mm.h @@ -19,6 +19,7 @@ struct nouveau_mm { u32 block_size; int heap_nodes; + u32 heap_size; }; int nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block); diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/core/object.h b/trunk/drivers/gpu/drm/nouveau/core/include/core/object.h index 486f1a9217fd..818feabbf4a0 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/core/object.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/core/object.h @@ -175,18 +175,14 @@ nv_mo32(void *obj, u32 addr, u32 mask, u32 data) return temp; } -static inline int -nv_memcmp(void *obj, u32 addr, const char *str, u32 len) +static inline bool +nv_strncmp(void *obj, u32 addr, u32 len, const char *str) { - unsigned char c1, c2; - while (len--) { - c1 = nv_ro08(obj, addr++); - c2 = *(str++); - if (c1 != c2) - return c1 - c2; + if (nv_ro08(obj, addr++) != *(str++)) + return false; } - return 0; + return true; } #endif diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/clock.h b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/clock.h index 41b7a6a76f19..39e73b91d360 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/subdev/clock.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/subdev/clock.h @@ -54,7 +54,6 @@ int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *, int clk, struct nouveau_pll_vals *); int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1, struct nouveau_pll_vals *); -int nva3_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *, - int clk, struct nouveau_pll_vals *); + #endif diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/base.c index 70ca7d5a1aa1..dcb5c2befc92 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/base.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/base.c @@ -72,7 +72,7 @@ nouveau_bios_shadow_of(struct nouveau_bios *bios) } data = of_get_property(dn, "NVDA,BMP", &size); - if (data && size) { + if (data) { bios->size = size; bios->data = kmalloc(bios->size, GFP_KERNEL); if (bios->data) @@ -104,9 +104,6 @@ nouveau_bios_shadow_pramin(struct nouveau_bios *bios) goto out; bios->size = nv_rd08(bios, 0x700002) * 512; - if (!bios->size) - goto out; - bios->data = kmalloc(bios->size, GFP_KERNEL); if (bios->data) { for (i = 0; i < bios->size; i++) @@ -158,9 +155,6 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios) /* read entire bios image to system memory */ bios->size = nv_rd08(bios, 0x300002) * 512; - if (!bios->size) - goto out; - bios->data = kmalloc(bios->size, GFP_KERNEL); if (bios->data) { for (i = 0; i < bios->size; i++) @@ -192,22 +186,14 @@ nouveau_bios_shadow_acpi(struct nouveau_bios *bios) { struct pci_dev *pdev = nv_device(bios)->pdev; int ret, cnt, i; + u8 data[3]; - if (!nouveau_acpi_rom_supported(pdev)) { - bios->data = NULL; + if (!nouveau_acpi_rom_supported(pdev)) return; - } bios->size = 0; - bios->data = kmalloc(4096, GFP_KERNEL); - if (bios->data) { - if (nouveau_acpi_get_bios_chunk(bios->data, 0, 4096) == 4096) - bios->size = bios->data[2] * 512; - kfree(bios->data); - } - - if (!bios->size) - return; + if (nouveau_acpi_get_bios_chunk(data, 0, 3) == 3) + bios->size = data[2] * 512; bios->data = kmalloc(bios->size, GFP_KERNEL); for (i = 0; bios->data && i < bios->size; i += cnt) { @@ -243,14 +229,12 @@ nouveau_bios_shadow_pci(struct nouveau_bios *bios) static int nouveau_bios_score(struct nouveau_bios *bios, const bool writeable) { - if (bios->size < 3 || !bios->data || bios->data[0] != 0x55 || - bios->data[1] != 0xAA) { + if (!bios->data || bios->data[0] != 0x55 || bios->data[1] != 0xAA) { nv_info(bios, "... signature not found\n"); return 0; } - if (nvbios_checksum(bios->data, - min_t(u32, bios->data[2] * 512, bios->size))) { + if (nvbios_checksum(bios->data, bios->data[2] * 512)) { nv_info(bios, "... checksum invalid\n"); /* if a ro image is somewhat bad, it's probably all rubbish */ return writeable ? 2 : 1; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c index c51197157749..7d750382a833 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c @@ -64,7 +64,7 @@ dcb_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) } } else if (*ver >= 0x15) { - if (!nv_memcmp(bios, dcb - 7, "DEV_REC", 7)) { + if (!nv_strncmp(bios, dcb - 7, 7, "DEV_REC")) { u16 i2c = nv_ro16(bios, dcb + 2); *hdr = 4; *cnt = (i2c - dcb) / 10; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c index f835501203e5..5e5f4cddae3c 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c @@ -157,10 +157,11 @@ pll_map_reg(struct nouveau_bios *bios, u32 reg, u32 *type, u8 *ver, u8 *len) while (map->reg) { if (map->reg == reg && *ver >= 0x20) { u16 addr = (data += hdr); - *type = map->type; while (cnt--) { - if (nv_ro32(bios, data) == map->reg) + if (nv_ro32(bios, data) == map->reg) { + *type = map->type; return data; + } data += *len; } return addr; @@ -199,10 +200,11 @@ pll_map_type(struct nouveau_bios *bios, u8 type, u32 *reg, u8 *ver, u8 *len) while (map->reg) { if (map->type == type && *ver >= 0x20) { u16 addr = (data += hdr); - *reg = map->reg; while (cnt--) { - if (nv_ro32(bios, data) == map->reg) + if (nv_ro32(bios, data) == map->reg) { + *reg = map->reg; return data; + } data += *len; } return addr; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c index 9068c98b96f6..cc8d7d162d7c 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c @@ -66,24 +66,6 @@ nva3_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq) return ret; } -int -nva3_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info, - int clk, struct nouveau_pll_vals *pv) -{ - int ret, N, M, P; - - ret = nva3_pll_calc(clock, info, clk, &N, NULL, &M, &P); - - if (ret > 0) { - pv->refclk = info->refclk; - pv->N1 = N; - pv->M1 = M; - pv->log2P = P; - } - return ret; -} - - static int nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -98,7 +80,6 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return ret; priv->base.pll_set = nva3_clock_pll_set; - priv->base.pll_calc = nva3_clock_pll_calc; return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c index f6962c9b6c36..5ccce0b17bf3 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c @@ -79,7 +79,6 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return ret; priv->base.pll_set = nvc0_clock_pll_set; - priv->base.pll_calc = nva3_clock_pll_calc; return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c index 5f570806143a..42d7539e6525 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c @@ -219,11 +219,13 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ((priv->base.ram.size & 0x000000ff) << 32); tags = nv_rd32(priv, 0x100320); - ret = nouveau_mm_init(&priv->base.tags, 0, tags, 1); - if (ret) - return ret; + if (tags) { + ret = nouveau_mm_init(&priv->base.tags, 0, tags, 1); + if (ret) + return ret; - nv_debug(priv, "%d compression tags\n", tags); + nv_debug(priv, "%d compression tags\n", tags); + } size = (priv->base.ram.size >> 12) - rsvd_head - rsvd_tail; switch (device->chipset) { @@ -235,7 +237,6 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return ret; priv->base.ram.stolen = (u64)nv_rd32(priv, 0x100e10) << 12; - priv->base.ram.type = NV_MEM_TYPE_STOLEN; break; default: ret = nouveau_mm_init(&priv->base.vram, rsvd_head, size, diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c index dbfc2abf0cfe..3d2c88310f98 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c @@ -292,7 +292,7 @@ nouveau_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine, case DCB_I2C_NVIO_BIT: port->drive = info.drive & 0x0f; if (device->card_type < NV_D0) { - if (port->drive >= ARRAY_SIZE(nv50_i2c_port)) + if (info.drive >= ARRAY_SIZE(nv50_i2c_port)) break; port->drive = nv50_i2c_port[port->drive]; port->sense = port->drive; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c index 9474cfca6e4c..0203e1e12caa 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c @@ -67,7 +67,7 @@ nv41_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt) static void nv41_vm_flush(struct nouveau_vm *vm) { - struct nv04_vmmgr_priv *priv = (void *)vm->vmm; + struct nv04_vm_priv *priv = (void *)vm->vmm; mutex_lock(&nv_subdev(priv)->mutex); nv_wr32(priv, 0x100810, 0x00000022); @@ -92,8 +92,7 @@ nv41_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nv04_vmmgr_priv *priv; int ret; - if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP) || - !nouveau_boolopt(device->cfgopt, "NvPCIE", true)) { + if (!nouveau_boolopt(device->cfgopt, "NvPCIE", true)) { return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass, data, size, pobject); } diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c index aa8131436e3d..0ac18d05a146 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c @@ -163,8 +163,7 @@ nv44_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nv04_vmmgr_priv *priv; int ret; - if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP) || - !nouveau_boolopt(device->cfgopt, "NvPCIE", true)) { + if (!nouveau_boolopt(device->cfgopt, "NvPCIE", true)) { return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass, data, size, pobject); } diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_abi16.c b/trunk/drivers/gpu/drm/nouveau/nouveau_abi16.c index cbf1fc60a386..cc79c796afee 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -241,10 +241,6 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) if (unlikely(!abi16)) return -ENOMEM; - - if (!drm->channel) - return nouveau_abi16_put(abi16, -ENODEV); - client = nv_client(abi16->client); if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c index d3595b23434a..9a6e2cb282dc 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -355,7 +355,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector, bool force) * valid - it's not (rh#613284) */ if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) { - if ((nv_connector->edid = nouveau_acpi_edid(dev, connector))) { + if (!(nv_connector->edid = nouveau_acpi_edid(dev, connector))) { status = connector_status_connected; goto out; } diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_display.c b/trunk/drivers/gpu/drm/nouveau/nouveau_display.c index 86124b131f4f..8f98e5a8c488 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_display.c @@ -290,7 +290,6 @@ nouveau_display_create(struct drm_device *dev) struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_disp *pdisp = nouveau_disp(drm->device); struct nouveau_display *disp; - u32 pclass = dev->pdev->class >> 8; int ret, gen; disp = drm->display = kzalloc(sizeof(*disp), GFP_KERNEL); @@ -361,27 +360,23 @@ nouveau_display_create(struct drm_device *dev) drm_kms_helper_poll_init(dev); drm_kms_helper_poll_disable(dev); - if (nouveau_modeset == 1 || - (nouveau_modeset < 0 && pclass == PCI_CLASS_DISPLAY_VGA)) { - if (nv_device(drm->device)->card_type < NV_50) - ret = nv04_display_create(dev); - else - if (nv_device(drm->device)->card_type < NV_D0) - ret = nv50_display_create(dev); - else - ret = nvd0_display_create(dev); - if (ret) - goto disp_create_err; - - if (dev->mode_config.num_crtc) { - ret = drm_vblank_init(dev, dev->mode_config.num_crtc); - if (ret) - goto vblank_err; - } + if (nv_device(drm->device)->card_type < NV_50) + ret = nv04_display_create(dev); + else + if (nv_device(drm->device)->card_type < NV_D0) + ret = nv50_display_create(dev); + else + ret = nvd0_display_create(dev); + if (ret) + goto disp_create_err; - nouveau_backlight_init(dev); + if (dev->mode_config.num_crtc) { + ret = drm_vblank_init(dev, dev->mode_config.num_crtc); + if (ret) + goto vblank_err; } + nouveau_backlight_init(dev); return 0; vblank_err: @@ -400,8 +395,7 @@ nouveau_display_destroy(struct drm_device *dev) nouveau_backlight_exit(dev); drm_vblank_cleanup(dev); - if (disp->dtor) - disp->dtor(dev); + disp->dtor(dev); drm_kms_helper_poll_fini(dev); drm_mode_config_cleanup(dev); @@ -536,11 +530,9 @@ nouveau_page_flip_reserve(struct nouveau_bo *old_bo, if (ret) goto fail; - if (likely(old_bo != new_bo)) { - ret = ttm_bo_reserve(&old_bo->bo, false, false, false, 0); - if (ret) - goto fail_unreserve; - } + ret = ttm_bo_reserve(&old_bo->bo, false, false, false, 0); + if (ret) + goto fail_unreserve; return 0; @@ -559,10 +551,8 @@ nouveau_page_flip_unreserve(struct nouveau_bo *old_bo, nouveau_bo_fence(new_bo, fence); ttm_bo_unreserve(&new_bo->bo); - if (likely(old_bo != new_bo)) { - nouveau_bo_fence(old_bo, fence); - ttm_bo_unreserve(&old_bo->bo); - } + nouveau_bo_fence(old_bo, fence); + ttm_bo_unreserve(&old_bo->bo); nouveau_bo_unpin(old_bo); } diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c index 8503b2ea570a..ccae8c26ae2b 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -63,9 +63,8 @@ MODULE_PARM_DESC(noaccel, "disable kernel/abi16 acceleration"); static int nouveau_noaccel = 0; module_param_named(noaccel, nouveau_noaccel, int, 0400); -MODULE_PARM_DESC(modeset, "enable driver (default: auto, " - "0 = disabled, 1 = enabled, 2 = headless)"); -int nouveau_modeset = -1; +MODULE_PARM_DESC(modeset, "enable driver"); +static int nouveau_modeset = -1; module_param_named(modeset, nouveau_modeset, int, 0400); static struct drm_driver driver; @@ -129,8 +128,7 @@ nouveau_accel_init(struct nouveau_drm *drm) /* initialise synchronisation routines */ if (device->card_type < NV_10) ret = nv04_fence_create(drm); - else if (device->card_type < NV_50) ret = nv10_fence_create(drm); - else if (device->chipset < 0x84) ret = nv50_fence_create(drm); + else if (device->chipset < 0x84) ret = nv10_fence_create(drm); else if (device->card_type < NV_C0) ret = nv84_fence_create(drm); else ret = nvc0_fence_create(drm); if (ret) { @@ -365,8 +363,7 @@ nouveau_drm_unload(struct drm_device *dev) nouveau_pm_fini(dev); - if (dev->mode_config.num_crtc) - nouveau_display_fini(dev); + nouveau_display_fini(dev); nouveau_display_destroy(dev); nouveau_irq_fini(dev); @@ -406,15 +403,13 @@ nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state) pm_state.event == PM_EVENT_PRETHAW) return 0; - if (dev->mode_config.num_crtc) { - NV_INFO(drm, "suspending fbcon...\n"); - nouveau_fbcon_set_suspend(dev, 1); + NV_INFO(drm, "suspending fbcon...\n"); + nouveau_fbcon_set_suspend(dev, 1); - NV_INFO(drm, "suspending display...\n"); - ret = nouveau_display_suspend(dev); - if (ret) - return ret; - } + NV_INFO(drm, "suspending display...\n"); + ret = nouveau_display_suspend(dev); + if (ret) + return ret; NV_INFO(drm, "evicting buffers...\n"); ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM); @@ -450,10 +445,8 @@ nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state) nouveau_client_init(&cli->base); } - if (dev->mode_config.num_crtc) { - NV_INFO(drm, "resuming display...\n"); - nouveau_display_resume(dev); - } + NV_INFO(drm, "resuming display...\n"); + nouveau_display_resume(dev); return ret; } @@ -493,10 +486,8 @@ nouveau_drm_resume(struct pci_dev *pdev) nouveau_irq_postinstall(dev); nouveau_pm_resume(dev); - if (dev->mode_config.num_crtc) { - NV_INFO(drm, "resuming display...\n"); - nouveau_display_resume(dev); - } + NV_INFO(drm, "resuming display...\n"); + nouveau_display_resume(dev); return 0; } @@ -671,7 +662,9 @@ nouveau_drm_init(void) #ifdef CONFIG_VGA_CONSOLE if (vgacon_text_force()) nouveau_modeset = 0; + else #endif + nouveau_modeset = 1; } if (!nouveau_modeset) diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h index a10169927086..819471217546 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h @@ -141,6 +141,4 @@ int nouveau_drm_resume(struct pci_dev *); nv_info((cli), fmt, ##args); \ } while (0) -extern int nouveau_modeset; - #endif diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_irq.c b/trunk/drivers/gpu/drm/nouveau/nouveau_irq.c index 1d8cb506a28a..9ca8afdb5549 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -61,15 +61,13 @@ nouveau_irq_handler(DRM_IRQ_ARGS) nv_subdev(pmc)->intr(nv_subdev(pmc)); - if (dev->mode_config.num_crtc) { - if (device->card_type >= NV_D0) { - if (nv_rd32(device, 0x000100) & 0x04000000) - nvd0_display_intr(dev); - } else - if (device->card_type >= NV_50) { - if (nv_rd32(device, 0x000100) & 0x04000000) - nv50_display_intr(dev); - } + if (device->card_type >= NV_D0) { + if (nv_rd32(device, 0x000100) & 0x04000000) + nvd0_display_intr(dev); + } else + if (device->card_type >= NV_50) { + if (nv_rd32(device, 0x000100) & 0x04000000) + nv50_display_intr(dev); } return IRQ_HANDLED; diff --git a/trunk/drivers/gpu/drm/nouveau/nv04_dac.c b/trunk/drivers/gpu/drm/nouveau/nv04_dac.c index 64f7020fb605..347a3bd78d04 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/trunk/drivers/gpu/drm/nouveau/nv04_dac.c @@ -220,7 +220,7 @@ static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder, NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode); if (blue == 0x18) { - NV_DEBUG(drm, "Load detected on head A\n"); + NV_INFO(drm, "Load detected on head A\n"); return connector_status_connected; } @@ -338,8 +338,8 @@ nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) if (nv17_dac_sample_load(encoder) & NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { - NV_DEBUG(drm, "Load detected on output %c\n", - '@' + ffs(dcb->or)); + NV_INFO(drm, "Load detected on output %c\n", + '@' + ffs(dcb->or)); return connector_status_connected; } else { return connector_status_disconnected; @@ -413,9 +413,9 @@ static void nv04_dac_commit(struct drm_encoder *encoder) helper->dpms(encoder, DRM_MODE_DPMS_ON); - NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n", - drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), - nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); + NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n", + drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), + nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); } void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable) @@ -461,8 +461,8 @@ static void nv04_dac_dpms(struct drm_encoder *encoder, int mode) return; nv_encoder->last_dpms = mode; - NV_DEBUG(drm, "Setting dpms mode %d on vga encoder (output %d)\n", - mode, nv_encoder->dcb->index); + NV_INFO(drm, "Setting dpms mode %d on vga encoder (output %d)\n", + mode, nv_encoder->dcb->index); nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON); } diff --git a/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c b/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c index 184cdf806761..da55d7642c8c 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c @@ -476,9 +476,9 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) helper->dpms(encoder, DRM_MODE_DPMS_ON); - NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n", - drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), - nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); + NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n", + drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), + nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); } static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode) @@ -520,8 +520,8 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) return; nv_encoder->last_dpms = mode; - NV_DEBUG(drm, "Setting dpms mode %d on lvds encoder (output %d)\n", - mode, nv_encoder->dcb->index); + NV_INFO(drm, "Setting dpms mode %d on lvds encoder (output %d)\n", + mode, nv_encoder->dcb->index); if (was_powersaving && is_powersaving_dpms(mode)) return; @@ -565,8 +565,8 @@ static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode) return; nv_encoder->last_dpms = mode; - NV_DEBUG(drm, "Setting dpms mode %d on tmds encoder (output %d)\n", - mode, nv_encoder->dcb->index); + NV_INFO(drm, "Setting dpms mode %d on tmds encoder (output %d)\n", + mode, nv_encoder->dcb->index); nv04_dfp_update_backlight(encoder, mode); nv04_dfp_update_fp_control(encoder, mode); diff --git a/trunk/drivers/gpu/drm/nouveau/nv04_tv.c b/trunk/drivers/gpu/drm/nouveau/nv04_tv.c index 62e826a139b3..099fbeda6e2e 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv04_tv.c +++ b/trunk/drivers/gpu/drm/nouveau/nv04_tv.c @@ -75,8 +75,8 @@ static void nv04_tv_dpms(struct drm_encoder *encoder, int mode) struct nv04_mode_state *state = &nv04_display(dev)->mode_reg; uint8_t crtc1A; - NV_DEBUG(drm, "Setting dpms mode %d on TV encoder (output %d)\n", - mode, nv_encoder->dcb->index); + NV_INFO(drm, "Setting dpms mode %d on TV encoder (output %d)\n", + mode, nv_encoder->dcb->index); state->pllsel &= ~(PLLSEL_TV_CRTC1_MASK | PLLSEL_TV_CRTC2_MASK); @@ -167,8 +167,9 @@ static void nv04_tv_commit(struct drm_encoder *encoder) helper->dpms(encoder, DRM_MODE_DPMS_ON); - NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n", - drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); + NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n", + drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, + '@' + ffs(nv_encoder->dcb->or)); } static void nv04_tv_destroy(struct drm_encoder *encoder) diff --git a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c index 24d932f53203..2e566e123e9e 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1697,22 +1697,34 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) DRM_ERROR("unable to allocate a PPLL\n"); return ATOM_PPLL_INVALID; } else { - /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */ - /* some atombios (observed in some DCE2/DCE3) code have a bug, - * the matching btw pll and crtc is done through - * PCLK_CRTC[1|2]_CNTL (0x480/0x484) but atombios code use the - * pll (1 or 2) to select which register to write. ie if using - * pll1 it will use PCLK_CRTC1_CNTL (0x480) and if using pll2 - * it will use PCLK_CRTC2_CNTL (0x484), it then use crtc id to - * choose which value to write. Which is reverse order from - * register logic. So only case that works is when pllid is - * same as crtcid or when both pll and crtc are enabled and - * both use same clock. - * - * So just return crtc id as if crtc and pll were hard linked - * together even if they aren't - */ - return radeon_crtc->crtc_id; + if (ASIC_IS_AVIVO(rdev)) { + /* in DP mode, the DP ref clock can come from either PPLL + * depending on the asic: + * DCE3: PPLL1 or PPLL2 + */ + if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) { + /* use the same PPLL for all DP monitors */ + pll = radeon_get_shared_dp_ppll(crtc); + if (pll != ATOM_PPLL_INVALID) + return pll; + } else { + /* use the same PPLL for all monitors with the same clock */ + pll = radeon_get_shared_nondp_ppll(crtc); + if (pll != ATOM_PPLL_INVALID) + return pll; + } + /* all other cases */ + pll_in_use = radeon_get_pll_use_mask(crtc); + if (!(pll_in_use & (1 << ATOM_PPLL1))) + return ATOM_PPLL1; + if (!(pll_in_use & (1 << ATOM_PPLL2))) + return ATOM_PPLL2; + DRM_ERROR("unable to allocate a PPLL\n"); + return ATOM_PPLL_INVALID; + } else { + /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */ + return radeon_crtc->crtc_id; + } } } diff --git a/trunk/drivers/gpu/drm/radeon/atombios_encoders.c b/trunk/drivers/gpu/drm/radeon/atombios_encoders.c index 010bae19554a..49cbb3795a10 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_encoders.c @@ -184,7 +184,6 @@ void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder, struct radeon_backlight_privdata *pdata; struct radeon_encoder_atom_dig *dig; u8 backlight_level; - char bl_name[16]; if (!radeon_encoder->enc_priv) return; @@ -204,9 +203,7 @@ void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder, memset(&props, 0, sizeof(props)); props.max_brightness = RADEON_MAX_BL_LEVEL; props.type = BACKLIGHT_RAW; - snprintf(bl_name, sizeof(bl_name), - "radeon_bl%d", dev->primary->index); - bd = backlight_device_register(bl_name, &drm_connector->kdev, + bd = backlight_device_register("radeon_bl", &drm_connector->kdev, pdata, &radeon_atom_backlight_ops, &props); if (IS_ERR(bd)) { DRM_ERROR("Backlight registration failed\n"); @@ -1625,7 +1622,7 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); /* some early dce3.2 boards have a bug in their transmitter control table */ - if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730)) + if ((rdev->family != CHIP_RV710) || (rdev->family != CHIP_RV730)) atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); } if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { diff --git a/trunk/drivers/gpu/drm/radeon/evergreen.c b/trunk/drivers/gpu/drm/radeon/evergreen.c index 219942c660d7..14313ad43b76 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen.c @@ -1330,8 +1330,6 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav break; udelay(1); } - } else { - save->crtc_enabled[i] = false; } } @@ -1374,7 +1372,7 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN); for (i = 0; i < rdev->num_crtc; i++) { - if (save->crtc_enabled[i]) { + if (save->crtc_enabled) { if (ASIC_IS_DCE6(rdev)) { tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]); tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; diff --git a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c index c042e497e450..573ed1bc6cf7 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c @@ -264,7 +264,7 @@ static int evergreen_surface_check_2d(struct radeon_cs_parser *p, /* macro tile width & height */ palign = (8 * surf->bankw * track->npipes) * surf->mtilea; halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea; - mtileb = (palign / 8) * (halign / 8) * tileb; + mtileb = (palign / 8) * (halign / 8) * tileb;; mtile_pr = surf->nbx / palign; mtile_ps = (mtile_pr * surf->nby) / halign; surf->layer_size = mtile_ps * mtileb * slice_pt; @@ -2725,9 +2725,6 @@ static bool evergreen_vm_reg_valid(u32 reg) /* check config regs */ switch (reg) { case GRBM_GFX_INDEX: - case CP_STRMOUT_CNTL: - case CP_COHER_CNTL: - case CP_COHER_SIZE: case VGT_VTX_VECT_EJECT_REG: case VGT_CACHE_INVALIDATION: case VGT_GS_VERTEX_REUSE: @@ -2832,7 +2829,6 @@ static bool evergreen_vm_reg_valid(u32 reg) case CAYMAN_SQ_EX_ALLOC_TABLE_SLOTS: return true; default: - DRM_ERROR("Invalid register 0x%x in CS\n", reg); return false; } } diff --git a/trunk/drivers/gpu/drm/radeon/evergreend.h b/trunk/drivers/gpu/drm/radeon/evergreend.h index 2bc0f6a1b428..df542f1a5dfb 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreend.h +++ b/trunk/drivers/gpu/drm/radeon/evergreend.h @@ -91,10 +91,6 @@ #define FB_READ_EN (1 << 0) #define FB_WRITE_EN (1 << 1) -#define CP_STRMOUT_CNTL 0x84FC - -#define CP_COHER_CNTL 0x85F0 -#define CP_COHER_SIZE 0x85F4 #define CP_COHER_BASE 0x85F8 #define CP_STALLED_STAT1 0x8674 #define CP_STALLED_STAT2 0x8678 diff --git a/trunk/drivers/gpu/drm/radeon/ni.c b/trunk/drivers/gpu/drm/radeon/ni.c index 81e6a568c29d..8c74c729586d 100644 --- a/trunk/drivers/gpu/drm/radeon/ni.c +++ b/trunk/drivers/gpu/drm/radeon/ni.c @@ -1538,31 +1538,26 @@ void cayman_vm_set_page(struct radeon_device *rdev, uint64_t pe, { struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index]; uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); + int i; - while (count) { - unsigned ndw = 1 + count * 2; - if (ndw > 0x3FFF) - ndw = 0x3FFF; - - radeon_ring_write(ring, PACKET3(PACKET3_ME_WRITE, ndw)); - radeon_ring_write(ring, pe); - radeon_ring_write(ring, upper_32_bits(pe) & 0xff); - for (; ndw > 1; ndw -= 2, --count, pe += 8) { - uint64_t value = 0; - if (flags & RADEON_VM_PAGE_SYSTEM) { - value = radeon_vm_map_gart(rdev, addr); - value &= 0xFFFFFFFFFFFFF000ULL; - addr += incr; - - } else if (flags & RADEON_VM_PAGE_VALID) { - value = addr; - addr += incr; - } - - value |= r600_flags; - radeon_ring_write(ring, value); - radeon_ring_write(ring, upper_32_bits(value)); + radeon_ring_write(ring, PACKET3(PACKET3_ME_WRITE, 1 + count * 2)); + radeon_ring_write(ring, pe); + radeon_ring_write(ring, upper_32_bits(pe) & 0xff); + for (i = 0; i < count; ++i) { + uint64_t value = 0; + if (flags & RADEON_VM_PAGE_SYSTEM) { + value = radeon_vm_map_gart(rdev, addr); + value &= 0xFFFFFFFFFFFFF000ULL; + addr += incr; + + } else if (flags & RADEON_VM_PAGE_VALID) { + value = addr; + addr += incr; } + + value |= r600_flags; + radeon_ring_write(ring, value); + radeon_ring_write(ring, upper_32_bits(value)); } } @@ -1591,8 +1586,4 @@ void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) /* bits 0-7 are the VM contexts0-7 */ radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0)); radeon_ring_write(ring, 1 << vm->id); - - /* sync PFP to ME, otherwise we might get invalid PFP reads */ - radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); - radeon_ring_write(ring, 0x0); } diff --git a/trunk/drivers/gpu/drm/radeon/nid.h b/trunk/drivers/gpu/drm/radeon/nid.h index cbef6815907a..2423d1b5d385 100644 --- a/trunk/drivers/gpu/drm/radeon/nid.h +++ b/trunk/drivers/gpu/drm/radeon/nid.h @@ -502,7 +502,6 @@ #define PACKET3_MPEG_INDEX 0x3A #define PACKET3_WAIT_REG_MEM 0x3C #define PACKET3_MEM_WRITE 0x3D -#define PACKET3_PFP_SYNC_ME 0x42 #define PACKET3_SURFACE_SYNC 0x43 # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) # define PACKET3_CB1_DEST_BASE_ENA (1 << 7) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_agp.c b/trunk/drivers/gpu/drm/radeon/radeon_agp.c index 42433344cb1b..10ea17a6b2a6 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_agp.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_agp.c @@ -69,12 +69,9 @@ static struct radeon_agpmode_quirk radeon_agpmode_quirk_list[] = { /* Intel 82830 830 Chipset Host Bridge / Mobility M6 LY Needs AGPMode 2 (fdo #17360)*/ { PCI_VENDOR_ID_INTEL, 0x3575, PCI_VENDOR_ID_ATI, 0x4c59, PCI_VENDOR_ID_DELL, 0x00e3, 2}, - /* Intel 82852/82855 host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 (lp #296617) */ + /* Intel 82852/82855 host bridge / Mobility FireGL 9000 R250 Needs AGPMode 1 (lp #296617) */ { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4c66, PCI_VENDOR_ID_DELL, 0x0149, 1}, - /* Intel 82855PM host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 for suspend/resume */ - { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c66, - PCI_VENDOR_ID_IBM, 0x0531, 1}, /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (deb #467460) */ { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50, 0x1025, 0x0061, 1}, diff --git a/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 15f5ded65e0c..1aa3f910b993 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -87,7 +87,7 @@ static union acpi_object *radeon_atpx_call(acpi_handle handle, int function, atpx_arg_elements[1].integer.value = 0; } - status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer); + status = acpi_evaluate_object(handle, "ATPX", &atpx_arg, &buffer); /* Fail only if calling the method fails and ATPX is supported */ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { @@ -352,9 +352,9 @@ static int radeon_atpx_switchto(enum vga_switcheroo_client_id id) } /** - * radeon_atpx_power_state - power down/up the requested GPU + * radeon_atpx_switchto - switch to the requested GPU * - * @id: GPU to power down/up + * @id: GPU to switch to * @state: requested power state (0 = off, 1 = on) * * Execute the necessary ATPX function to power down/up the discrete GPU @@ -373,11 +373,11 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id, } /** - * radeon_atpx_pci_probe_handle - look up the ATPX handle + * radeon_atpx_pci_probe_handle - look up the ATRM and ATPX handles * * @pdev: pci device * - * Look up the ATPX handles (all asics). + * Look up the ATPX and ATRM handles (all asics). * Returns true if the handles are found, false if not. */ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c index b884c362a8c2..67cfc1795ecd 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c @@ -941,7 +941,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) struct drm_mode_object *obj; int i; enum drm_connector_status ret = connector_status_disconnected; - bool dret = false, broken_edid = false; + bool dret = false; if (!force && radeon_check_hpd_status_unchanged(connector)) return connector->status; @@ -965,9 +965,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) ret = connector_status_disconnected; DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector)); radeon_connector->ddc_bus = NULL; - } else { - ret = connector_status_connected; - broken_edid = true; /* defer use_digital to later */ } } else { radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); @@ -1050,24 +1047,13 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) encoder_funcs = encoder->helper_private; if (encoder_funcs->detect) { - if (!broken_edid) { - if (ret != connector_status_connected) { - /* deal with analog monitors without DDC */ - ret = encoder_funcs->detect(encoder, connector); - if (ret == connector_status_connected) { - radeon_connector->use_digital = false; - } - if (ret != connector_status_disconnected) - radeon_connector->detected_by_load = true; - } - } else { - enum drm_connector_status lret; - /* assume digital unless load detected otherwise */ - radeon_connector->use_digital = true; - lret = encoder_funcs->detect(encoder, connector); - DRM_DEBUG_KMS("load_detect %x returned: %x\n",encoder->encoder_type,lret); - if (lret == connector_status_connected) + if (ret != connector_status_connected) { + ret = encoder_funcs->detect(encoder, connector); + if (ret == connector_status_connected) { radeon_connector->use_digital = false; + } + if (ret != connector_status_disconnected) + radeon_connector->detected_by_load = true; } break; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_device.c b/trunk/drivers/gpu/drm/radeon/radeon_device.c index e2f5f888c374..bd13ca09eb62 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_device.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_device.c @@ -355,8 +355,6 @@ int radeon_wb_init(struct radeon_device *rdev) */ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base) { - uint64_t limit = (uint64_t)radeon_vram_limit << 20; - mc->vram_start = base; if (mc->mc_vram_size > (0xFFFFFFFF - base + 1)) { dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); @@ -370,8 +368,8 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 mc->mc_vram_size = mc->aper_size; } mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; - if (limit && limit < mc->real_vram_size) - mc->real_vram_size = limit; + if (radeon_vram_limit && radeon_vram_limit < mc->real_vram_size) + mc->real_vram_size = radeon_vram_limit; dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n", mc->mc_vram_size >> 20, mc->vram_start, mc->vram_end, mc->real_vram_size >> 20); @@ -836,19 +834,6 @@ static unsigned int radeon_vga_set_decode(void *cookie, bool state) return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; } -/** - * radeon_check_pot_argument - check that argument is a power of two - * - * @arg: value to check - * - * Validates that a certain argument is a power of two (all asics). - * Returns true if argument is valid. - */ -static bool radeon_check_pot_argument(int arg) -{ - return (arg & (arg - 1)) == 0; -} - /** * radeon_check_arguments - validate module params * @@ -860,25 +845,52 @@ static bool radeon_check_pot_argument(int arg) static void radeon_check_arguments(struct radeon_device *rdev) { /* vramlimit must be a power of two */ - if (!radeon_check_pot_argument(radeon_vram_limit)) { + switch (radeon_vram_limit) { + case 0: + case 4: + case 8: + case 16: + case 32: + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + break; + default: dev_warn(rdev->dev, "vram limit (%d) must be a power of 2\n", radeon_vram_limit); radeon_vram_limit = 0; + break; } - + radeon_vram_limit = radeon_vram_limit << 20; /* gtt size must be power of two and greater or equal to 32M */ - if (radeon_gart_size < 32) { + switch (radeon_gart_size) { + case 4: + case 8: + case 16: dev_warn(rdev->dev, "gart size (%d) too small forcing to 512M\n", radeon_gart_size); radeon_gart_size = 512; - - } else if (!radeon_check_pot_argument(radeon_gart_size)) { + break; + case 32: + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + break; + default: dev_warn(rdev->dev, "gart size (%d) must be a power of 2\n", radeon_gart_size); radeon_gart_size = 512; + break; } - rdev->mc.gtt_size = (uint64_t)radeon_gart_size << 20; - + rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; /* AGP mode can only be -1, 1, 2, 4, 8 */ switch (radeon_agpmode) { case -1: diff --git a/trunk/drivers/gpu/drm/radeon/radeon_gart.c b/trunk/drivers/gpu/drm/radeon/radeon_gart.c index 4debd60e5aa6..a7677dd1ce98 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_gart.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_gart.c @@ -355,13 +355,14 @@ int radeon_gart_init(struct radeon_device *rdev) DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n", rdev->gart.num_cpu_pages, rdev->gart.num_gpu_pages); /* Allocate pages table */ - rdev->gart.pages = vzalloc(sizeof(void *) * rdev->gart.num_cpu_pages); + rdev->gart.pages = kzalloc(sizeof(void *) * rdev->gart.num_cpu_pages, + GFP_KERNEL); if (rdev->gart.pages == NULL) { radeon_gart_fini(rdev); return -ENOMEM; } - rdev->gart.pages_addr = vzalloc(sizeof(dma_addr_t) * - rdev->gart.num_cpu_pages); + rdev->gart.pages_addr = kzalloc(sizeof(dma_addr_t) * + rdev->gart.num_cpu_pages, GFP_KERNEL); if (rdev->gart.pages_addr == NULL) { radeon_gart_fini(rdev); return -ENOMEM; @@ -387,8 +388,8 @@ void radeon_gart_fini(struct radeon_device *rdev) radeon_gart_unbind(rdev, 0, rdev->gart.num_cpu_pages); } rdev->gart.ready = false; - vfree(rdev->gart.pages); - vfree(rdev->gart.pages_addr); + kfree(rdev->gart.pages); + kfree(rdev->gart.pages_addr); rdev->gart.pages = NULL; rdev->gart.pages_addr = NULL; @@ -576,7 +577,7 @@ void radeon_vm_manager_fini(struct radeon_device *rdev) * * Global and local mutex must be locked! */ -static int radeon_vm_evict(struct radeon_device *rdev, struct radeon_vm *vm) +int radeon_vm_evict(struct radeon_device *rdev, struct radeon_vm *vm) { struct radeon_vm *vm_evict; @@ -1035,7 +1036,8 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev, pte = radeon_sa_bo_gpu_addr(vm->page_tables[pt_idx]); pte += (addr & mask) * 8; - if ((last_pte + 8 * count) != pte) { + if (((last_pte + 8 * count) != pte) || + ((count + nptes) > 1 << 11)) { if (count) { radeon_asic_vm_set_page(rdev, last_pte, @@ -1146,17 +1148,17 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, if (RADEON_VM_BLOCK_SIZE > 11) /* reserve space for one header for every 2k dwords */ - ndw += (nptes >> 11) * 4; + ndw += (nptes >> 11) * 3; else /* reserve space for one header for every (1 << BLOCK_SIZE) entries */ - ndw += (nptes >> RADEON_VM_BLOCK_SIZE) * 4; + ndw += (nptes >> RADEON_VM_BLOCK_SIZE) * 3; /* reserve space for pte addresses */ ndw += nptes * 2; /* reserve space for one header for every 2k dwords */ - ndw += (npdes >> 11) * 4; + ndw += (npdes >> 11) * 3; /* reserve space for pde addresses */ ndw += npdes * 2; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_gem.c b/trunk/drivers/gpu/drm/radeon/radeon_gem.c index fe5c1f6b7957..f38fbcc46935 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_gem.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_gem.c @@ -53,7 +53,6 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size, struct drm_gem_object **obj) { struct radeon_bo *robj; - unsigned long max_size; int r; *obj = NULL; @@ -61,26 +60,11 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size, if (alignment < PAGE_SIZE) { alignment = PAGE_SIZE; } - - /* maximun bo size is the minimun btw visible vram and gtt size */ - max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size); - if (size > max_size) { - printk(KERN_WARNING "%s:%d alloc size %dMb bigger than %ldMb limit\n", - __func__, __LINE__, size >> 20, max_size >> 20); - return -ENOMEM; - } - -retry: r = radeon_bo_create(rdev, size, alignment, kernel, initial_domain, NULL, &robj); if (r) { - if (r != -ERESTARTSYS) { - if (initial_domain == RADEON_GEM_DOMAIN_VRAM) { - initial_domain |= RADEON_GEM_DOMAIN_GTT; - goto retry; - } + if (r != -ERESTARTSYS) DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n", size, initial_domain, alignment, r); - } return r; } *obj = &robj->gem_base; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 6857cb4efb76..5677a424b585 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c @@ -295,7 +295,6 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; struct radeon_device *rdev = dev->dev_private; - uint32_t crtc_ext_cntl = 0; uint32_t mask; if (radeon_crtc->crtc_id) @@ -308,16 +307,6 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS); - /* - * On all dual CRTC GPUs this bit controls the CRTC of the primary DAC. - * Therefore it is set in the DAC DMPS function. - * This is different for GPU's with a single CRTC but a primary and a - * TV DAC: here it controls the single CRTC no matter where it is - * routed. Therefore we set it here. - */ - if (rdev->flags & RADEON_SINGLE_CRTC) - crtc_ext_cntl = RADEON_CRTC_CRT_ON; - switch (mode) { case DRM_MODE_DPMS_ON: radeon_crtc->enabled = true; @@ -328,7 +317,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) else { WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | RADEON_CRTC_DISP_REQ_EN_B)); - WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl)); + WREG32_P(RADEON_CRTC_EXT_CNTL, 0, ~mask); } drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); radeon_crtc_load_lut(crtc); @@ -342,7 +331,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) else { WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | RADEON_CRTC_DISP_REQ_EN_B)); - WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~(mask | crtc_ext_cntl)); + WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~mask); } radeon_crtc->enabled = false; /* adjust pm to dpms changes AFTER disabling crtcs */ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index f5ba2241dacc..a13ad9d707cf 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -370,7 +370,6 @@ void radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, struct backlight_properties props; struct radeon_backlight_privdata *pdata; uint8_t backlight_level; - char bl_name[16]; if (!radeon_encoder->enc_priv) return; @@ -390,9 +389,7 @@ void radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, memset(&props, 0, sizeof(props)); props.max_brightness = RADEON_MAX_BL_LEVEL; props.type = BACKLIGHT_RAW; - snprintf(bl_name, sizeof(bl_name), - "radeon_bl%d", dev->primary->index); - bd = backlight_device_register(bl_name, &drm_connector->kdev, + bd = backlight_device_register("radeon_bl", &drm_connector->kdev, pdata, &radeon_backlight_ops, &props); if (IS_ERR(bd)) { DRM_ERROR("Backlight registration failed\n"); @@ -537,9 +534,7 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode break; } - /* handled in radeon_crtc_dpms() */ - if (!(rdev->flags & RADEON_SINGLE_CRTC)) - WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); + WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); WREG32(RADEON_DAC_CNTL, dac_cntl); WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); @@ -664,8 +659,6 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc if (ASIC_IS_R300(rdev)) tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT); - else if (ASIC_IS_RV100(rdev)) - tmp |= (0x1ac << RADEON_DAC_FORCE_DATA_SHIFT); else tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT); @@ -675,7 +668,6 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN; WREG32(RADEON_DAC_CNTL, tmp); - tmp = dac_macro_cntl; tmp &= ~(RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G | RADEON_DAC_PDWN_B); @@ -1097,8 +1089,7 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) } else { if (is_tv) WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); - /* handled in radeon_crtc_dpms() */ - else if (!(rdev->flags & RADEON_SINGLE_CRTC)) + else WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); } @@ -1422,104 +1413,13 @@ static bool radeon_legacy_tv_detect(struct drm_encoder *encoder, return found; } -static bool radeon_legacy_ext_dac_detect(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl; - uint32_t disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c; - uint32_t disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f; - uint32_t tmp, crtc2_h_total_disp, crtc2_v_total_disp; - uint32_t crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid; - bool found = false; - int i; - - /* save the regs we need */ - gpio_monid = RREG32(RADEON_GPIO_MONID); - fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); - disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); - crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); - disp_lin_trans_grph_a = RREG32(RADEON_DISP_LIN_TRANS_GRPH_A); - disp_lin_trans_grph_b = RREG32(RADEON_DISP_LIN_TRANS_GRPH_B); - disp_lin_trans_grph_c = RREG32(RADEON_DISP_LIN_TRANS_GRPH_C); - disp_lin_trans_grph_d = RREG32(RADEON_DISP_LIN_TRANS_GRPH_D); - disp_lin_trans_grph_e = RREG32(RADEON_DISP_LIN_TRANS_GRPH_E); - disp_lin_trans_grph_f = RREG32(RADEON_DISP_LIN_TRANS_GRPH_F); - crtc2_h_total_disp = RREG32(RADEON_CRTC2_H_TOTAL_DISP); - crtc2_v_total_disp = RREG32(RADEON_CRTC2_V_TOTAL_DISP); - crtc2_h_sync_strt_wid = RREG32(RADEON_CRTC2_H_SYNC_STRT_WID); - crtc2_v_sync_strt_wid = RREG32(RADEON_CRTC2_V_SYNC_STRT_WID); - - tmp = RREG32(RADEON_GPIO_MONID); - tmp &= ~RADEON_GPIO_A_0; - WREG32(RADEON_GPIO_MONID, tmp); - - WREG32(RADEON_FP2_GEN_CNTL, (RADEON_FP2_ON | - RADEON_FP2_PANEL_FORMAT | - R200_FP2_SOURCE_SEL_TRANS_UNIT | - RADEON_FP2_DVO_EN | - R200_FP2_DVO_RATE_SEL_SDR)); - - WREG32(RADEON_DISP_OUTPUT_CNTL, (RADEON_DISP_DAC_SOURCE_RMX | - RADEON_DISP_TRANS_MATRIX_GRAPHICS)); - - WREG32(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_EN | - RADEON_CRTC2_DISP_REQ_EN_B)); - - WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0); - - WREG32(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008); - WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800); - WREG32(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001); - WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080); - - for (i = 0; i < 200; i++) { - tmp = RREG32(RADEON_GPIO_MONID); - if (tmp & RADEON_GPIO_Y_0) - found = true; - - if (found) - break; - - if (!drm_can_sleep()) - mdelay(1); - else - msleep(1); - } - - /* restore the regs we used */ - WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f); - WREG32(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp); - WREG32(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp); - WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid); - WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid); - WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); - WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); - WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); - WREG32(RADEON_GPIO_MONID, gpio_monid); - - return found; -} - static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) { struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; - uint32_t crtc2_gen_cntl = 0, tv_dac_cntl, dac_cntl2, dac_ext_cntl; - uint32_t gpiopad_a = 0, pixclks_cntl, tmp; - uint32_t disp_output_cntl = 0, disp_hw_debug = 0, crtc_ext_cntl = 0; + uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; + uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp; enum drm_connector_status found = connector_status_disconnected; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; @@ -1556,27 +1456,12 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder return connector_status_disconnected; } - /* R200 uses an external DAC for secondary DAC */ - if (rdev->family == CHIP_R200) { - if (radeon_legacy_ext_dac_detect(encoder, connector)) - found = connector_status_connected; - return found; - } - /* save the regs we need */ pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); - - if (rdev->flags & RADEON_SINGLE_CRTC) { - crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); - } else { - if (ASIC_IS_R300(rdev)) { - gpiopad_a = RREG32(RADEON_GPIOPAD_A); - disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); - } else { - disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); - } - crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); - } + gpiopad_a = ASIC_IS_R300(rdev) ? RREG32(RADEON_GPIOPAD_A) : 0; + disp_output_cntl = ASIC_IS_R300(rdev) ? RREG32(RADEON_DISP_OUTPUT_CNTL) : 0; + disp_hw_debug = ASIC_IS_R300(rdev) ? 0 : RREG32(RADEON_DISP_HW_DEBUG); + crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL); dac_cntl2 = RREG32(RADEON_DAC_CNTL2); @@ -1585,24 +1470,22 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder | RADEON_PIX2CLK_DAC_ALWAYS_ONb); WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); - if (rdev->flags & RADEON_SINGLE_CRTC) { - tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON; - WREG32(RADEON_CRTC_EXT_CNTL, tmp); - } else { - tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; - tmp |= RADEON_CRTC2_CRT2_ON | - (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); - WREG32(RADEON_CRTC2_GEN_CNTL, tmp); + if (ASIC_IS_R300(rdev)) + WREG32_P(RADEON_GPIOPAD_A, 1, ~1); - if (ASIC_IS_R300(rdev)) { - WREG32_P(RADEON_GPIOPAD_A, 1, ~1); - tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; - tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; - WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); - } else { - tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; - WREG32(RADEON_DISP_HW_DEBUG, tmp); - } + tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; + tmp |= RADEON_CRTC2_CRT2_ON | + (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); + + WREG32(RADEON_CRTC2_GEN_CNTL, tmp); + + if (ASIC_IS_R300(rdev)) { + tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; + tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; + WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); + } else { + tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; + WREG32(RADEON_DISP_HW_DEBUG, tmp); } tmp = RADEON_TV_DAC_NBLANK | @@ -1644,19 +1527,14 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder WREG32(RADEON_DAC_CNTL2, dac_cntl2); WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl); WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); + WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); - if (rdev->flags & RADEON_SINGLE_CRTC) { - WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); + if (ASIC_IS_R300(rdev)) { + WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); + WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); } else { - WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); - if (ASIC_IS_R300(rdev)) { - WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); - WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); - } else { - WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); - } + WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); } - WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); return found; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_object.c b/trunk/drivers/gpu/drm/radeon/radeon_object.c index b91118ccef86..8b27dd6e3144 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_object.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_object.c @@ -105,6 +105,7 @@ int radeon_bo_create(struct radeon_device *rdev, struct radeon_bo *bo; enum ttm_bo_type type; unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; + unsigned long max_size = 0; size_t acc_size; int r; @@ -120,9 +121,18 @@ int radeon_bo_create(struct radeon_device *rdev, } *bo_ptr = NULL; + /* maximun bo size is the minimun btw visible vram and gtt size */ + max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size); + if ((page_align << PAGE_SHIFT) >= max_size) { + printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n", + __func__, __LINE__, page_align >> (20 - PAGE_SHIFT), max_size >> 20); + return -ENOMEM; + } + acc_size = ttm_bo_dma_acc_size(&rdev->mman.bdev, size, sizeof(struct radeon_bo)); +retry: bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); if (bo == NULL) return -ENOMEM; @@ -144,6 +154,15 @@ int radeon_bo_create(struct radeon_device *rdev, acc_size, sg, &radeon_ttm_bo_destroy); up_read(&rdev->pm.mclk_lock); if (unlikely(r != 0)) { + if (r != -ERESTARTSYS) { + if (domain == RADEON_GEM_DOMAIN_VRAM) { + domain |= RADEON_GEM_DOMAIN_GTT; + goto retry; + } + dev_err(rdev->dev, + "object_init failed for (%lu, 0x%08X)\n", + size, domain); + } return r; } *bo_ptr = bo; diff --git a/trunk/drivers/gpu/drm/radeon/si.c b/trunk/drivers/gpu/drm/radeon/si.c index 4422d630b33b..df8dd7701643 100644 --- a/trunk/drivers/gpu/drm/radeon/si.c +++ b/trunk/drivers/gpu/drm/radeon/si.c @@ -2474,7 +2474,6 @@ static bool si_vm_reg_valid(u32 reg) /* check config regs */ switch (reg) { case GRBM_GFX_INDEX: - case CP_STRMOUT_CNTL: case VGT_VTX_VECT_EJECT_REG: case VGT_CACHE_INVALIDATION: case VGT_ESGS_RING_SIZE: @@ -2809,31 +2808,26 @@ void si_vm_set_page(struct radeon_device *rdev, uint64_t pe, { struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index]; uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); + int i; + uint64_t value; - while (count) { - unsigned ndw = 2 + count * 2; - if (ndw > 0x3FFE) - ndw = 0x3FFE; - - radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, ndw)); - radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | - WRITE_DATA_DST_SEL(1))); - radeon_ring_write(ring, pe); - radeon_ring_write(ring, upper_32_bits(pe)); - for (; ndw > 2; ndw -= 2, --count, pe += 8) { - uint64_t value; - if (flags & RADEON_VM_PAGE_SYSTEM) { - value = radeon_vm_map_gart(rdev, addr); - value &= 0xFFFFFFFFFFFFF000ULL; - } else if (flags & RADEON_VM_PAGE_VALID) - value = addr; - else - value = 0; - addr += incr; - value |= r600_flags; - radeon_ring_write(ring, value); - radeon_ring_write(ring, upper_32_bits(value)); - } + radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 2 + count * 2)); + radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | + WRITE_DATA_DST_SEL(1))); + radeon_ring_write(ring, pe); + radeon_ring_write(ring, upper_32_bits(pe)); + for (i = 0; i < count; ++i) { + if (flags & RADEON_VM_PAGE_SYSTEM) { + value = radeon_vm_map_gart(rdev, addr); + value &= 0xFFFFFFFFFFFFF000ULL; + } else if (flags & RADEON_VM_PAGE_VALID) + value = addr; + else + value = 0; + addr += incr; + value |= r600_flags; + radeon_ring_write(ring, value); + radeon_ring_write(ring, upper_32_bits(value)); } } @@ -2874,10 +2868,6 @@ void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); radeon_ring_write(ring, 0); radeon_ring_write(ring, 1 << vm->id); - - /* sync PFP to ME, otherwise we might get invalid PFP reads */ - radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); - radeon_ring_write(ring, 0x0); } /* diff --git a/trunk/drivers/gpu/drm/radeon/sid.h b/trunk/drivers/gpu/drm/radeon/sid.h index a8871afc5b4e..7d2a20e56577 100644 --- a/trunk/drivers/gpu/drm/radeon/sid.h +++ b/trunk/drivers/gpu/drm/radeon/sid.h @@ -424,7 +424,6 @@ # define RDERR_INT_ENABLE (1 << 0) # define GUI_IDLE_INT_ENABLE (1 << 19) -#define CP_STRMOUT_CNTL 0x84FC #define SCRATCH_REG0 0x8500 #define SCRATCH_REG1 0x8504 #define SCRATCH_REG2 0x8508 diff --git a/trunk/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/trunk/drivers/gpu/drm/shmobile/shmob_drm_drv.c index 1c350fc4e449..c71d493fd0c5 100644 --- a/trunk/drivers/gpu/drm/shmobile/shmob_drm_drv.c +++ b/trunk/drivers/gpu/drm/shmobile/shmob_drm_drv.c @@ -201,8 +201,6 @@ static int shmob_drm_load(struct drm_device *dev, unsigned long flags) goto done; } - platform_set_drvdata(pdev, sdev); - done: if (ret) shmob_drm_unload(dev); @@ -301,9 +299,11 @@ static struct drm_driver shmob_drm_driver = { #if CONFIG_PM_SLEEP static int shmob_drm_pm_suspend(struct device *dev) { - struct shmob_drm_device *sdev = dev_get_drvdata(dev); + struct platform_device *pdev = to_platform_device(dev); + struct drm_device *ddev = platform_get_drvdata(pdev); + struct shmob_drm_device *sdev = ddev->dev_private; - drm_kms_helper_poll_disable(sdev->ddev); + drm_kms_helper_poll_disable(ddev); shmob_drm_crtc_suspend(&sdev->crtc); return 0; @@ -311,7 +311,9 @@ static int shmob_drm_pm_suspend(struct device *dev) static int shmob_drm_pm_resume(struct device *dev) { - struct shmob_drm_device *sdev = dev_get_drvdata(dev); + struct platform_device *pdev = to_platform_device(dev); + struct drm_device *ddev = platform_get_drvdata(pdev); + struct shmob_drm_device *sdev = ddev->dev_private; mutex_lock(&sdev->ddev->mode_config.mutex); shmob_drm_crtc_resume(&sdev->crtc); diff --git a/trunk/drivers/gpu/drm/ttm/ttm_bo.c b/trunk/drivers/gpu/drm/ttm/ttm_bo.c index bf6e4b5a73b5..402ab69f9f99 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_bo.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_bo.c @@ -580,7 +580,6 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, if (unlikely(ret != 0)) return ret; -retry_reserve: spin_lock(&glob->lru_lock); if (unlikely(list_empty(&bo->ddestroy))) { @@ -588,20 +587,14 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, return 0; } - ret = ttm_bo_reserve_locked(bo, false, true, false, 0); + ret = ttm_bo_reserve_locked(bo, interruptible, + no_wait_reserve, false, 0); - if (unlikely(ret == -EBUSY)) { + if (unlikely(ret != 0)) { spin_unlock(&glob->lru_lock); - if (likely(!no_wait_reserve)) - ret = ttm_bo_wait_unreserved(bo, interruptible); - if (unlikely(ret != 0)) - return ret; - - goto retry_reserve; + return ret; } - BUG_ON(ret != 0); - /** * We can re-check for sync object without taking * the bo::lock since setting the sync object requires @@ -818,14 +811,17 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev, no_wait_reserve, no_wait_gpu); kref_put(&bo->list_kref, ttm_bo_release_list); - return ret; + if (likely(ret == 0 || ret == -ERESTARTSYS)) + return ret; + + goto retry; } - ret = ttm_bo_reserve_locked(bo, false, true, false, 0); + ret = ttm_bo_reserve_locked(bo, false, no_wait_reserve, false, 0); if (unlikely(ret == -EBUSY)) { spin_unlock(&glob->lru_lock); - if (likely(!no_wait_reserve)) + if (likely(!no_wait_gpu)) ret = ttm_bo_wait_unreserved(bo, interruptible); kref_put(&bo->list_kref, ttm_bo_release_list); diff --git a/trunk/drivers/gpu/drm/ttm/ttm_page_alloc.c b/trunk/drivers/gpu/drm/ttm/ttm_page_alloc.c index bd2a3b40cd12..860dc4813e99 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -749,10 +749,7 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, /* clear the pages coming from the pool if requested */ if (flags & TTM_PAGE_FLAG_ZERO_ALLOC) { list_for_each_entry(p, &plist, lru) { - if (PageHighMem(p)) - clear_highpage(p); - else - clear_page(page_address(p)); + clear_page(page_address(p)); } } diff --git a/trunk/drivers/gpu/drm/ttm/ttm_tt.c b/trunk/drivers/gpu/drm/ttm/ttm_tt.c index 7d759a430294..bf8260133ea9 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_tt.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_tt.c @@ -308,7 +308,9 @@ int ttm_tt_swapin(struct ttm_tt *ttm) if (unlikely(to_page == NULL)) goto out_err; + preempt_disable(); copy_highpage(to_page, from_page); + preempt_enable(); page_cache_release(from_page); } @@ -356,7 +358,9 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage) ret = PTR_ERR(to_page); goto out_err; } + preempt_disable(); copy_highpage(to_page, from_page); + preempt_enable(); set_page_dirty(to_page); mark_page_accessed(to_page); page_cache_release(to_page); diff --git a/trunk/drivers/gpu/drm/udl/udl_drv.h b/trunk/drivers/gpu/drm/udl/udl_drv.h index 87aa5f5d3c88..fccd361f7b50 100644 --- a/trunk/drivers/gpu/drm/udl/udl_drv.h +++ b/trunk/drivers/gpu/drm/udl/udl_drv.h @@ -104,7 +104,7 @@ udl_fb_user_fb_create(struct drm_device *dev, int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, const char *front, char **urb_buf_ptr, - u32 byte_offset, u32 device_byte_offset, u32 byte_width, + u32 byte_offset, u32 byte_width, int *ident_ptr, int *sent_ptr); int udl_dumb_create(struct drm_file *file_priv, diff --git a/trunk/drivers/gpu/drm/udl/udl_fb.c b/trunk/drivers/gpu/drm/udl/udl_fb.c index d4ab3beaada0..69a2b16f42a6 100644 --- a/trunk/drivers/gpu/drm/udl/udl_fb.c +++ b/trunk/drivers/gpu/drm/udl/udl_fb.c @@ -114,10 +114,9 @@ static void udlfb_dpy_deferred_io(struct fb_info *info, list_for_each_entry(cur, &fbdefio->pagelist, lru) { if (udl_render_hline(dev, (ufbdev->ufb.base.bits_per_pixel / 8), - &urb, (char *) info->fix.smem_start, - &cmd, cur->index << PAGE_SHIFT, - cur->index << PAGE_SHIFT, - PAGE_SIZE, &bytes_identical, &bytes_sent)) + &urb, (char *) info->fix.smem_start, + &cmd, cur->index << PAGE_SHIFT, + PAGE_SIZE, &bytes_identical, &bytes_sent)) goto error; bytes_rendered += PAGE_SIZE; } @@ -188,11 +187,10 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, for (i = y; i < y + height ; i++) { const int line_offset = fb->base.pitches[0] * i; const int byte_offset = line_offset + (x * bpp); - const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp); + if (udl_render_hline(dev, bpp, &urb, (char *) fb->obj->vmapping, - &cmd, byte_offset, dev_byte_offset, - width * bpp, + &cmd, byte_offset, width * bpp, &bytes_identical, &bytes_sent)) goto error; } diff --git a/trunk/drivers/gpu/drm/udl/udl_transfer.c b/trunk/drivers/gpu/drm/udl/udl_transfer.c index 142fee5f983f..dc095526ffb7 100644 --- a/trunk/drivers/gpu/drm/udl/udl_transfer.c +++ b/trunk/drivers/gpu/drm/udl/udl_transfer.c @@ -213,12 +213,11 @@ static void udl_compress_hline16( */ int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, const char *front, char **urb_buf_ptr, - u32 byte_offset, u32 device_byte_offset, - u32 byte_width, + u32 byte_offset, u32 byte_width, int *ident_ptr, int *sent_ptr) { const u8 *line_start, *line_end, *next_pixel; - u32 base16 = 0 + (device_byte_offset / bpp) * 2; + u32 base16 = 0 + (byte_offset / bpp) * 2; struct urb *urb = *urb_ptr; u8 *cmd = *urb_buf_ptr; u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length; diff --git a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c index d1498bfd7873..3ce68a2e312d 100644 --- a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c +++ b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c @@ -306,7 +306,7 @@ void vmw_bo_pin(struct ttm_buffer_object *bo, bool pin) BUG_ON(!atomic_read(&bo->reserved)); BUG_ON(old_mem_type != TTM_PL_VRAM && - old_mem_type != VMW_PL_GMR); + old_mem_type != VMW_PL_FLAG_GMR); pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED; if (pin) diff --git a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 2dd185e42f21..ed3c1e7ddde9 100644 --- a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -1098,11 +1098,6 @@ static void vmw_pm_complete(struct device *kdev) struct drm_device *dev = pci_get_drvdata(pdev); struct vmw_private *dev_priv = vmw_priv(dev); - mutex_lock(&dev_priv->hw_mutex); - vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); - (void) vmw_read(dev_priv, SVGA_REG_ID); - mutex_unlock(&dev_priv->hw_mutex); - /** * Reclaim 3d reference held by fbdev and potentially * start fifo. diff --git a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 7290811f89be..b07ca2e4d04b 100644 --- a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -110,8 +110,6 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, memcpy_fromio(bounce, &fifo_mem[SVGA_FIFO_3D_CAPS], size); ret = copy_to_user(buffer, bounce, size); - if (ret) - ret = -EFAULT; vfree(bounce); if (unlikely(ret != 0)) diff --git a/trunk/drivers/hid/hid-apple.c b/trunk/drivers/hid/hid-apple.c index fd7722aecf77..06ebdbb6ea02 100644 --- a/trunk/drivers/hid/hid-apple.c +++ b/trunk/drivers/hid/hid-apple.c @@ -522,12 +522,6 @@ static const struct hid_device_id apple_devices[] = { .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS), .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI), - .driver_data = APPLE_HAS_FN }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO), - .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS), - .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), diff --git a/trunk/drivers/hid/hid-core.c b/trunk/drivers/hid/hid-core.c index f4109fd657ff..bd3971bf31bf 100644 --- a/trunk/drivers/hid/hid-core.c +++ b/trunk/drivers/hid/hid-core.c @@ -1532,9 +1532,6 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, @@ -2142,9 +2139,6 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, { } diff --git a/trunk/drivers/hid/hid-ids.h b/trunk/drivers/hid/hid-ids.h index 9d7a42857ea1..269b50912a4a 100644 --- a/trunk/drivers/hid/hid-ids.h +++ b/trunk/drivers/hid/hid-ids.h @@ -118,9 +118,6 @@ #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI 0x0252 #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO 0x0253 #define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS 0x0254 -#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI 0x0259 -#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a -#define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI 0x0249 #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO 0x024a #define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS 0x024b diff --git a/trunk/drivers/hid/hid-microsoft.c b/trunk/drivers/hid/hid-microsoft.c index 6fcd466d0825..3acdcfcc17df 100644 --- a/trunk/drivers/hid/hid-microsoft.c +++ b/trunk/drivers/hid/hid-microsoft.c @@ -28,30 +28,22 @@ #define MS_RDESC 0x08 #define MS_NOGET 0x10 #define MS_DUPLICATE_USAGES 0x20 -#define MS_RDESC_3K 0x40 +/* + * Microsoft Wireless Desktop Receiver (Model 1028) has + * 'Usage Min/Max' where it ought to have 'Physical Min/Max' + */ static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); - /* - * Microsoft Wireless Desktop Receiver (Model 1028) has - * 'Usage Min/Max' where it ought to have 'Physical Min/Max' - */ if ((quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 && rdesc[559] == 0x29) { hid_info(hdev, "fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n"); rdesc[557] = 0x35; rdesc[559] = 0x45; } - /* the same as above (s/usage/physical/) */ - if ((quirks & MS_RDESC_3K) && *rsize == 106 && rdesc[94] == 0x19 && - rdesc[95] == 0x00 && rdesc[96] == 0x29 && - rdesc[97] == 0xff) { - rdesc[94] = 0x35; - rdesc[96] = 0x45; - } return rdesc; } @@ -200,7 +192,7 @@ static const struct hid_device_id ms_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB), .driver_data = MS_PRESENTER }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K), - .driver_data = MS_ERGONOMY | MS_RDESC_3K }, + .driver_data = MS_ERGONOMY }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0), .driver_data = MS_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), diff --git a/trunk/drivers/hid/hid-multitouch.c b/trunk/drivers/hid/hid-multitouch.c index 7867d69f0efe..3eb02b94fc87 100644 --- a/trunk/drivers/hid/hid-multitouch.c +++ b/trunk/drivers/hid/hid-multitouch.c @@ -210,7 +210,8 @@ static struct mt_class mt_classes[] = { }, { .name = MT_CLS_GENERALTOUCH_PWT_TENFINGERS, .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | - MT_QUIRK_SLOT_IS_CONTACTNUMBER + MT_QUIRK_SLOT_IS_CONTACTNUMBER, + .maxcontacts = 10 }, { .name = MT_CLS_FLATFROG, @@ -420,11 +421,11 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, * contact max are global to the report */ td->last_field_index = field->index; return -1; + } case HID_DG_TOUCH: /* Legacy devices use TIPSWITCH and not TOUCH. * Let's just ignore this field. */ return -1; - } /* let hid-input decide for the others */ return 0; diff --git a/trunk/drivers/hid/hidraw.c b/trunk/drivers/hid/hidraw.c index 7c47fc3f7b2b..17d15bb610d1 100644 --- a/trunk/drivers/hid/hidraw.c +++ b/trunk/drivers/hid/hidraw.c @@ -42,6 +42,7 @@ static struct cdev hidraw_cdev; static struct class *hidraw_class; static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES]; static DEFINE_MUTEX(minors_lock); +static void drop_ref(struct hidraw *hid, int exists_bit); static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { @@ -113,7 +114,7 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, __u8 *buf; int ret = 0; - if (!hidraw_table[minor]) { + if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { ret = -ENODEV; goto out; } @@ -261,7 +262,7 @@ static int hidraw_open(struct inode *inode, struct file *file) } mutex_lock(&minors_lock); - if (!hidraw_table[minor]) { + if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { err = -ENODEV; goto out_unlock; } @@ -298,36 +299,12 @@ static int hidraw_open(struct inode *inode, struct file *file) static int hidraw_release(struct inode * inode, struct file * file) { unsigned int minor = iminor(inode); - struct hidraw *dev; struct hidraw_list *list = file->private_data; - int ret; - int i; - - mutex_lock(&minors_lock); - if (!hidraw_table[minor]) { - ret = -ENODEV; - goto unlock; - } + drop_ref(hidraw_table[minor], 0); list_del(&list->node); - dev = hidraw_table[minor]; - if (!--dev->open) { - if (list->hidraw->exist) { - hid_hw_power(dev->hid, PM_HINT_NORMAL); - hid_hw_close(dev->hid); - } else { - kfree(list->hidraw); - } - } - - for (i = 0; i < HIDRAW_BUFFER_SIZE; ++i) - kfree(list->buffer[i].value); kfree(list); - ret = 0; -unlock: - mutex_unlock(&minors_lock); - - return ret; + return 0; } static long hidraw_ioctl(struct file *file, unsigned int cmd, @@ -529,21 +506,7 @@ EXPORT_SYMBOL_GPL(hidraw_connect); void hidraw_disconnect(struct hid_device *hid) { struct hidraw *hidraw = hid->hidraw; - - mutex_lock(&minors_lock); - hidraw->exist = 0; - - device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); - - hidraw_table[hidraw->minor] = NULL; - - if (hidraw->open) { - hid_hw_close(hid); - wake_up_interruptible(&hidraw->wait); - } else { - kfree(hidraw); - } - mutex_unlock(&minors_lock); + drop_ref(hidraw, 1); } EXPORT_SYMBOL_GPL(hidraw_disconnect); @@ -592,3 +555,23 @@ void hidraw_exit(void) unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES); } + +static void drop_ref(struct hidraw *hidraw, int exists_bit) +{ + mutex_lock(&minors_lock); + if (exists_bit) { + hid_hw_close(hidraw->hid); + hidraw->exist = 0; + if (hidraw->open) + wake_up_interruptible(&hidraw->wait); + } else { + --hidraw->open; + } + + if (!hidraw->open && !hidraw->exist) { + device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); + hidraw_table[hidraw->minor] = NULL; + kfree(hidraw); + } + mutex_unlock(&minors_lock); +} diff --git a/trunk/drivers/hv/channel.c b/trunk/drivers/hv/channel.c index f4c3d28cd1fc..406537420fff 100644 --- a/trunk/drivers/hv/channel.c +++ b/trunk/drivers/hv/channel.c @@ -146,14 +146,14 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, if (ret != 0) { err = ret; - goto error0; + goto errorout; } ret = hv_ringbuffer_init( &newchannel->inbound, in, recv_ringbuffer_size); if (ret != 0) { err = ret; - goto error0; + goto errorout; } @@ -168,7 +168,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, if (ret != 0) { err = ret; - goto error0; + goto errorout; } /* Create and init the channel open message */ @@ -177,7 +177,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, GFP_KERNEL); if (!open_info) { err = -ENOMEM; - goto error0; + goto errorout; } init_completion(&open_info->waitevent); @@ -193,7 +193,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, if (userdatalen > MAX_USER_DEFINED_BYTES) { err = -EINVAL; - goto error0; + goto errorout; } if (userdatalen) @@ -208,18 +208,19 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, sizeof(struct vmbus_channel_open_channel)); if (ret != 0) - goto error1; + goto cleanup; t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ); if (t == 0) { err = -ETIMEDOUT; - goto error1; + goto errorout; } if (open_info->response.open_result.status) err = open_info->response.open_result.status; +cleanup: spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); list_del(&open_info->msglistentry); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); @@ -227,12 +228,9 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, kfree(open_info); return err; -error1: - spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_del(&open_info->msglistentry); - spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); - -error0: +errorout: + hv_ringbuffer_cleanup(&newchannel->outbound); + hv_ringbuffer_cleanup(&newchannel->inbound); free_pages((unsigned long)out, get_order(send_ringbuffer_size + recv_ringbuffer_size)); kfree(open_info); diff --git a/trunk/drivers/hwmon/Kconfig b/trunk/drivers/hwmon/Kconfig index 4800d4c2a7b7..c4633de64465 100644 --- a/trunk/drivers/hwmon/Kconfig +++ b/trunk/drivers/hwmon/Kconfig @@ -334,16 +334,6 @@ config SENSORS_DA9052_ADC This driver can also be built as module. If so, the module will be called da9052-hwmon. -config SENSORS_DA9055 - tristate "Dialog Semiconductor DA9055 ADC" - depends on MFD_DA9055 - help - If you say yes here you get support for ADC on the Dialog - Semiconductor DA9055 PMIC. - - This driver can also be built as a module. If so, the module - will be called da9055-hwmon. - config SENSORS_I5K_AMB tristate "FB-DIMM AMB temperature sensor on Intel 5000 series chipsets" depends on PCI @@ -465,7 +455,7 @@ config SENSORS_HIH6130 config SENSORS_CORETEMP tristate "Intel Core/Core2/Atom temperature sensor" - depends on X86 + depends on X86 && PCI help If you say yes here you get support for the temperature sensor inside your CPU. Most of the family 6 CPUs @@ -1116,12 +1106,11 @@ config SENSORS_ADS1015 will be called ads1015. config SENSORS_ADS7828 - tristate "Texas Instruments ADS7828 and compatibles" + tristate "Texas Instruments ADS7828" depends on I2C help - If you say yes here you get support for Texas Instruments ADS7828 and - ADS7830 8-channel A/D converters. ADS7828 resolution is 12-bit, while - it is 8-bit on ADS7830. + If you say yes here you get support for Texas Instruments ADS7828 + 12-bit 8-channel ADC device. This driver can also be built as a module. If so, the module will be called ads7828. diff --git a/trunk/drivers/hwmon/Makefile b/trunk/drivers/hwmon/Makefile index a930f0997d25..8d5fcb5e8e9f 100644 --- a/trunk/drivers/hwmon/Makefile +++ b/trunk/drivers/hwmon/Makefile @@ -44,7 +44,6 @@ obj-$(CONFIG_SENSORS_ASC7621) += asc7621.o obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o -obj-$(CONFIG_SENSORS_DA9055)+= da9055-hwmon.o obj-$(CONFIG_SENSORS_DME1737) += dme1737.o obj-$(CONFIG_SENSORS_DS620) += ds620.o obj-$(CONFIG_SENSORS_DS1621) += ds1621.o diff --git a/trunk/drivers/hwmon/ads7828.c b/trunk/drivers/hwmon/ads7828.c index 409b5c16defb..1f9e8af0f322 100644 --- a/trunk/drivers/hwmon/ads7828.c +++ b/trunk/drivers/hwmon/ads7828.c @@ -1,14 +1,12 @@ /* - * ads7828.c - driver for TI ADS7828 8-channel A/D converter and compatibles + * ads7828.c - lm_sensors driver for ads7828 12-bit 8-channel ADC * (C) 2007 EADS Astrium * * This driver is based on the lm75 and other lm_sensors/hwmon drivers * * Written by Steve Hardy * - * ADS7830 support, by Guillaume Roguez - * - * For further information, see the Documentation/hwmon/ads7828 file. + * Datasheet available at: http://focus.ti.com/lit/ds/symlink/ads7828.pdf * * 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 @@ -25,48 +23,63 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include -#include -#include +#include #include +#include #include -#include +#include +#include +#include +#include #include -#include -#include /* The ADS7828 registers */ -#define ADS7828_NCH 8 /* 8 channels supported */ -#define ADS7828_CMD_SD_SE 0x80 /* Single ended inputs */ -#define ADS7828_CMD_PD1 0x04 /* Internal vref OFF && A/D ON */ -#define ADS7828_CMD_PD3 0x0C /* Internal vref ON && A/D ON */ -#define ADS7828_INT_VREF_MV 2500 /* Internal vref is 2.5V, 2500mV */ -#define ADS7828_EXT_VREF_MV_MIN 50 /* External vref min value 0.05V */ -#define ADS7828_EXT_VREF_MV_MAX 5250 /* External vref max value 5.25V */ - -/* List of supported devices */ -enum ads7828_chips { ads7828, ads7830 }; - -/* Client specific data */ +#define ADS7828_NCH 8 /* 8 channels of 12-bit A-D supported */ +#define ADS7828_CMD_SD_SE 0x80 /* Single ended inputs */ +#define ADS7828_CMD_SD_DIFF 0x00 /* Differential inputs */ +#define ADS7828_CMD_PD0 0x0 /* Power Down between A-D conversions */ +#define ADS7828_CMD_PD1 0x04 /* Internal ref OFF && A-D ON */ +#define ADS7828_CMD_PD2 0x08 /* Internal ref ON && A-D OFF */ +#define ADS7828_CMD_PD3 0x0C /* Internal ref ON && A-D ON */ +#define ADS7828_INT_VREF_MV 2500 /* Internal vref is 2.5V, 2500mV */ + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, + I2C_CLIENT_END }; + +/* Module parameters */ +static bool se_input = 1; /* Default is SE, 0 == diff */ +static bool int_vref = 1; /* Default is internal ref ON */ +static int vref_mv = ADS7828_INT_VREF_MV; /* set if vref != 2.5V */ +module_param(se_input, bool, S_IRUGO); +module_param(int_vref, bool, S_IRUGO); +module_param(vref_mv, int, S_IRUGO); + +/* Global Variables */ +static u8 ads7828_cmd_byte; /* cmd byte without channel bits */ +static unsigned int ads7828_lsb_resol; /* resolution of the ADC sample lsb */ + +/* Each client has this additional data */ struct ads7828_data { struct device *hwmon_dev; - struct mutex update_lock; /* Mutex protecting updates */ - unsigned long last_updated; /* Last updated time (in jiffies) */ - u16 adc_input[ADS7828_NCH]; /* ADS7828_NCH samples */ - bool valid; /* Validity flag */ - bool diff_input; /* Differential input */ - bool ext_vref; /* External voltage reference */ - unsigned int vref_mv; /* voltage reference value */ - u8 cmd_byte; /* Command byte without channel bits */ - unsigned int lsb_resol; /* Resolution of the ADC sample LSB */ - s32 (*read_channel)(const struct i2c_client *client, u8 command); + struct mutex update_lock; /* mutex protect updates */ + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + u16 adc_input[ADS7828_NCH]; /* ADS7828_NCH 12-bit samples */ }; -/* Command byte C2,C1,C0 - see datasheet */ -static inline u8 ads7828_cmd_byte(u8 cmd, int ch) +/* Function declaration - necessary due to function dependencies */ +static int ads7828_detect(struct i2c_client *client, + struct i2c_board_info *info); +static int ads7828_probe(struct i2c_client *client, + const struct i2c_device_id *id); + +static inline u8 channel_cmd_byte(int ch) { - return cmd | (((ch >> 1) | (ch & 0x01) << 2) << 4); + /* cmd byte C2,C1,C0 - see datasheet */ + u8 cmd = (((ch>>1) | (ch&0x01)<<2)<<4); + cmd |= ads7828_cmd_byte; + return cmd; } /* Update data for the device (all 8 channels) */ @@ -83,11 +96,12 @@ static struct ads7828_data *ads7828_update_device(struct device *dev) dev_dbg(&client->dev, "Starting ads7828 update\n"); for (ch = 0; ch < ADS7828_NCH; ch++) { - u8 cmd = ads7828_cmd_byte(data->cmd_byte, ch); - data->adc_input[ch] = data->read_channel(client, cmd); + u8 cmd = channel_cmd_byte(ch); + data->adc_input[ch] = + i2c_smbus_read_word_swapped(client, cmd); } data->last_updated = jiffies; - data->valid = true; + data->valid = 1; } mutex_unlock(&data->update_lock); @@ -96,25 +110,28 @@ static struct ads7828_data *ads7828_update_device(struct device *dev) } /* sysfs callback function */ -static ssize_t ads7828_show_in(struct device *dev, struct device_attribute *da, - char *buf) +static ssize_t show_in(struct device *dev, struct device_attribute *da, + char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct ads7828_data *data = ads7828_update_device(dev); - unsigned int value = DIV_ROUND_CLOSEST(data->adc_input[attr->index] * - data->lsb_resol, 1000); - - return sprintf(buf, "%d\n", value); + /* Print value (in mV as specified in sysfs-interface documentation) */ + return sprintf(buf, "%d\n", (data->adc_input[attr->index] * + ads7828_lsb_resol)/1000); } -static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ads7828_show_in, NULL, 0); -static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ads7828_show_in, NULL, 1); -static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ads7828_show_in, NULL, 2); -static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, ads7828_show_in, NULL, 3); -static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, ads7828_show_in, NULL, 4); -static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, ads7828_show_in, NULL, 5); -static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, ads7828_show_in, NULL, 6); -static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, ads7828_show_in, NULL, 7); +#define in_reg(offset)\ +static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in,\ + NULL, offset) + +in_reg(0); +in_reg(1); +in_reg(2); +in_reg(3); +in_reg(4); +in_reg(5); +in_reg(6); +in_reg(7); static struct attribute *ads7828_attributes[] = { &sensor_dev_attr_in0_input.dev_attr.attr, @@ -135,9 +152,60 @@ static const struct attribute_group ads7828_group = { static int ads7828_remove(struct i2c_client *client) { struct ads7828_data *data = i2c_get_clientdata(client); - hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &ads7828_group); + return 0; +} + +static const struct i2c_device_id ads7828_id[] = { + { "ads7828", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ads7828_id); + +/* This is the driver that will be inserted */ +static struct i2c_driver ads7828_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "ads7828", + }, + .probe = ads7828_probe, + .remove = ads7828_remove, + .id_table = ads7828_id, + .detect = ads7828_detect, + .address_list = normal_i2c, +}; + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int ads7828_detect(struct i2c_client *client, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + int ch; + + /* Check we have a valid client */ + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA)) + return -ENODEV; + + /* + * Now, we do the remaining detection. There is no identification + * dedicated register so attempt to sanity check using knowledge of + * the chip + * - Read from the 8 channel addresses + * - Check the top 4 bits of each result are not set (12 data bits) + */ + for (ch = 0; ch < ADS7828_NCH; ch++) { + u16 in_data; + u8 cmd = channel_cmd_byte(ch); + in_data = i2c_smbus_read_word_swapped(client, cmd); + if (in_data & 0xF000) { + pr_debug("%s : Doesn't look like an ads7828 device\n", + __func__); + return -ENODEV; + } + } + + strlcpy(info->type, "ads7828", I2C_NAME_SIZE); return 0; } @@ -145,7 +213,6 @@ static int ads7828_remove(struct i2c_client *client) static int ads7828_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct ads7828_platform_data *pdata = client->dev.platform_data; struct ads7828_data *data; int err; @@ -154,37 +221,10 @@ static int ads7828_probe(struct i2c_client *client, if (!data) return -ENOMEM; - if (pdata) { - data->diff_input = pdata->diff_input; - data->ext_vref = pdata->ext_vref; - if (data->ext_vref) - data->vref_mv = pdata->vref_mv; - } - - /* Bound Vref with min/max values if it was provided */ - if (data->vref_mv) - data->vref_mv = SENSORS_LIMIT(data->vref_mv, - ADS7828_EXT_VREF_MV_MIN, - ADS7828_EXT_VREF_MV_MAX); - else - data->vref_mv = ADS7828_INT_VREF_MV; - - /* ADS7828 uses 12-bit samples, while ADS7830 is 8-bit */ - if (id->driver_data == ads7828) { - data->lsb_resol = DIV_ROUND_CLOSEST(data->vref_mv * 1000, 4096); - data->read_channel = i2c_smbus_read_word_swapped; - } else { - data->lsb_resol = DIV_ROUND_CLOSEST(data->vref_mv * 1000, 256); - data->read_channel = i2c_smbus_read_byte_data; - } - - data->cmd_byte = data->ext_vref ? ADS7828_CMD_PD1 : ADS7828_CMD_PD3; - if (!data->diff_input) - data->cmd_byte |= ADS7828_CMD_SD_SE; - i2c_set_clientdata(client, data); mutex_init(&data->update_lock); + /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &ads7828_group); if (err) return err; @@ -192,35 +232,38 @@ static int ads7828_probe(struct i2c_client *client, data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { err = PTR_ERR(data->hwmon_dev); - goto error; + goto exit_remove; } return 0; -error: +exit_remove: sysfs_remove_group(&client->dev.kobj, &ads7828_group); return err; } -static const struct i2c_device_id ads7828_device_ids[] = { - { "ads7828", ads7828 }, - { "ads7830", ads7830 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, ads7828_device_ids); +static int __init sensors_ads7828_init(void) +{ + /* Initialize the command byte according to module parameters */ + ads7828_cmd_byte = se_input ? + ADS7828_CMD_SD_SE : ADS7828_CMD_SD_DIFF; + ads7828_cmd_byte |= int_vref ? + ADS7828_CMD_PD3 : ADS7828_CMD_PD1; -static struct i2c_driver ads7828_driver = { - .driver = { - .name = "ads7828", - }, + /* Calculate the LSB resolution */ + ads7828_lsb_resol = (vref_mv*1000)/4096; - .id_table = ads7828_device_ids, - .probe = ads7828_probe, - .remove = ads7828_remove, -}; + return i2c_add_driver(&ads7828_driver); +} -module_i2c_driver(ads7828_driver); +static void __exit sensors_ads7828_exit(void) +{ + i2c_del_driver(&ads7828_driver); +} -MODULE_LICENSE("GPL"); MODULE_AUTHOR("Steve Hardy "); -MODULE_DESCRIPTION("Driver for TI ADS7828 A/D converter and compatibles"); +MODULE_DESCRIPTION("ADS7828 driver"); +MODULE_LICENSE("GPL"); + +module_init(sensors_ads7828_init); +module_exit(sensors_ads7828_exit); diff --git a/trunk/drivers/hwmon/asb100.c b/trunk/drivers/hwmon/asb100.c index 520e5bf4f76d..a227be47149f 100644 --- a/trunk/drivers/hwmon/asb100.c +++ b/trunk/drivers/hwmon/asb100.c @@ -32,7 +32,7 @@ * ASB100-A supports pwm1, while plain ASB100 does not. There is no known * way for the driver to tell which one is there. * - * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * asb100 7 3 1 4 0x31 0x0694 yes no */ diff --git a/trunk/drivers/hwmon/coretemp.c b/trunk/drivers/hwmon/coretemp.c index 24426a785ad5..47b8d84b489d 100644 --- a/trunk/drivers/hwmon/coretemp.c +++ b/trunk/drivers/hwmon/coretemp.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -196,6 +197,14 @@ struct tjmax { }; static const struct tjmax __cpuinitconst tjmax_table[] = { + { "CPU D410", 100000 }, + { "CPU D425", 100000 }, + { "CPU D510", 100000 }, + { "CPU D525", 100000 }, + { "CPU N450", 100000 }, + { "CPU N455", 100000 }, + { "CPU N470", 100000 }, + { "CPU N475", 100000 }, { "CPU 230", 100000 }, /* Model 0x1c, stepping 2 */ { "CPU 330", 125000 }, /* Model 0x1c, stepping 2 */ { "CPU CE4110", 110000 }, /* Model 0x1c, stepping 10 */ @@ -203,28 +212,6 @@ static const struct tjmax __cpuinitconst tjmax_table[] = { { "CPU CE4170", 110000 }, /* Model 0x1c, stepping 10 */ }; -struct tjmax_model { - u8 model; - u8 mask; - int tjmax; -}; - -#define ANY 0xff - -static const struct tjmax_model __cpuinitconst tjmax_model_table[] = { - { 0x1c, 10, 100000 }, /* D4xx, N4xx, D5xx, N5xx */ - { 0x1c, ANY, 90000 }, /* Z5xx, N2xx, possibly others - * Note: Also matches 230 and 330, - * which are covered by tjmax_table - */ - { 0x26, ANY, 90000 }, /* Atom Tunnel Creek (Exx), Lincroft (Z6xx) - * Note: TjMax for E6xxT is 110C, but CPU type - * is undetectable by software - */ - { 0x27, ANY, 90000 }, /* Atom Medfield (Z2460) */ - { 0x36, ANY, 100000 }, /* Atom Cedar Trail/Cedarview (N2xxx, D2xxx) */ -}; - static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) { @@ -235,6 +222,7 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, int usemsr_ee = 1; int err; u32 eax, edx; + struct pci_dev *host_bridge; int i; /* explicit tjmax table entries override heuristics */ @@ -243,18 +231,32 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, return tjmax_table[i].tjmax; } - for (i = 0; i < ARRAY_SIZE(tjmax_model_table); i++) { - const struct tjmax_model *tm = &tjmax_model_table[i]; - if (c->x86_model == tm->model && - (tm->mask == ANY || c->x86_mask == tm->mask)) - return tm->tjmax; - } - /* Early chips have no MSR for TjMax */ if (c->x86_model == 0xf && c->x86_mask < 4) usemsr_ee = 0; + /* Atom CPUs */ + + if (c->x86_model == 0x1c || c->x86_model == 0x26 + || c->x86_model == 0x27) { + usemsr_ee = 0; + + host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); + + if (host_bridge && host_bridge->vendor == PCI_VENDOR_ID_INTEL + && (host_bridge->device == 0xa000 /* NM10 based nettop */ + || host_bridge->device == 0xa010)) /* NM10 based netbook */ + tjmax = 100000; + else + tjmax = 90000; + + pci_dev_put(host_bridge); + } else if (c->x86_model == 0x36) { + usemsr_ee = 0; + tjmax = 100000; + } + if (c->x86_model > 0xe && usemsr_ee) { u8 platform_id; diff --git a/trunk/drivers/hwmon/da9052-hwmon.c b/trunk/drivers/hwmon/da9052-hwmon.c index 19704948801c..b8d01c5f5713 100644 --- a/trunk/drivers/hwmon/da9052-hwmon.c +++ b/trunk/drivers/hwmon/da9052-hwmon.c @@ -60,17 +60,30 @@ static inline int vbbat_reg_to_mV(int value) return DIV_ROUND_CLOSEST(value * 2500, 512); } -static inline int da9052_enable_vddout_channel(struct da9052 *da9052) +static int da9052_enable_vddout_channel(struct da9052 *da9052) { - return da9052_reg_update(da9052, DA9052_ADC_CONT_REG, - DA9052_ADCCONT_AUTOVDDEN, - DA9052_ADCCONT_AUTOVDDEN); + int ret; + + ret = da9052_reg_read(da9052, DA9052_ADC_CONT_REG); + if (ret < 0) + return ret; + + ret |= DA9052_ADCCONT_AUTOVDDEN; + + return da9052_reg_write(da9052, DA9052_ADC_CONT_REG, ret); } -static inline int da9052_disable_vddout_channel(struct da9052 *da9052) +static int da9052_disable_vddout_channel(struct da9052 *da9052) { - return da9052_reg_update(da9052, DA9052_ADC_CONT_REG, - DA9052_ADCCONT_AUTOVDDEN, 0); + int ret; + + ret = da9052_reg_read(da9052, DA9052_ADC_CONT_REG); + if (ret < 0) + return ret; + + ret &= ~DA9052_ADCCONT_AUTOVDDEN; + + return da9052_reg_write(da9052, DA9052_ADC_CONT_REG, ret); } static ssize_t da9052_read_vddout(struct device *dev, diff --git a/trunk/drivers/hwmon/da9055-hwmon.c b/trunk/drivers/hwmon/da9055-hwmon.c deleted file mode 100644 index 9465c050c326..000000000000 --- a/trunk/drivers/hwmon/da9055-hwmon.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * HWMON Driver for Dialog DA9055 - * - * Copyright(c) 2012 Dialog Semiconductor Ltd. - * - * Author: David Dajun Chen - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define DA9055_ADCIN_DIV 102 -#define DA9055_VSYS_DIV 85 - -#define DA9055_ADC_VSYS 0 -#define DA9055_ADC_ADCIN1 1 -#define DA9055_ADC_ADCIN2 2 -#define DA9055_ADC_ADCIN3 3 -#define DA9055_ADC_TJUNC 4 - -struct da9055_hwmon { - struct da9055 *da9055; - struct device *class_device; - struct mutex hwmon_lock; - struct mutex irq_lock; - struct completion done; -}; - -static const char * const input_names[] = { - [DA9055_ADC_VSYS] = "VSYS", - [DA9055_ADC_ADCIN1] = "ADC IN1", - [DA9055_ADC_ADCIN2] = "ADC IN2", - [DA9055_ADC_ADCIN3] = "ADC IN3", - [DA9055_ADC_TJUNC] = "CHIP TEMP", -}; - -static const u8 chan_mux[DA9055_ADC_TJUNC + 1] = { - [DA9055_ADC_VSYS] = DA9055_ADC_MUX_VSYS, - [DA9055_ADC_ADCIN1] = DA9055_ADC_MUX_ADCIN1, - [DA9055_ADC_ADCIN2] = DA9055_ADC_MUX_ADCIN2, - [DA9055_ADC_ADCIN3] = DA9055_ADC_MUX_ADCIN3, - [DA9055_ADC_TJUNC] = DA9055_ADC_MUX_T_SENSE, -}; - -static int da9055_adc_manual_read(struct da9055_hwmon *hwmon, - unsigned char channel) -{ - int ret; - unsigned short calc_data; - unsigned short data; - unsigned char mux_sel; - struct da9055 *da9055 = hwmon->da9055; - - if (channel > DA9055_ADC_TJUNC) - return -EINVAL; - - mutex_lock(&hwmon->irq_lock); - - /* Selects desired MUX for manual conversion */ - mux_sel = chan_mux[channel] | DA9055_ADC_MAN_CONV; - - ret = da9055_reg_write(da9055, DA9055_REG_ADC_MAN, mux_sel); - if (ret < 0) - goto err; - - /* Wait for an interrupt */ - if (!wait_for_completion_timeout(&hwmon->done, - msecs_to_jiffies(500))) { - dev_err(da9055->dev, - "timeout waiting for ADC conversion interrupt\n"); - ret = -ETIMEDOUT; - goto err; - } - - ret = da9055_reg_read(da9055, DA9055_REG_ADC_RES_H); - if (ret < 0) - goto err; - - calc_data = (unsigned short)ret; - data = calc_data << 2; - - ret = da9055_reg_read(da9055, DA9055_REG_ADC_RES_L); - if (ret < 0) - goto err; - - calc_data = (unsigned short)(ret & DA9055_ADC_LSB_MASK); - data |= calc_data; - - ret = data; - -err: - mutex_unlock(&hwmon->irq_lock); - return ret; -} - -static irqreturn_t da9055_auxadc_irq(int irq, void *irq_data) -{ - struct da9055_hwmon *hwmon = irq_data; - - complete(&hwmon->done); - - return IRQ_HANDLED; -} - -/* Conversion function for VSYS and ADCINx */ -static inline int volt_reg_to_mV(int value, int channel) -{ - if (channel == DA9055_ADC_VSYS) - return DIV_ROUND_CLOSEST(value * 1000, DA9055_VSYS_DIV) + 2500; - else - return DIV_ROUND_CLOSEST(value * 1000, DA9055_ADCIN_DIV); -} - -static int da9055_enable_auto_mode(struct da9055 *da9055, int channel) -{ - - return da9055_reg_update(da9055, DA9055_REG_ADC_CONT, 1 << channel, - 1 << channel); - -} - -static int da9055_disable_auto_mode(struct da9055 *da9055, int channel) -{ - - return da9055_reg_update(da9055, DA9055_REG_ADC_CONT, 1 << channel, 0); -} - -static ssize_t da9055_read_auto_ch(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct da9055_hwmon *hwmon = dev_get_drvdata(dev); - int ret, adc; - int channel = to_sensor_dev_attr(devattr)->index; - - mutex_lock(&hwmon->hwmon_lock); - - ret = da9055_enable_auto_mode(hwmon->da9055, channel); - if (ret < 0) - goto hwmon_err; - - usleep_range(10000, 10500); - - adc = da9055_reg_read(hwmon->da9055, DA9055_REG_VSYS_RES + channel); - if (adc < 0) { - ret = adc; - goto hwmon_err_release; - } - - ret = da9055_disable_auto_mode(hwmon->da9055, channel); - if (ret < 0) - goto hwmon_err; - - mutex_unlock(&hwmon->hwmon_lock); - - return sprintf(buf, "%d\n", volt_reg_to_mV(adc, channel)); - -hwmon_err_release: - da9055_disable_auto_mode(hwmon->da9055, channel); -hwmon_err: - mutex_unlock(&hwmon->hwmon_lock); - return ret; -} - -static ssize_t da9055_read_tjunc(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct da9055_hwmon *hwmon = dev_get_drvdata(dev); - int tjunc; - int toffset; - - tjunc = da9055_adc_manual_read(hwmon, DA9055_ADC_TJUNC); - if (tjunc < 0) - return tjunc; - - toffset = da9055_reg_read(hwmon->da9055, DA9055_REG_T_OFFSET); - if (toffset < 0) - return toffset; - - /* - * Degrees celsius = -0.4084 * (ADC_RES - T_OFFSET) + 307.6332 - * T_OFFSET is a trim value used to improve accuracy of the result - */ - return sprintf(buf, "%d\n", DIV_ROUND_CLOSEST(-4084 * (tjunc - toffset) - + 3076332, 10000)); -} - -static ssize_t da9055_hwmon_show_name(struct device *dev, - struct device_attribute *devattr, - char *buf) -{ - return sprintf(buf, "da9055-hwmon\n"); -} - -static ssize_t show_label(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - return sprintf(buf, "%s\n", - input_names[to_sensor_dev_attr(devattr)->index]); -} - -static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, da9055_read_auto_ch, NULL, - DA9055_ADC_VSYS); -static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, show_label, NULL, - DA9055_ADC_VSYS); -static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, da9055_read_auto_ch, NULL, - DA9055_ADC_ADCIN1); -static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, show_label, NULL, - DA9055_ADC_ADCIN1); -static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, da9055_read_auto_ch, NULL, - DA9055_ADC_ADCIN2); -static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, show_label, NULL, - DA9055_ADC_ADCIN2); -static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, da9055_read_auto_ch, NULL, - DA9055_ADC_ADCIN3); -static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, - DA9055_ADC_ADCIN3); - -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, da9055_read_tjunc, NULL, - DA9055_ADC_TJUNC); -static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_label, NULL, - DA9055_ADC_TJUNC); - -static DEVICE_ATTR(name, S_IRUGO, da9055_hwmon_show_name, NULL); - -static struct attribute *da9055_attr[] = { - &dev_attr_name.attr, - &sensor_dev_attr_in0_input.dev_attr.attr, - &sensor_dev_attr_in0_label.dev_attr.attr, - &sensor_dev_attr_in1_input.dev_attr.attr, - &sensor_dev_attr_in1_label.dev_attr.attr, - &sensor_dev_attr_in2_input.dev_attr.attr, - &sensor_dev_attr_in2_label.dev_attr.attr, - &sensor_dev_attr_in3_input.dev_attr.attr, - &sensor_dev_attr_in3_label.dev_attr.attr, - - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp1_label.dev_attr.attr, - NULL -}; - -static const struct attribute_group da9055_attr_group = {.attrs = da9055_attr}; - -static int da9055_hwmon_probe(struct platform_device *pdev) -{ - struct da9055_hwmon *hwmon; - int hwmon_irq, ret; - - hwmon = devm_kzalloc(&pdev->dev, sizeof(struct da9055_hwmon), - GFP_KERNEL); - if (!hwmon) - return -ENOMEM; - - mutex_init(&hwmon->hwmon_lock); - mutex_init(&hwmon->irq_lock); - - init_completion(&hwmon->done); - hwmon->da9055 = dev_get_drvdata(pdev->dev.parent); - - platform_set_drvdata(pdev, hwmon); - - hwmon_irq = platform_get_irq_byname(pdev, "HWMON"); - if (hwmon_irq < 0) - return hwmon_irq; - - hwmon_irq = regmap_irq_get_virq(hwmon->da9055->irq_data, hwmon_irq); - if (hwmon_irq < 0) - return hwmon_irq; - - ret = devm_request_threaded_irq(&pdev->dev, hwmon_irq, - NULL, da9055_auxadc_irq, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, - "adc-irq", hwmon); - if (ret != 0) { - dev_err(hwmon->da9055->dev, "DA9055 ADC IRQ failed ret=%d\n", - ret); - return ret; - } - - ret = sysfs_create_group(&pdev->dev.kobj, &da9055_attr_group); - if (ret) - return ret; - - hwmon->class_device = hwmon_device_register(&pdev->dev); - if (IS_ERR(hwmon->class_device)) { - ret = PTR_ERR(hwmon->class_device); - goto err; - } - - return 0; - -err: - sysfs_remove_group(&pdev->dev.kobj, &da9055_attr_group); - return ret; -} - -static int da9055_hwmon_remove(struct platform_device *pdev) -{ - struct da9055_hwmon *hwmon = platform_get_drvdata(pdev); - - sysfs_remove_group(&pdev->dev.kobj, &da9055_attr_group); - hwmon_device_unregister(hwmon->class_device); - - return 0; -} - -static struct platform_driver da9055_hwmon_driver = { - .probe = da9055_hwmon_probe, - .remove = da9055_hwmon_remove, - .driver = { - .name = "da9055-hwmon", - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(da9055_hwmon_driver); - -MODULE_AUTHOR("David Dajun Chen "); -MODULE_DESCRIPTION("DA9055 HWMON driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:da9055-hwmon"); diff --git a/trunk/drivers/hwmon/fam15h_power.c b/trunk/drivers/hwmon/fam15h_power.c index 34ab2a8f9654..68ad7d255512 100644 --- a/trunk/drivers/hwmon/fam15h_power.c +++ b/trunk/drivers/hwmon/fam15h_power.c @@ -2,7 +2,7 @@ * fam15h_power.c - AMD Family 15h processor power monitoring * * Copyright (c) 2011 Advanced Micro Devices, Inc. - * Author: Andreas Herrmann + * Author: Andreas Herrmann * * * This driver is free software; you can redistribute it and/or @@ -28,12 +28,9 @@ #include MODULE_DESCRIPTION("AMD Family 15h CPU processor power monitor"); -MODULE_AUTHOR("Andreas Herrmann "); +MODULE_AUTHOR("Andreas Herrmann "); MODULE_LICENSE("GPL"); -/* Family 16h Northbridge's function 4 PCI ID */ -#define PCI_DEVICE_ID_AMD_16H_NB_F4 0x1534 - /* D18F3 */ #define REG_NORTHBRIDGE_CAP 0xe8 @@ -251,7 +248,6 @@ static void __devexit fam15h_power_remove(struct pci_dev *pdev) static DEFINE_PCI_DEVICE_TABLE(fam15h_power_id_table) = { { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }, - { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) }, {} }; MODULE_DEVICE_TABLE(pci, fam15h_power_id_table); diff --git a/trunk/drivers/hwmon/gpio-fan.c b/trunk/drivers/hwmon/gpio-fan.c index 1381a2e3bbd4..36509ae32083 100644 --- a/trunk/drivers/hwmon/gpio-fan.c +++ b/trunk/drivers/hwmon/gpio-fan.c @@ -630,9 +630,7 @@ static struct platform_driver gpio_fan_driver = { .driver = { .name = "gpio-fan", .pm = GPIO_FAN_PM, -#ifdef CONFIG_OF_GPIO .of_match_table = of_match_ptr(of_gpio_fan_match), -#endif }, }; diff --git a/trunk/drivers/hwmon/ina2xx.c b/trunk/drivers/hwmon/ina2xx.c index 8e7158c3ad2f..2b726346f8fa 100644 --- a/trunk/drivers/hwmon/ina2xx.c +++ b/trunk/drivers/hwmon/ina2xx.c @@ -302,8 +302,19 @@ static struct i2c_driver ina2xx_driver = { .id_table = ina2xx_id, }; -module_i2c_driver(ina2xx_driver); +static int __init ina2xx_init(void) +{ + return i2c_add_driver(&ina2xx_driver); +} + +static void __exit ina2xx_exit(void) +{ + i2c_del_driver(&ina2xx_driver); +} MODULE_AUTHOR("Lothar Felten "); MODULE_DESCRIPTION("ina2xx driver"); MODULE_LICENSE("GPL"); + +module_init(ina2xx_init); +module_exit(ina2xx_exit); diff --git a/trunk/drivers/hwmon/w83627ehf.c b/trunk/drivers/hwmon/w83627ehf.c index de3c7e04c3b5..1821b7423d5b 100644 --- a/trunk/drivers/hwmon/w83627ehf.c +++ b/trunk/drivers/hwmon/w83627ehf.c @@ -2083,7 +2083,6 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) mutex_init(&data->lock); mutex_init(&data->update_lock); data->name = w83627ehf_device_names[sio_data->kind]; - data->bank = 0xff; /* Force initial bank selection */ platform_set_drvdata(pdev, data); /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */ diff --git a/trunk/drivers/hwmon/w83627hf.c b/trunk/drivers/hwmon/w83627hf.c index af1589908709..5b1a6a666441 100644 --- a/trunk/drivers/hwmon/w83627hf.c +++ b/trunk/drivers/hwmon/w83627hf.c @@ -25,7 +25,7 @@ /* * Supports following chips: * - * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC) * w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) * w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC) diff --git a/trunk/drivers/hwmon/w83781d.c b/trunk/drivers/hwmon/w83781d.c index 20f11d31da40..5a5046d94c3e 100644 --- a/trunk/drivers/hwmon/w83781d.c +++ b/trunk/drivers/hwmon/w83781d.c @@ -24,7 +24,7 @@ /* * Supports following chips: * - * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * as99127f 7 3 0 3 0x31 0x12c3 yes no * as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no * w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes diff --git a/trunk/drivers/hwmon/w83791d.c b/trunk/drivers/hwmon/w83791d.c index ed397c645198..39ab7bcc616e 100644 --- a/trunk/drivers/hwmon/w83791d.c +++ b/trunk/drivers/hwmon/w83791d.c @@ -22,7 +22,7 @@ /* * Supports following chips: * - * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * w83791d 10 5 5 3 0x71 0x5ca3 yes no * * The w83791d chip appears to be part way between the 83781d and the diff --git a/trunk/drivers/hwmon/w83792d.c b/trunk/drivers/hwmon/w83792d.c index 301942d08453..053645279f38 100644 --- a/trunk/drivers/hwmon/w83792d.c +++ b/trunk/drivers/hwmon/w83792d.c @@ -31,7 +31,7 @@ /* * Supports following chips: * - * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * w83792d 9 7 7 3 0x7a 0x5ca3 yes no */ diff --git a/trunk/drivers/hwmon/w83l786ng.c b/trunk/drivers/hwmon/w83l786ng.c index 79710bcac2f7..f0e8286c3c70 100644 --- a/trunk/drivers/hwmon/w83l786ng.c +++ b/trunk/drivers/hwmon/w83l786ng.c @@ -20,7 +20,7 @@ /* * Supports following chips: * - * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * w83l786ng 3 2 2 2 0x7b 0x5ca3 yes no */ diff --git a/trunk/drivers/i2c/Makefile b/trunk/drivers/i2c/Makefile index 1722f50f2473..beee6b2d361d 100644 --- a/trunk/drivers/i2c/Makefile +++ b/trunk/drivers/i2c/Makefile @@ -8,7 +8,6 @@ obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o obj-$(CONFIG_I2C_MUX) += i2c-mux.o obj-y += algos/ busses/ muxes/ -obj-$(CONFIG_I2C_STUB) += i2c-stub.o ccflags-$(CONFIG_I2C_DEBUG_CORE) := -DDEBUG CFLAGS_i2c-core.o := -Wno-deprecated-declarations diff --git a/trunk/drivers/i2c/busses/Kconfig b/trunk/drivers/i2c/busses/Kconfig index e9df4612b7eb..65dd599a0262 100644 --- a/trunk/drivers/i2c/busses/Kconfig +++ b/trunk/drivers/i2c/busses/Kconfig @@ -81,6 +81,7 @@ config I2C_I801 tristate "Intel 82801 (ICH/PCH)" depends on PCI select CHECK_SIGNATURE if X86 && DMI + select GPIOLIB if I2C_MUX help If you say yes to this option, support will be included for the Intel 801 family of mainboard I2C interfaces. Specifically, the following diff --git a/trunk/drivers/i2c/busses/Makefile b/trunk/drivers/i2c/busses/Makefile index 395b516ffa08..2d33d62952c1 100644 --- a/trunk/drivers/i2c/busses/Makefile +++ b/trunk/drivers/i2c/busses/Makefile @@ -85,6 +85,7 @@ obj-$(CONFIG_I2C_ACORN) += i2c-acorn.o obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o +obj-$(CONFIG_I2C_STUB) += i2c-stub.o obj-$(CONFIG_SCx200_ACB) += scx200_acb.o obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o diff --git a/trunk/drivers/i2c/busses/i2c-at91.c b/trunk/drivers/i2c/busses/i2c-at91.c index c02bf208084f..aa59a254be2c 100644 --- a/trunk/drivers/i2c/busses/i2c-at91.c +++ b/trunk/drivers/i2c/busses/i2c-at91.c @@ -39,7 +39,6 @@ #define AT91_TWI_STOP 0x0002 /* Send a Stop Condition */ #define AT91_TWI_MSEN 0x0004 /* Master Transfer Enable */ #define AT91_TWI_SVDIS 0x0020 /* Slave Transfer Disable */ -#define AT91_TWI_QUICK 0x0040 /* SMBus quick command */ #define AT91_TWI_SWRST 0x0080 /* Software Reset */ #define AT91_TWI_MMR 0x0004 /* Master Mode Register */ @@ -213,11 +212,7 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev) INIT_COMPLETION(dev->cmd_complete); dev->transfer_status = 0; - - if (!dev->buf_len) { - at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_QUICK); - at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP); - } else if (dev->msg->flags & I2C_M_RD) { + if (dev->msg->flags & I2C_M_RD) { unsigned start_flags = AT91_TWI_START; if (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY) { diff --git a/trunk/drivers/i2c/busses/i2c-i801.c b/trunk/drivers/i2c/busses/i2c-i801.c index 6abc00d59881..37793156bd93 100644 --- a/trunk/drivers/i2c/busses/i2c-i801.c +++ b/trunk/drivers/i2c/busses/i2c-i801.c @@ -82,8 +82,7 @@ #include #include -#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ - defined CONFIG_DMI +#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE #include #include #include @@ -193,8 +192,7 @@ struct i801_priv { int len; u8 *data; -#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ - defined CONFIG_DMI +#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE const struct i801_mux_config *mux_drvdata; struct platform_device *mux_pdev; #endif @@ -923,8 +921,7 @@ static void __init input_apanel_init(void) {} static void __devinit i801_probe_optional_slaves(struct i801_priv *priv) {} #endif /* CONFIG_X86 && CONFIG_DMI */ -#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ - defined CONFIG_DMI +#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE static struct i801_mux_config i801_mux_config_asus_z8_d12 = { .gpio_chip = "gpio_ich", .values = { 0x02, 0x03 }, @@ -1062,7 +1059,7 @@ static unsigned int __devinit i801_get_adapter_class(struct i801_priv *priv) id = dmi_first_match(mux_dmi_table); if (id) { - /* Remove branch classes from trunk */ + /* Remove from branch classes from trunk */ mux_config = id->driver_data; for (i = 0; i < mux_config->n_values; i++) class &= ~mux_config->classes[i]; diff --git a/trunk/drivers/i2c/busses/i2c-mxs.c b/trunk/drivers/i2c/busses/i2c-mxs.c index 0670da79ee5e..1f58197062cf 100644 --- a/trunk/drivers/i2c/busses/i2c-mxs.c +++ b/trunk/drivers/i2c/busses/i2c-mxs.c @@ -1,7 +1,7 @@ /* * Freescale MXS I2C bus driver * - * Copyright (C) 2011-2012 Wolfram Sang, Pengutronix e.K. + * Copyright (C) 2011 Wolfram Sang, Pengutronix e.K. * * based on a (non-working) driver which was: * @@ -35,6 +35,10 @@ #define DRIVER_NAME "mxs-i2c" +static bool use_pioqueue; +module_param(use_pioqueue, bool, 0); +MODULE_PARM_DESC(use_pioqueue, "Use PIOQUEUE mode for transfer instead of DMA"); + #define MXS_I2C_CTRL0 (0x00) #define MXS_I2C_CTRL0_SET (0x04) @@ -71,6 +75,23 @@ MXS_I2C_CTRL1_SLAVE_STOP_IRQ | \ MXS_I2C_CTRL1_SLAVE_IRQ) +#define MXS_I2C_QUEUECTRL (0x60) +#define MXS_I2C_QUEUECTRL_SET (0x64) +#define MXS_I2C_QUEUECTRL_CLR (0x68) + +#define MXS_I2C_QUEUECTRL_QUEUE_RUN 0x20 +#define MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE 0x04 + +#define MXS_I2C_QUEUESTAT (0x70) +#define MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY 0x00002000 +#define MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK 0x0000001F + +#define MXS_I2C_QUEUECMD (0x80) + +#define MXS_I2C_QUEUEDATA (0x90) + +#define MXS_I2C_DATA (0xa0) + #define MXS_CMD_I2C_SELECT (MXS_I2C_CTRL0_RETAIN_CLOCK | \ MXS_I2C_CTRL0_PRE_SEND_START | \ @@ -132,6 +153,7 @@ struct mxs_i2c_dev { const struct mxs_i2c_speed_config *speed; /* DMA support components */ + bool dma_mode; int dma_channel; struct dma_chan *dmach; struct mxs_dma_data dma_data; @@ -150,6 +172,99 @@ static void mxs_i2c_reset(struct mxs_i2c_dev *i2c) writel(i2c->speed->timing2, i2c->regs + MXS_I2C_TIMING2); writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET); + if (i2c->dma_mode) + writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE, + i2c->regs + MXS_I2C_QUEUECTRL_CLR); + else + writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE, + i2c->regs + MXS_I2C_QUEUECTRL_SET); +} + +static void mxs_i2c_pioq_setup_read(struct mxs_i2c_dev *i2c, u8 addr, int len, + int flags) +{ + u32 data; + + writel(MXS_CMD_I2C_SELECT, i2c->regs + MXS_I2C_QUEUECMD); + + data = (addr << 1) | I2C_SMBUS_READ; + writel(data, i2c->regs + MXS_I2C_DATA); + + data = MXS_CMD_I2C_READ | MXS_I2C_CTRL0_XFER_COUNT(len) | flags; + writel(data, i2c->regs + MXS_I2C_QUEUECMD); +} + +static void mxs_i2c_pioq_setup_write(struct mxs_i2c_dev *i2c, + u8 addr, u8 *buf, int len, int flags) +{ + u32 data; + int i, shifts_left; + + data = MXS_CMD_I2C_WRITE | MXS_I2C_CTRL0_XFER_COUNT(len + 1) | flags; + writel(data, i2c->regs + MXS_I2C_QUEUECMD); + + /* + * We have to copy the slave address (u8) and buffer (arbitrary number + * of u8) into the data register (u32). To achieve that, the u8 are put + * into the MSBs of 'data' which is then shifted for the next u8. When + * appropriate, 'data' is written to MXS_I2C_DATA. So, the first u32 + * looks like this: + * + * 3 2 1 0 + * 10987654|32109876|54321098|76543210 + * --------+--------+--------+-------- + * buffer+2|buffer+1|buffer+0|slave_addr + */ + + data = ((addr << 1) | I2C_SMBUS_WRITE) << 24; + + for (i = 0; i < len; i++) { + data >>= 8; + data |= buf[i] << 24; + if ((i & 3) == 2) + writel(data, i2c->regs + MXS_I2C_DATA); + } + + /* Write out the remaining bytes if any */ + shifts_left = 24 - (i & 3) * 8; + if (shifts_left) + writel(data >> shifts_left, i2c->regs + MXS_I2C_DATA); +} + +/* + * TODO: should be replaceable with a waitqueue and RD_QUEUE_IRQ (setting the + * rd_threshold to 1). Couldn't get this to work, though. + */ +static int mxs_i2c_wait_for_data(struct mxs_i2c_dev *i2c) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(1000); + + while (readl(i2c->regs + MXS_I2C_QUEUESTAT) + & MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY) { + if (time_after(jiffies, timeout)) + return -ETIMEDOUT; + cond_resched(); + } + + return 0; +} + +static int mxs_i2c_finish_read(struct mxs_i2c_dev *i2c, u8 *buf, int len) +{ + u32 uninitialized_var(data); + int i; + + for (i = 0; i < len; i++) { + if ((i & 3) == 0) { + if (mxs_i2c_wait_for_data(i2c)) + return -ETIMEDOUT; + data = readl(i2c->regs + MXS_I2C_QUEUEDATA); + } + buf[i] = data & 0xff; + data >>= 8; + } + + return 0; } static void mxs_i2c_dma_finish(struct mxs_i2c_dev *i2c) @@ -287,14 +402,12 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap, select_init_dma_fail: dma_unmap_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE); select_init_pio_fail: - dmaengine_terminate_all(i2c->dmach); return -EINVAL; /* Write failpath. */ write_init_dma_fail: dma_unmap_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE); write_init_pio_fail: - dmaengine_terminate_all(i2c->dmach); return -EINVAL; } @@ -319,17 +432,39 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, init_completion(&i2c->cmd_complete); i2c->cmd_err = 0; - ret = mxs_i2c_dma_setup_xfer(adap, msg, flags); - if (ret) - return ret; + if (i2c->dma_mode) { + ret = mxs_i2c_dma_setup_xfer(adap, msg, flags); + if (ret) + return ret; + } else { + if (msg->flags & I2C_M_RD) { + mxs_i2c_pioq_setup_read(i2c, msg->addr, + msg->len, flags); + } else { + mxs_i2c_pioq_setup_write(i2c, msg->addr, msg->buf, + msg->len, flags); + } + + writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, + i2c->regs + MXS_I2C_QUEUECTRL_SET); + } ret = wait_for_completion_timeout(&i2c->cmd_complete, msecs_to_jiffies(1000)); if (ret == 0) goto timeout; + if (!i2c->dma_mode && !i2c->cmd_err && (msg->flags & I2C_M_RD)) { + ret = mxs_i2c_finish_read(i2c, msg->buf, msg->len); + if (ret) + goto timeout; + } + if (i2c->cmd_err == -ENXIO) mxs_i2c_reset(i2c); + else + writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, + i2c->regs + MXS_I2C_QUEUECTRL_CLR); dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err); @@ -337,7 +472,8 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, timeout: dev_dbg(i2c->dev, "Timeout!\n"); - mxs_i2c_dma_finish(i2c); + if (i2c->dma_mode) + mxs_i2c_dma_finish(i2c); mxs_i2c_reset(i2c); return -ETIMEDOUT; } @@ -366,6 +502,7 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) { struct mxs_i2c_dev *i2c = dev_id; u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK; + bool is_last_cmd; if (!stat) return IRQ_NONE; @@ -378,6 +515,14 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) /* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */ i2c->cmd_err = -EIO; + if (!i2c->dma_mode) { + is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) & + MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0; + + if (is_last_cmd || i2c->cmd_err) + complete(&i2c->cmd_complete); + } + writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR); return IRQ_HANDLED; @@ -410,6 +555,15 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c) struct device_node *node = dev->of_node; int ret; + /* + * The MXS I2C DMA mode is prefered and enabled by default. + * The PIO mode is still supported, but should be used only + * for debuging purposes etc. + */ + i2c->dma_mode = !use_pioqueue; + if (!i2c->dma_mode) + dev_info(dev, "Using PIOQUEUE mode for I2C transfers!\n"); + /* * TODO: This is a temporary solution and should be changed * to use generic DMA binding later when the helpers get in. @@ -417,8 +571,8 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c) ret = of_property_read_u32(node, "fsl,i2c-dma-channel", &i2c->dma_channel); if (ret) { - dev_err(dev, "Failed to get DMA channel!\n"); - return -ENODEV; + dev_warn(dev, "Failed to get DMA channel, using PIOQUEUE!\n"); + i2c->dma_mode = 0; } ret = of_property_read_u32(node, "clock-frequency", &speed); @@ -480,13 +634,15 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev) } /* Setup the DMA */ - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - i2c->dma_data.chan_irq = dmairq; - i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c); - if (!i2c->dmach) { - dev_err(dev, "Failed to request dma\n"); - return -ENODEV; + if (i2c->dma_mode) { + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + i2c->dma_data.chan_irq = dmairq; + i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c); + if (!i2c->dmach) { + dev_err(dev, "Failed to request dma\n"); + return -ENODEV; + } } platform_set_drvdata(pdev, i2c); diff --git a/trunk/drivers/i2c/busses/i2c-nomadik.c b/trunk/drivers/i2c/busses/i2c-nomadik.c index 02c3115a2dfa..698d7acb0f08 100644 --- a/trunk/drivers/i2c/busses/i2c-nomadik.c +++ b/trunk/drivers/i2c/busses/i2c-nomadik.c @@ -644,11 +644,7 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, pm_runtime_get_sync(&dev->adev->dev); - status = clk_prepare_enable(dev->clk); - if (status) { - dev_err(&dev->adev->dev, "can't prepare_enable clock\n"); - goto out_clk; - } + clk_enable(dev->clk); status = init_hw(dev); if (status) @@ -675,8 +671,7 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, } out: - clk_disable_unprepare(dev->clk); -out_clk: + clk_disable(dev->clk); pm_runtime_put_sync(&dev->adev->dev); dev->busy = false; diff --git a/trunk/drivers/i2c/busses/i2c-omap.c b/trunk/drivers/i2c/busses/i2c-omap.c index 3525c9e62cb0..db31eaed6ea5 100644 --- a/trunk/drivers/i2c/busses/i2c-omap.c +++ b/trunk/drivers/i2c/busses/i2c-omap.c @@ -43,6 +43,7 @@ #include #include #include +#include /* I2C controller revisions */ #define OMAP_I2C_OMAP1_REV_2 0x20 @@ -186,9 +187,8 @@ struct omap_i2c_dev { int reg_shift; /* bit shift for I2C register addresses */ struct completion cmd_complete; struct resource *ioarea; - u32 latency; /* maximum mpu wkup latency */ - void (*set_mpu_wkup_lat)(struct device *dev, - long latency); + u32 latency; /* maximum MPU wkup latency */ + struct pm_qos_request pm_qos_request; u32 speed; /* Speed of bus in kHz */ u32 dtrev; /* extra revision from DT */ u32 flags; @@ -494,9 +494,7 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx) dev->b_hw = 1; /* Enable hardware fixes */ /* calculate wakeup latency constraint for MPU */ - if (dev->set_mpu_wkup_lat != NULL) - dev->latency = (1000000 * dev->threshold) / - (1000 * dev->speed / 8); + dev->latency = (1000000 * dev->threshold) / (1000 * dev->speed / 8); } /* @@ -524,9 +522,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, dev->buf = msg->buf; dev->buf_len = msg->len; - /* make sure writes to dev->buf_len are ordered */ - barrier(); - omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len); /* Clear the FIFO Buffers */ @@ -584,6 +579,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, */ timeout = wait_for_completion_timeout(&dev->cmd_complete, OMAP_I2C_TIMEOUT); + dev->buf_len = 0; if (timeout == 0) { dev_err(dev->dev, "controller timed out\n"); omap_i2c_init(dev); @@ -633,8 +629,16 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) if (r < 0) goto out; - if (dev->set_mpu_wkup_lat != NULL) - dev->set_mpu_wkup_lat(dev->dev, dev->latency); + /* + * When waiting for completion of a i2c transfer, we need to + * set a wake up latency constraint for the MPU. This is to + * ensure quick enough wakeup from idle, when transfer + * completes. + */ + if (dev->latency) + pm_qos_add_request(&dev->pm_qos_request, + PM_QOS_CPU_DMA_LATENCY, + dev->latency); for (i = 0; i < num; i++) { r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1))); @@ -642,8 +646,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) break; } - if (dev->set_mpu_wkup_lat != NULL) - dev->set_mpu_wkup_lat(dev->dev, -1); + if (dev->latency) + pm_qos_remove_request(&dev->pm_qos_request); if (r == 0) r = num; @@ -1100,7 +1104,6 @@ omap_i2c_probe(struct platform_device *pdev) } else if (pdata != NULL) { dev->speed = pdata->clkrate; dev->flags = pdata->flags; - dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat; dev->dtrev = pdata->rev; } @@ -1156,9 +1159,8 @@ omap_i2c_probe(struct platform_device *pdev) dev->b_hw = 1; /* Enable hardware fixes */ /* calculate wakeup latency constraint for MPU */ - if (dev->set_mpu_wkup_lat != NULL) - dev->latency = (1000000 * dev->fifo_size) / - (1000 * dev->speed / 8); + dev->latency = (1000000 * dev->fifo_size) / + (1000 * dev->speed / 8); } /* reset ASAP, clearing any IRQs */ diff --git a/trunk/drivers/i2c/busses/i2c-s3c2410.c b/trunk/drivers/i2c/busses/i2c-s3c2410.c index 9d902725bac9..3e0335f1fc60 100644 --- a/trunk/drivers/i2c/busses/i2c-s3c2410.c +++ b/trunk/drivers/i2c/busses/i2c-s3c2410.c @@ -806,7 +806,6 @@ static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c) dev_err(i2c->dev, "invalid gpio[%d]: %d\n", idx, gpio); goto free_gpio; } - i2c->gpios[idx] = gpio; ret = gpio_request(gpio, "i2c-bus"); if (ret) { diff --git a/trunk/drivers/i2c/i2c-stub.c b/trunk/drivers/i2c/busses/i2c-stub.c similarity index 75% rename from trunk/drivers/i2c/i2c-stub.c rename to trunk/drivers/i2c/busses/i2c-stub.c index d0a9c590c3cd..b1b3447942c9 100644 --- a/trunk/drivers/i2c/i2c-stub.c +++ b/trunk/drivers/i2c/busses/i2c-stub.c @@ -2,7 +2,7 @@ i2c-stub.c - I2C/SMBus chip emulator Copyright (c) 2004 Mark M. Hoffman - Copyright (C) 2007, 2012 Jean Delvare + Copyright (C) 2007 Jean Delvare 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 @@ -51,8 +51,8 @@ struct stub_chip { static struct stub_chip *stub_chips; /* Return negative errno on error. */ -static s32 stub_xfer(struct i2c_adapter *adap, u16 addr, unsigned short flags, - char read_write, u8 command, int size, union i2c_smbus_data *data) +static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, + char read_write, u8 command, int size, union i2c_smbus_data * data) { s32 ret; int i, len; @@ -78,14 +78,14 @@ static s32 stub_xfer(struct i2c_adapter *adap, u16 addr, unsigned short flags, case I2C_SMBUS_BYTE: if (read_write == I2C_SMBUS_WRITE) { chip->pointer = command; - dev_dbg(&adap->dev, - "smbus byte - addr 0x%02x, wrote 0x%02x.\n", - addr, command); + dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, " + "wrote 0x%02x.\n", + addr, command); } else { data->byte = chip->words[chip->pointer++] & 0xff; - dev_dbg(&adap->dev, - "smbus byte - addr 0x%02x, read 0x%02x.\n", - addr, data->byte); + dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, " + "read 0x%02x.\n", + addr, data->byte); } ret = 0; @@ -95,14 +95,14 @@ static s32 stub_xfer(struct i2c_adapter *adap, u16 addr, unsigned short flags, if (read_write == I2C_SMBUS_WRITE) { chip->words[command] &= 0xff00; chip->words[command] |= data->byte; - dev_dbg(&adap->dev, - "smbus byte data - addr 0x%02x, wrote 0x%02x at 0x%02x.\n", - addr, data->byte, command); + dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, " + "wrote 0x%02x at 0x%02x.\n", + addr, data->byte, command); } else { data->byte = chip->words[command] & 0xff; - dev_dbg(&adap->dev, - "smbus byte data - addr 0x%02x, read 0x%02x at 0x%02x.\n", - addr, data->byte, command); + dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, " + "read 0x%02x at 0x%02x.\n", + addr, data->byte, command); } chip->pointer = command + 1; @@ -112,14 +112,14 @@ static s32 stub_xfer(struct i2c_adapter *adap, u16 addr, unsigned short flags, case I2C_SMBUS_WORD_DATA: if (read_write == I2C_SMBUS_WRITE) { chip->words[command] = data->word; - dev_dbg(&adap->dev, - "smbus word data - addr 0x%02x, wrote 0x%04x at 0x%02x.\n", - addr, data->word, command); + dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, " + "wrote 0x%04x at 0x%02x.\n", + addr, data->word, command); } else { data->word = chip->words[command]; - dev_dbg(&adap->dev, - "smbus word data - addr 0x%02x, read 0x%04x at 0x%02x.\n", - addr, data->word, command); + dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, " + "read 0x%04x at 0x%02x.\n", + addr, data->word, command); } ret = 0; @@ -132,17 +132,17 @@ static s32 stub_xfer(struct i2c_adapter *adap, u16 addr, unsigned short flags, chip->words[command + i] &= 0xff00; chip->words[command + i] |= data->block[1 + i]; } - dev_dbg(&adap->dev, - "i2c block data - addr 0x%02x, wrote %d bytes at 0x%02x.\n", - addr, len, command); + dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, " + "wrote %d bytes at 0x%02x.\n", + addr, len, command); } else { for (i = 0; i < len; i++) { data->block[1 + i] = chip->words[command + i] & 0xff; } - dev_dbg(&adap->dev, - "i2c block data - addr 0x%02x, read %d bytes at 0x%02x.\n", - addr, len, command); + dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, " + "read %d bytes at 0x%02x.\n", + addr, len, command); } ret = 0; @@ -179,24 +179,25 @@ static int __init i2c_stub_init(void) int i, ret; if (!chip_addr[0]) { - pr_err("i2c-stub: Please specify a chip address\n"); + printk(KERN_ERR "i2c-stub: Please specify a chip address\n"); return -ENODEV; } for (i = 0; i < MAX_CHIPS && chip_addr[i]; i++) { if (chip_addr[i] < 0x03 || chip_addr[i] > 0x77) { - pr_err("i2c-stub: Invalid chip address 0x%02x\n", - chip_addr[i]); + printk(KERN_ERR "i2c-stub: Invalid chip address " + "0x%02x\n", chip_addr[i]); return -EINVAL; } - pr_info("i2c-stub: Virtual chip at 0x%02x\n", chip_addr[i]); + printk(KERN_INFO "i2c-stub: Virtual chip at 0x%02x\n", + chip_addr[i]); } /* Allocate memory for all chips at once */ stub_chips = kzalloc(i * sizeof(struct stub_chip), GFP_KERNEL); if (!stub_chips) { - pr_err("i2c-stub: Out of memory\n"); + printk(KERN_ERR "i2c-stub: Out of memory\n"); return -ENOMEM; } @@ -218,3 +219,4 @@ MODULE_LICENSE("GPL"); module_init(i2c_stub_init); module_exit(i2c_stub_exit); + diff --git a/trunk/drivers/i2c/busses/i2c-tegra.c b/trunk/drivers/i2c/busses/i2c-tegra.c index dcea77bf6f50..f981ac4e6783 100644 --- a/trunk/drivers/i2c/busses/i2c-tegra.c +++ b/trunk/drivers/i2c/busses/i2c-tegra.c @@ -742,7 +742,7 @@ static int __devinit tegra_i2c_probe(struct platform_device *pdev) } ret = devm_request_irq(&pdev->dev, i2c_dev->irq, - tegra_i2c_isr, 0, dev_name(&pdev->dev), i2c_dev); + tegra_i2c_isr, 0, pdev->name, i2c_dev); if (ret) { dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq); return ret; diff --git a/trunk/drivers/i2c/muxes/i2c-mux-pinctrl.c b/trunk/drivers/i2c/muxes/i2c-mux-pinctrl.c index 7fa5b24b16db..5f097f309b9f 100644 --- a/trunk/drivers/i2c/muxes/i2c-mux-pinctrl.c +++ b/trunk/drivers/i2c/muxes/i2c-mux-pinctrl.c @@ -169,7 +169,7 @@ static int __devinit i2c_mux_pinctrl_probe(struct platform_device *pdev) mux->busses = devm_kzalloc(&pdev->dev, sizeof(mux->busses) * mux->pdata->bus_count, GFP_KERNEL); - if (!mux->busses) { + if (!mux->states) { dev_err(&pdev->dev, "Cannot allocate busses\n"); ret = -ENOMEM; goto err; diff --git a/trunk/drivers/iio/Kconfig b/trunk/drivers/iio/Kconfig index fc937aca71fb..6e3f143fc71d 100644 --- a/trunk/drivers/iio/Kconfig +++ b/trunk/drivers/iio/Kconfig @@ -62,6 +62,7 @@ source "drivers/iio/frequency/Kconfig" source "drivers/iio/dac/Kconfig" source "drivers/iio/common/Kconfig" source "drivers/iio/gyro/Kconfig" +source "drivers/iio/light/Kconfig" source "drivers/iio/magnetometer/Kconfig" endif # IIO diff --git a/trunk/drivers/iio/Makefile b/trunk/drivers/iio/Makefile index 761f2b65ac52..f7fa3c0867b4 100644 --- a/trunk/drivers/iio/Makefile +++ b/trunk/drivers/iio/Makefile @@ -18,4 +18,5 @@ obj-y += frequency/ obj-y += dac/ obj-y += common/ obj-y += gyro/ +obj-y += light/ obj-y += magnetometer/ diff --git a/trunk/drivers/infiniband/hw/cxgb4/mem.c b/trunk/drivers/infiniband/hw/cxgb4/mem.c index afd81790ab3c..57e07c61ace2 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/mem.c +++ b/trunk/drivers/infiniband/hw/cxgb4/mem.c @@ -468,7 +468,7 @@ struct ib_mr *c4iw_register_phys_mem(struct ib_pd *pd, ret = alloc_pbl(mhp, npages); if (ret) { kfree(page_list); - goto err; + goto err_pbl; } ret = write_pbl(&mhp->rhp->rdev, page_list, mhp->attr.pbl_addr, diff --git a/trunk/drivers/infiniband/hw/mlx4/alias_GUID.c b/trunk/drivers/infiniband/hw/mlx4/alias_GUID.c index 2f215b93db6b..d2fb38d43571 100644 --- a/trunk/drivers/infiniband/hw/mlx4/alias_GUID.c +++ b/trunk/drivers/infiniband/hw/mlx4/alias_GUID.c @@ -107,7 +107,7 @@ static __be64 get_cached_alias_guid(struct mlx4_ib_dev *dev, int port, int index { if (index >= NUM_ALIAS_GUID_PER_PORT) { pr_err("%s: ERROR: asked for index:%d\n", __func__, index); - return (__force __be64) -1; + return (__force __be64) ((u64) 0xFFFFFFFFFFFFFFFFUL); } return *(__be64 *)&dev->sriov.demux[port - 1].guid_cache[index]; } diff --git a/trunk/drivers/infiniband/hw/mlx4/mad.c b/trunk/drivers/infiniband/hw/mlx4/mad.c index 0a903c129f0a..21a794152d15 100644 --- a/trunk/drivers/infiniband/hw/mlx4/mad.c +++ b/trunk/drivers/infiniband/hw/mlx4/mad.c @@ -409,45 +409,38 @@ int mlx4_ib_find_real_gid(struct ib_device *ibdev, u8 port, __be64 guid) } -static int find_slave_port_pkey_ix(struct mlx4_ib_dev *dev, int slave, - u8 port, u16 pkey, u16 *ix) +static int get_pkey_phys_indices(struct mlx4_ib_dev *ibdev, u8 port, u8 ph_pkey_ix, + u8 *full_pk_ix, u8 *partial_pk_ix, + int *is_full_member) { - int i, ret; - u8 unassigned_pkey_ix, pkey_ix, partial_ix = 0xFF; - u16 slot_pkey; - - if (slave == mlx4_master_func_num(dev->dev)) - return ib_find_cached_pkey(&dev->ib_dev, port, pkey, ix); - - unassigned_pkey_ix = dev->dev->phys_caps.pkey_phys_table_len[port] - 1; + u16 search_pkey; + int fm; + int err = 0; + u16 pk; - for (i = 0; i < dev->dev->caps.pkey_table_len[port]; i++) { - if (dev->pkeys.virt2phys_pkey[slave][port - 1][i] == unassigned_pkey_ix) - continue; - - pkey_ix = dev->pkeys.virt2phys_pkey[slave][port - 1][i]; + err = ib_get_cached_pkey(&ibdev->ib_dev, port, ph_pkey_ix, &search_pkey); + if (err) + return err; - ret = ib_get_cached_pkey(&dev->ib_dev, port, pkey_ix, &slot_pkey); - if (ret) - continue; - if ((slot_pkey & 0x7FFF) == (pkey & 0x7FFF)) { - if (slot_pkey & 0x8000) { - *ix = (u16) pkey_ix; - return 0; - } else { - /* take first partial pkey index found */ - if (partial_ix == 0xFF) - partial_ix = pkey_ix; - } - } + fm = (search_pkey & 0x8000) ? 1 : 0; + if (fm) { + *full_pk_ix = ph_pkey_ix; + search_pkey &= 0x7FFF; + } else { + *partial_pk_ix = ph_pkey_ix; + search_pkey |= 0x8000; } - if (partial_ix < 0xFF) { - *ix = (u16) partial_ix; - return 0; - } + if (ib_find_exact_cached_pkey(&ibdev->ib_dev, port, search_pkey, &pk)) + pk = 0xFFFF; - return -EINVAL; + if (fm) + *partial_pk_ix = (pk & 0xFF); + else + *full_pk_ix = (pk & 0xFF); + + *is_full_member = fm; + return err; } int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, @@ -465,8 +458,10 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, unsigned tun_tx_ix = 0; int dqpn; int ret = 0; + int i; + int is_full_member = 0; u16 tun_pkey_ix; - u16 cached_pkey; + u8 ph_pkey_ix, full_pk_ix = 0, partial_pk_ix = 0; if (dest_qpt > IB_QPT_GSI) return -EINVAL; @@ -486,17 +481,27 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, else tun_qp = &tun_ctx->qp[1]; - /* compute P_Key index to put in tunnel header for slave */ + /* compute pkey index for slave */ + /* get physical pkey -- virtualized Dom0 pkey to phys*/ if (dest_qpt) { - u16 pkey_ix; - ret = ib_get_cached_pkey(&dev->ib_dev, port, wc->pkey_index, &cached_pkey); + ph_pkey_ix = + dev->pkeys.virt2phys_pkey[mlx4_master_func_num(dev->dev)][port - 1][wc->pkey_index]; + + /* now, translate this to the slave pkey index */ + ret = get_pkey_phys_indices(dev, port, ph_pkey_ix, &full_pk_ix, + &partial_pk_ix, &is_full_member); if (ret) return -EINVAL; - ret = find_slave_port_pkey_ix(dev, slave, port, cached_pkey, &pkey_ix); - if (ret) + for (i = 0; i < dev->dev->caps.pkey_table_len[port]; i++) { + if ((dev->pkeys.virt2phys_pkey[slave][port - 1][i] == full_pk_ix) || + (is_full_member && + (dev->pkeys.virt2phys_pkey[slave][port - 1][i] == partial_pk_ix))) + break; + } + if (i == dev->dev->caps.pkey_table_len[port]) return -EINVAL; - tun_pkey_ix = pkey_ix; + tun_pkey_ix = i; } else tun_pkey_ix = dev->pkeys.virt2phys_pkey[slave][port - 1][0]; diff --git a/trunk/drivers/infiniband/hw/mlx4/mcg.c b/trunk/drivers/infiniband/hw/mlx4/mcg.c index 25b2cdff00f8..3c3b54c3fdd9 100644 --- a/trunk/drivers/infiniband/hw/mlx4/mcg.c +++ b/trunk/drivers/infiniband/hw/mlx4/mcg.c @@ -233,8 +233,7 @@ static int send_mad_to_slave(int slave, struct mlx4_ib_demux_ctx *ctx, ib_query_ah(dev->sm_ah[ctx->port - 1], &ah_attr); - if (ib_find_cached_pkey(&dev->ib_dev, ctx->port, IB_DEFAULT_PKEY_FULL, &wc.pkey_index)) - return -EINVAL; + wc.pkey_index = 0; wc.sl = 0; wc.dlid_path_bits = 0; wc.port_num = ctx->port; @@ -1075,6 +1074,10 @@ static void _mlx4_ib_mcg_port_cleanup(struct mlx4_ib_demux_ctx *ctx, int destroy unsigned long end; int count; + if (ctx->flushing) + return; + + ctx->flushing = 1; for (i = 0; i < MAX_VFS; ++i) clean_vf_mcast(ctx, i); @@ -1104,6 +1107,9 @@ static void _mlx4_ib_mcg_port_cleanup(struct mlx4_ib_demux_ctx *ctx, int destroy force_clean_group(group); } mutex_unlock(&ctx->mcg_table_lock); + + if (!destroy_wq) + ctx->flushing = 0; } struct clean_work { @@ -1117,7 +1123,6 @@ static void mcg_clean_task(struct work_struct *work) struct clean_work *cw = container_of(work, struct clean_work, work); _mlx4_ib_mcg_port_cleanup(cw->ctx, cw->destroy_wq); - cw->ctx->flushing = 0; kfree(cw); } @@ -1125,20 +1130,13 @@ void mlx4_ib_mcg_port_cleanup(struct mlx4_ib_demux_ctx *ctx, int destroy_wq) { struct clean_work *work; - if (ctx->flushing) - return; - - ctx->flushing = 1; - if (destroy_wq) { _mlx4_ib_mcg_port_cleanup(ctx, destroy_wq); - ctx->flushing = 0; return; } work = kmalloc(sizeof *work, GFP_KERNEL); if (!work) { - ctx->flushing = 0; mcg_warn("failed allocating work for cleanup\n"); return; } diff --git a/trunk/drivers/input/evdev.c b/trunk/drivers/input/evdev.c index f0f8928b3c8a..6ae2ac47c9c8 100644 --- a/trunk/drivers/input/evdev.c +++ b/trunk/drivers/input/evdev.c @@ -292,6 +292,7 @@ static int evdev_release(struct inode *inode, struct file *file) kfree(client); evdev_close_device(evdev); + put_device(&evdev->dev); return 0; } @@ -330,6 +331,7 @@ static int evdev_open(struct inode *inode, struct file *file) file->private_data = client; nonseekable_open(inode, file); + get_device(&evdev->dev); return 0; err_free_client: @@ -999,7 +1001,6 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, goto err_free_evdev; cdev_init(&evdev->cdev, &evdev_fops); - evdev->cdev.kobj.parent = &evdev->dev.kobj; error = cdev_add(&evdev->cdev, evdev->dev.devt, 1); if (error) goto err_unregister_handle; diff --git a/trunk/drivers/input/input-mt.c b/trunk/drivers/input/input-mt.c index 1abbc170d8b7..c0ec7d42c3be 100644 --- a/trunk/drivers/input/input-mt.c +++ b/trunk/drivers/input/input-mt.c @@ -26,14 +26,10 @@ static void copy_abs(struct input_dev *dev, unsigned int dst, unsigned int src) * input_mt_init_slots() - initialize MT input slots * @dev: input device supporting MT events and finger tracking * @num_slots: number of slots used by the device - * @flags: mt tasks to handle in core * * This function allocates all necessary memory for MT slot handling * in the input device, prepares the ABS_MT_SLOT and * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers. - * Depending on the flags set, it also performs pointer emulation and - * frame synchronization. - * * May be called repeatedly. Returns -EINVAL if attempting to * reinitialize with a different number of slots. */ diff --git a/trunk/drivers/input/joydev.c b/trunk/drivers/input/joydev.c index f362883c94e3..b62b5891f399 100644 --- a/trunk/drivers/input/joydev.c +++ b/trunk/drivers/input/joydev.c @@ -243,6 +243,7 @@ static int joydev_release(struct inode *inode, struct file *file) kfree(client); joydev_close_device(joydev); + put_device(&joydev->dev); return 0; } @@ -269,6 +270,7 @@ static int joydev_open(struct inode *inode, struct file *file) file->private_data = client; nonseekable_open(inode, file); + get_device(&joydev->dev); return 0; err_free_client: @@ -856,7 +858,6 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, goto err_free_joydev; cdev_init(&joydev->cdev, &joydev_fops); - joydev->cdev.kobj.parent = &joydev->dev.kobj; error = cdev_add(&joydev->cdev, joydev->dev.devt, 1); if (error) goto err_unregister_handle; diff --git a/trunk/drivers/input/keyboard/Kconfig b/trunk/drivers/input/keyboard/Kconfig index de0874054e9f..b4b65af8612a 100644 --- a/trunk/drivers/input/keyboard/Kconfig +++ b/trunk/drivers/input/keyboard/Kconfig @@ -335,7 +335,6 @@ config KEYBOARD_LOCOMO config KEYBOARD_LPC32XX tristate "LPC32XX matrix key scanner support" depends on ARCH_LPC32XX && OF - select INPUT_MATRIXKMAP help Say Y here if you want to use NXP LPC32XX SoC key scanner interface, connected to a key matrix. diff --git a/trunk/drivers/input/keyboard/pxa27x_keypad.c b/trunk/drivers/input/keyboard/pxa27x_keypad.c index cad9d5dd5973..803ff6fe021e 100644 --- a/trunk/drivers/input/keyboard/pxa27x_keypad.c +++ b/trunk/drivers/input/keyboard/pxa27x_keypad.c @@ -368,9 +368,6 @@ static void pxa27x_keypad_config(struct pxa27x_keypad *keypad) unsigned int mask = 0, direct_key_num = 0; unsigned long kpc = 0; - /* clear pending interrupt bit */ - keypad_readl(KPC); - /* enable matrix keys with automatic scan */ if (pdata->matrix_key_rows && pdata->matrix_key_cols) { kpc |= KPC_ASACT | KPC_MIE | KPC_ME | KPC_MS_ALL; diff --git a/trunk/drivers/input/matrix-keymap.c b/trunk/drivers/input/matrix-keymap.c index d88d9be1d1b7..443ad64b7f2a 100644 --- a/trunk/drivers/input/matrix-keymap.c +++ b/trunk/drivers/input/matrix-keymap.c @@ -23,7 +23,6 @@ #include #include #include -#include #include static bool matrix_keypad_map_key(struct input_dev *input_dev, @@ -162,5 +161,3 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, return 0; } EXPORT_SYMBOL(matrix_keypad_build_keymap); - -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/input/misc/xen-kbdfront.c b/trunk/drivers/input/misc/xen-kbdfront.c index 6f7d99013031..02ca8680ea5b 100644 --- a/trunk/drivers/input/misc/xen-kbdfront.c +++ b/trunk/drivers/input/misc/xen-kbdfront.c @@ -311,6 +311,7 @@ static void xenkbd_backend_changed(struct xenbus_device *dev, case XenbusStateReconfiguring: case XenbusStateReconfigured: case XenbusStateUnknown: + case XenbusStateClosed: break; case XenbusStateInitWait: @@ -349,10 +350,6 @@ static void xenkbd_backend_changed(struct xenbus_device *dev, break; - case XenbusStateClosed: - if (dev->state == XenbusStateClosed) - break; - /* Missed the backend's CLOSING state -- fallthrough */ case XenbusStateClosing: xenbus_frontend_closed(dev); break; diff --git a/trunk/drivers/input/mouse/bcm5974.c b/trunk/drivers/input/mouse/bcm5974.c index 2baff1b79a55..3a78f235fa3e 100644 --- a/trunk/drivers/input/mouse/bcm5974.c +++ b/trunk/drivers/input/mouse/bcm5974.c @@ -84,10 +84,6 @@ #define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI 0x0262 #define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO 0x0263 #define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS 0x0264 -/* MacbookPro10,2 (unibody, October 2012) */ -#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI 0x0259 -#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a -#define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b #define BCM5974_DEVICE(prod) { \ .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ @@ -141,10 +137,6 @@ static const struct usb_device_id bcm5974_table[] = { BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI), BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ISO), BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_JIS), - /* MacbookPro10,2 */ - BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI), - BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO), - BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS), /* Terminating entry */ {} }; @@ -387,19 +379,6 @@ static const struct bcm5974_config bcm5974_config_table[] = { { SN_COORD, -150, 6730 }, { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } }, - { - USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI, - USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO, - USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS, - HAS_INTEGRATED_BUTTON, - 0x84, sizeof(struct bt_data), - 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, - { SN_PRESSURE, 0, 300 }, - { SN_WIDTH, 0, 2048 }, - { SN_COORD, -4750, 5280 }, - { SN_COORD, -150, 6730 }, - { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } - }, {} }; diff --git a/trunk/drivers/input/mousedev.c b/trunk/drivers/input/mousedev.c index 4c842c320c2e..a1b4c37956b2 100644 --- a/trunk/drivers/input/mousedev.c +++ b/trunk/drivers/input/mousedev.c @@ -12,8 +12,8 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define MOUSEDEV_MINOR_BASE 32 -#define MOUSEDEV_MINORS 31 -#define MOUSEDEV_MIX 63 +#define MOUSEDEV_MINORS 32 +#define MOUSEDEV_MIX 31 #include #include @@ -523,6 +523,7 @@ static int mousedev_release(struct inode *inode, struct file *file) kfree(client); mousedev_close_device(mousedev); + put_device(&mousedev->dev); return 0; } @@ -557,6 +558,7 @@ static int mousedev_open(struct inode *inode, struct file *file) file->private_data = client; nonseekable_open(inode, file); + get_device(&mousedev->dev); return 0; err_free_client: @@ -890,7 +892,6 @@ static struct mousedev *mousedev_create(struct input_dev *dev, } cdev_init(&mousedev->cdev, &mousedev_fops); - mousedev->cdev.kobj.parent = &mousedev->dev.kobj; error = cdev_add(&mousedev->cdev, mousedev->dev.devt, 1); if (error) goto err_unregister_handle; diff --git a/trunk/drivers/input/tablet/wacom_sys.c b/trunk/drivers/input/tablet/wacom_sys.c index 858ad446de91..9edf9806cff9 100644 --- a/trunk/drivers/input/tablet/wacom_sys.c +++ b/trunk/drivers/input/tablet/wacom_sys.c @@ -391,7 +391,7 @@ static int wacom_parse_hid(struct usb_interface *intf, features->pktlen = WACOM_PKGLEN_TPC2FG; } - if (features->type == MTSCREEN || features->type == WACOM_24HDT) + if (features->type == MTSCREEN) features->pktlen = WACOM_PKGLEN_MTOUCH; if (features->type == BAMBOO_PT) { @@ -402,14 +402,6 @@ static int wacom_parse_hid(struct usb_interface *intf, features->x_max = get_unaligned_le16(&report[i + 8]); i += 15; - } else if (features->type == WACOM_24HDT) { - features->x_max = - get_unaligned_le16(&report[i + 3]); - features->x_phy = - get_unaligned_le16(&report[i + 8]); - features->unit = report[i - 1]; - features->unitExpo = report[i - 3]; - i += 12; } else { features->x_max = get_unaligned_le16(&report[i + 3]); @@ -442,12 +434,6 @@ static int wacom_parse_hid(struct usb_interface *intf, features->y_phy = get_unaligned_le16(&report[i + 6]); i += 7; - } else if (type == WACOM_24HDT) { - features->y_max = - get_unaligned_le16(&report[i + 3]); - features->y_phy = - get_unaligned_le16(&report[i - 2]); - i += 7; } else if (type == BAMBOO_PT) { features->y_phy = get_unaligned_le16(&report[i + 3]); @@ -555,9 +541,6 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat /* MT Tablet PC touch */ return wacom_set_device_mode(intf, 3, 4, 4); } - else if (features->type == WACOM_24HDT) { - return wacom_set_device_mode(intf, 18, 3, 2); - } } else if (features->device_type == BTN_TOOL_PEN) { if (features->type <= BAMBOO_PT && features->type != WIRELESS) { return wacom_set_device_mode(intf, 2, 2, 2); @@ -630,30 +613,6 @@ struct wacom_usbdev_data { static LIST_HEAD(wacom_udev_list); static DEFINE_MUTEX(wacom_udev_list_lock); -static struct usb_device *wacom_get_sibling(struct usb_device *dev, int vendor, int product) -{ - int port1; - struct usb_device *sibling; - - if (vendor == 0 && product == 0) - return dev; - - if (dev->parent == NULL) - return NULL; - - usb_hub_for_each_child(dev->parent, port1, sibling) { - struct usb_device_descriptor *d; - if (sibling == NULL) - continue; - - d = &sibling->descriptor; - if (d->idVendor == vendor && d->idProduct == product) - return sibling; - } - - return NULL; -} - static struct wacom_usbdev_data *wacom_get_usbdev_data(struct usb_device *dev) { struct wacom_usbdev_data *data; @@ -1298,19 +1257,13 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); if (features->quirks & WACOM_QUIRK_MULTI_INPUT) { - struct usb_device *other_dev; - /* Append the device type to the name */ strlcat(wacom_wac->name, features->device_type == BTN_TOOL_PEN ? " Pen" : " Finger", sizeof(wacom_wac->name)); - - other_dev = wacom_get_sibling(dev, features->oVid, features->oPid); - if (other_dev == NULL || wacom_get_usbdev_data(other_dev) == NULL) - other_dev = dev; - error = wacom_add_shared_data(wacom_wac, other_dev); + error = wacom_add_shared_data(wacom_wac, dev); if (error) goto fail3; } diff --git a/trunk/drivers/input/tablet/wacom_wac.c b/trunk/drivers/input/tablet/wacom_wac.c index 0a67031ffc13..c3468c8dbd89 100644 --- a/trunk/drivers/input/tablet/wacom_wac.c +++ b/trunk/drivers/input/tablet/wacom_wac.c @@ -806,70 +806,6 @@ static int find_slot_from_contactid(struct wacom_wac *wacom, int contactid) return -1; } -static int int_dist(int x1, int y1, int x2, int y2) -{ - int x = x2 - x1; - int y = y2 - y1; - - return int_sqrt(x*x + y*y); -} - -static int wacom_24hdt_irq(struct wacom_wac *wacom) -{ - struct input_dev *input = wacom->input; - char *data = wacom->data; - int i; - int current_num_contacts = data[61]; - int contacts_to_send = 0; - - /* - * First packet resets the counter since only the first - * packet in series will have non-zero current_num_contacts. - */ - if (current_num_contacts) - wacom->num_contacts_left = current_num_contacts; - - /* There are at most 4 contacts per packet */ - contacts_to_send = min(4, wacom->num_contacts_left); - - for (i = 0; i < contacts_to_send; i++) { - int offset = (WACOM_BYTES_PER_24HDT_PACKET * i) + 1; - bool touch = data[offset] & 0x1 && !wacom->shared->stylus_in_proximity; - int id = data[offset + 1]; - int slot = find_slot_from_contactid(wacom, id); - - if (slot < 0) - continue; - input_mt_slot(input, slot); - input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); - - if (touch) { - int t_x = le16_to_cpup((__le16 *)&data[offset + 2]); - int c_x = le16_to_cpup((__le16 *)&data[offset + 4]); - int t_y = le16_to_cpup((__le16 *)&data[offset + 6]); - int c_y = le16_to_cpup((__le16 *)&data[offset + 8]); - int w = le16_to_cpup((__le16 *)&data[offset + 10]); - int h = le16_to_cpup((__le16 *)&data[offset + 12]); - - input_report_abs(input, ABS_MT_POSITION_X, t_x); - input_report_abs(input, ABS_MT_POSITION_Y, t_y); - input_report_abs(input, ABS_MT_TOUCH_MAJOR, min(w,h)); - input_report_abs(input, ABS_MT_WIDTH_MAJOR, min(w, h) + int_dist(t_x, t_y, c_x, c_y)); - input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h)); - input_report_abs(input, ABS_MT_ORIENTATION, w > h); - } - wacom->slots[slot] = touch ? id : -1; - } - - input_mt_report_pointer_emulation(input, true); - - wacom->num_contacts_left -= contacts_to_send; - if (wacom->num_contacts_left <= 0) - wacom->num_contacts_left = 0; - - return 1; -} - static int wacom_mt_touch(struct wacom_wac *wacom) { struct input_dev *input = wacom->input; @@ -1319,10 +1255,6 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) sync = wacom_intuos_irq(wacom_wac); break; - case WACOM_24HDT: - sync = wacom_24hdt_irq(wacom_wac); - break; - case INTUOS5S: case INTUOS5: case INTUOS5L: @@ -1408,8 +1340,7 @@ void wacom_setup_device_quirks(struct wacom_features *features) /* these device have multiple inputs */ if (features->type >= WIRELESS || - (features->type >= INTUOS5S && features->type <= INTUOS5L) || - (features->oVid && features->oPid)) + (features->type >= INTUOS5S && features->type <= INTUOS5L)) features->quirks |= WACOM_QUIRK_MULTI_INPUT; /* quirk for bamboo touch with 2 low res touches */ @@ -1518,9 +1449,6 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); - - __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); - wacom_setup_cintiq(wacom_wac); break; @@ -1647,15 +1575,6 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, __set_bit(INPUT_PROP_POINTER, input_dev->propbit); break; - case WACOM_24HDT: - if (features->device_type == BTN_TOOL_FINGER) { - input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0); - input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, features->x_max, 0, 0); - input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, 0, features->y_max, 0, 0); - input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0); - } - /* fall through */ - case MTSCREEN: if (features->device_type == BTN_TOOL_FINGER) { wacom_wac->slots = kmalloc(features->touch_max * @@ -1950,11 +1869,8 @@ static const struct wacom_features wacom_features_0xF4 = { "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xF8 = - { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, /* Pen */ - 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 }; -static const struct wacom_features wacom_features_0xF6 = - { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */ - .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10 }; + { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, + 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0x3F = { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, 63, CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; @@ -2197,7 +2113,6 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0x47) }, { USB_DEVICE_WACOM(0xF4) }, { USB_DEVICE_WACOM(0xF8) }, - { USB_DEVICE_WACOM(0xF6) }, { USB_DEVICE_WACOM(0xFA) }, { USB_DEVICE_LENOVO(0x6004) }, { } diff --git a/trunk/drivers/input/tablet/wacom_wac.h b/trunk/drivers/input/tablet/wacom_wac.h index 345f1e76975e..96c185cc301e 100644 --- a/trunk/drivers/input/tablet/wacom_wac.h +++ b/trunk/drivers/input/tablet/wacom_wac.h @@ -29,7 +29,6 @@ /* wacom data size per MT contact */ #define WACOM_BYTES_PER_MT_PACKET 11 -#define WACOM_BYTES_PER_24HDT_PACKET 14 /* device IDs */ #define STYLUS_DEVICE_ID 0x02 @@ -50,7 +49,6 @@ #define WACOM_REPORT_TPCHID 15 #define WACOM_REPORT_TPCST 16 #define WACOM_REPORT_TPC1FGE 18 -#define WACOM_REPORT_24HDT 1 /* device quirks */ #define WACOM_QUIRK_MULTI_INPUT 0x0001 @@ -83,7 +81,6 @@ enum { WACOM_MO, WIRELESS, BAMBOO_PT, - WACOM_24HDT, TABLETPC, /* add new TPC below */ TABLETPCE, TABLETPC2FG, @@ -112,8 +109,6 @@ struct wacom_features { int distance_fuzz; unsigned quirks; unsigned touch_max; - int oVid; - int oPid; }; struct wacom_shared { diff --git a/trunk/drivers/input/touchscreen/Kconfig b/trunk/drivers/input/touchscreen/Kconfig index f7668b24c378..1ba232cbc09d 100644 --- a/trunk/drivers/input/touchscreen/Kconfig +++ b/trunk/drivers/input/touchscreen/Kconfig @@ -239,7 +239,7 @@ config TOUCHSCREEN_EETI config TOUCHSCREEN_EGALAX tristate "EETI eGalax multi-touch panel support" - depends on I2C && OF + depends on I2C help Say Y here to enable support for I2C connected EETI eGalax multi-touch panels. diff --git a/trunk/drivers/input/touchscreen/ads7846.c b/trunk/drivers/input/touchscreen/ads7846.c index 78e5d9ab0ba7..f02028ec3db6 100644 --- a/trunk/drivers/input/touchscreen/ads7846.c +++ b/trunk/drivers/input/touchscreen/ads7846.c @@ -955,8 +955,7 @@ static int ads7846_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume); -static int __devinit ads7846_setup_pendown(struct spi_device *spi, - struct ads7846 *ts) +static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads7846 *ts) { struct ads7846_platform_data *pdata = spi->dev.platform_data; int err; @@ -982,9 +981,6 @@ static int __devinit ads7846_setup_pendown(struct spi_device *spi, ts->gpio_pendown = pdata->gpio_pendown; - if (pdata->gpio_pendown_debounce) - gpio_set_debounce(pdata->gpio_pendown, - pdata->gpio_pendown_debounce); } else { dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); return -EINVAL; diff --git a/trunk/drivers/input/touchscreen/egalax_ts.c b/trunk/drivers/input/touchscreen/egalax_ts.c index 13fa62fdfb0b..c1e3460f1195 100644 --- a/trunk/drivers/input/touchscreen/egalax_ts.c +++ b/trunk/drivers/input/touchscreen/egalax_ts.c @@ -28,7 +28,6 @@ #include #include #include -#include /* * Mouse Mode: some panel may configure the controller to mouse mode, @@ -123,17 +122,9 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id) /* wake up controller by an falling edge of interrupt gpio. */ static int egalax_wake_up_device(struct i2c_client *client) { - struct device_node *np = client->dev.of_node; - int gpio; + int gpio = irq_to_gpio(client->irq); int ret; - if (!np) - return -ENODEV; - - gpio = of_get_named_gpio(np, "wakeup-gpios", 0); - if (!gpio_is_valid(gpio)) - return -ENODEV; - ret = gpio_request(gpio, "egalax_irq"); if (ret < 0) { dev_err(&client->dev, @@ -190,11 +181,7 @@ static int __devinit egalax_ts_probe(struct i2c_client *client, ts->input_dev = input_dev; /* controller may be in sleep, wake it up. */ - error = egalax_wake_up_device(client); - if (error) { - dev_err(&client->dev, "Failed to wake up the controller\n"); - goto err_free_dev; - } + egalax_wake_up_device(client); ret = egalax_firmware_version(client); if (ret < 0) { @@ -287,17 +274,11 @@ static int egalax_ts_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, egalax_ts_resume); -static struct of_device_id egalax_ts_dt_ids[] = { - { .compatible = "eeti,egalax_ts" }, - { /* sentinel */ } -}; - static struct i2c_driver egalax_ts_driver = { .driver = { .name = "egalax_ts", .owner = THIS_MODULE, .pm = &egalax_ts_pm_ops, - .of_match_table = of_match_ptr(egalax_ts_dt_ids), }, .id_table = egalax_ts_id, .probe = egalax_ts_probe, diff --git a/trunk/drivers/input/touchscreen/tsc40.c b/trunk/drivers/input/touchscreen/tsc40.c index eb96f168fb9d..63209aaa55f0 100644 --- a/trunk/drivers/input/touchscreen/tsc40.c +++ b/trunk/drivers/input/touchscreen/tsc40.c @@ -107,6 +107,7 @@ static int tsc_connect(struct serio *serio, struct serio_driver *drv) __set_bit(BTN_TOUCH, input_dev->keybit); input_set_abs_params(ptsc->dev, ABS_X, 0, 0x3ff, 0, 0); input_set_abs_params(ptsc->dev, ABS_Y, 0, 0x3ff, 0, 0); + input_set_abs_params(ptsc->dev, ABS_PRESSURE, 0, 0, 0, 0); serio_set_drvdata(serio, ptsc); diff --git a/trunk/drivers/iommu/amd_iommu_init.c b/trunk/drivers/iommu/amd_iommu_init.c index 81837b0710a9..18b0d99bd4d6 100644 --- a/trunk/drivers/iommu/amd_iommu_init.c +++ b/trunk/drivers/iommu/amd_iommu_init.c @@ -1599,46 +1599,21 @@ static void __init free_on_init_error(void) #endif } -/* SB IOAPIC is always on this device in AMD systems */ -#define IOAPIC_SB_DEVID ((0x00 << 8) | PCI_DEVFN(0x14, 0)) - static bool __init check_ioapic_information(void) { - bool ret, has_sb_ioapic; int idx; - has_sb_ioapic = false; - ret = false; - for (idx = 0; idx < nr_ioapics; idx++) { - int devid, id = mpc_ioapic_id(idx); - - devid = get_ioapic_devid(id); - if (devid < 0) { - pr_err(FW_BUG "AMD-Vi: IOAPIC[%d] not in IVRS table\n", id); - ret = false; - } else if (devid == IOAPIC_SB_DEVID) { - has_sb_ioapic = true; - ret = true; - } - } + int id = mpc_ioapic_id(idx); - if (!has_sb_ioapic) { - /* - * We expect the SB IOAPIC to be listed in the IVRS - * table. The system timer is connected to the SB IOAPIC - * and if we don't have it in the list the system will - * panic at boot time. This situation usually happens - * when the BIOS is buggy and provides us the wrong - * device id for the IOAPIC in the system. - */ - pr_err(FW_BUG "AMD-Vi: No southbridge IOAPIC found in IVRS table\n"); + if (get_ioapic_devid(id) < 0) { + pr_err(FW_BUG "AMD-Vi: IO-APIC[%d] not in IVRS table\n", id); + pr_err("AMD-Vi: Disabling interrupt remapping due to BIOS Bug\n"); + return false; + } } - if (!ret) - pr_err("AMD-Vi: Disabling interrupt remapping due to BIOS Bug(s)\n"); - - return ret; + return true; } static void __init free_dma_resources(void) diff --git a/trunk/drivers/iommu/intel-iommu.c b/trunk/drivers/iommu/intel-iommu.c index 0badfa48b32b..d4a4cd445cab 100644 --- a/trunk/drivers/iommu/intel-iommu.c +++ b/trunk/drivers/iommu/intel-iommu.c @@ -4108,7 +4108,7 @@ static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to) static int intel_iommu_add_device(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); - struct pci_dev *bridge, *dma_pdev = NULL; + struct pci_dev *bridge, *dma_pdev; struct iommu_group *group; int ret; @@ -4122,7 +4122,7 @@ static int intel_iommu_add_device(struct device *dev) dma_pdev = pci_get_domain_bus_and_slot( pci_domain_nr(pdev->bus), bridge->subordinate->number, 0); - if (!dma_pdev) + else dma_pdev = pci_dev_get(bridge); } else dma_pdev = pci_dev_get(pdev); diff --git a/trunk/drivers/iommu/tegra-smmu.c b/trunk/drivers/iommu/tegra-smmu.c index c0f7a4266263..0b4d62e0c645 100644 --- a/trunk/drivers/iommu/tegra-smmu.c +++ b/trunk/drivers/iommu/tegra-smmu.c @@ -200,7 +200,7 @@ enum { #define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12) #define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22) -#define SMMU_PDN_TO_ADDR(pdn) ((pdn) << 22) +#define SMMU_PDN_TO_ADDR(addr) ((pdn) << 22) #define _READABLE (1 << SMMU_PTB_DATA_ASID_READABLE_SHIFT) #define _WRITABLE (1 << SMMU_PTB_DATA_ASID_WRITABLE_SHIFT) @@ -1054,7 +1054,6 @@ static int smmu_debugfs_stats_show(struct seq_file *s, void *v) stats[i], val, offs); } seq_printf(s, "\n"); - dput(dent); return 0; } diff --git a/trunk/drivers/irqchip/irq-bcm2835.c b/trunk/drivers/irqchip/irq-bcm2835.c index 16c78f1c5ef2..dc670ccc6978 100644 --- a/trunk/drivers/irqchip/irq-bcm2835.c +++ b/trunk/drivers/irqchip/irq-bcm2835.c @@ -168,8 +168,7 @@ static int __init armctrl_of_init(struct device_node *node, } static struct of_device_id irq_of_match[] __initconst = { - { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init }, - { } + { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init } }; void __init bcm2835_init_irq(void) diff --git a/trunk/drivers/isdn/Kconfig b/trunk/drivers/isdn/Kconfig index 86cd75a0e84d..a233ed53913a 100644 --- a/trunk/drivers/isdn/Kconfig +++ b/trunk/drivers/isdn/Kconfig @@ -4,7 +4,7 @@ menuconfig ISDN bool "ISDN support" - depends on NET && NETDEVICES + depends on NET depends on !S390 && !UML ---help--- ISDN ("Integrated Services Digital Network", called RNIS in France) diff --git a/trunk/drivers/isdn/gigaset/bas-gigaset.c b/trunk/drivers/isdn/gigaset/bas-gigaset.c index c44950d3eb7b..527588708948 100644 --- a/trunk/drivers/isdn/gigaset/bas-gigaset.c +++ b/trunk/drivers/isdn/gigaset/bas-gigaset.c @@ -617,13 +617,7 @@ static void int_in_work(struct work_struct *work) if (rc == 0) /* success, resubmit interrupt read URB */ rc = usb_submit_urb(urb, GFP_ATOMIC); - - switch (rc) { - case 0: /* success */ - case -ENODEV: /* device gone */ - case -EINVAL: /* URB already resubmitted, or terminal badness */ - break; - default: /* failure: try to recover by resetting the device */ + if (rc != 0 && rc != -ENODEV) { dev_err(cs->dev, "clear halt failed: %s\n", get_usb_rcmsg(rc)); rc = usb_lock_device_for_reset(ucs->udev, ucs->interface); if (rc == 0) { @@ -2448,9 +2442,7 @@ static void gigaset_disconnect(struct usb_interface *interface) } /* gigaset_suspend - * This function is called before the USB connection is suspended - * or before the USB device is reset. - * In the latter case, message == PMSG_ON. + * This function is called before the USB connection is suspended. */ static int gigaset_suspend(struct usb_interface *intf, pm_message_t message) { @@ -2506,12 +2498,7 @@ static int gigaset_suspend(struct usb_interface *intf, pm_message_t message) del_timer_sync(&ucs->timer_atrdy); del_timer_sync(&ucs->timer_cmd_in); del_timer_sync(&ucs->timer_int_in); - - /* don't try to cancel int_in_wq from within reset as it - * might be the one requesting the reset - */ - if (message.event != PM_EVENT_ON) - cancel_work_sync(&ucs->int_in_wq); + cancel_work_sync(&ucs->int_in_wq); gig_dbg(DEBUG_SUSPEND, "suspend complete"); return 0; diff --git a/trunk/drivers/isdn/i4l/Kconfig b/trunk/drivers/isdn/i4l/Kconfig index 9c6650ea848e..2302fbe70ac6 100644 --- a/trunk/drivers/isdn/i4l/Kconfig +++ b/trunk/drivers/isdn/i4l/Kconfig @@ -6,7 +6,7 @@ if ISDN_I4L config ISDN_PPP bool "Support synchronous PPP" - depends on INET + depends on INET && NETDEVICES select SLHC help Over digital connections such as ISDN, there is no need to diff --git a/trunk/drivers/isdn/i4l/isdn_common.c b/trunk/drivers/isdn/i4l/isdn_common.c index e2a945ee9f05..8c610fa6782b 100644 --- a/trunk/drivers/isdn/i4l/isdn_common.c +++ b/trunk/drivers/isdn/i4l/isdn_common.c @@ -1312,6 +1312,7 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) } else return -EINVAL; break; +#ifdef CONFIG_NETDEVICES case IIOCNETGPN: /* Get peer phone number of a connected * isdn network interface */ @@ -1321,6 +1322,7 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) return isdn_net_getpeer(&phone, argp); } else return -EINVAL; +#endif default: return -EINVAL; } @@ -1350,6 +1352,7 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) case IIOCNETLCR: printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n"); return -ENODEV; +#ifdef CONFIG_NETDEVICES case IIOCNETAIF: /* Add a network-interface */ if (arg) { @@ -1488,6 +1491,7 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) return -EFAULT; return isdn_net_force_hangup(name); break; +#endif /* CONFIG_NETDEVICES */ case IIOCSETVER: dev->net_verbose = arg; printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose); diff --git a/trunk/drivers/leds/ledtrig-cpu.c b/trunk/drivers/leds/ledtrig-cpu.c index 4239b3955ff0..b312056da14d 100644 --- a/trunk/drivers/leds/ledtrig-cpu.c +++ b/trunk/drivers/leds/ledtrig-cpu.c @@ -33,6 +33,8 @@ struct led_trigger_cpu { char name[MAX_NAME_LEN]; struct led_trigger *_trig; + struct mutex lock; + int lock_is_inited; }; static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig); @@ -48,6 +50,12 @@ void ledtrig_cpu(enum cpu_led_event ledevt) { struct led_trigger_cpu *trig = &__get_cpu_var(cpu_trig); + /* mutex lock should be initialized before calling mutex_call() */ + if (!trig->lock_is_inited) + return; + + mutex_lock(&trig->lock); + /* Locate the correct CPU LED */ switch (ledevt) { case CPU_LED_IDLE_END: @@ -67,6 +75,8 @@ void ledtrig_cpu(enum cpu_led_event ledevt) /* Will leave the LED as it is */ break; } + + mutex_unlock(&trig->lock); } EXPORT_SYMBOL(ledtrig_cpu); @@ -107,9 +117,14 @@ static int __init ledtrig_cpu_init(void) for_each_possible_cpu(cpu) { struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); + mutex_init(&trig->lock); + snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu); + mutex_lock(&trig->lock); led_trigger_register_simple(trig->name, &trig->_trig); + trig->lock_is_inited = 1; + mutex_unlock(&trig->lock); } register_syscore_ops(&ledtrig_cpu_syscore_ops); @@ -127,9 +142,15 @@ static void __exit ledtrig_cpu_exit(void) for_each_possible_cpu(cpu) { struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); + mutex_lock(&trig->lock); + led_trigger_unregister_simple(trig->_trig); trig->_trig = NULL; memset(trig->name, 0, MAX_NAME_LEN); + trig->lock_is_inited = 0; + + mutex_unlock(&trig->lock); + mutex_destroy(&trig->lock); } unregister_syscore_ops(&ledtrig_cpu_syscore_ops); diff --git a/trunk/drivers/md/dm.c b/trunk/drivers/md/dm.c index 77e6eff41cae..02db9183ca01 100644 --- a/trunk/drivers/md/dm.c +++ b/trunk/drivers/md/dm.c @@ -740,14 +740,8 @@ static void rq_completed(struct mapped_device *md, int rw, int run_queue) if (!md_in_flight(md)) wake_up(&md->wait); - /* - * Run this off this callpath, as drivers could invoke end_io while - * inside their request_fn (and holding the queue lock). Calling - * back into ->request_fn() could deadlock attempting to grab the - * queue lock again. - */ if (run_queue) - blk_run_queue_async(md->queue); + blk_run_queue(md->queue); /* * dm_put() must be at the end of this function. See the comment above diff --git a/trunk/drivers/md/faulty.c b/trunk/drivers/md/faulty.c index 5e7dc772f5de..45135f69509c 100644 --- a/trunk/drivers/md/faulty.c +++ b/trunk/drivers/md/faulty.c @@ -315,11 +315,8 @@ static int run(struct mddev *mddev) } conf->nfaults = 0; - rdev_for_each(rdev, mddev) { + rdev_for_each(rdev, mddev) conf->rdev = rdev; - disk_stack_limits(mddev->gendisk, rdev->bdev, - rdev->data_offset << 9); - } md_set_array_sectors(mddev, faulty_size(mddev, 0, 0)); mddev->private = conf; diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 61200717687b..9ab768acfb62 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -1817,10 +1817,10 @@ static void super_1_sync(struct mddev *mddev, struct md_rdev *rdev) memset(bbp, 0xff, PAGE_SIZE); for (i = 0 ; i < bb->count ; i++) { - u64 internal_bb = p[i]; + u64 internal_bb = *p++; u64 store_bb = ((BB_OFFSET(internal_bb) << 10) | BB_LEN(internal_bb)); - bbp[i] = cpu_to_le64(store_bb); + *bbp++ = cpu_to_le64(store_bb); } bb->changed = 0; if (read_seqretry(&bb->lock, seq)) @@ -5294,7 +5294,7 @@ void md_stop_writes(struct mddev *mddev) } EXPORT_SYMBOL_GPL(md_stop_writes); -static void __md_stop(struct mddev *mddev) +void md_stop(struct mddev *mddev) { mddev->ready = 0; mddev->pers->stop(mddev); @@ -5304,18 +5304,6 @@ static void __md_stop(struct mddev *mddev) mddev->pers = NULL; clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); } - -void md_stop(struct mddev *mddev) -{ - /* stop the array and free an attached data structures. - * This is called from dm-raid - */ - __md_stop(mddev); - bitmap_destroy(mddev); - if (mddev->bio_set) - bioset_free(mddev->bio_set); -} - EXPORT_SYMBOL_GPL(md_stop); static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) @@ -5376,7 +5364,7 @@ static int do_md_stop(struct mddev * mddev, int mode, set_disk_ro(disk, 0); __md_stop_writes(mddev); - __md_stop(mddev); + md_stop(mddev); mddev->queue->merge_bvec_fn = NULL; mddev->queue->backing_dev_info.congested_fn = NULL; @@ -7948,9 +7936,9 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors, sector_t *first_bad, int *bad_sectors) { int hi; - int lo; + int lo = 0; u64 *p = bb->page; - int rv; + int rv = 0; sector_t target = s + sectors; unsigned seq; @@ -7965,8 +7953,7 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors, retry: seq = read_seqbegin(&bb->lock); - lo = 0; - rv = 0; + hi = bb->count; /* Binary search between lo and hi for 'target' diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index a0f73092176e..8034fbd6190c 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -963,7 +963,7 @@ static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule) struct r1conf *conf = mddev->private; struct bio *bio; - if (from_schedule || current->bio_list) { + if (from_schedule) { spin_lock_irq(&conf->device_lock); bio_list_merge(&conf->pending_bio_list, &plug->pending); conf->pending_count += plug->pending_cnt; @@ -2710,7 +2710,7 @@ static struct r1conf *setup_conf(struct mddev *mddev) || disk_idx < 0) continue; if (test_bit(Replacement, &rdev->flags)) - disk = conf->mirrors + mddev->raid_disks + disk_idx; + disk = conf->mirrors + conf->raid_disks + disk_idx; else disk = conf->mirrors + disk_idx; diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index c9acbd717131..906ccbd0f7dc 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -499,7 +499,7 @@ static void raid10_end_write_request(struct bio *bio, int error) */ one_write_done(r10_bio); if (dec_rdev) - rdev_dec_pending(rdev, conf->mddev); + rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev); } /* @@ -1069,7 +1069,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule) struct r10conf *conf = mddev->private; struct bio *bio; - if (from_schedule || current->bio_list) { + if (from_schedule) { spin_lock_irq(&conf->device_lock); bio_list_merge(&conf->pending_bio_list, &plug->pending); conf->pending_count += plug->pending_cnt; @@ -1334,21 +1334,18 @@ static void make_request(struct mddev *mddev, struct bio * bio) blocked_rdev = rrdev; break; } - if (rdev && (test_bit(Faulty, &rdev->flags) - || test_bit(Unmerged, &rdev->flags))) - rdev = NULL; if (rrdev && (test_bit(Faulty, &rrdev->flags) || test_bit(Unmerged, &rrdev->flags))) rrdev = NULL; r10_bio->devs[i].bio = NULL; r10_bio->devs[i].repl_bio = NULL; - - if (!rdev && !rrdev) { + if (!rdev || test_bit(Faulty, &rdev->flags) || + test_bit(Unmerged, &rdev->flags)) { set_bit(R10BIO_Degraded, &r10_bio->state); continue; } - if (rdev && test_bit(WriteErrorSeen, &rdev->flags)) { + if (test_bit(WriteErrorSeen, &rdev->flags)) { sector_t first_bad; sector_t dev_sector = r10_bio->devs[i].addr; int bad_sectors; @@ -1390,10 +1387,8 @@ static void make_request(struct mddev *mddev, struct bio * bio) max_sectors = good_sectors; } } - if (rdev) { - r10_bio->devs[i].bio = bio; - atomic_inc(&rdev->nr_pending); - } + r10_bio->devs[i].bio = bio; + atomic_inc(&rdev->nr_pending); if (rrdev) { r10_bio->devs[i].repl_bio = bio; atomic_inc(&rrdev->nr_pending); @@ -1449,71 +1444,69 @@ static void make_request(struct mddev *mddev, struct bio * bio) for (i = 0; i < conf->copies; i++) { struct bio *mbio; int d = r10_bio->devs[i].devnum; - if (r10_bio->devs[i].bio) { - struct md_rdev *rdev = conf->mirrors[d].rdev; - mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); - md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, - max_sectors); - r10_bio->devs[i].bio = mbio; - - mbio->bi_sector = (r10_bio->devs[i].addr+ - choose_data_offset(r10_bio, - rdev)); - mbio->bi_bdev = rdev->bdev; - mbio->bi_end_io = raid10_end_write_request; - mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; - mbio->bi_private = r10_bio; + if (!r10_bio->devs[i].bio) + continue; - atomic_inc(&r10_bio->remaining); + mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); + md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, + max_sectors); + r10_bio->devs[i].bio = mbio; - cb = blk_check_plugged(raid10_unplug, mddev, - sizeof(*plug)); - if (cb) - plug = container_of(cb, struct raid10_plug_cb, - cb); - else - plug = NULL; - spin_lock_irqsave(&conf->device_lock, flags); - if (plug) { - bio_list_add(&plug->pending, mbio); - plug->pending_cnt++; - } else { - bio_list_add(&conf->pending_bio_list, mbio); - conf->pending_count++; - } - spin_unlock_irqrestore(&conf->device_lock, flags); - if (!plug) - md_wakeup_thread(mddev->thread); - } + mbio->bi_sector = (r10_bio->devs[i].addr+ + choose_data_offset(r10_bio, + conf->mirrors[d].rdev)); + mbio->bi_bdev = conf->mirrors[d].rdev->bdev; + mbio->bi_end_io = raid10_end_write_request; + mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; + mbio->bi_private = r10_bio; - if (r10_bio->devs[i].repl_bio) { - struct md_rdev *rdev = conf->mirrors[d].replacement; - if (rdev == NULL) { - /* Replacement just got moved to main 'rdev' */ - smp_mb(); - rdev = conf->mirrors[d].rdev; - } - mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); - md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, - max_sectors); - r10_bio->devs[i].repl_bio = mbio; - - mbio->bi_sector = (r10_bio->devs[i].addr + - choose_data_offset( - r10_bio, rdev)); - mbio->bi_bdev = rdev->bdev; - mbio->bi_end_io = raid10_end_write_request; - mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; - mbio->bi_private = r10_bio; + atomic_inc(&r10_bio->remaining); - atomic_inc(&r10_bio->remaining); - spin_lock_irqsave(&conf->device_lock, flags); + cb = blk_check_plugged(raid10_unplug, mddev, sizeof(*plug)); + if (cb) + plug = container_of(cb, struct raid10_plug_cb, cb); + else + plug = NULL; + spin_lock_irqsave(&conf->device_lock, flags); + if (plug) { + bio_list_add(&plug->pending, mbio); + plug->pending_cnt++; + } else { bio_list_add(&conf->pending_bio_list, mbio); conf->pending_count++; - spin_unlock_irqrestore(&conf->device_lock, flags); - if (!mddev_check_plugged(mddev)) - md_wakeup_thread(mddev->thread); } + spin_unlock_irqrestore(&conf->device_lock, flags); + if (!plug) + md_wakeup_thread(mddev->thread); + + if (!r10_bio->devs[i].repl_bio) + continue; + + mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); + md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, + max_sectors); + r10_bio->devs[i].repl_bio = mbio; + + /* We are actively writing to the original device + * so it cannot disappear, so the replacement cannot + * become NULL here + */ + mbio->bi_sector = (r10_bio->devs[i].addr + + choose_data_offset( + r10_bio, + conf->mirrors[d].replacement)); + mbio->bi_bdev = conf->mirrors[d].replacement->bdev; + mbio->bi_end_io = raid10_end_write_request; + mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; + mbio->bi_private = r10_bio; + + atomic_inc(&r10_bio->remaining); + spin_lock_irqsave(&conf->device_lock, flags); + bio_list_add(&conf->pending_bio_list, mbio); + conf->pending_count++; + spin_unlock_irqrestore(&conf->device_lock, flags); + if (!mddev_check_plugged(mddev)) + md_wakeup_thread(mddev->thread); } /* Don't remove the bias on 'remaining' (one_write_done) until @@ -1790,7 +1783,7 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev) clear_bit(Unmerged, &rdev->flags); } md_integrity_add_rdev(rdev, mddev); - if (mddev->queue && blk_queue_discard(bdev_get_queue(rdev->bdev))) + if (blk_queue_discard(bdev_get_queue(rdev->bdev))) queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); print_conf(conf); @@ -3620,14 +3613,11 @@ static int run(struct mddev *mddev) discard_supported = true; } - if (mddev->queue) { - if (discard_supported) - queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, - mddev->queue); - else - queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, - mddev->queue); - } + if (discard_supported) + queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); + else + queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); + /* need to check that every block has at least one working mirror */ if (!enough(conf, -1)) { printk(KERN_ERR "md/raid10:%s: not enough operational mirrors.\n", diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index a4502686e7a8..c5439dce0295 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -2774,12 +2774,10 @@ static void handle_stripe_clean_event(struct r5conf *conf, dev = &sh->dev[i]; if (!test_bit(R5_LOCKED, &dev->flags) && (test_bit(R5_UPTODATE, &dev->flags) || - test_bit(R5_Discard, &dev->flags))) { + test_and_clear_bit(R5_Discard, &dev->flags))) { /* We can return any write requests */ struct bio *wbi, *wbi2; pr_debug("Return write for disc %d\n", i); - if (test_and_clear_bit(R5_Discard, &dev->flags)) - clear_bit(R5_UPTODATE, &dev->flags); wbi = dev->written; dev->written = NULL; while (wbi && wbi->bi_sector < @@ -2797,8 +2795,7 @@ static void handle_stripe_clean_event(struct r5conf *conf, !test_bit(STRIPE_DEGRADED, &sh->state), 0); } - } else if (test_bit(R5_Discard, &sh->dev[i].flags)) - clear_bit(R5_Discard, &sh->dev[i].flags); + } if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state)) if (atomic_dec_and_test(&conf->pending_full_writes)) @@ -3493,6 +3490,40 @@ static void handle_stripe(struct stripe_head *sh) handle_failed_sync(conf, sh, &s); } + /* + * might be able to return some write requests if the parity blocks + * are safe, or on a failed drive + */ + pdev = &sh->dev[sh->pd_idx]; + s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx) + || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx); + qdev = &sh->dev[sh->qd_idx]; + s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx) + || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx) + || conf->level < 6; + + if (s.written && + (s.p_failed || ((test_bit(R5_Insync, &pdev->flags) + && !test_bit(R5_LOCKED, &pdev->flags) + && (test_bit(R5_UPTODATE, &pdev->flags) || + test_bit(R5_Discard, &pdev->flags))))) && + (s.q_failed || ((test_bit(R5_Insync, &qdev->flags) + && !test_bit(R5_LOCKED, &qdev->flags) + && (test_bit(R5_UPTODATE, &qdev->flags) || + test_bit(R5_Discard, &qdev->flags)))))) + handle_stripe_clean_event(conf, sh, disks, &s.return_bi); + + /* Now we might consider reading some blocks, either to check/generate + * parity, or to satisfy requests + * or to load a block that is being partially written. + */ + if (s.to_read || s.non_overwrite + || (conf->level == 6 && s.to_write && s.failed) + || (s.syncing && (s.uptodate + s.compute < disks)) + || s.replacing + || s.expanding) + handle_stripe_fill(sh, &s, disks); + /* Now we check to see if any write operations have recently * completed */ @@ -3530,40 +3561,6 @@ static void handle_stripe(struct stripe_head *sh) s.dec_preread_active = 1; } - /* - * might be able to return some write requests if the parity blocks - * are safe, or on a failed drive - */ - pdev = &sh->dev[sh->pd_idx]; - s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx) - || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx); - qdev = &sh->dev[sh->qd_idx]; - s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx) - || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx) - || conf->level < 6; - - if (s.written && - (s.p_failed || ((test_bit(R5_Insync, &pdev->flags) - && !test_bit(R5_LOCKED, &pdev->flags) - && (test_bit(R5_UPTODATE, &pdev->flags) || - test_bit(R5_Discard, &pdev->flags))))) && - (s.q_failed || ((test_bit(R5_Insync, &qdev->flags) - && !test_bit(R5_LOCKED, &qdev->flags) - && (test_bit(R5_UPTODATE, &qdev->flags) || - test_bit(R5_Discard, &qdev->flags)))))) - handle_stripe_clean_event(conf, sh, disks, &s.return_bi); - - /* Now we might consider reading some blocks, either to check/generate - * parity, or to satisfy requests - * or to load a block that is being partially written. - */ - if (s.to_read || s.non_overwrite - || (conf->level == 6 && s.to_write && s.failed) - || (s.syncing && (s.uptodate + s.compute < disks)) - || s.replacing - || s.expanding) - handle_stripe_fill(sh, &s, disks); - /* Now to consider new write requests and what else, if anything * should be read. We do not handle new writes when: * 1/ A 'write' operation (copy+xor) is already in flight. @@ -5532,10 +5529,6 @@ static int run(struct mddev *mddev) * discard data disk but write parity disk */ stripe = stripe * PAGE_SIZE; - /* Round up to power of 2, as discard handling - * currently assumes that */ - while ((stripe-1) & stripe) - stripe = (stripe | (stripe-1)) + 1; mddev->queue->limits.discard_alignment = stripe; mddev->queue->limits.discard_granularity = stripe; /* diff --git a/trunk/drivers/media/dvb-frontends/stv0900_core.c b/trunk/drivers/media/dvb-frontends/stv0900_core.c index b551ca350e00..262dfa503c2a 100644 --- a/trunk/drivers/media/dvb-frontends/stv0900_core.c +++ b/trunk/drivers/media/dvb-frontends/stv0900_core.c @@ -300,15 +300,15 @@ static enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 { u32 m_div, clk_sel; + dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk, + intp->quartz); + if (intp == NULL) return STV0900_INVALID_HANDLE; if (intp->errs) return STV0900_I2C_ERROR; - dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk, - intp->quartz); - clk_sel = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6); m_div = ((clk_sel * mclk) / intp->quartz) - 1; stv0900_write_bits(intp, F0900_M_DIV, m_div); diff --git a/trunk/drivers/media/i2c/adv7604.c b/trunk/drivers/media/i2c/adv7604.c index 05f8950f6f91..109bc9b12e74 100644 --- a/trunk/drivers/media/i2c/adv7604.c +++ b/trunk/drivers/media/i2c/adv7604.c @@ -53,7 +53,8 @@ MODULE_LICENSE("GPL"); /* ADV7604 system clock frequency */ #define ADV7604_fsc (28636360) -#define DIGITAL_INPUT (state->mode == ADV7604_MODE_HDMI) +#define DIGITAL_INPUT ((state->prim_mode == ADV7604_PRIM_MODE_HDMI_COMP) || \ + (state->prim_mode == ADV7604_PRIM_MODE_HDMI_GR)) /* ********************************************************************** @@ -67,7 +68,7 @@ struct adv7604_state { struct v4l2_subdev sd; struct media_pad pad; struct v4l2_ctrl_handler hdl; - enum adv7604_mode mode; + enum adv7604_prim_mode prim_mode; struct v4l2_dv_timings timings; u8 edid[256]; unsigned edid_blocks; @@ -76,7 +77,6 @@ struct adv7604_state { struct workqueue_struct *work_queues; struct delayed_work delayed_work_enable_hotplug; bool connector_hdmi; - bool restart_stdi_once; /* i2c clients */ struct i2c_client *i2c_avlink; @@ -106,6 +106,7 @@ static const struct v4l2_dv_timings adv7604_timings[] = { V4L2_DV_BT_CEA_720X576P50, V4L2_DV_BT_CEA_1280X720P24, V4L2_DV_BT_CEA_1280X720P25, + V4L2_DV_BT_CEA_1280X720P30, V4L2_DV_BT_CEA_1280X720P50, V4L2_DV_BT_CEA_1280X720P60, V4L2_DV_BT_CEA_1920X1080P24, @@ -114,7 +115,6 @@ static const struct v4l2_dv_timings adv7604_timings[] = { V4L2_DV_BT_CEA_1920X1080P50, V4L2_DV_BT_CEA_1920X1080P60, - /* sorted by DMT ID */ V4L2_DV_BT_DMT_640X350P85, V4L2_DV_BT_DMT_640X400P85, V4L2_DV_BT_DMT_720X400P85, @@ -164,89 +164,6 @@ static const struct v4l2_dv_timings adv7604_timings[] = { { }, }; -struct adv7604_video_standards { - struct v4l2_dv_timings timings; - u8 vid_std; - u8 v_freq; -}; - -/* sorted by number of lines */ -static const struct adv7604_video_standards adv7604_prim_mode_comp[] = { - /* { V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 }, TODO flickering */ - { V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 }, - { V4L2_DV_BT_CEA_1280X720P50, 0x19, 0x01 }, - { V4L2_DV_BT_CEA_1280X720P60, 0x19, 0x00 }, - { V4L2_DV_BT_CEA_1920X1080P24, 0x1e, 0x04 }, - { V4L2_DV_BT_CEA_1920X1080P25, 0x1e, 0x03 }, - { V4L2_DV_BT_CEA_1920X1080P30, 0x1e, 0x02 }, - { V4L2_DV_BT_CEA_1920X1080P50, 0x1e, 0x01 }, - { V4L2_DV_BT_CEA_1920X1080P60, 0x1e, 0x00 }, - /* TODO add 1920x1080P60_RB (CVT timing) */ - { }, -}; - -/* sorted by number of lines */ -static const struct adv7604_video_standards adv7604_prim_mode_gr[] = { - { V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 }, - { V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 }, - { V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 }, - { V4L2_DV_BT_DMT_640X480P85, 0x0b, 0x00 }, - { V4L2_DV_BT_DMT_800X600P56, 0x00, 0x00 }, - { V4L2_DV_BT_DMT_800X600P60, 0x01, 0x00 }, - { V4L2_DV_BT_DMT_800X600P72, 0x02, 0x00 }, - { V4L2_DV_BT_DMT_800X600P75, 0x03, 0x00 }, - { V4L2_DV_BT_DMT_800X600P85, 0x04, 0x00 }, - { V4L2_DV_BT_DMT_1024X768P60, 0x0c, 0x00 }, - { V4L2_DV_BT_DMT_1024X768P70, 0x0d, 0x00 }, - { V4L2_DV_BT_DMT_1024X768P75, 0x0e, 0x00 }, - { V4L2_DV_BT_DMT_1024X768P85, 0x0f, 0x00 }, - { V4L2_DV_BT_DMT_1280X1024P60, 0x05, 0x00 }, - { V4L2_DV_BT_DMT_1280X1024P75, 0x06, 0x00 }, - { V4L2_DV_BT_DMT_1360X768P60, 0x12, 0x00 }, - { V4L2_DV_BT_DMT_1366X768P60, 0x13, 0x00 }, - { V4L2_DV_BT_DMT_1400X1050P60, 0x14, 0x00 }, - { V4L2_DV_BT_DMT_1400X1050P75, 0x15, 0x00 }, - { V4L2_DV_BT_DMT_1600X1200P60, 0x16, 0x00 }, /* TODO not tested */ - /* TODO add 1600X1200P60_RB (not a DMT timing) */ - { V4L2_DV_BT_DMT_1680X1050P60, 0x18, 0x00 }, - { V4L2_DV_BT_DMT_1920X1200P60_RB, 0x19, 0x00 }, /* TODO not tested */ - { }, -}; - -/* sorted by number of lines */ -static const struct adv7604_video_standards adv7604_prim_mode_hdmi_comp[] = { - { V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 }, - { V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 }, - { V4L2_DV_BT_CEA_1280X720P50, 0x13, 0x01 }, - { V4L2_DV_BT_CEA_1280X720P60, 0x13, 0x00 }, - { V4L2_DV_BT_CEA_1920X1080P24, 0x1e, 0x04 }, - { V4L2_DV_BT_CEA_1920X1080P25, 0x1e, 0x03 }, - { V4L2_DV_BT_CEA_1920X1080P30, 0x1e, 0x02 }, - { V4L2_DV_BT_CEA_1920X1080P50, 0x1e, 0x01 }, - { V4L2_DV_BT_CEA_1920X1080P60, 0x1e, 0x00 }, - { }, -}; - -/* sorted by number of lines */ -static const struct adv7604_video_standards adv7604_prim_mode_hdmi_gr[] = { - { V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 }, - { V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 }, - { V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 }, - { V4L2_DV_BT_DMT_640X480P85, 0x0b, 0x00 }, - { V4L2_DV_BT_DMT_800X600P56, 0x00, 0x00 }, - { V4L2_DV_BT_DMT_800X600P60, 0x01, 0x00 }, - { V4L2_DV_BT_DMT_800X600P72, 0x02, 0x00 }, - { V4L2_DV_BT_DMT_800X600P75, 0x03, 0x00 }, - { V4L2_DV_BT_DMT_800X600P85, 0x04, 0x00 }, - { V4L2_DV_BT_DMT_1024X768P60, 0x0c, 0x00 }, - { V4L2_DV_BT_DMT_1024X768P70, 0x0d, 0x00 }, - { V4L2_DV_BT_DMT_1024X768P75, 0x0e, 0x00 }, - { V4L2_DV_BT_DMT_1024X768P85, 0x0f, 0x00 }, - { V4L2_DV_BT_DMT_1280X1024P60, 0x05, 0x00 }, - { V4L2_DV_BT_DMT_1280X1024P75, 0x06, 0x00 }, - { }, -}; - /* ----------------------------------------------------------------------- */ static inline struct adv7604_state *to_state(struct v4l2_subdev *sd) @@ -755,145 +672,65 @@ static int adv7604_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd) ((io_read(sd, 0x6f) & 0x10) >> 4)); } -static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd, - u8 prim_mode, - const struct adv7604_video_standards *predef_vid_timings, - const struct v4l2_dv_timings *timings) -{ - struct adv7604_state *state = to_state(sd); - int i; - - for (i = 0; predef_vid_timings[i].timings.bt.width; i++) { - if (!v4l_match_dv_timings(timings, &predef_vid_timings[i].timings, - DIGITAL_INPUT ? 250000 : 1000000)) - continue; - io_write(sd, 0x00, predef_vid_timings[i].vid_std); /* video std */ - io_write(sd, 0x01, (predef_vid_timings[i].v_freq << 4) + - prim_mode); /* v_freq and prim mode */ - return 0; - } - - return -1; -} - -static int configure_predefined_video_timings(struct v4l2_subdev *sd, - struct v4l2_dv_timings *timings) +static void configure_free_run(struct v4l2_subdev *sd, const struct v4l2_bt_timings *timings) { - struct adv7604_state *state = to_state(sd); - int err; - - v4l2_dbg(1, debug, sd, "%s", __func__); - - /* reset to default values */ - io_write(sd, 0x16, 0x43); - io_write(sd, 0x17, 0x5a); - /* disable embedded syncs for auto graphics mode */ - cp_write_and_or(sd, 0x81, 0xef, 0x00); - cp_write(sd, 0x8f, 0x00); - cp_write(sd, 0x90, 0x00); - cp_write(sd, 0xa2, 0x00); - cp_write(sd, 0xa3, 0x00); - cp_write(sd, 0xa4, 0x00); - cp_write(sd, 0xa5, 0x00); - cp_write(sd, 0xa6, 0x00); - cp_write(sd, 0xa7, 0x00); - cp_write(sd, 0xab, 0x00); - cp_write(sd, 0xac, 0x00); - - switch (state->mode) { - case ADV7604_MODE_COMP: - case ADV7604_MODE_GR: - err = find_and_set_predefined_video_timings(sd, - 0x01, adv7604_prim_mode_comp, timings); - if (err) - err = find_and_set_predefined_video_timings(sd, - 0x02, adv7604_prim_mode_gr, timings); - break; - case ADV7604_MODE_HDMI: - err = find_and_set_predefined_video_timings(sd, - 0x05, adv7604_prim_mode_hdmi_comp, timings); - if (err) - err = find_and_set_predefined_video_timings(sd, - 0x06, adv7604_prim_mode_hdmi_gr, timings); - break; - default: - v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", - __func__, state->mode); - err = -1; - break; - } - - - return err; -} - -static void configure_custom_video_timings(struct v4l2_subdev *sd, - const struct v4l2_bt_timings *bt) -{ - struct adv7604_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - u32 width = htotal(bt); - u32 height = vtotal(bt); - u16 cp_start_sav = bt->hsync + bt->hbackporch - 4; - u16 cp_start_eav = width - bt->hfrontporch; - u16 cp_start_vbi = height - bt->vfrontporch; - u16 cp_end_vbi = bt->vsync + bt->vbackporch; - u16 ch1_fr_ll = (((u32)bt->pixelclock / 100) > 0) ? - ((width * (ADV7604_fsc / 100)) / ((u32)bt->pixelclock / 100)) : 0; - const u8 pll[2] = { - 0xc0 | ((width >> 8) & 0x1f), - width & 0xff - }; + u32 width = htotal(timings); + u32 height = vtotal(timings); + u16 ch1_fr_ll = (((u32)timings->pixelclock / 100) > 0) ? + ((width * (ADV7604_fsc / 100)) / ((u32)timings->pixelclock / 100)) : 0; v4l2_dbg(2, debug, sd, "%s\n", __func__); - switch (state->mode) { - case ADV7604_MODE_COMP: - case ADV7604_MODE_GR: - /* auto graphics */ - io_write(sd, 0x00, 0x07); /* video std */ - io_write(sd, 0x01, 0x02); /* prim mode */ - /* enable embedded syncs for auto graphics mode */ - cp_write_and_or(sd, 0x81, 0xef, 0x10); + cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7); /* CH1_FR_LL */ + cp_write(sd, 0x90, ch1_fr_ll & 0xff); /* CH1_FR_LL */ + cp_write(sd, 0xab, (height >> 4) & 0xff); /* CP_LCOUNT_MAX */ + cp_write(sd, 0xac, (height & 0x0f) << 4); /* CP_LCOUNT_MAX */ + /* TODO support interlaced */ + cp_write(sd, 0x91, 0x10); /* INTERLACED */ + + /* Should only be set in auto-graphics mode [REF_02 p. 91-92] */ + if ((io_read(sd, 0x00) == 0x07) && (io_read(sd, 0x01) == 0x02)) { + u16 cp_start_sav, cp_start_eav, cp_start_vbi, cp_end_vbi; + const u8 pll[2] = { + (0xc0 | ((width >> 8) & 0x1f)), + (width & 0xff) + }; - /* Should only be set in auto-graphics mode [REF_02, p. 91-92] */ /* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */ /* IO-map reg. 0x16 and 0x17 should be written in sequence */ if (adv_smbus_write_i2c_block_data(client, 0x16, 2, pll)) { v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n"); - break; + return; } /* active video - horizontal timing */ + cp_start_sav = timings->hsync + timings->hbackporch - 4; + cp_start_eav = width - timings->hfrontporch; cp_write(sd, 0xa2, (cp_start_sav >> 4) & 0xff); - cp_write(sd, 0xa3, ((cp_start_sav & 0x0f) << 4) | - ((cp_start_eav >> 8) & 0x0f)); + cp_write(sd, 0xa3, ((cp_start_sav & 0x0f) << 4) | ((cp_start_eav >> 8) & 0x0f)); cp_write(sd, 0xa4, cp_start_eav & 0xff); /* active video - vertical timing */ + cp_start_vbi = height - timings->vfrontporch; + cp_end_vbi = timings->vsync + timings->vbackporch; cp_write(sd, 0xa5, (cp_start_vbi >> 4) & 0xff); - cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) | - ((cp_end_vbi >> 8) & 0xf)); + cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) | ((cp_end_vbi >> 8) & 0xf)); cp_write(sd, 0xa7, cp_end_vbi & 0xff); - break; - case ADV7604_MODE_HDMI: - /* set default prim_mode/vid_std for HDMI - accoring to [REF_03, c. 4.2] */ - io_write(sd, 0x00, 0x02); /* video std */ - io_write(sd, 0x01, 0x06); /* prim mode */ - break; - default: - v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", - __func__, state->mode); - break; + } else { + /* reset to default values */ + io_write(sd, 0x16, 0x43); + io_write(sd, 0x17, 0x5a); + cp_write(sd, 0xa2, 0x00); + cp_write(sd, 0xa3, 0x00); + cp_write(sd, 0xa4, 0x00); + cp_write(sd, 0xa5, 0x00); + cp_write(sd, 0xa6, 0x00); + cp_write(sd, 0xa7, 0x00); } - - cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7); - cp_write(sd, 0x90, ch1_fr_ll & 0xff); - cp_write(sd, 0xab, (height >> 4) & 0xff); - cp_write(sd, 0xac, (height & 0x0f) << 4); } + static void set_rgb_quantization_range(struct v4l2_subdev *sd) { struct adv7604_state *state = to_state(sd); @@ -901,7 +738,12 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd) switch (state->rgb_quantization_range) { case V4L2_DV_RGB_RANGE_AUTO: /* automatic */ - if (DIGITAL_INPUT && !(hdmi_read(sd, 0x05) & 0x80)) { + if ((hdmi_read(sd, 0x05) & 0x80) || + (state->prim_mode == ADV7604_PRIM_MODE_COMP) || + (state->prim_mode == ADV7604_PRIM_MODE_RGB)) { + /* receiving HDMI or analog signal */ + io_write_and_or(sd, 0x02, 0x0f, 0xf0); + } else { /* receiving DVI-D signal */ /* ADV7604 selects RGB limited range regardless of @@ -914,9 +756,6 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd) /* RGB full range (0-255) */ io_write_and_or(sd, 0x02, 0x0f, 0x10); } - } else { - /* receiving HDMI or analog signal, set automode */ - io_write_and_or(sd, 0x02, 0x0f, 0xf0); } break; case V4L2_DV_RGB_RANGE_LIMITED: @@ -1128,10 +967,8 @@ static int stdi2dv_timings(struct v4l2_subdev *sd, state->aspect_ratio, timings)) return 0; - v4l2_dbg(2, debug, sd, - "%s: No format candidate found for lcvs = %d, lcf=%d, bl = %d, %chsync, %cvsync\n", - __func__, stdi->lcvs, stdi->lcf, stdi->bl, - stdi->hs_pol, stdi->vs_pol); + v4l2_dbg(2, debug, sd, "%s: No format candidate found for lcf=%d, bl = %d\n", + __func__, stdi->lcf, stdi->bl); return -1; } @@ -1286,7 +1123,7 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd, adv7604_fill_optional_dv_timings_fields(sd, timings); } else { /* find format - * Since LCVS values are inaccurate [REF_03, p. 275-276], + * Since LCVS values are inaccurate (REF_03, page 275-276), * stdi2dv_timings() is called with lcvs +-1 if the first attempt fails. */ if (!stdi2dv_timings(sd, &stdi, timings)) @@ -1298,31 +1135,9 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd, stdi.lcvs -= 2; v4l2_dbg(1, debug, sd, "%s: lcvs - 1 = %d\n", __func__, stdi.lcvs); if (stdi2dv_timings(sd, &stdi, timings)) { - /* - * The STDI block may measure wrong values, especially - * for lcvs and lcf. If the driver can not find any - * valid timing, the STDI block is restarted to measure - * the video timings again. The function will return an - * error, but the restart of STDI will generate a new - * STDI interrupt and the format detection process will - * restart. - */ - if (state->restart_stdi_once) { - v4l2_dbg(1, debug, sd, "%s: restart STDI\n", __func__); - /* TODO restart STDI for Sync Channel 2 */ - /* enter one-shot mode */ - cp_write_and_or(sd, 0x86, 0xf9, 0x00); - /* trigger STDI restart */ - cp_write_and_or(sd, 0x86, 0xf9, 0x04); - /* reset to continuous mode */ - cp_write_and_or(sd, 0x86, 0xf9, 0x02); - state->restart_stdi_once = false; - return -ENOLINK; - } v4l2_dbg(1, debug, sd, "%s: format not supported\n", __func__); return -ERANGE; } - state->restart_stdi_once = true; } found: @@ -1351,7 +1166,6 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd, { struct adv7604_state *state = to_state(sd); struct v4l2_bt_timings *bt; - int err; if (!timings) return -EINVAL; @@ -1364,20 +1178,12 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd, __func__, (u32)bt->pixelclock); return -ERANGE; } - adv7604_fill_optional_dv_timings_fields(sd, timings); state->timings = *timings; - cp_write(sd, 0x91, bt->interlaced ? 0x50 : 0x10); - - /* Use prim_mode and vid_std when available */ - err = configure_predefined_video_timings(sd, timings); - if (err) { - /* custom settings when the video format - does not have prim_mode/vid_std */ - configure_custom_video_timings(sd, bt); - } + /* freerun */ + configure_free_run(sd, bt); set_rgb_quantization_range(sd); @@ -1397,25 +1203,24 @@ static int adv7604_g_dv_timings(struct v4l2_subdev *sd, return 0; } -static void enable_input(struct v4l2_subdev *sd) +static void enable_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode) { - struct adv7604_state *state = to_state(sd); - - switch (state->mode) { - case ADV7604_MODE_COMP: - case ADV7604_MODE_GR: + switch (prim_mode) { + case ADV7604_PRIM_MODE_COMP: + case ADV7604_PRIM_MODE_RGB: /* enable */ io_write(sd, 0x15, 0xb0); /* Disable Tristate of Pins (no audio) */ break; - case ADV7604_MODE_HDMI: + case ADV7604_PRIM_MODE_HDMI_COMP: + case ADV7604_PRIM_MODE_HDMI_GR: /* enable */ hdmi_write(sd, 0x1a, 0x0a); /* Unmute audio */ hdmi_write(sd, 0x01, 0x00); /* Enable HDMI clock terminators */ io_write(sd, 0x15, 0xa0); /* Disable Tristate of Pins */ break; default: - v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", - __func__, state->mode); + v4l2_err(sd, "%s: reserved primary mode 0x%0x\n", + __func__, prim_mode); break; } } @@ -1428,13 +1233,17 @@ static void disable_input(struct v4l2_subdev *sd) hdmi_write(sd, 0x01, 0x78); /* Disable HDMI clock terminators */ } -static void select_input(struct v4l2_subdev *sd) +static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode) { - struct adv7604_state *state = to_state(sd); + switch (prim_mode) { + case ADV7604_PRIM_MODE_COMP: + case ADV7604_PRIM_MODE_RGB: + /* set mode and select free run resolution */ + io_write(sd, 0x00, 0x07); /* video std */ + io_write(sd, 0x01, 0x02); /* prim mode */ + /* enable embedded syncs for auto graphics mode */ + cp_write_and_or(sd, 0x81, 0xef, 0x10); - switch (state->mode) { - case ADV7604_MODE_COMP: - case ADV7604_MODE_GR: /* reset ADI recommended settings for HDMI: */ /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */ hdmi_write(sd, 0x0d, 0x04); /* HDMI filter optimization */ @@ -1462,7 +1271,16 @@ static void select_input(struct v4l2_subdev *sd) cp_write(sd, 0x40, 0x5c); /* CP core pre-gain control. Graphics mode */ break; - case ADV7604_MODE_HDMI: + case ADV7604_PRIM_MODE_HDMI_COMP: + case ADV7604_PRIM_MODE_HDMI_GR: + /* set mode and select free run resolution */ + /* video std */ + io_write(sd, 0x00, + (prim_mode == ADV7604_PRIM_MODE_HDMI_GR) ? 0x02 : 0x1e); + io_write(sd, 0x01, prim_mode); /* prim mode */ + /* disable embedded syncs for auto graphics mode */ + cp_write_and_or(sd, 0x81, 0xef, 0x00); + /* set ADI recommended settings for HDMI: */ /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */ hdmi_write(sd, 0x0d, 0x84); /* HDMI filter optimization */ @@ -1491,8 +1309,7 @@ static void select_input(struct v4l2_subdev *sd) break; default: - v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", - __func__, state->mode); + v4l2_err(sd, "%s: reserved primary mode 0x%0x\n", __func__, prim_mode); break; } } @@ -1504,13 +1321,26 @@ static int adv7604_s_routing(struct v4l2_subdev *sd, v4l2_dbg(2, debug, sd, "%s: input %d", __func__, input); - state->mode = input; + switch (input) { + case 0: + /* TODO select HDMI_COMP or HDMI_GR */ + state->prim_mode = ADV7604_PRIM_MODE_HDMI_COMP; + break; + case 1: + state->prim_mode = ADV7604_PRIM_MODE_RGB; + break; + case 2: + state->prim_mode = ADV7604_PRIM_MODE_COMP; + break; + default: + return -EINVAL; + } disable_input(sd); - select_input(sd); + select_input(sd, state->prim_mode); - enable_input(sd); + enable_input(sd, state->prim_mode); return 0; } @@ -1719,9 +1549,8 @@ static int adv7604_log_status(struct v4l2_subdev *sd) v4l2_info(sd, "CP locked: %s\n", no_lock_cp(sd) ? "false" : "true"); v4l2_info(sd, "CP free run: %s\n", (!!(cp_read(sd, 0xff) & 0x10) ? "on" : "off")); - v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x, v_freq = 0x%x\n", - io_read(sd, 0x01) & 0x0f, io_read(sd, 0x00) & 0x3f, - (io_read(sd, 0x01) & 0x70) >> 4); + v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x\n", + io_read(sd, 0x01) & 0x0f, io_read(sd, 0x00) & 0x3f); v4l2_info(sd, "-----Video Timings-----\n"); if (read_stdi(sd, &stdi)) @@ -1883,9 +1712,9 @@ static int adv7604_core_init(struct v4l2_subdev *sd) cp_write(sd, 0xba, (pdata->hdmi_free_run_mode << 1) | 0x01); /* HDMI free run */ cp_write(sd, 0xf3, 0xdc); /* Low threshold to enter/exit free run mode */ cp_write(sd, 0xf9, 0x23); /* STDI ch. 1 - LCVS change threshold - - ADI recommended setting [REF_01, c. 2.3.3] */ + ADI recommended setting [REF_01 c. 2.3.3] */ cp_write(sd, 0x45, 0x23); /* STDI ch. 2 - LCVS change threshold - - ADI recommended setting [REF_01, c. 2.3.3] */ + ADI recommended setting [REF_01 c. 2.3.3] */ cp_write(sd, 0xc9, 0x2d); /* use prim_mode and vid_std as free run resolution for digital formats */ @@ -1895,6 +1724,11 @@ static int adv7604_core_init(struct v4l2_subdev *sd) afe_write(sd, 0x02, pdata->ain_sel); /* Select analog input muxing mode */ io_write_and_or(sd, 0x30, ~(1 << 4), pdata->output_bus_lsb_to_msb << 4); + state->prim_mode = pdata->prim_mode; + select_input(sd, pdata->prim_mode); + + enable_input(sd, pdata->prim_mode); + /* interrupts */ io_write(sd, 0x40, 0xc2); /* Configure INT1 */ io_write(sd, 0x41, 0xd7); /* STDI irq for any change, disable INT2 */ @@ -2049,7 +1883,6 @@ static int adv7604_probe(struct i2c_client *client, v4l2_err(sd, "failed to create all i2c clients\n"); goto err_i2c; } - state->restart_stdi_once = true; /* work queues */ state->work_queues = create_singlethread_workqueue(client->name); diff --git a/trunk/drivers/media/i2c/soc_camera/mt9v022.c b/trunk/drivers/media/i2c/soc_camera/mt9v022.c index 333ef178d6fb..13057b966ee9 100644 --- a/trunk/drivers/media/i2c/soc_camera/mt9v022.c +++ b/trunk/drivers/media/i2c/soc_camera/mt9v022.c @@ -263,14 +263,9 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) if (ret & 1) /* Autoexposure */ ret = reg_write(client, mt9v022->reg->max_total_shutter_width, rect.height + mt9v022->y_skip_top + 43); - /* - * If autoexposure is off, there is no need to set - * MT9V022_TOTAL_SHUTTER_WIDTH here. Autoexposure can be off - * only if the user has set exposure manually, using the - * V4L2_CID_EXPOSURE_AUTO with the value V4L2_EXPOSURE_MANUAL. - * In this case the register MT9V022_TOTAL_SHUTTER_WIDTH - * already contains the correct value. - */ + else + ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, + rect.height + mt9v022->y_skip_top + 43); } /* Setup frame format: defaults apart from width and height */ if (!ret) diff --git a/trunk/drivers/media/platform/exynos-gsc/gsc-core.c b/trunk/drivers/media/platform/exynos-gsc/gsc-core.c index 19cbb12a12a2..bfec9e65aefb 100644 --- a/trunk/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/trunk/drivers/media/platform/exynos-gsc/gsc-core.c @@ -965,10 +965,8 @@ static struct platform_device_id gsc_driver_ids[] = { MODULE_DEVICE_TABLE(platform, gsc_driver_ids); static const struct of_device_id exynos_gsc_match[] = { - { - .compatible = "samsung,exynos5-gsc", - .data = &gsc_v_100_drvdata, - }, + { .compatible = "samsung,exynos5250-gsc", + .data = &gsc_v_100_drvdata, }, {}, }; MODULE_DEVICE_TABLE(of, exynos_gsc_match); diff --git a/trunk/drivers/media/platform/exynos-gsc/gsc-m2m.c b/trunk/drivers/media/platform/exynos-gsc/gsc-m2m.c index c065d040ed94..3c7f00577bd9 100644 --- a/trunk/drivers/media/platform/exynos-gsc/gsc-m2m.c +++ b/trunk/drivers/media/platform/exynos-gsc/gsc-m2m.c @@ -657,7 +657,8 @@ static int gsc_m2m_release(struct file *file) pr_debug("pid: %d, state: 0x%lx, refcnt= %d", task_pid_nr(current), gsc->state, gsc->m2m.refcnt); - mutex_lock(&gsc->lock); + if (mutex_lock_interruptible(&gsc->lock)) + return -ERESTARTSYS; v4l2_m2m_ctx_release(ctx->m2m_ctx); gsc_ctrls_delete(ctx); @@ -731,7 +732,6 @@ int gsc_register_m2m_device(struct gsc_dev *gsc) gsc->vdev.ioctl_ops = &gsc_m2m_ioctl_ops; gsc->vdev.release = video_device_release_empty; gsc->vdev.lock = &gsc->lock; - gsc->vdev.vfl_dir = VFL_DIR_M2M; snprintf(gsc->vdev.name, sizeof(gsc->vdev.name), "%s.%d:m2m", GSC_MODULE_NAME, gsc->id); diff --git a/trunk/drivers/media/platform/exynos-gsc/gsc-regs.h b/trunk/drivers/media/platform/exynos-gsc/gsc-regs.h index 4678f9a6a4fd..533e9947a925 100644 --- a/trunk/drivers/media/platform/exynos-gsc/gsc-regs.h +++ b/trunk/drivers/media/platform/exynos-gsc/gsc-regs.h @@ -40,10 +40,10 @@ #define GSC_IN_ROT_YFLIP (2 << 16) #define GSC_IN_ROT_XFLIP (1 << 16) #define GSC_IN_RGB_TYPE_MASK (3 << 14) -#define GSC_IN_RGB_HD_NARROW (3 << 14) -#define GSC_IN_RGB_HD_WIDE (2 << 14) -#define GSC_IN_RGB_SD_NARROW (1 << 14) -#define GSC_IN_RGB_SD_WIDE (0 << 14) +#define GSC_IN_RGB_HD_WIDE (3 << 14) +#define GSC_IN_RGB_HD_NARROW (2 << 14) +#define GSC_IN_RGB_SD_WIDE (1 << 14) +#define GSC_IN_RGB_SD_NARROW (0 << 14) #define GSC_IN_YUV422_1P_ORDER_MASK (1 << 13) #define GSC_IN_YUV422_1P_ORDER_LSB_Y (0 << 13) #define GSC_IN_YUV422_1P_OEDER_LSB_C (1 << 13) @@ -85,10 +85,10 @@ #define GSC_OUT_GLOBAL_ALPHA_MASK (0xff << 24) #define GSC_OUT_GLOBAL_ALPHA(x) ((x) << 24) #define GSC_OUT_RGB_TYPE_MASK (3 << 10) -#define GSC_OUT_RGB_HD_WIDE (3 << 10) -#define GSC_OUT_RGB_HD_NARROW (2 << 10) -#define GSC_OUT_RGB_SD_WIDE (1 << 10) -#define GSC_OUT_RGB_SD_NARROW (0 << 10) +#define GSC_OUT_RGB_HD_NARROW (3 << 10) +#define GSC_OUT_RGB_HD_WIDE (2 << 10) +#define GSC_OUT_RGB_SD_NARROW (1 << 10) +#define GSC_OUT_RGB_SD_WIDE (0 << 10) #define GSC_OUT_YUV422_1P_ORDER_MASK (1 << 9) #define GSC_OUT_YUV422_1P_ORDER_LSB_Y (0 << 9) #define GSC_OUT_YUV422_1P_OEDER_LSB_C (1 << 9) diff --git a/trunk/drivers/media/platform/omap3isp/ispccdc.c b/trunk/drivers/media/platform/omap3isp/ispccdc.c index aa9df9d71a7b..60181ab96063 100644 --- a/trunk/drivers/media/platform/omap3isp/ispccdc.c +++ b/trunk/drivers/media/platform/omap3isp/ispccdc.c @@ -1706,7 +1706,7 @@ static long ccdc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) } static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, - struct v4l2_event_subscription *sub) + const struct v4l2_event_subscription *sub) { if (sub->type != V4L2_EVENT_FRAME_SYNC) return -EINVAL; @@ -1719,7 +1719,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, } static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, - struct v4l2_event_subscription *sub) + const struct v4l2_event_subscription *sub) { return v4l2_event_unsubscribe(fh, sub); } diff --git a/trunk/drivers/media/platform/omap3isp/ispstat.c b/trunk/drivers/media/platform/omap3isp/ispstat.c index b8640be692f1..d7ac76b5c2ae 100644 --- a/trunk/drivers/media/platform/omap3isp/ispstat.c +++ b/trunk/drivers/media/platform/omap3isp/ispstat.c @@ -1025,7 +1025,7 @@ void omap3isp_stat_dma_isr(struct ispstat *stat) int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev, struct v4l2_fh *fh, - struct v4l2_event_subscription *sub) + const struct v4l2_event_subscription *sub) { struct ispstat *stat = v4l2_get_subdevdata(subdev); @@ -1037,7 +1037,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev, int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev, struct v4l2_fh *fh, - struct v4l2_event_subscription *sub) + const struct v4l2_event_subscription *sub) { return v4l2_event_unsubscribe(fh, sub); } diff --git a/trunk/drivers/media/platform/omap3isp/ispstat.h b/trunk/drivers/media/platform/omap3isp/ispstat.h index 9b7c8654dc8a..a6fe653eb237 100644 --- a/trunk/drivers/media/platform/omap3isp/ispstat.h +++ b/trunk/drivers/media/platform/omap3isp/ispstat.h @@ -147,10 +147,10 @@ int omap3isp_stat_init(struct ispstat *stat, const char *name, void omap3isp_stat_cleanup(struct ispstat *stat); int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev, struct v4l2_fh *fh, - struct v4l2_event_subscription *sub); + const struct v4l2_event_subscription *sub); int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev, struct v4l2_fh *fh, - struct v4l2_event_subscription *sub); + const struct v4l2_event_subscription *sub); int omap3isp_stat_s_stream(struct v4l2_subdev *subdev, int enable); int omap3isp_stat_busy(struct ispstat *stat); diff --git a/trunk/drivers/media/platform/omap3isp/ispvideo.c b/trunk/drivers/media/platform/omap3isp/ispvideo.c index 75cd309035f9..a0b737fecf13 100644 --- a/trunk/drivers/media/platform/omap3isp/ispvideo.c +++ b/trunk/drivers/media/platform/omap3isp/ispvideo.c @@ -792,7 +792,7 @@ isp_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop) } static int -isp_video_set_crop(struct file *file, void *fh, const struct v4l2_crop *crop) +isp_video_set_crop(struct file *file, void *fh, struct v4l2_crop *crop) { struct isp_video *video = video_drvdata(file); struct v4l2_subdev *subdev; diff --git a/trunk/drivers/media/platform/s5p-fimc/Kconfig b/trunk/drivers/media/platform/s5p-fimc/Kconfig index c16b20d86ed2..8f090a8f270e 100644 --- a/trunk/drivers/media/platform/s5p-fimc/Kconfig +++ b/trunk/drivers/media/platform/s5p-fimc/Kconfig @@ -24,7 +24,6 @@ config VIDEO_S5P_FIMC config VIDEO_S5P_MIPI_CSIS tristate "S5P/EXYNOS MIPI-CSI2 receiver (MIPI-CSIS) driver" depends on REGULATOR - select S5P_SETUP_MIPIPHY help This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC MIPI-CSI2 receiver (MIPI-CSIS) devices. diff --git a/trunk/drivers/media/platform/s5p-fimc/fimc-capture.c b/trunk/drivers/media/platform/s5p-fimc/fimc-capture.c index 891ee873c62b..367efd164d0f 100644 --- a/trunk/drivers/media/platform/s5p-fimc/fimc-capture.c +++ b/trunk/drivers/media/platform/s5p-fimc/fimc-capture.c @@ -556,7 +556,8 @@ static int fimc_capture_close(struct file *file) dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); - mutex_lock(&fimc->lock); + if (mutex_lock_interruptible(&fimc->lock)) + return -ERESTARTSYS; if (--fimc->vid_cap.refcnt == 0) { clear_bit(ST_CAPT_BUSY, &fimc->state); @@ -1735,9 +1736,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc, q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct fimc_vid_buffer); - ret = vb2_queue_init(q); - if (ret) - goto err_ent; + vb2_queue_init(q); vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK; ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0); @@ -1773,13 +1772,9 @@ static int fimc_capture_subdev_registered(struct v4l2_subdev *sd) if (ret) return ret; - fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd); - ret = fimc_register_capture_device(fimc, sd->v4l2_dev); - if (ret) { + if (ret) fimc_unregister_m2m_device(fimc); - fimc->pipeline_ops = NULL; - } return ret; } @@ -1796,7 +1791,6 @@ static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd) if (video_is_registered(&fimc->vid_cap.vfd)) { video_unregister_device(&fimc->vid_cap.vfd); media_entity_cleanup(&fimc->vid_cap.vfd.entity); - fimc->pipeline_ops = NULL; } kfree(fimc->vid_cap.ctx); fimc->vid_cap.ctx = NULL; diff --git a/trunk/drivers/media/platform/s5p-fimc/fimc-lite.c b/trunk/drivers/media/platform/s5p-fimc/fimc-lite.c index 1b309a72f09f..70bcf39de879 100644 --- a/trunk/drivers/media/platform/s5p-fimc/fimc-lite.c +++ b/trunk/drivers/media/platform/s5p-fimc/fimc-lite.c @@ -491,7 +491,8 @@ static int fimc_lite_close(struct file *file) struct fimc_lite *fimc = video_drvdata(file); int ret; - mutex_lock(&fimc->lock); + if (mutex_lock_interruptible(&fimc->lock)) + return -ERESTARTSYS; if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) { clear_bit(ST_FLITE_IN_USE, &fimc->state); @@ -1252,9 +1253,7 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd) q->buf_struct_size = sizeof(struct flite_buffer); q->drv_priv = fimc; - ret = vb2_queue_init(q); - if (ret < 0) - return ret; + vb2_queue_init(q); fimc->vd_pad.flags = MEDIA_PAD_FL_SINK; ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0); @@ -1262,12 +1261,10 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd) return ret; video_set_drvdata(vfd, fimc); - fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd); ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); if (ret < 0) { media_entity_cleanup(&vfd->entity); - fimc->pipeline_ops = NULL; return ret; } @@ -1286,7 +1283,6 @@ static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd) if (video_is_registered(&fimc->vfd)) { video_unregister_device(&fimc->vfd); media_entity_cleanup(&fimc->vfd.entity); - fimc->pipeline_ops = NULL; } } diff --git a/trunk/drivers/media/platform/s5p-fimc/fimc-m2m.c b/trunk/drivers/media/platform/s5p-fimc/fimc-m2m.c index 62afed3162ea..4500e44f6857 100644 --- a/trunk/drivers/media/platform/s5p-fimc/fimc-m2m.c +++ b/trunk/drivers/media/platform/s5p-fimc/fimc-m2m.c @@ -718,7 +718,8 @@ static int fimc_m2m_release(struct file *file) dbg("pid: %d, state: 0x%lx, refcnt= %d", task_pid_nr(current), fimc->state, fimc->m2m.refcnt); - mutex_lock(&fimc->lock); + if (mutex_lock_interruptible(&fimc->lock)) + return -ERESTARTSYS; v4l2_m2m_ctx_release(ctx->m2m_ctx); fimc_ctrls_delete(ctx); diff --git a/trunk/drivers/media/platform/s5p-fimc/fimc-mdevice.c b/trunk/drivers/media/platform/s5p-fimc/fimc-mdevice.c index 0531ab70a94c..80ada5882f62 100644 --- a/trunk/drivers/media/platform/s5p-fimc/fimc-mdevice.c +++ b/trunk/drivers/media/platform/s5p-fimc/fimc-mdevice.c @@ -343,50 +343,53 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) static int fimc_register_callback(struct device *dev, void *p) { struct fimc_dev *fimc = dev_get_drvdata(dev); - struct v4l2_subdev *sd; + struct v4l2_subdev *sd = &fimc->vid_cap.subdev; struct fimc_md *fmd = p; - int ret; + int ret = 0; - if (fimc == NULL || fimc->id >= FIMC_MAX_DEVS) + if (!fimc || !fimc->pdev) return 0; - sd = &fimc->vid_cap.subdev; + if (fimc->pdev->id < 0 || fimc->pdev->id >= FIMC_MAX_DEVS) + return 0; + + fimc->pipeline_ops = &fimc_pipeline_ops; + fmd->fimc[fimc->pdev->id] = fimc; sd->grp_id = FIMC_GROUP_ID; - v4l2_set_subdev_hostdata(sd, (void *)&fimc_pipeline_ops); ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); if (ret) { v4l2_err(&fmd->v4l2_dev, "Failed to register FIMC.%d (%d)\n", fimc->id, ret); - return ret; } - fmd->fimc[fimc->id] = fimc; - return 0; + return ret; } static int fimc_lite_register_callback(struct device *dev, void *p) { struct fimc_lite *fimc = dev_get_drvdata(dev); + struct v4l2_subdev *sd = &fimc->subdev; struct fimc_md *fmd = p; int ret; - if (fimc == NULL || fimc->index >= FIMC_LITE_MAX_DEVS) + if (fimc == NULL) return 0; - fimc->subdev.grp_id = FLITE_GROUP_ID; - v4l2_set_subdev_hostdata(&fimc->subdev, (void *)&fimc_pipeline_ops); + if (fimc->index >= FIMC_LITE_MAX_DEVS) + return 0; + + fimc->pipeline_ops = &fimc_pipeline_ops; + fmd->fimc_lite[fimc->index] = fimc; + sd->grp_id = FLITE_GROUP_ID; - ret = v4l2_device_register_subdev(&fmd->v4l2_dev, &fimc->subdev); + ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); if (ret) { v4l2_err(&fmd->v4l2_dev, "Failed to register FIMC-LITE.%d (%d)\n", fimc->index, ret); - return ret; } - - fmd->fimc_lite[fimc->index] = fimc; - return 0; + return ret; } static int csis_register_callback(struct device *dev, void *p) @@ -404,12 +407,10 @@ static int csis_register_callback(struct device *dev, void *p) v4l2_info(sd, "csis%d sd: %s\n", pdev->id, sd->name); id = pdev->id < 0 ? 0 : pdev->id; + fmd->csis[id].sd = sd; sd->grp_id = CSIS_GROUP_ID; - ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); - if (!ret) - fmd->csis[id].sd = sd; - else + if (ret) v4l2_err(&fmd->v4l2_dev, "Failed to register CSIS subdevice: %d\n", ret); return ret; diff --git a/trunk/drivers/media/platform/s5p-mfc/s5p_mfc.c b/trunk/drivers/media/platform/s5p-mfc/s5p_mfc.c index 3afe879d54d7..130f4ac8649e 100644 --- a/trunk/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/trunk/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -381,8 +381,11 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, ctx->consumed_stream += s5p_mfc_hw_call(dev->mfc_ops, get_consumed_stream, dev); if (ctx->codec_mode != S5P_MFC_CODEC_H264_DEC && - ctx->consumed_stream + STUFF_BYTE < - src_buf->b->v4l2_planes[0].bytesused) { + s5p_mfc_hw_call(dev->mfc_ops, + get_dec_frame_type, dev) == + S5P_FIMV_DECODE_FRAME_P_FRAME + && ctx->consumed_stream + STUFF_BYTE < + src_buf->b->v4l2_planes[0].bytesused) { /* Run MFC again on the same buffer */ mfc_debug(2, "Running again the same buffer\n"); ctx->after_packed_pb = 1; diff --git a/trunk/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/trunk/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c index 3a8cfd9fc1bd..50b5bee3c44e 100644 --- a/trunk/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c +++ b/trunk/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c @@ -1762,7 +1762,7 @@ int s5p_mfc_get_dspl_y_adr_v6(struct s5p_mfc_dev *dev) int s5p_mfc_get_dec_y_adr_v6(struct s5p_mfc_dev *dev) { - return mfc_read(dev, S5P_FIMV_D_DECODED_LUMA_ADDR_V6); + return mfc_read(dev, S5P_FIMV_D_DISPLAY_LUMA_ADDR_V6); } int s5p_mfc_get_dspl_status_v6(struct s5p_mfc_dev *dev) diff --git a/trunk/drivers/media/platform/sh_vou.c b/trunk/drivers/media/platform/sh_vou.c index a1c87f0ceaab..85fd312f0a82 100644 --- a/trunk/drivers/media/platform/sh_vou.c +++ b/trunk/drivers/media/platform/sh_vou.c @@ -935,10 +935,9 @@ static int sh_vou_g_crop(struct file *file, void *fh, struct v4l2_crop *a) /* Assume a dull encoder, do all the work ourselves. */ static int sh_vou_s_crop(struct file *file, void *fh, const struct v4l2_crop *a) { - struct v4l2_crop a_writable = *a; struct video_device *vdev = video_devdata(file); struct sh_vou_device *vou_dev = video_get_drvdata(vdev); - struct v4l2_rect *rect = &a_writable.c; + struct v4l2_rect *rect = &a->c; struct v4l2_crop sd_crop = {.type = V4L2_BUF_TYPE_VIDEO_OUTPUT}; struct v4l2_pix_format *pix = &vou_dev->pix; struct sh_vou_geometry geo; diff --git a/trunk/drivers/media/platform/soc_camera/mx1_camera.c b/trunk/drivers/media/platform/soc_camera/mx1_camera.c index 032b8c9097f9..bbe70991d30b 100644 --- a/trunk/drivers/media/platform/soc_camera/mx1_camera.c +++ b/trunk/drivers/media/platform/soc_camera/mx1_camera.c @@ -470,6 +470,14 @@ static void mx1_camera_remove_device(struct soc_camera_device *icd) pcdev->icd = NULL; } +static int mx1_camera_set_crop(struct soc_camera_device *icd, + struct v4l2_crop *a) +{ + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + + return v4l2_subdev_call(sd, video, s_crop, a); +} + static int mx1_camera_set_bus_param(struct soc_camera_device *icd) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); @@ -681,6 +689,7 @@ static struct soc_camera_host_ops mx1_soc_camera_host_ops = { .add = mx1_camera_add_device, .remove = mx1_camera_remove_device, .set_bus_param = mx1_camera_set_bus_param, + .set_crop = mx1_camera_set_crop, .set_fmt = mx1_camera_set_fmt, .try_fmt = mx1_camera_try_fmt, .init_videobuf = mx1_camera_init_videobuf, diff --git a/trunk/drivers/media/platform/soc_camera/mx2_camera.c b/trunk/drivers/media/platform/soc_camera/mx2_camera.c index 9a55f4c4c7f4..9fd9d1c5b218 100644 --- a/trunk/drivers/media/platform/soc_camera/mx2_camera.c +++ b/trunk/drivers/media/platform/soc_camera/mx2_camera.c @@ -864,10 +864,8 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count) bytesperline = soc_mbus_bytes_per_line(icd->user_width, icd->current_fmt->host_fmt); - if (bytesperline < 0) { - spin_unlock_irqrestore(&pcdev->lock, flags); + if (bytesperline < 0) return bytesperline; - } /* * I didn't manage to properly enable/disable the prp @@ -880,10 +878,8 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count) pcdev->discard_buffer = dma_alloc_coherent(ici->v4l2_dev.dev, pcdev->discard_size, &pcdev->discard_buffer_dma, GFP_KERNEL); - if (!pcdev->discard_buffer) { - spin_unlock_irqrestore(&pcdev->lock, flags); + if (!pcdev->discard_buffer) return -ENOMEM; - } pcdev->buf_discard[0].discard = true; list_add_tail(&pcdev->buf_discard[0].queue, @@ -1103,10 +1099,9 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd) } static int mx2_camera_set_crop(struct soc_camera_device *icd, - const struct v4l2_crop *a) + struct v4l2_crop *a) { - struct v4l2_crop a_writable = *a; - struct v4l2_rect *rect = &a_writable.c; + struct v4l2_rect *rect = &a->c; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct v4l2_mbus_framefmt mf; int ret; diff --git a/trunk/drivers/media/platform/soc_camera/mx3_camera.c b/trunk/drivers/media/platform/soc_camera/mx3_camera.c index 261f6e9e1b17..3557ac97e430 100644 --- a/trunk/drivers/media/platform/soc_camera/mx3_camera.c +++ b/trunk/drivers/media/platform/soc_camera/mx3_camera.c @@ -799,10 +799,9 @@ static inline void stride_align(__u32 *width) * default g_crop and cropcap from soc_camera.c */ static int mx3_camera_set_crop(struct soc_camera_device *icd, - const struct v4l2_crop *a) + struct v4l2_crop *a) { - struct v4l2_crop a_writable = *a; - struct v4l2_rect *rect = &a_writable.c; + struct v4l2_rect *rect = &a->c; struct soc_camera_host *ici = to_soc_camera_host(icd->parent); struct mx3_camera_dev *mx3_cam = ici->priv; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); diff --git a/trunk/drivers/media/platform/soc_camera/omap1_camera.c b/trunk/drivers/media/platform/soc_camera/omap1_camera.c index 13636a585106..fa08c7695ccb 100644 --- a/trunk/drivers/media/platform/soc_camera/omap1_camera.c +++ b/trunk/drivers/media/platform/soc_camera/omap1_camera.c @@ -1215,9 +1215,9 @@ static int set_mbus_format(struct omap1_cam_dev *pcdev, struct device *dev, } static int omap1_cam_set_crop(struct soc_camera_device *icd, - const struct v4l2_crop *crop) + struct v4l2_crop *crop) { - const struct v4l2_rect *rect = &crop->c; + struct v4l2_rect *rect = &crop->c; const struct soc_camera_format_xlate *xlate = icd->current_fmt; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->parent; diff --git a/trunk/drivers/media/platform/soc_camera/pxa_camera.c b/trunk/drivers/media/platform/soc_camera/pxa_camera.c index 3434ffe79c6e..1e3776d08dac 100644 --- a/trunk/drivers/media/platform/soc_camera/pxa_camera.c +++ b/trunk/drivers/media/platform/soc_camera/pxa_camera.c @@ -1337,9 +1337,9 @@ static int pxa_camera_check_frame(u32 width, u32 height) } static int pxa_camera_set_crop(struct soc_camera_device *icd, - const struct v4l2_crop *a) + struct v4l2_crop *a) { - const struct v4l2_rect *rect = &a->c; + struct v4l2_rect *rect = &a->c; struct device *dev = icd->parent; struct soc_camera_host *ici = to_soc_camera_host(dev); struct pxa_camera_dev *pcdev = ici->priv; diff --git a/trunk/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/trunk/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 2d8861c0e8f2..0a24253dcda2 100644 --- a/trunk/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/trunk/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -1182,13 +1182,13 @@ static void sh_mobile_ceu_put_formats(struct soc_camera_device *icd) } /* Check if any dimension of r1 is smaller than respective one of r2 */ -static bool is_smaller(const struct v4l2_rect *r1, const struct v4l2_rect *r2) +static bool is_smaller(struct v4l2_rect *r1, struct v4l2_rect *r2) { return r1->width < r2->width || r1->height < r2->height; } /* Check if r1 fails to cover r2 */ -static bool is_inside(const struct v4l2_rect *r1, const struct v4l2_rect *r2) +static bool is_inside(struct v4l2_rect *r1, struct v4l2_rect *r2) { return r1->left > r2->left || r1->top > r2->top || r1->left + r1->width < r2->left + r2->width || @@ -1263,7 +1263,7 @@ static void update_subrect(struct sh_mobile_ceu_cam *cam) * 3. if (2) failed, try to request the maximum image */ static int client_s_crop(struct soc_camera_device *icd, struct v4l2_crop *crop, - struct v4l2_crop *cam_crop) + const struct v4l2_crop *cam_crop) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c; @@ -1519,8 +1519,7 @@ static int client_scale(struct soc_camera_device *icd, static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, const struct v4l2_crop *a) { - struct v4l2_crop a_writable = *a; - const struct v4l2_rect *rect = &a_writable.c; + struct v4l2_rect *rect = &a->c; struct device *dev = icd->parent; struct soc_camera_host *ici = to_soc_camera_host(dev); struct sh_mobile_ceu_dev *pcdev = ici->priv; @@ -1546,7 +1545,7 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, * 1. - 2. Apply iterative camera S_CROP for new input window, read back * actual camera rectangle. */ - ret = client_s_crop(icd, &a_writable, &cam_crop); + ret = client_s_crop(icd, a, &cam_crop); if (ret < 0) return ret; @@ -1947,7 +1946,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, } static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd, - const struct v4l2_crop *a) + struct v4l2_crop *a) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); diff --git a/trunk/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/trunk/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index ba51f65204de..9859d2a2449b 100644 --- a/trunk/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/trunk/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -283,13 +283,14 @@ static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, /* activate the pid on the device pid filter */ if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER && - adap->pid_filtering && adap->props->pid_filter) { + adap->pid_filtering && + adap->props->pid_filter) ret = adap->props->pid_filter(adap, dvbdmxfeed->index, dvbdmxfeed->pid, (count == 1) ? 1 : 0); - if (ret < 0) - dev_err(&d->udev->dev, "%s: pid_filter() failed=%d\n", - KBUILD_MODNAME, ret); - } + if (ret < 0) + dev_err(&d->udev->dev, "%s: pid_filter() " \ + "failed=%d\n", KBUILD_MODNAME, + ret); /* start feeding if it is first pid */ if (adap->feed_count == 1 && count == 1) { diff --git a/trunk/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c b/trunk/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c index 5716662b4834..0431beed0ef4 100644 --- a/trunk/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c +++ b/trunk/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c @@ -32,7 +32,9 @@ int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, return -EINVAL; } - mutex_lock(&d->usb_mutex); + ret = mutex_lock_interruptible(&d->usb_mutex); + if (ret < 0) + return ret; dev_dbg(&d->udev->dev, "%s: >>> %*ph\n", __func__, wlen, wbuf); diff --git a/trunk/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/trunk/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 093f1acce403..adabba8d28bc 100644 --- a/trunk/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/trunk/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -1346,10 +1346,6 @@ static const struct usb_device_id rtl28xxu_id_table[] = { &rtl2832u_props, "DigitalNow Quad DVB-T Receiver", NULL) }, { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00d3, &rtl2832u_props, "TerraTec Cinergy T Stick RC (Rev. 3)", NULL) }, - { DVB_USB_DEVICE(USB_VID_DEXATEK, 0x1102, - &rtl2832u_props, "Dexatek DK mini DVB-T Dongle", NULL) }, - { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00d7, - &rtl2832u_props, "TerraTec Cinergy T Stick+", NULL) }, { } }; MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table); diff --git a/trunk/drivers/mfd/arizona-core.c b/trunk/drivers/mfd/arizona-core.c index f4f9bf84bc7b..1b48f2094806 100644 --- a/trunk/drivers/mfd/arizona-core.c +++ b/trunk/drivers/mfd/arizona-core.c @@ -96,11 +96,11 @@ static irqreturn_t arizona_underclocked(int irq, void *data) return IRQ_NONE; } + if (val & ARIZONA_AIF3_UNDERCLOCKED_STS) + dev_err(arizona->dev, "AIF3 underclocked\n"); if (val & ARIZONA_AIF3_UNDERCLOCKED_STS) dev_err(arizona->dev, "AIF3 underclocked\n"); if (val & ARIZONA_AIF2_UNDERCLOCKED_STS) - dev_err(arizona->dev, "AIF2 underclocked\n"); - if (val & ARIZONA_AIF1_UNDERCLOCKED_STS) dev_err(arizona->dev, "AIF1 underclocked\n"); if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS) dev_err(arizona->dev, "ISRC2 underclocked\n"); @@ -415,19 +415,11 @@ int __devinit arizona_dev_init(struct arizona *arizona) /* If we have a /RESET GPIO we'll already be reset */ if (!arizona->pdata.reset) { - regcache_mark_dirty(arizona->regmap); - ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0); if (ret != 0) { dev_err(dev, "Failed to reset device: %d\n", ret); goto err_reset; } - - ret = regcache_sync(arizona->regmap); - if (ret != 0) { - dev_err(dev, "Failed to sync device: %d\n", ret); - goto err_reset; - } } ret = arizona_wait_for_boot(arizona); @@ -528,7 +520,7 @@ int __devinit arizona_dev_init(struct arizona *arizona) break; case WM5110: ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, - ARRAY_SIZE(wm5110_devs), NULL, 0, NULL); + ARRAY_SIZE(wm5102_devs), NULL, 0, NULL); break; } diff --git a/trunk/drivers/mfd/arizona-irq.c b/trunk/drivers/mfd/arizona-irq.c index b1b009177405..ef0f2d001df2 100644 --- a/trunk/drivers/mfd/arizona-irq.c +++ b/trunk/drivers/mfd/arizona-irq.c @@ -178,7 +178,6 @@ int arizona_irq_init(struct arizona *arizona) switch (arizona->rev) { case 0: - case 1: ctrlif_error = false; break; default: diff --git a/trunk/drivers/mfd/db8500-prcmu.c b/trunk/drivers/mfd/db8500-prcmu.c index b96661d453aa..00b8b0f3dfb6 100644 --- a/trunk/drivers/mfd/db8500-prcmu.c +++ b/trunk/drivers/mfd/db8500-prcmu.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -421,6 +420,9 @@ static struct { static atomic_t ac_wake_req_state = ATOMIC_INIT(0); +/* Functions definition */ +static void compute_armss_rate(void); + /* Spinlocks */ static DEFINE_SPINLOCK(prcmu_lock); static DEFINE_SPINLOCK(clkout_lock); @@ -1017,6 +1019,7 @@ int db8500_prcmu_set_arm_opp(u8 opp) (mb1_transfer.ack.arm_opp != opp)) r = -EIO; + compute_armss_rate(); mutex_unlock(&mb1_transfer.lock); return r; @@ -1166,12 +1169,12 @@ int db8500_prcmu_get_ape_opp(void) } /** - * db8500_prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage + * prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage * @enable: true to request the higher voltage, false to drop a request. * * Calls to this function to enable and disable requests must be balanced. */ -int db8500_prcmu_request_ape_opp_100_voltage(bool enable) +int prcmu_request_ape_opp_100_voltage(bool enable) { int r = 0; u8 header; @@ -1666,8 +1669,13 @@ static unsigned long clock_rate(u8 clock) else return 0; } - +static unsigned long latest_armss_rate; static unsigned long armss_rate(void) +{ + return latest_armss_rate; +} + +static void compute_armss_rate(void) { u32 r; unsigned long rate; @@ -1692,7 +1700,7 @@ static unsigned long armss_rate(void) rate = pll_rate(PRCM_PLLARM_FREQ, ROOT_CLOCK_RATE, PLL_DIV); } - return rate; + latest_armss_rate = rate; } static unsigned long dsiclk_rate(u8 n) @@ -1812,35 +1820,6 @@ static long round_clock_rate(u8 clock, unsigned long rate) return rounded_rate; } -/* CPU FREQ table, may be changed due to if MAX_OPP is supported. */ -static struct cpufreq_frequency_table db8500_cpufreq_table[] = { - { .frequency = 200000, .index = ARM_EXTCLK,}, - { .frequency = 400000, .index = ARM_50_OPP,}, - { .frequency = 800000, .index = ARM_100_OPP,}, - { .frequency = CPUFREQ_TABLE_END,}, /* To be used for MAX_OPP. */ - { .frequency = CPUFREQ_TABLE_END,}, -}; - -static long round_armss_rate(unsigned long rate) -{ - long freq = 0; - int i = 0; - - /* cpufreq table frequencies is in KHz. */ - rate = rate / 1000; - - /* Find the corresponding arm opp from the cpufreq table. */ - while (db8500_cpufreq_table[i].frequency != CPUFREQ_TABLE_END) { - freq = db8500_cpufreq_table[i].frequency; - if (freq == rate) - break; - i++; - } - - /* Return the last valid value, even if a match was not found. */ - return freq * 1000; -} - #define MIN_PLL_VCO_RATE 600000000ULL #define MAX_PLL_VCO_RATE 1680640000ULL @@ -1912,8 +1891,6 @@ long prcmu_round_clock_rate(u8 clock, unsigned long rate) { if (clock < PRCMU_NUM_REG_CLOCKS) return round_clock_rate(clock, rate); - else if (clock == PRCMU_ARMSS) - return round_armss_rate(rate); else if (clock == PRCMU_PLLDSI) return round_plldsi_rate(rate); else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK)) @@ -1973,27 +1950,6 @@ static void set_clock_rate(u8 clock, unsigned long rate) spin_unlock_irqrestore(&clk_mgt_lock, flags); } -static int set_armss_rate(unsigned long rate) -{ - int i = 0; - - /* cpufreq table frequencies is in KHz. */ - rate = rate / 1000; - - /* Find the corresponding arm opp from the cpufreq table. */ - while (db8500_cpufreq_table[i].frequency != CPUFREQ_TABLE_END) { - if (db8500_cpufreq_table[i].frequency == rate) - break; - i++; - } - - if (db8500_cpufreq_table[i].frequency != rate) - return -EINVAL; - - /* Set the new arm opp. */ - return db8500_prcmu_set_arm_opp(db8500_cpufreq_table[i].index); -} - static int set_plldsi_rate(unsigned long rate) { unsigned long src_rate; @@ -2074,8 +2030,6 @@ int prcmu_set_clock_rate(u8 clock, unsigned long rate) { if (clock < PRCMU_NUM_REG_CLOCKS) set_clock_rate(clock, rate); - else if (clock == PRCMU_ARMSS) - return set_armss_rate(rate); else if (clock == PRCMU_PLLDSI) return set_plldsi_rate(rate); else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK)) @@ -2800,6 +2754,8 @@ void __init db8500_prcmu_early_init(void) init_completion(&mb5_transfer.work); INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work); + + compute_armss_rate(); } static void __init init_prcm_registers(void) @@ -3064,8 +3020,6 @@ static struct mfd_cell db8500_prcmu_devs[] = { { .name = "cpufreq-u8500", .of_compatible = "stericsson,cpufreq-u8500", - .platform_data = &db8500_cpufreq_table, - .pdata_size = sizeof(db8500_cpufreq_table), }, { .name = "ab8500-core", @@ -3076,14 +3030,6 @@ static struct mfd_cell db8500_prcmu_devs[] = { }, }; -static void db8500_prcmu_update_cpufreq(void) -{ - if (prcmu_has_arm_maxopp()) { - db8500_cpufreq_table[3].frequency = 1000000; - db8500_cpufreq_table[3].index = ARM_MAX_OPP; - } -} - /** * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic * @@ -3128,8 +3074,6 @@ static int __devinit db8500_prcmu_probe(struct platform_device *pdev) if (cpu_is_u8500v20_or_later()) prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); - db8500_prcmu_update_cpufreq(); - err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, ARRAY_SIZE(db8500_prcmu_devs), NULL, 0, NULL); if (err) { diff --git a/trunk/drivers/mfd/twl-core.c b/trunk/drivers/mfd/twl-core.c index a071a8643a47..4ae642320205 100644 --- a/trunk/drivers/mfd/twl-core.c +++ b/trunk/drivers/mfd/twl-core.c @@ -671,7 +671,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base, } if (IS_ENABLED(CONFIG_PWM_TWL6030) && twl_class_is_6030()) { - child = add_child(SUB_CHIP_ID1, "twl6030-pwm", NULL, 0, + child = add_child(TWL6030_MODULE_ID1, "twl6030-pwm", NULL, 0, false, 0, 0); if (IS_ERR(child)) return PTR_ERR(child); diff --git a/trunk/drivers/mfd/twl4030-irq.c b/trunk/drivers/mfd/twl4030-irq.c index cdd1173ed4e9..ad733d76207a 100644 --- a/trunk/drivers/mfd/twl4030-irq.c +++ b/trunk/drivers/mfd/twl4030-irq.c @@ -672,8 +672,7 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base) irq = sih_mod + twl4030_irq_base; irq_set_handler_data(irq, agent); agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name); - status = request_threaded_irq(irq, NULL, handle_twl4030_sih, - IRQF_EARLY_RESUME, + status = request_threaded_irq(irq, NULL, handle_twl4030_sih, 0, agent->irq_name ?: sih->name, NULL); dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name, diff --git a/trunk/drivers/mfd/wm5102-tables.c b/trunk/drivers/mfd/wm5102-tables.c index 14490cc785d2..01b9255ed631 100644 --- a/trunk/drivers/mfd/wm5102-tables.c +++ b/trunk/drivers/mfd/wm5102-tables.c @@ -43,7 +43,6 @@ static const struct reg_default wm5102_reva_patch[] = { { 0x479, 0x0A30 }, { 0x47B, 0x0810 }, { 0x47D, 0x0510 }, - { 0x4D1, 0x017F }, { 0x500, 0x000D }, { 0x507, 0x1820 }, { 0x508, 0x1820 }, @@ -53,6 +52,524 @@ static const struct reg_default wm5102_reva_patch[] = { { 0x580, 0x000D }, { 0x587, 0x1820 }, { 0x588, 0x1820 }, + { 0x101, 0x8140 }, + { 0x3000, 0x2225 }, + { 0x3001, 0x3a03 }, + { 0x3002, 0x0225 }, + { 0x3003, 0x0801 }, + { 0x3004, 0x6249 }, + { 0x3005, 0x0c04 }, + { 0x3006, 0x0225 }, + { 0x3007, 0x5901 }, + { 0x3008, 0xe249 }, + { 0x3009, 0x030d }, + { 0x300a, 0x0249 }, + { 0x300b, 0x2c01 }, + { 0x300c, 0xe249 }, + { 0x300d, 0x4342 }, + { 0x300e, 0xe249 }, + { 0x300f, 0x73c0 }, + { 0x3010, 0x4249 }, + { 0x3011, 0x0c00 }, + { 0x3012, 0x0225 }, + { 0x3013, 0x1f01 }, + { 0x3014, 0x0225 }, + { 0x3015, 0x1e01 }, + { 0x3016, 0x0225 }, + { 0x3017, 0xfa00 }, + { 0x3018, 0x0000 }, + { 0x3019, 0xf000 }, + { 0x301a, 0x0000 }, + { 0x301b, 0xf000 }, + { 0x301c, 0x0000 }, + { 0x301d, 0xf000 }, + { 0x301e, 0x0000 }, + { 0x301f, 0xf000 }, + { 0x3020, 0x0000 }, + { 0x3021, 0xf000 }, + { 0x3022, 0x0000 }, + { 0x3023, 0xf000 }, + { 0x3024, 0x0000 }, + { 0x3025, 0xf000 }, + { 0x3026, 0x0000 }, + { 0x3027, 0xf000 }, + { 0x3028, 0x0000 }, + { 0x3029, 0xf000 }, + { 0x302a, 0x0000 }, + { 0x302b, 0xf000 }, + { 0x302c, 0x0000 }, + { 0x302d, 0xf000 }, + { 0x302e, 0x0000 }, + { 0x302f, 0xf000 }, + { 0x3030, 0x0225 }, + { 0x3031, 0x1a01 }, + { 0x3032, 0x0225 }, + { 0x3033, 0x1e00 }, + { 0x3034, 0x0225 }, + { 0x3035, 0x1f00 }, + { 0x3036, 0x6225 }, + { 0x3037, 0xf800 }, + { 0x3038, 0x0000 }, + { 0x3039, 0xf000 }, + { 0x303a, 0x0000 }, + { 0x303b, 0xf000 }, + { 0x303c, 0x0000 }, + { 0x303d, 0xf000 }, + { 0x303e, 0x0000 }, + { 0x303f, 0xf000 }, + { 0x3040, 0x2226 }, + { 0x3041, 0x3a03 }, + { 0x3042, 0x0226 }, + { 0x3043, 0x0801 }, + { 0x3044, 0x6249 }, + { 0x3045, 0x0c06 }, + { 0x3046, 0x0226 }, + { 0x3047, 0x5901 }, + { 0x3048, 0xe249 }, + { 0x3049, 0x030d }, + { 0x304a, 0x0249 }, + { 0x304b, 0x2c01 }, + { 0x304c, 0xe249 }, + { 0x304d, 0x4342 }, + { 0x304e, 0xe249 }, + { 0x304f, 0x73c0 }, + { 0x3050, 0x4249 }, + { 0x3051, 0x0c00 }, + { 0x3052, 0x0226 }, + { 0x3053, 0x1f01 }, + { 0x3054, 0x0226 }, + { 0x3055, 0x1e01 }, + { 0x3056, 0x0226 }, + { 0x3057, 0xfa00 }, + { 0x3058, 0x0000 }, + { 0x3059, 0xf000 }, + { 0x305a, 0x0000 }, + { 0x305b, 0xf000 }, + { 0x305c, 0x0000 }, + { 0x305d, 0xf000 }, + { 0x305e, 0x0000 }, + { 0x305f, 0xf000 }, + { 0x3060, 0x0000 }, + { 0x3061, 0xf000 }, + { 0x3062, 0x0000 }, + { 0x3063, 0xf000 }, + { 0x3064, 0x0000 }, + { 0x3065, 0xf000 }, + { 0x3066, 0x0000 }, + { 0x3067, 0xf000 }, + { 0x3068, 0x0000 }, + { 0x3069, 0xf000 }, + { 0x306a, 0x0000 }, + { 0x306b, 0xf000 }, + { 0x306c, 0x0000 }, + { 0x306d, 0xf000 }, + { 0x306e, 0x0000 }, + { 0x306f, 0xf000 }, + { 0x3070, 0x0226 }, + { 0x3071, 0x1a01 }, + { 0x3072, 0x0226 }, + { 0x3073, 0x1e00 }, + { 0x3074, 0x0226 }, + { 0x3075, 0x1f00 }, + { 0x3076, 0x6226 }, + { 0x3077, 0xf800 }, + { 0x3078, 0x0000 }, + { 0x3079, 0xf000 }, + { 0x307a, 0x0000 }, + { 0x307b, 0xf000 }, + { 0x307c, 0x0000 }, + { 0x307d, 0xf000 }, + { 0x307e, 0x0000 }, + { 0x307f, 0xf000 }, + { 0x3080, 0x2227 }, + { 0x3081, 0x3a03 }, + { 0x3082, 0x0227 }, + { 0x3083, 0x0801 }, + { 0x3084, 0x6255 }, + { 0x3085, 0x0c04 }, + { 0x3086, 0x0227 }, + { 0x3087, 0x5901 }, + { 0x3088, 0xe255 }, + { 0x3089, 0x030d }, + { 0x308a, 0x0255 }, + { 0x308b, 0x2c01 }, + { 0x308c, 0xe255 }, + { 0x308d, 0x4342 }, + { 0x308e, 0xe255 }, + { 0x308f, 0x73c0 }, + { 0x3090, 0x4255 }, + { 0x3091, 0x0c00 }, + { 0x3092, 0x0227 }, + { 0x3093, 0x1f01 }, + { 0x3094, 0x0227 }, + { 0x3095, 0x1e01 }, + { 0x3096, 0x0227 }, + { 0x3097, 0xfa00 }, + { 0x3098, 0x0000 }, + { 0x3099, 0xf000 }, + { 0x309a, 0x0000 }, + { 0x309b, 0xf000 }, + { 0x309c, 0x0000 }, + { 0x309d, 0xf000 }, + { 0x309e, 0x0000 }, + { 0x309f, 0xf000 }, + { 0x30a0, 0x0000 }, + { 0x30a1, 0xf000 }, + { 0x30a2, 0x0000 }, + { 0x30a3, 0xf000 }, + { 0x30a4, 0x0000 }, + { 0x30a5, 0xf000 }, + { 0x30a6, 0x0000 }, + { 0x30a7, 0xf000 }, + { 0x30a8, 0x0000 }, + { 0x30a9, 0xf000 }, + { 0x30aa, 0x0000 }, + { 0x30ab, 0xf000 }, + { 0x30ac, 0x0000 }, + { 0x30ad, 0xf000 }, + { 0x30ae, 0x0000 }, + { 0x30af, 0xf000 }, + { 0x30b0, 0x0227 }, + { 0x30b1, 0x1a01 }, + { 0x30b2, 0x0227 }, + { 0x30b3, 0x1e00 }, + { 0x30b4, 0x0227 }, + { 0x30b5, 0x1f00 }, + { 0x30b6, 0x6227 }, + { 0x30b7, 0xf800 }, + { 0x30b8, 0x0000 }, + { 0x30b9, 0xf000 }, + { 0x30ba, 0x0000 }, + { 0x30bb, 0xf000 }, + { 0x30bc, 0x0000 }, + { 0x30bd, 0xf000 }, + { 0x30be, 0x0000 }, + { 0x30bf, 0xf000 }, + { 0x30c0, 0x2228 }, + { 0x30c1, 0x3a03 }, + { 0x30c2, 0x0228 }, + { 0x30c3, 0x0801 }, + { 0x30c4, 0x6255 }, + { 0x30c5, 0x0c06 }, + { 0x30c6, 0x0228 }, + { 0x30c7, 0x5901 }, + { 0x30c8, 0xe255 }, + { 0x30c9, 0x030d }, + { 0x30ca, 0x0255 }, + { 0x30cb, 0x2c01 }, + { 0x30cc, 0xe255 }, + { 0x30cd, 0x4342 }, + { 0x30ce, 0xe255 }, + { 0x30cf, 0x73c0 }, + { 0x30d0, 0x4255 }, + { 0x30d1, 0x0c00 }, + { 0x30d2, 0x0228 }, + { 0x30d3, 0x1f01 }, + { 0x30d4, 0x0228 }, + { 0x30d5, 0x1e01 }, + { 0x30d6, 0x0228 }, + { 0x30d7, 0xfa00 }, + { 0x30d8, 0x0000 }, + { 0x30d9, 0xf000 }, + { 0x30da, 0x0000 }, + { 0x30db, 0xf000 }, + { 0x30dc, 0x0000 }, + { 0x30dd, 0xf000 }, + { 0x30de, 0x0000 }, + { 0x30df, 0xf000 }, + { 0x30e0, 0x0000 }, + { 0x30e1, 0xf000 }, + { 0x30e2, 0x0000 }, + { 0x30e3, 0xf000 }, + { 0x30e4, 0x0000 }, + { 0x30e5, 0xf000 }, + { 0x30e6, 0x0000 }, + { 0x30e7, 0xf000 }, + { 0x30e8, 0x0000 }, + { 0x30e9, 0xf000 }, + { 0x30ea, 0x0000 }, + { 0x30eb, 0xf000 }, + { 0x30ec, 0x0000 }, + { 0x30ed, 0xf000 }, + { 0x30ee, 0x0000 }, + { 0x30ef, 0xf000 }, + { 0x30f0, 0x0228 }, + { 0x30f1, 0x1a01 }, + { 0x30f2, 0x0228 }, + { 0x30f3, 0x1e00 }, + { 0x30f4, 0x0228 }, + { 0x30f5, 0x1f00 }, + { 0x30f6, 0x6228 }, + { 0x30f7, 0xf800 }, + { 0x30f8, 0x0000 }, + { 0x30f9, 0xf000 }, + { 0x30fa, 0x0000 }, + { 0x30fb, 0xf000 }, + { 0x30fc, 0x0000 }, + { 0x30fd, 0xf000 }, + { 0x30fe, 0x0000 }, + { 0x30ff, 0xf000 }, + { 0x3100, 0x222b }, + { 0x3101, 0x3a03 }, + { 0x3102, 0x222b }, + { 0x3103, 0x5803 }, + { 0x3104, 0xe26f }, + { 0x3105, 0x030d }, + { 0x3106, 0x626f }, + { 0x3107, 0x2c01 }, + { 0x3108, 0xe26f }, + { 0x3109, 0x4342 }, + { 0x310a, 0xe26f }, + { 0x310b, 0x73c0 }, + { 0x310c, 0x026f }, + { 0x310d, 0x0c00 }, + { 0x310e, 0x022b }, + { 0x310f, 0x1f01 }, + { 0x3110, 0x022b }, + { 0x3111, 0x1e01 }, + { 0x3112, 0x022b }, + { 0x3113, 0xfa00 }, + { 0x3114, 0x0000 }, + { 0x3115, 0xf000 }, + { 0x3116, 0x0000 }, + { 0x3117, 0xf000 }, + { 0x3118, 0x0000 }, + { 0x3119, 0xf000 }, + { 0x311a, 0x0000 }, + { 0x311b, 0xf000 }, + { 0x311c, 0x0000 }, + { 0x311d, 0xf000 }, + { 0x311e, 0x0000 }, + { 0x311f, 0xf000 }, + { 0x3120, 0x022b }, + { 0x3121, 0x0a01 }, + { 0x3122, 0x022b }, + { 0x3123, 0x1e00 }, + { 0x3124, 0x022b }, + { 0x3125, 0x1f00 }, + { 0x3126, 0x622b }, + { 0x3127, 0xf800 }, + { 0x3128, 0x0000 }, + { 0x3129, 0xf000 }, + { 0x312a, 0x0000 }, + { 0x312b, 0xf000 }, + { 0x312c, 0x0000 }, + { 0x312d, 0xf000 }, + { 0x312e, 0x0000 }, + { 0x312f, 0xf000 }, + { 0x3130, 0x0000 }, + { 0x3131, 0xf000 }, + { 0x3132, 0x0000 }, + { 0x3133, 0xf000 }, + { 0x3134, 0x0000 }, + { 0x3135, 0xf000 }, + { 0x3136, 0x0000 }, + { 0x3137, 0xf000 }, + { 0x3138, 0x0000 }, + { 0x3139, 0xf000 }, + { 0x313a, 0x0000 }, + { 0x313b, 0xf000 }, + { 0x313c, 0x0000 }, + { 0x313d, 0xf000 }, + { 0x313e, 0x0000 }, + { 0x313f, 0xf000 }, + { 0x3140, 0x0000 }, + { 0x3141, 0xf000 }, + { 0x3142, 0x0000 }, + { 0x3143, 0xf000 }, + { 0x3144, 0x0000 }, + { 0x3145, 0xf000 }, + { 0x3146, 0x0000 }, + { 0x3147, 0xf000 }, + { 0x3148, 0x0000 }, + { 0x3149, 0xf000 }, + { 0x314a, 0x0000 }, + { 0x314b, 0xf000 }, + { 0x314c, 0x0000 }, + { 0x314d, 0xf000 }, + { 0x314e, 0x0000 }, + { 0x314f, 0xf000 }, + { 0x3150, 0x0000 }, + { 0x3151, 0xf000 }, + { 0x3152, 0x0000 }, + { 0x3153, 0xf000 }, + { 0x3154, 0x0000 }, + { 0x3155, 0xf000 }, + { 0x3156, 0x0000 }, + { 0x3157, 0xf000 }, + { 0x3158, 0x0000 }, + { 0x3159, 0xf000 }, + { 0x315a, 0x0000 }, + { 0x315b, 0xf000 }, + { 0x315c, 0x0000 }, + { 0x315d, 0xf000 }, + { 0x315e, 0x0000 }, + { 0x315f, 0xf000 }, + { 0x3160, 0x0000 }, + { 0x3161, 0xf000 }, + { 0x3162, 0x0000 }, + { 0x3163, 0xf000 }, + { 0x3164, 0x0000 }, + { 0x3165, 0xf000 }, + { 0x3166, 0x0000 }, + { 0x3167, 0xf000 }, + { 0x3168, 0x0000 }, + { 0x3169, 0xf000 }, + { 0x316a, 0x0000 }, + { 0x316b, 0xf000 }, + { 0x316c, 0x0000 }, + { 0x316d, 0xf000 }, + { 0x316e, 0x0000 }, + { 0x316f, 0xf000 }, + { 0x3170, 0x0000 }, + { 0x3171, 0xf000 }, + { 0x3172, 0x0000 }, + { 0x3173, 0xf000 }, + { 0x3174, 0x0000 }, + { 0x3175, 0xf000 }, + { 0x3176, 0x0000 }, + { 0x3177, 0xf000 }, + { 0x3178, 0x0000 }, + { 0x3179, 0xf000 }, + { 0x317a, 0x0000 }, + { 0x317b, 0xf000 }, + { 0x317c, 0x0000 }, + { 0x317d, 0xf000 }, + { 0x317e, 0x0000 }, + { 0x317f, 0xf000 }, + { 0x3180, 0x2001 }, + { 0x3181, 0xf101 }, + { 0x3182, 0x0000 }, + { 0x3183, 0xf000 }, + { 0x3184, 0x0000 }, + { 0x3185, 0xf000 }, + { 0x3186, 0x0000 }, + { 0x3187, 0xf000 }, + { 0x3188, 0x0000 }, + { 0x3189, 0xf000 }, + { 0x318a, 0x0000 }, + { 0x318b, 0xf000 }, + { 0x318c, 0x0000 }, + { 0x318d, 0xf000 }, + { 0x318e, 0x0000 }, + { 0x318f, 0xf000 }, + { 0x3190, 0x0000 }, + { 0x3191, 0xf000 }, + { 0x3192, 0x0000 }, + { 0x3193, 0xf000 }, + { 0x3194, 0x0000 }, + { 0x3195, 0xf000 }, + { 0x3196, 0x0000 }, + { 0x3197, 0xf000 }, + { 0x3198, 0x0000 }, + { 0x3199, 0xf000 }, + { 0x319a, 0x0000 }, + { 0x319b, 0xf000 }, + { 0x319c, 0x0000 }, + { 0x319d, 0xf000 }, + { 0x319e, 0x0000 }, + { 0x319f, 0xf000 }, + { 0x31a0, 0x0000 }, + { 0x31a1, 0xf000 }, + { 0x31a2, 0x0000 }, + { 0x31a3, 0xf000 }, + { 0x31a4, 0x0000 }, + { 0x31a5, 0xf000 }, + { 0x31a6, 0x0000 }, + { 0x31a7, 0xf000 }, + { 0x31a8, 0x0000 }, + { 0x31a9, 0xf000 }, + { 0x31aa, 0x0000 }, + { 0x31ab, 0xf000 }, + { 0x31ac, 0x0000 }, + { 0x31ad, 0xf000 }, + { 0x31ae, 0x0000 }, + { 0x31af, 0xf000 }, + { 0x31b0, 0x0000 }, + { 0x31b1, 0xf000 }, + { 0x31b2, 0x0000 }, + { 0x31b3, 0xf000 }, + { 0x31b4, 0x0000 }, + { 0x31b5, 0xf000 }, + { 0x31b6, 0x0000 }, + { 0x31b7, 0xf000 }, + { 0x31b8, 0x0000 }, + { 0x31b9, 0xf000 }, + { 0x31ba, 0x0000 }, + { 0x31bb, 0xf000 }, + { 0x31bc, 0x0000 }, + { 0x31bd, 0xf000 }, + { 0x31be, 0x0000 }, + { 0x31bf, 0xf000 }, + { 0x31c0, 0x0000 }, + { 0x31c1, 0xf000 }, + { 0x31c2, 0x0000 }, + { 0x31c3, 0xf000 }, + { 0x31c4, 0x0000 }, + { 0x31c5, 0xf000 }, + { 0x31c6, 0x0000 }, + { 0x31c7, 0xf000 }, + { 0x31c8, 0x0000 }, + { 0x31c9, 0xf000 }, + { 0x31ca, 0x0000 }, + { 0x31cb, 0xf000 }, + { 0x31cc, 0x0000 }, + { 0x31cd, 0xf000 }, + { 0x31ce, 0x0000 }, + { 0x31cf, 0xf000 }, + { 0x31d0, 0x0000 }, + { 0x31d1, 0xf000 }, + { 0x31d2, 0x0000 }, + { 0x31d3, 0xf000 }, + { 0x31d4, 0x0000 }, + { 0x31d5, 0xf000 }, + { 0x31d6, 0x0000 }, + { 0x31d7, 0xf000 }, + { 0x31d8, 0x0000 }, + { 0x31d9, 0xf000 }, + { 0x31da, 0x0000 }, + { 0x31db, 0xf000 }, + { 0x31dc, 0x0000 }, + { 0x31dd, 0xf000 }, + { 0x31de, 0x0000 }, + { 0x31df, 0xf000 }, + { 0x31e0, 0x0000 }, + { 0x31e1, 0xf000 }, + { 0x31e2, 0x0000 }, + { 0x31e3, 0xf000 }, + { 0x31e4, 0x0000 }, + { 0x31e5, 0xf000 }, + { 0x31e6, 0x0000 }, + { 0x31e7, 0xf000 }, + { 0x31e8, 0x0000 }, + { 0x31e9, 0xf000 }, + { 0x31ea, 0x0000 }, + { 0x31eb, 0xf000 }, + { 0x31ec, 0x0000 }, + { 0x31ed, 0xf000 }, + { 0x31ee, 0x0000 }, + { 0x31ef, 0xf000 }, + { 0x31f0, 0x0000 }, + { 0x31f1, 0xf000 }, + { 0x31f2, 0x0000 }, + { 0x31f3, 0xf000 }, + { 0x31f4, 0x0000 }, + { 0x31f5, 0xf000 }, + { 0x31f6, 0x0000 }, + { 0x31f7, 0xf000 }, + { 0x31f8, 0x0000 }, + { 0x31f9, 0xf000 }, + { 0x31fa, 0x0000 }, + { 0x31fb, 0xf000 }, + { 0x31fc, 0x0000 }, + { 0x31fd, 0xf000 }, + { 0x31fe, 0x0000 }, + { 0x31ff, 0xf000 }, + { 0x024d, 0xff50 }, + { 0x0252, 0xff50 }, + { 0x0259, 0x0112 }, + { 0x025e, 0x0112 }, + { 0x101, 0x0304 }, { 0x80, 0x0000 }, }; diff --git a/trunk/drivers/mmc/card/block.c b/trunk/drivers/mmc/card/block.c index 21056b9ef0a0..172a768036d8 100644 --- a/trunk/drivers/mmc/card/block.c +++ b/trunk/drivers/mmc/card/block.c @@ -57,7 +57,6 @@ MODULE_ALIAS("mmc:block"); #define INAND_CMD38_ARG_SECERASE 0x80 #define INAND_CMD38_ARG_SECTRIM1 0x81 #define INAND_CMD38_ARG_SECTRIM2 0x88 -#define MMC_BLK_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ static DEFINE_MUTEX(block_mutex); @@ -127,10 +126,6 @@ enum mmc_blk_status { module_param(perdev_minors, int, 0444); MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device"); -static inline int mmc_blk_part_switch(struct mmc_card *card, - struct mmc_blk_data *md); -static int get_card_status(struct mmc_card *card, u32 *status, int retries); - static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) { struct mmc_blk_data *md; @@ -362,38 +357,6 @@ static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user( return ERR_PTR(err); } -static int ioctl_rpmb_card_status_poll(struct mmc_card *card, u32 *status, - u32 retries_max) -{ - int err; - u32 retry_count = 0; - - if (!status || !retries_max) - return -EINVAL; - - do { - err = get_card_status(card, status, 5); - if (err) - break; - - if (!R1_STATUS(*status) && - (R1_CURRENT_STATE(*status) != R1_STATE_PRG)) - break; /* RPMB programming operation complete */ - - /* - * Rechedule to give the MMC device a chance to continue - * processing the previous command without being polled too - * frequently. - */ - usleep_range(1000, 5000); - } while (++retry_count < retries_max); - - if (retry_count == retries_max) - err = -EPERM; - - return err; -} - static int mmc_blk_ioctl_cmd(struct block_device *bdev, struct mmc_ioc_cmd __user *ic_ptr) { @@ -405,8 +368,6 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, struct mmc_request mrq = {NULL}; struct scatterlist sg; int err; - int is_rpmb = false; - u32 status = 0; /* * The caller must have CAP_SYS_RAWIO, and must be calling this on the @@ -426,9 +387,6 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, goto cmd_err; } - if (md->area_type & MMC_BLK_DATA_AREA_RPMB) - is_rpmb = true; - card = md->queue.card; if (IS_ERR(card)) { err = PTR_ERR(card); @@ -479,23 +437,12 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, mmc_claim_host(card->host); - err = mmc_blk_part_switch(card, md); - if (err) - goto cmd_rel_host; - if (idata->ic.is_acmd) { err = mmc_app_cmd(card->host, card); if (err) goto cmd_rel_host; } - if (is_rpmb) { - err = mmc_set_blockcount(card, data.blocks, - idata->ic.write_flag & (1 << 31)); - if (err) - goto cmd_rel_host; - } - mmc_wait_for_req(card->host, &mrq); if (cmd.error) { @@ -531,18 +478,6 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, } } - if (is_rpmb) { - /* - * Ensure RPMB command has completed by polling CMD13 - * "Send Status". - */ - err = ioctl_rpmb_card_status_poll(card, &status, 5); - if (err) - dev_err(mmc_dev(card->host), - "%s: Card Status=0x%08X, error %d\n", - __func__, status, err); - } - cmd_rel_host: mmc_release_host(card->host); @@ -1099,9 +1034,6 @@ static int mmc_blk_err_check(struct mmc_card *card, */ if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) { u32 status; - unsigned long timeout; - - timeout = jiffies + msecs_to_jiffies(MMC_BLK_TIMEOUT_MS); do { int err = get_card_status(card, &status, 5); if (err) { @@ -1109,17 +1041,6 @@ static int mmc_blk_err_check(struct mmc_card *card, req->rq_disk->disk_name, err); return MMC_BLK_CMD_ERR; } - - /* Timeout if the device never becomes ready for data - * and never leaves the program state. - */ - if (time_after(jiffies, timeout)) { - pr_err("%s: Card stuck in programming state!"\ - " %s %s\n", mmc_hostname(card->host), - req->rq_disk->disk_name, __func__); - - return MMC_BLK_CMD_ERR; - } /* * Some cards mishandle the status bits, * so make sure to check both the busy @@ -1583,8 +1504,6 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, md->disk->queue = md->queue.queue; md->disk->driverfs_dev = parent; set_disk_ro(md->disk, md->read_only || default_ro); - if (area_type & MMC_BLK_DATA_AREA_RPMB) - md->disk->flags |= GENHD_FL_NO_PART_SCAN; /* * As discussed on lkml, GENHD_FL_REMOVABLE should: diff --git a/trunk/drivers/mmc/card/queue.c b/trunk/drivers/mmc/card/queue.c index fadf52eb5d70..e360a979857d 100644 --- a/trunk/drivers/mmc/card/queue.c +++ b/trunk/drivers/mmc/card/queue.c @@ -68,16 +68,6 @@ static int mmc_queue_thread(void *d) if (req || mq->mqrq_prev->req) { set_current_state(TASK_RUNNING); mq->issue_fn(mq, req); - - /* - * Current request becomes previous request - * and vice versa. - */ - mq->mqrq_prev->brq.mrq.data = NULL; - mq->mqrq_prev->req = NULL; - tmp = mq->mqrq_prev; - mq->mqrq_prev = mq->mqrq_cur; - mq->mqrq_cur = tmp; } else { if (kthread_should_stop()) { set_current_state(TASK_RUNNING); @@ -87,6 +77,13 @@ static int mmc_queue_thread(void *d) schedule(); down(&mq->thread_sem); } + + /* Current request becomes previous request and vice versa. */ + mq->mqrq_prev->brq.mrq.data = NULL; + mq->mqrq_prev->req = NULL; + tmp = mq->mqrq_prev; + mq->mqrq_prev = mq->mqrq_cur; + mq->mqrq_cur = tmp; } while (1); up(&mq->thread_sem); diff --git a/trunk/drivers/mmc/core/bus.c b/trunk/drivers/mmc/core/bus.c index 420cb6753c1e..9b68933f27e7 100644 --- a/trunk/drivers/mmc/core/bus.c +++ b/trunk/drivers/mmc/core/bus.c @@ -225,7 +225,8 @@ static void mmc_release_card(struct device *dev) sdio_free_common_cis(card); - kfree(card->info); + if (card->info) + kfree(card->info); kfree(card); } diff --git a/trunk/drivers/mmc/core/core.c b/trunk/drivers/mmc/core/core.c index aaed7687cf09..06c42cfb7c34 100644 --- a/trunk/drivers/mmc/core/core.c +++ b/trunk/drivers/mmc/core/core.c @@ -42,9 +42,6 @@ #include "sd_ops.h" #include "sdio_ops.h" -/* If the device is not responding */ -#define MMC_CORE_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ - /* * Background operations can take a long time, depending on the housekeeping * operations the card has to perform. @@ -1634,7 +1631,6 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, { struct mmc_command cmd = {0}; unsigned int qty = 0; - unsigned long timeout; int err; /* @@ -1712,7 +1708,6 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, if (mmc_host_is_spi(card->host)) goto out; - timeout = jiffies + msecs_to_jiffies(MMC_CORE_TIMEOUT_MS); do { memset(&cmd, 0, sizeof(struct mmc_command)); cmd.opcode = MMC_SEND_STATUS; @@ -1726,19 +1721,8 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, err = -EIO; goto out; } - - /* Timeout if the device never becomes ready for data and - * never leaves the program state. - */ - if (time_after(jiffies, timeout)) { - pr_err("%s: Card stuck in programming state! %s\n", - mmc_hostname(card->host), __func__); - err = -EIO; - goto out; - } - } while (!(cmd.resp[0] & R1_READY_FOR_DATA) || - (R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG)); + R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG); out: return err; } @@ -1958,20 +1942,6 @@ int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen) } EXPORT_SYMBOL(mmc_set_blocklen); -int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount, - bool is_rel_write) -{ - struct mmc_command cmd = {0}; - - cmd.opcode = MMC_SET_BLOCK_COUNT; - cmd.arg = blockcount & 0x0000FFFF; - if (is_rel_write) - cmd.arg |= 1 << 31; - cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; - return mmc_wait_for_cmd(card->host, &cmd, 5); -} -EXPORT_SYMBOL(mmc_set_blockcount); - static void mmc_hw_reset_for_init(struct mmc_host *host) { if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset) diff --git a/trunk/drivers/mmc/core/debugfs.c b/trunk/drivers/mmc/core/debugfs.c index 35c2f85b1956..d96c643dde1c 100644 --- a/trunk/drivers/mmc/core/debugfs.c +++ b/trunk/drivers/mmc/core/debugfs.c @@ -144,22 +144,6 @@ static int mmc_ios_show(struct seq_file *s, void *data) } seq_printf(s, "timing spec:\t%u (%s)\n", ios->timing, str); - switch (ios->signal_voltage) { - case MMC_SIGNAL_VOLTAGE_330: - str = "3.30 V"; - break; - case MMC_SIGNAL_VOLTAGE_180: - str = "1.80 V"; - break; - case MMC_SIGNAL_VOLTAGE_120: - str = "1.20 V"; - break; - default: - str = "invalid"; - break; - } - seq_printf(s, "signal voltage:\t%u (%s)\n", ios->chip_select, str); - return 0; } diff --git a/trunk/drivers/mmc/core/mmc.c b/trunk/drivers/mmc/core/mmc.c index e6e39111e05b..7cc46382fd64 100644 --- a/trunk/drivers/mmc/core/mmc.c +++ b/trunk/drivers/mmc/core/mmc.c @@ -239,7 +239,7 @@ static void mmc_select_card_type(struct mmc_card *card) { struct mmc_host *host = card->host; u8 card_type = card->ext_csd.raw_card_type & EXT_CSD_CARD_TYPE_MASK; - u32 caps = host->caps, caps2 = host->caps2; + unsigned int caps = host->caps, caps2 = host->caps2; unsigned int hs_max_dtr = 0; if (card_type & EXT_CSD_CARD_TYPE_26) @@ -491,17 +491,6 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM]; card->ext_csd.rst_n_function = ext_csd[EXT_CSD_RST_N_FUNCTION]; - - /* - * RPMB regions are defined in multiples of 128K. - */ - card->ext_csd.raw_rpmb_size_mult = ext_csd[EXT_CSD_RPMB_MULT]; - if (ext_csd[EXT_CSD_RPMB_MULT]) { - mmc_part_add(card, ext_csd[EXT_CSD_RPMB_MULT] << 17, - EXT_CSD_PART_CONFIG_ACC_RPMB, - "rpmb", 0, false, - MMC_BLK_DATA_AREA_RPMB); - } } card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT]; @@ -626,8 +615,6 @@ MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial); MMC_DEV_ATTR(enhanced_area_offset, "%llu\n", card->ext_csd.enhanced_area_offset); MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size); -MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult); -MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors); static struct attribute *mmc_std_attrs[] = { &dev_attr_cid.attr, @@ -643,8 +630,6 @@ static struct attribute *mmc_std_attrs[] = { &dev_attr_serial.attr, &dev_attr_enhanced_area_offset.attr, &dev_attr_enhanced_area_size.attr, - &dev_attr_raw_rpmb_size_mult.attr, - &dev_attr_rel_sectors.attr, NULL, }; @@ -1066,8 +1051,6 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, if (mmc_card_highspeed(card) || mmc_card_hs200(card)) { if (max_dtr > card->ext_csd.hs_max_dtr) max_dtr = card->ext_csd.hs_max_dtr; - if (mmc_card_highspeed(card) && (max_dtr > 52000000)) - max_dtr = 52000000; } else if (max_dtr > card->csd.max_dtr) { max_dtr = card->csd.max_dtr; } diff --git a/trunk/drivers/mmc/core/mmc_ops.c b/trunk/drivers/mmc/core/mmc_ops.c index 6d8f7012d73a..a0e172042e65 100644 --- a/trunk/drivers/mmc/core/mmc_ops.c +++ b/trunk/drivers/mmc/core/mmc_ops.c @@ -21,8 +21,6 @@ #include "core.h" #include "mmc_ops.h" -#define MMC_OPS_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ - static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card) { int err; @@ -411,7 +409,6 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, { int err; struct mmc_command cmd = {0}; - unsigned long timeout; u32 status; BUG_ON(!card); @@ -440,7 +437,6 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, return 0; /* Must check status to be sure of no errors */ - timeout = jiffies + msecs_to_jiffies(MMC_OPS_TIMEOUT_MS); do { err = mmc_send_status(card, &status); if (err) @@ -449,13 +445,6 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, break; if (mmc_host_is_spi(card->host)) break; - - /* Timeout if the device never leaves the program state. */ - if (time_after(jiffies, timeout)) { - pr_err("%s: Card stuck in programming state! %s\n", - mmc_hostname(card->host), __func__); - return -ETIMEDOUT; - } } while (R1_CURRENT_STATE(status) == R1_STATE_PRG); if (mmc_host_is_spi(card->host)) { diff --git a/trunk/drivers/mmc/core/sdio_bus.c b/trunk/drivers/mmc/core/sdio_bus.c index 5e57048e2c1d..6bf68799fe97 100644 --- a/trunk/drivers/mmc/core/sdio_bus.c +++ b/trunk/drivers/mmc/core/sdio_bus.c @@ -193,21 +193,7 @@ static int sdio_bus_remove(struct device *dev) } #ifdef CONFIG_PM - -#ifdef CONFIG_PM_SLEEP -static int pm_no_operation(struct device *dev) -{ - /* - * Prevent the PM core from calling SDIO device drivers' suspend - * callback routines, which it is not supposed to do, by using this - * empty function as the bus type suspend callaback for SDIO. - */ - return 0; -} -#endif - static const struct dev_pm_ops sdio_bus_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(pm_no_operation, pm_no_operation) SET_RUNTIME_PM_OPS( pm_generic_runtime_suspend, pm_generic_runtime_resume, @@ -272,7 +258,8 @@ static void sdio_release_func(struct device *dev) sdio_free_func_cis(func); - kfree(func->info); + if (func->info) + kfree(func->info); kfree(func); } diff --git a/trunk/drivers/mmc/core/sdio_io.c b/trunk/drivers/mmc/core/sdio_io.c index 78cb4d5d9d58..8f6f5ac131fc 100644 --- a/trunk/drivers/mmc/core/sdio_io.c +++ b/trunk/drivers/mmc/core/sdio_io.c @@ -188,7 +188,8 @@ EXPORT_SYMBOL_GPL(sdio_set_block_size); */ static inline unsigned int sdio_max_byte_size(struct sdio_func *func) { - unsigned mval = func->card->host->max_blk_size; + unsigned mval = min(func->card->host->max_seg_size, + func->card->host->max_blk_size); if (mmc_blksz_for_byte_mode(func->card)) mval = min(mval, func->cur_blksize); @@ -310,8 +311,11 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write, /* Do the bulk of the transfer using block mode (if supported). */ if (func->card->cccr.multi_block && (size > sdio_max_byte_size(func))) { /* Blocks per command is limited by host count, host transfer - * size and the maximum for IO_RW_EXTENDED of 511 blocks. */ - max_blocks = min(func->card->host->max_blk_count, 511u); + * size (we only use a single sg entry) and the maximum for + * IO_RW_EXTENDED of 511 blocks. */ + max_blocks = min(func->card->host->max_blk_count, + func->card->host->max_seg_size / func->cur_blksize); + max_blocks = min(max_blocks, 511u); while (remainder >= func->cur_blksize) { unsigned blocks; diff --git a/trunk/drivers/mmc/core/sdio_ops.c b/trunk/drivers/mmc/core/sdio_ops.c index 62508b457c4f..d29e20630eed 100644 --- a/trunk/drivers/mmc/core/sdio_ops.c +++ b/trunk/drivers/mmc/core/sdio_ops.c @@ -124,10 +124,7 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, struct mmc_request mrq = {NULL}; struct mmc_command cmd = {0}; struct mmc_data data = {0}; - struct scatterlist sg, *sg_ptr; - struct sg_table sgtable; - unsigned int nents, left_size, i; - unsigned int seg_size = card->host->max_seg_size; + struct scatterlist sg; BUG_ON(!card); BUG_ON(fn > 7); @@ -155,36 +152,15 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, /* Code in host drivers/fwk assumes that "blocks" always is >=1 */ data.blocks = blocks ? blocks : 1; data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; + data.sg = &sg; + data.sg_len = 1; - left_size = data.blksz * data.blocks; - nents = (left_size - 1) / seg_size + 1; - if (nents > 1) { - if (sg_alloc_table(&sgtable, nents, GFP_KERNEL)) - return -ENOMEM; - - data.sg = sgtable.sgl; - data.sg_len = nents; - - for_each_sg(data.sg, sg_ptr, data.sg_len, i) { - sg_set_page(sg_ptr, virt_to_page(buf + (i * seg_size)), - min(seg_size, left_size), - offset_in_page(buf + (i * seg_size))); - left_size = left_size - seg_size; - } - } else { - data.sg = &sg; - data.sg_len = 1; - - sg_init_one(&sg, buf, left_size); - } + sg_init_one(&sg, buf, data.blksz * data.blocks); mmc_set_data_timeout(&data, card); mmc_wait_for_req(card->host, &mrq); - if (nents > 1) - sg_free_table(&sgtable); - if (cmd.error) return cmd.error; if (data.error) diff --git a/trunk/drivers/mmc/core/slot-gpio.c b/trunk/drivers/mmc/core/slot-gpio.c index 16a1c0b6f264..08c6b3dfe080 100644 --- a/trunk/drivers/mmc/core/slot-gpio.c +++ b/trunk/drivers/mmc/core/slot-gpio.c @@ -27,13 +27,7 @@ struct mmc_gpio { static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id) { /* Schedule a card detection after a debounce timeout */ - struct mmc_host *host = dev_id; - - if (host->ops->card_event) - host->ops->card_event(host); - - mmc_detect_change(host, msecs_to_jiffies(200)); - + mmc_detect_change(dev_id, msecs_to_jiffies(100)); return IRQ_HANDLED; } diff --git a/trunk/drivers/mmc/host/Kconfig b/trunk/drivers/mmc/host/Kconfig index 83eb1e06ff76..9bf10e7bbfaf 100644 --- a/trunk/drivers/mmc/host/Kconfig +++ b/trunk/drivers/mmc/host/Kconfig @@ -270,8 +270,26 @@ config MMC_AU1X If unsure, say N. +choice + prompt "Atmel SD/MMC Driver" + depends on AVR32 || ARCH_AT91 + default MMC_ATMELMCI if AVR32 + help + Choose which driver to use for the Atmel MCI Silicon + +config MMC_AT91 + tristate "AT91 SD/MMC Card Interface support (DEPRECATED)" + depends on ARCH_AT91 + help + This selects the AT91 MCI controller. This driver will + be removed soon (for more information have a look to + Documentation/feature-removal-schedule.txt). Please use + MMC_ATMEL_MCI. + + If unsure, say N. + config MMC_ATMELMCI - tristate "Atmel SD/MMC Driver (Multimedia Card Interface)" + tristate "Atmel Multimedia Card Interface support" depends on AVR32 || ARCH_AT91 help This selects the Atmel Multimedia Card Interface driver. If @@ -280,6 +298,8 @@ config MMC_ATMELMCI If unsure, say N. +endchoice + config MMC_ATMELMCI_DMA bool "Atmel MCI DMA support" depends on MMC_ATMELMCI && (AVR32 || ARCH_AT91SAM9G45) && DMA_ENGINE @@ -601,14 +621,3 @@ config MMC_USHC Note: These controllers only support SDIO cards and do not support MMC or SD memory cards. - -config MMC_WMT - tristate "Wondermedia SD/MMC Host Controller support" - depends on ARCH_VT8500 - default y - help - This selects support for the SD/MMC Host Controller on - Wondermedia WM8505/WM8650 based SoCs. - - To compile this driver as a module, choose M here: the - module will be called wmt-sdmmc. diff --git a/trunk/drivers/mmc/host/Makefile b/trunk/drivers/mmc/host/Makefile index 39d5e1234709..17ad0a7ba40b 100644 --- a/trunk/drivers/mmc/host/Makefile +++ b/trunk/drivers/mmc/host/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o obj-$(CONFIG_MMC_OMAP) += omap.o obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o +obj-$(CONFIG_MMC_AT91) += at91_mci.o obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o obj-$(CONFIG_MMC_MSM) += msm_sdcc.o @@ -44,7 +45,6 @@ obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o obj-$(CONFIG_MMC_VUB300) += vub300.o obj-$(CONFIG_MMC_USHC) += ushc.o -obj-$(CONFIG_MMC_WMT) += wmt-sdmmc.o obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o obj-$(CONFIG_MMC_SDHCI_CNS3XXX) += sdhci-cns3xxx.o diff --git a/trunk/drivers/mmc/host/at91_mci.c b/trunk/drivers/mmc/host/at91_mci.c new file mode 100644 index 000000000000..74bed0fc23e7 --- /dev/null +++ b/trunk/drivers/mmc/host/at91_mci.c @@ -0,0 +1,1219 @@ +/* + * linux/drivers/mmc/host/at91_mci.c - ATMEL AT91 MCI Driver + * + * Copyright (C) 2005 Cougar Creek Computing Devices Ltd, All Rights Reserved + * + * Copyright (C) 2006 Malcolm Noyes + * + * 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 is the AT91 MCI driver that has been tested with both MMC cards + and SD-cards. Boards that support write protect are now supported. + The CCAT91SBC001 board does not support SD cards. + + The three entry points are at91_mci_request, at91_mci_set_ios + and at91_mci_get_ro. + + SET IOS + This configures the device to put it into the correct mode and clock speed + required. + + MCI REQUEST + MCI request processes the commands sent in the mmc_request structure. This + can consist of a processing command and a stop command in the case of + multiple block transfers. + + There are three main types of request, commands, reads and writes. + + Commands are straight forward. The command is submitted to the controller and + the request function returns. When the controller generates an interrupt to indicate + the command is finished, the response to the command are read and the mmc_request_done + function called to end the request. + + Reads and writes work in a similar manner to normal commands but involve the PDC (DMA) + controller to manage the transfers. + + A read is done from the controller directly to the scatterlist passed in from the request. + Due to a bug in the AT91RM9200 controller, when a read is completed, all the words are byte + swapped in the scatterlist buffers. AT91SAM926x are not affected by this bug. + + The sequence of read interrupts is: ENDRX, RXBUFF, CMDRDY + + A write is slightly different in that the bytes to write are read from the scatterlist + into a dma memory buffer (this is in case the source buffer should be read only). The + entire write buffer is then done from this single dma memory buffer. + + The sequence of write interrupts is: ENDTX, TXBUFE, NOTBUSY, CMDRDY + + GET RO + Gets the status of the write protect pin, if available. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include "at91_mci.h" + +#define DRIVER_NAME "at91_mci" + +static inline int at91mci_is_mci1rev2xx(void) +{ + return ( cpu_is_at91sam9260() + || cpu_is_at91sam9263() + || cpu_is_at91sam9rl() + || cpu_is_at91sam9g10() + || cpu_is_at91sam9g20() + ); +} + +#define FL_SENT_COMMAND (1 << 0) +#define FL_SENT_STOP (1 << 1) + +#define AT91_MCI_ERRORS (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE \ + | AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE \ + | AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE) + +#define at91_mci_read(host, reg) __raw_readl((host)->baseaddr + (reg)) +#define at91_mci_write(host, reg, val) __raw_writel((val), (host)->baseaddr + (reg)) + +#define MCI_BLKSIZE 512 +#define MCI_MAXBLKSIZE 4095 +#define MCI_BLKATONCE 256 +#define MCI_BUFSIZE (MCI_BLKSIZE * MCI_BLKATONCE) + +/* + * Low level type for this driver + */ +struct at91mci_host +{ + struct mmc_host *mmc; + struct mmc_command *cmd; + struct mmc_request *request; + + void __iomem *baseaddr; + int irq; + + struct at91_mmc_data *board; + int present; + + struct clk *mci_clk; + + /* + * Flag indicating when the command has been sent. This is used to + * work out whether or not to send the stop + */ + unsigned int flags; + /* flag for current bus settings */ + u32 bus_mode; + + /* DMA buffer used for transmitting */ + unsigned int* buffer; + dma_addr_t physical_address; + unsigned int total_length; + + /* Latest in the scatterlist that has been enabled for transfer, but not freed */ + int in_use_index; + + /* Latest in the scatterlist that has been enabled for transfer */ + int transfer_index; + + /* Timer for timeouts */ + struct timer_list timer; +}; + +/* + * Reset the controller and restore most of the state + */ +static void at91_reset_host(struct at91mci_host *host) +{ + unsigned long flags; + u32 mr; + u32 sdcr; + u32 dtor; + u32 imr; + + local_irq_save(flags); + imr = at91_mci_read(host, AT91_MCI_IMR); + + at91_mci_write(host, AT91_MCI_IDR, 0xffffffff); + + /* save current state */ + mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff; + sdcr = at91_mci_read(host, AT91_MCI_SDCR); + dtor = at91_mci_read(host, AT91_MCI_DTOR); + + /* reset the controller */ + at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIDIS | AT91_MCI_SWRST); + + /* restore state */ + at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN); + at91_mci_write(host, AT91_MCI_MR, mr); + at91_mci_write(host, AT91_MCI_SDCR, sdcr); + at91_mci_write(host, AT91_MCI_DTOR, dtor); + at91_mci_write(host, AT91_MCI_IER, imr); + + /* make sure sdio interrupts will fire */ + at91_mci_read(host, AT91_MCI_SR); + + local_irq_restore(flags); +} + +static void at91_timeout_timer(unsigned long data) +{ + struct at91mci_host *host; + + host = (struct at91mci_host *)data; + + if (host->request) { + dev_err(host->mmc->parent, "Timeout waiting end of packet\n"); + + if (host->cmd && host->cmd->data) { + host->cmd->data->error = -ETIMEDOUT; + } else { + if (host->cmd) + host->cmd->error = -ETIMEDOUT; + else + host->request->cmd->error = -ETIMEDOUT; + } + + at91_reset_host(host); + mmc_request_done(host->mmc, host->request); + } +} + +/* + * Copy from sg to a dma block - used for transfers + */ +static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data *data) +{ + unsigned int len, i, size; + unsigned *dmabuf = host->buffer; + + size = data->blksz * data->blocks; + len = data->sg_len; + + /* MCI1 rev2xx Data Write Operation and number of bytes erratum */ + if (at91mci_is_mci1rev2xx()) + if (host->total_length == 12) + memset(dmabuf, 0, 12); + + /* + * Just loop through all entries. Size might not + * be the entire list though so make sure that + * we do not transfer too much. + */ + for (i = 0; i < len; i++) { + struct scatterlist *sg; + int amount; + unsigned int *sgbuffer; + + sg = &data->sg[i]; + + sgbuffer = kmap_atomic(sg_page(sg)) + sg->offset; + amount = min(size, sg->length); + size -= amount; + + if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */ + int index; + + for (index = 0; index < (amount / 4); index++) + *dmabuf++ = swab32(sgbuffer[index]); + } else { + char *tmpv = (char *)dmabuf; + memcpy(tmpv, sgbuffer, amount); + tmpv += amount; + dmabuf = (unsigned *)tmpv; + } + + kunmap_atomic(sgbuffer); + + if (size == 0) + break; + } + + /* + * Check that we didn't get a request to transfer + * more data than can fit into the SG list. + */ + BUG_ON(size != 0); +} + +/* + * Handle after a dma read + */ +static void at91_mci_post_dma_read(struct at91mci_host *host) +{ + struct mmc_command *cmd; + struct mmc_data *data; + unsigned int len, i, size; + unsigned *dmabuf = host->buffer; + + pr_debug("post dma read\n"); + + cmd = host->cmd; + if (!cmd) { + pr_debug("no command\n"); + return; + } + + data = cmd->data; + if (!data) { + pr_debug("no data\n"); + return; + } + + size = data->blksz * data->blocks; + len = data->sg_len; + + at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX); + at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF); + + for (i = 0; i < len; i++) { + struct scatterlist *sg; + int amount; + unsigned int *sgbuffer; + + sg = &data->sg[i]; + + sgbuffer = kmap_atomic(sg_page(sg)) + sg->offset; + amount = min(size, sg->length); + size -= amount; + + if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */ + int index; + for (index = 0; index < (amount / 4); index++) + sgbuffer[index] = swab32(*dmabuf++); + } else { + char *tmpv = (char *)dmabuf; + memcpy(sgbuffer, tmpv, amount); + tmpv += amount; + dmabuf = (unsigned *)tmpv; + } + + flush_kernel_dcache_page(sg_page(sg)); + kunmap_atomic(sgbuffer); + data->bytes_xfered += amount; + if (size == 0) + break; + } + + pr_debug("post dma read done\n"); +} + +/* + * Handle transmitted data + */ +static void at91_mci_handle_transmitted(struct at91mci_host *host) +{ + struct mmc_command *cmd; + struct mmc_data *data; + + pr_debug("Handling the transmit\n"); + + /* Disable the transfer */ + at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS); + + /* Now wait for cmd ready */ + at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_TXBUFE); + + cmd = host->cmd; + if (!cmd) return; + + data = cmd->data; + if (!data) return; + + if (cmd->data->blocks > 1) { + pr_debug("multiple write : wait for BLKE...\n"); + at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE); + } else + at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY); +} + +/* + * Update bytes transfered count during a write operation + */ +static void at91_mci_update_bytes_xfered(struct at91mci_host *host) +{ + struct mmc_data *data; + + /* always deal with the effective request (and not the current cmd) */ + + if (host->request->cmd && host->request->cmd->error != 0) + return; + + if (host->request->data) { + data = host->request->data; + if (data->flags & MMC_DATA_WRITE) { + /* card is in IDLE mode now */ + pr_debug("-> bytes_xfered %d, total_length = %d\n", + data->bytes_xfered, host->total_length); + data->bytes_xfered = data->blksz * data->blocks; + } + } +} + + +/*Handle after command sent ready*/ +static int at91_mci_handle_cmdrdy(struct at91mci_host *host) +{ + if (!host->cmd) + return 1; + else if (!host->cmd->data) { + if (host->flags & FL_SENT_STOP) { + /*After multi block write, we must wait for NOTBUSY*/ + at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY); + } else return 1; + } else if (host->cmd->data->flags & MMC_DATA_WRITE) { + /*After sendding multi-block-write command, start DMA transfer*/ + at91_mci_write(host, AT91_MCI_IER, AT91_MCI_TXBUFE | AT91_MCI_BLKE); + at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN); + } + + /* command not completed, have to wait */ + return 0; +} + + +/* + * Enable the controller + */ +static void at91_mci_enable(struct at91mci_host *host) +{ + unsigned int mr; + + at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN); + at91_mci_write(host, AT91_MCI_IDR, 0xffffffff); + at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC); + mr = AT91_MCI_PDCMODE | 0x34a; + + if (at91mci_is_mci1rev2xx()) + mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF; + + at91_mci_write(host, AT91_MCI_MR, mr); + + /* use Slot A or B (only one at same time) */ + at91_mci_write(host, AT91_MCI_SDCR, host->board->slot_b); +} + +/* + * Disable the controller + */ +static void at91_mci_disable(struct at91mci_host *host) +{ + at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIDIS | AT91_MCI_SWRST); +} + +/* + * Send a command + */ +static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command *cmd) +{ + unsigned int cmdr, mr; + unsigned int block_length; + struct mmc_data *data = cmd->data; + + unsigned int blocks; + unsigned int ier = 0; + + host->cmd = cmd; + + /* Needed for leaving busy state before CMD1 */ + if ((at91_mci_read(host, AT91_MCI_SR) & AT91_MCI_RTOE) && (cmd->opcode == 1)) { + pr_debug("Clearing timeout\n"); + at91_mci_write(host, AT91_MCI_ARGR, 0); + at91_mci_write(host, AT91_MCI_CMDR, AT91_MCI_OPDCMD); + while (!(at91_mci_read(host, AT91_MCI_SR) & AT91_MCI_CMDRDY)) { + /* spin */ + pr_debug("Clearing: SR = %08X\n", at91_mci_read(host, AT91_MCI_SR)); + } + } + + cmdr = cmd->opcode; + + if (mmc_resp_type(cmd) == MMC_RSP_NONE) + cmdr |= AT91_MCI_RSPTYP_NONE; + else { + /* if a response is expected then allow maximum response latancy */ + cmdr |= AT91_MCI_MAXLAT; + /* set 136 bit response for R2, 48 bit response otherwise */ + if (mmc_resp_type(cmd) == MMC_RSP_R2) + cmdr |= AT91_MCI_RSPTYP_136; + else + cmdr |= AT91_MCI_RSPTYP_48; + } + + if (data) { + + if (cpu_is_at91rm9200() || cpu_is_at91sam9261()) { + if (data->blksz & 0x3) { + pr_debug("Unsupported block size\n"); + cmd->error = -EINVAL; + mmc_request_done(host->mmc, host->request); + return; + } + if (data->flags & MMC_DATA_STREAM) { + pr_debug("Stream commands not supported\n"); + cmd->error = -EINVAL; + mmc_request_done(host->mmc, host->request); + return; + } + } + + block_length = data->blksz; + blocks = data->blocks; + + /* always set data start - also set direction flag for read */ + if (data->flags & MMC_DATA_READ) + cmdr |= (AT91_MCI_TRDIR | AT91_MCI_TRCMD_START); + else if (data->flags & MMC_DATA_WRITE) + cmdr |= AT91_MCI_TRCMD_START; + + if (cmd->opcode == SD_IO_RW_EXTENDED) { + cmdr |= AT91_MCI_TRTYP_SDIO_BLOCK; + } else { + if (data->flags & MMC_DATA_STREAM) + cmdr |= AT91_MCI_TRTYP_STREAM; + if (data->blocks > 1) + cmdr |= AT91_MCI_TRTYP_MULTIPLE; + } + } + else { + block_length = 0; + blocks = 0; + } + + if (host->flags & FL_SENT_STOP) + cmdr |= AT91_MCI_TRCMD_STOP; + + if (host->bus_mode == MMC_BUSMODE_OPENDRAIN) + cmdr |= AT91_MCI_OPDCMD; + + /* + * Set the arguments and send the command + */ + pr_debug("Sending command %d as %08X, arg = %08X, blocks = %d, length = %d (MR = %08X)\n", + cmd->opcode, cmdr, cmd->arg, blocks, block_length, at91_mci_read(host, AT91_MCI_MR)); + + if (!data) { + at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS | ATMEL_PDC_RXTDIS); + at91_mci_write(host, ATMEL_PDC_RPR, 0); + at91_mci_write(host, ATMEL_PDC_RCR, 0); + at91_mci_write(host, ATMEL_PDC_RNPR, 0); + at91_mci_write(host, ATMEL_PDC_RNCR, 0); + at91_mci_write(host, ATMEL_PDC_TPR, 0); + at91_mci_write(host, ATMEL_PDC_TCR, 0); + at91_mci_write(host, ATMEL_PDC_TNPR, 0); + at91_mci_write(host, ATMEL_PDC_TNCR, 0); + ier = AT91_MCI_CMDRDY; + } else { + /* zero block length and PDC mode */ + mr = at91_mci_read(host, AT91_MCI_MR) & 0x5fff; + mr |= (data->blksz & 0x3) ? AT91_MCI_PDCFBYTE : 0; + mr |= (block_length << 16); + mr |= AT91_MCI_PDCMODE; + at91_mci_write(host, AT91_MCI_MR, mr); + + if (!(cpu_is_at91rm9200() || cpu_is_at91sam9261())) + at91_mci_write(host, AT91_MCI_BLKR, + AT91_MCI_BLKR_BCNT(blocks) | + AT91_MCI_BLKR_BLKLEN(block_length)); + + /* + * Disable the PDC controller + */ + at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS); + + if (cmdr & AT91_MCI_TRCMD_START) { + data->bytes_xfered = 0; + host->transfer_index = 0; + host->in_use_index = 0; + if (cmdr & AT91_MCI_TRDIR) { + /* + * Handle a read + */ + host->total_length = 0; + + at91_mci_write(host, ATMEL_PDC_RPR, host->physical_address); + at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ? + (blocks * block_length) : (blocks * block_length) / 4); + at91_mci_write(host, ATMEL_PDC_RNPR, 0); + at91_mci_write(host, ATMEL_PDC_RNCR, 0); + + ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */; + } + else { + /* + * Handle a write + */ + host->total_length = block_length * blocks; + /* + * MCI1 rev2xx Data Write Operation and + * number of bytes erratum + */ + if (at91mci_is_mci1rev2xx()) + if (host->total_length < 12) + host->total_length = 12; + + at91_mci_sg_to_dma(host, data); + + pr_debug("Transmitting %d bytes\n", host->total_length); + + at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address); + at91_mci_write(host, ATMEL_PDC_TCR, (data->blksz & 0x3) ? + host->total_length : host->total_length / 4); + + ier = AT91_MCI_CMDRDY; + } + } + } + + /* + * Send the command and then enable the PDC - not the other way round as + * the data sheet says + */ + + at91_mci_write(host, AT91_MCI_ARGR, cmd->arg); + at91_mci_write(host, AT91_MCI_CMDR, cmdr); + + if (cmdr & AT91_MCI_TRCMD_START) { + if (cmdr & AT91_MCI_TRDIR) + at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN); + } + + /* Enable selected interrupts */ + at91_mci_write(host, AT91_MCI_IER, AT91_MCI_ERRORS | ier); +} + +/* + * Process the next step in the request + */ +static void at91_mci_process_next(struct at91mci_host *host) +{ + if (!(host->flags & FL_SENT_COMMAND)) { + host->flags |= FL_SENT_COMMAND; + at91_mci_send_command(host, host->request->cmd); + } + else if ((!(host->flags & FL_SENT_STOP)) && host->request->stop) { + host->flags |= FL_SENT_STOP; + at91_mci_send_command(host, host->request->stop); + } else { + del_timer(&host->timer); + /* the at91rm9200 mci controller hangs after some transfers, + * and the workaround is to reset it after each transfer. + */ + if (cpu_is_at91rm9200()) + at91_reset_host(host); + mmc_request_done(host->mmc, host->request); + } +} + +/* + * Handle a command that has been completed + */ +static void at91_mci_completed_command(struct at91mci_host *host, unsigned int status) +{ + struct mmc_command *cmd = host->cmd; + struct mmc_data *data = cmd->data; + + at91_mci_write(host, AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB)); + + cmd->resp[0] = at91_mci_read(host, AT91_MCI_RSPR(0)); + cmd->resp[1] = at91_mci_read(host, AT91_MCI_RSPR(1)); + cmd->resp[2] = at91_mci_read(host, AT91_MCI_RSPR(2)); + cmd->resp[3] = at91_mci_read(host, AT91_MCI_RSPR(3)); + + pr_debug("Status = %08X/%08x [%08X %08X %08X %08X]\n", + status, at91_mci_read(host, AT91_MCI_SR), + cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); + + if (status & AT91_MCI_ERRORS) { + if ((status & AT91_MCI_RCRCE) && !(mmc_resp_type(cmd) & MMC_RSP_CRC)) { + cmd->error = 0; + } + else { + if (status & (AT91_MCI_DTOE | AT91_MCI_DCRCE)) { + if (data) { + if (status & AT91_MCI_DTOE) + data->error = -ETIMEDOUT; + else if (status & AT91_MCI_DCRCE) + data->error = -EILSEQ; + } + } else { + if (status & AT91_MCI_RTOE) + cmd->error = -ETIMEDOUT; + else if (status & AT91_MCI_RCRCE) + cmd->error = -EILSEQ; + else + cmd->error = -EIO; + } + + pr_debug("Error detected and set to %d/%d (cmd = %d, retries = %d)\n", + cmd->error, data ? data->error : 0, + cmd->opcode, cmd->retries); + } + } + else + cmd->error = 0; + + at91_mci_process_next(host); +} + +/* + * Handle an MMC request + */ +static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct at91mci_host *host = mmc_priv(mmc); + host->request = mrq; + host->flags = 0; + + /* more than 1s timeout needed with slow SD cards */ + mod_timer(&host->timer, jiffies + msecs_to_jiffies(2000)); + + at91_mci_process_next(host); +} + +/* + * Set the IOS + */ +static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + int clkdiv; + struct at91mci_host *host = mmc_priv(mmc); + unsigned long at91_master_clock = clk_get_rate(host->mci_clk); + + host->bus_mode = ios->bus_mode; + + if (ios->clock == 0) { + /* Disable the MCI controller */ + at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIDIS); + clkdiv = 0; + } + else { + /* Enable the MCI controller */ + at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN); + + if ((at91_master_clock % (ios->clock * 2)) == 0) + clkdiv = ((at91_master_clock / ios->clock) / 2) - 1; + else + clkdiv = (at91_master_clock / ios->clock) / 2; + + pr_debug("clkdiv = %d. mcck = %ld\n", clkdiv, + at91_master_clock / (2 * (clkdiv + 1))); + } + if (ios->bus_width == MMC_BUS_WIDTH_4 && host->board->wire4) { + pr_debug("MMC: Setting controller bus width to 4\n"); + at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) | AT91_MCI_SDCBUS); + } + else { + pr_debug("MMC: Setting controller bus width to 1\n"); + at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS); + } + + /* Set the clock divider */ + at91_mci_write(host, AT91_MCI_MR, (at91_mci_read(host, AT91_MCI_MR) & ~AT91_MCI_CLKDIV) | clkdiv); + + /* maybe switch power to the card */ + if (gpio_is_valid(host->board->vcc_pin)) { + switch (ios->power_mode) { + case MMC_POWER_OFF: + gpio_set_value(host->board->vcc_pin, 0); + break; + case MMC_POWER_UP: + gpio_set_value(host->board->vcc_pin, 1); + break; + case MMC_POWER_ON: + break; + default: + WARN_ON(1); + } + } +} + +/* + * Handle an interrupt + */ +static irqreturn_t at91_mci_irq(int irq, void *devid) +{ + struct at91mci_host *host = devid; + int completed = 0; + unsigned int int_status, int_mask; + + int_status = at91_mci_read(host, AT91_MCI_SR); + int_mask = at91_mci_read(host, AT91_MCI_IMR); + + pr_debug("MCI irq: status = %08X, %08X, %08X\n", int_status, int_mask, + int_status & int_mask); + + int_status = int_status & int_mask; + + if (int_status & AT91_MCI_ERRORS) { + completed = 1; + + if (int_status & AT91_MCI_UNRE) + pr_debug("MMC: Underrun error\n"); + if (int_status & AT91_MCI_OVRE) + pr_debug("MMC: Overrun error\n"); + if (int_status & AT91_MCI_DTOE) + pr_debug("MMC: Data timeout\n"); + if (int_status & AT91_MCI_DCRCE) + pr_debug("MMC: CRC error in data\n"); + if (int_status & AT91_MCI_RTOE) + pr_debug("MMC: Response timeout\n"); + if (int_status & AT91_MCI_RENDE) + pr_debug("MMC: Response end bit error\n"); + if (int_status & AT91_MCI_RCRCE) + pr_debug("MMC: Response CRC error\n"); + if (int_status & AT91_MCI_RDIRE) + pr_debug("MMC: Response direction error\n"); + if (int_status & AT91_MCI_RINDE) + pr_debug("MMC: Response index error\n"); + } else { + /* Only continue processing if no errors */ + + if (int_status & AT91_MCI_TXBUFE) { + pr_debug("TX buffer empty\n"); + at91_mci_handle_transmitted(host); + } + + if (int_status & AT91_MCI_ENDRX) { + pr_debug("ENDRX\n"); + at91_mci_post_dma_read(host); + } + + if (int_status & AT91_MCI_RXBUFF) { + pr_debug("RX buffer full\n"); + at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS); + at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_RXBUFF | AT91_MCI_ENDRX); + completed = 1; + } + + if (int_status & AT91_MCI_ENDTX) + pr_debug("Transmit has ended\n"); + + if (int_status & AT91_MCI_NOTBUSY) { + pr_debug("Card is ready\n"); + at91_mci_update_bytes_xfered(host); + completed = 1; + } + + if (int_status & AT91_MCI_DTIP) + pr_debug("Data transfer in progress\n"); + + if (int_status & AT91_MCI_BLKE) { + pr_debug("Block transfer has ended\n"); + if (host->request->data && host->request->data->blocks > 1) { + /* multi block write : complete multi write + * command and send stop */ + completed = 1; + } else { + at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY); + } + } + + if (int_status & AT91_MCI_SDIOIRQA) + mmc_signal_sdio_irq(host->mmc); + + if (int_status & AT91_MCI_SDIOIRQB) + mmc_signal_sdio_irq(host->mmc); + + if (int_status & AT91_MCI_TXRDY) + pr_debug("Ready to transmit\n"); + + if (int_status & AT91_MCI_RXRDY) + pr_debug("Ready to receive\n"); + + if (int_status & AT91_MCI_CMDRDY) { + pr_debug("Command ready\n"); + completed = at91_mci_handle_cmdrdy(host); + } + } + + if (completed) { + pr_debug("Completed command\n"); + at91_mci_write(host, AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB)); + at91_mci_completed_command(host, int_status); + } else + at91_mci_write(host, AT91_MCI_IDR, int_status & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB)); + + return IRQ_HANDLED; +} + +static irqreturn_t at91_mmc_det_irq(int irq, void *_host) +{ + struct at91mci_host *host = _host; + int present; + + /* entering this ISR means that we have configured det_pin: + * we can use its value in board structure */ + present = !gpio_get_value(host->board->det_pin); + + /* + * we expect this irq on both insert and remove, + * and use a short delay to debounce. + */ + if (present != host->present) { + host->present = present; + pr_debug("%s: card %s\n", mmc_hostname(host->mmc), + present ? "insert" : "remove"); + if (!present) { + pr_debug("****** Resetting SD-card bus width ******\n"); + at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS); + } + /* 0.5s needed because of early card detect switch firing */ + mmc_detect_change(host->mmc, msecs_to_jiffies(500)); + } + return IRQ_HANDLED; +} + +static int at91_mci_get_ro(struct mmc_host *mmc) +{ + struct at91mci_host *host = mmc_priv(mmc); + + if (gpio_is_valid(host->board->wp_pin)) + return !!gpio_get_value(host->board->wp_pin); + /* + * Board doesn't support read only detection; let the mmc core + * decide what to do. + */ + return -ENOSYS; +} + +static void at91_mci_enable_sdio_irq(struct mmc_host *mmc, int enable) +{ + struct at91mci_host *host = mmc_priv(mmc); + + pr_debug("%s: sdio_irq %c : %s\n", mmc_hostname(host->mmc), + host->board->slot_b ? 'B':'A', enable ? "enable" : "disable"); + at91_mci_write(host, enable ? AT91_MCI_IER : AT91_MCI_IDR, + host->board->slot_b ? AT91_MCI_SDIOIRQB : AT91_MCI_SDIOIRQA); + +} + +static const struct mmc_host_ops at91_mci_ops = { + .request = at91_mci_request, + .set_ios = at91_mci_set_ios, + .get_ro = at91_mci_get_ro, + .enable_sdio_irq = at91_mci_enable_sdio_irq, +}; + +/* + * Probe for the device + */ +static int __init at91_mci_probe(struct platform_device *pdev) +{ + struct mmc_host *mmc; + struct at91mci_host *host; + struct resource *res; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENXIO; + + if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) + return -EBUSY; + + mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev); + if (!mmc) { + ret = -ENOMEM; + dev_dbg(&pdev->dev, "couldn't allocate mmc host\n"); + goto fail6; + } + + mmc->ops = &at91_mci_ops; + mmc->f_min = 375000; + mmc->f_max = 25000000; + mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; + mmc->caps = 0; + + mmc->max_blk_size = MCI_MAXBLKSIZE; + mmc->max_blk_count = MCI_BLKATONCE; + mmc->max_req_size = MCI_BUFSIZE; + mmc->max_segs = MCI_BLKATONCE; + mmc->max_seg_size = MCI_BUFSIZE; + + host = mmc_priv(mmc); + host->mmc = mmc; + host->bus_mode = 0; + host->board = pdev->dev.platform_data; + if (host->board->wire4) { + if (at91mci_is_mci1rev2xx()) + mmc->caps |= MMC_CAP_4_BIT_DATA; + else + dev_warn(&pdev->dev, "4 wire bus mode not supported" + " - using 1 wire\n"); + } + + host->buffer = dma_alloc_coherent(&pdev->dev, MCI_BUFSIZE, + &host->physical_address, GFP_KERNEL); + if (!host->buffer) { + ret = -ENOMEM; + dev_err(&pdev->dev, "Can't allocate transmit buffer\n"); + goto fail5; + } + + /* Add SDIO capability when available */ + if (at91mci_is_mci1rev2xx()) { + /* at91mci MCI1 rev2xx sdio interrupt erratum */ + if (host->board->wire4 || !host->board->slot_b) + mmc->caps |= MMC_CAP_SDIO_IRQ; + } + + /* + * Reserve GPIOs ... board init code makes sure these pins are set + * up as GPIOs with the right direction (input, except for vcc) + */ + if (gpio_is_valid(host->board->det_pin)) { + ret = gpio_request(host->board->det_pin, "mmc_detect"); + if (ret < 0) { + dev_dbg(&pdev->dev, "couldn't claim card detect pin\n"); + goto fail4b; + } + } + if (gpio_is_valid(host->board->wp_pin)) { + ret = gpio_request(host->board->wp_pin, "mmc_wp"); + if (ret < 0) { + dev_dbg(&pdev->dev, "couldn't claim wp sense pin\n"); + goto fail4; + } + } + if (gpio_is_valid(host->board->vcc_pin)) { + ret = gpio_request(host->board->vcc_pin, "mmc_vcc"); + if (ret < 0) { + dev_dbg(&pdev->dev, "couldn't claim vcc switch pin\n"); + goto fail3; + } + } + + /* + * Get Clock + */ + host->mci_clk = clk_get(&pdev->dev, "mci_clk"); + if (IS_ERR(host->mci_clk)) { + ret = -ENODEV; + dev_dbg(&pdev->dev, "no mci_clk?\n"); + goto fail2; + } + + /* + * Map I/O region + */ + host->baseaddr = ioremap(res->start, resource_size(res)); + if (!host->baseaddr) { + ret = -ENOMEM; + goto fail1; + } + + /* + * Reset hardware + */ + clk_enable(host->mci_clk); /* Enable the peripheral clock */ + at91_mci_disable(host); + at91_mci_enable(host); + + /* + * Allocate the MCI interrupt + */ + host->irq = platform_get_irq(pdev, 0); + ret = request_irq(host->irq, at91_mci_irq, IRQF_SHARED, + mmc_hostname(mmc), host); + if (ret) { + dev_dbg(&pdev->dev, "request MCI interrupt failed\n"); + goto fail0; + } + + setup_timer(&host->timer, at91_timeout_timer, (unsigned long)host); + + platform_set_drvdata(pdev, mmc); + + /* + * Add host to MMC layer + */ + if (gpio_is_valid(host->board->det_pin)) { + host->present = !gpio_get_value(host->board->det_pin); + } + else + host->present = -1; + + mmc_add_host(mmc); + + /* + * monitor card insertion/removal if we can + */ + if (gpio_is_valid(host->board->det_pin)) { + ret = request_irq(gpio_to_irq(host->board->det_pin), + at91_mmc_det_irq, 0, mmc_hostname(mmc), host); + if (ret) + dev_warn(&pdev->dev, "request MMC detect irq failed\n"); + else + device_init_wakeup(&pdev->dev, 1); + } + + pr_debug("Added MCI driver\n"); + + return 0; + +fail0: + clk_disable(host->mci_clk); + iounmap(host->baseaddr); +fail1: + clk_put(host->mci_clk); +fail2: + if (gpio_is_valid(host->board->vcc_pin)) + gpio_free(host->board->vcc_pin); +fail3: + if (gpio_is_valid(host->board->wp_pin)) + gpio_free(host->board->wp_pin); +fail4: + if (gpio_is_valid(host->board->det_pin)) + gpio_free(host->board->det_pin); +fail4b: + if (host->buffer) + dma_free_coherent(&pdev->dev, MCI_BUFSIZE, + host->buffer, host->physical_address); +fail5: + mmc_free_host(mmc); +fail6: + release_mem_region(res->start, resource_size(res)); + dev_err(&pdev->dev, "probe failed, err %d\n", ret); + return ret; +} + +/* + * Remove a device + */ +static int __exit at91_mci_remove(struct platform_device *pdev) +{ + struct mmc_host *mmc = platform_get_drvdata(pdev); + struct at91mci_host *host; + struct resource *res; + + if (!mmc) + return -1; + + host = mmc_priv(mmc); + + if (host->buffer) + dma_free_coherent(&pdev->dev, MCI_BUFSIZE, + host->buffer, host->physical_address); + + if (gpio_is_valid(host->board->det_pin)) { + if (device_can_wakeup(&pdev->dev)) + free_irq(gpio_to_irq(host->board->det_pin), host); + device_init_wakeup(&pdev->dev, 0); + gpio_free(host->board->det_pin); + } + + at91_mci_disable(host); + del_timer_sync(&host->timer); + mmc_remove_host(mmc); + free_irq(host->irq, host); + + clk_disable(host->mci_clk); /* Disable the peripheral clock */ + clk_put(host->mci_clk); + + if (gpio_is_valid(host->board->vcc_pin)) + gpio_free(host->board->vcc_pin); + if (gpio_is_valid(host->board->wp_pin)) + gpio_free(host->board->wp_pin); + + iounmap(host->baseaddr); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(res->start, resource_size(res)); + + mmc_free_host(mmc); + platform_set_drvdata(pdev, NULL); + pr_debug("MCI Removed\n"); + + return 0; +} + +#ifdef CONFIG_PM +static int at91_mci_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct mmc_host *mmc = platform_get_drvdata(pdev); + struct at91mci_host *host = mmc_priv(mmc); + int ret = 0; + + if (gpio_is_valid(host->board->det_pin) && device_may_wakeup(&pdev->dev)) + enable_irq_wake(host->board->det_pin); + + if (mmc) + ret = mmc_suspend_host(mmc); + + return ret; +} + +static int at91_mci_resume(struct platform_device *pdev) +{ + struct mmc_host *mmc = platform_get_drvdata(pdev); + struct at91mci_host *host = mmc_priv(mmc); + int ret = 0; + + if (gpio_is_valid(host->board->det_pin) && device_may_wakeup(&pdev->dev)) + disable_irq_wake(host->board->det_pin); + + if (mmc) + ret = mmc_resume_host(mmc); + + return ret; +} +#else +#define at91_mci_suspend NULL +#define at91_mci_resume NULL +#endif + +static struct platform_driver at91_mci_driver = { + .remove = __exit_p(at91_mci_remove), + .suspend = at91_mci_suspend, + .resume = at91_mci_resume, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init at91_mci_init(void) +{ + return platform_driver_probe(&at91_mci_driver, at91_mci_probe); +} + +static void __exit at91_mci_exit(void) +{ + platform_driver_unregister(&at91_mci_driver); +} + +module_init(at91_mci_init); +module_exit(at91_mci_exit); + +MODULE_DESCRIPTION("AT91 Multimedia Card Interface driver"); +MODULE_AUTHOR("Nick Randell"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:at91_mci"); diff --git a/trunk/drivers/mmc/host/at91_mci.h b/trunk/drivers/mmc/host/at91_mci.h new file mode 100644 index 000000000000..eec3a6b1c2bc --- /dev/null +++ b/trunk/drivers/mmc/host/at91_mci.h @@ -0,0 +1,115 @@ +/* + * drivers/mmc/host/at91_mci.h + * + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * + * MultiMedia Card Interface (MCI) registers. + * Based on AT91RM9200 datasheet revision F. + * + * 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. + */ + +#ifndef AT91_MCI_H +#define AT91_MCI_H + +#define AT91_MCI_CR 0x00 /* Control Register */ +#define AT91_MCI_MCIEN (1 << 0) /* Multi-Media Interface Enable */ +#define AT91_MCI_MCIDIS (1 << 1) /* Multi-Media Interface Disable */ +#define AT91_MCI_PWSEN (1 << 2) /* Power Save Mode Enable */ +#define AT91_MCI_PWSDIS (1 << 3) /* Power Save Mode Disable */ +#define AT91_MCI_SWRST (1 << 7) /* Software Reset */ + +#define AT91_MCI_MR 0x04 /* Mode Register */ +#define AT91_MCI_CLKDIV (0xff << 0) /* Clock Divider */ +#define AT91_MCI_PWSDIV (7 << 8) /* Power Saving Divider */ +#define AT91_MCI_RDPROOF (1 << 11) /* Read Proof Enable [SAM926[03] only] */ +#define AT91_MCI_WRPROOF (1 << 12) /* Write Proof Enable [SAM926[03] only] */ +#define AT91_MCI_PDCFBYTE (1 << 13) /* PDC Force Byte Transfer [SAM926[03] only] */ +#define AT91_MCI_PDCPADV (1 << 14) /* PDC Padding Value */ +#define AT91_MCI_PDCMODE (1 << 15) /* PDC-orientated Mode */ +#define AT91_MCI_BLKLEN (0xfff << 18) /* Data Block Length */ + +#define AT91_MCI_DTOR 0x08 /* Data Timeout Register */ +#define AT91_MCI_DTOCYC (0xf << 0) /* Data Timeout Cycle Number */ +#define AT91_MCI_DTOMUL (7 << 4) /* Data Timeout Multiplier */ +#define AT91_MCI_DTOMUL_1 (0 << 4) +#define AT91_MCI_DTOMUL_16 (1 << 4) +#define AT91_MCI_DTOMUL_128 (2 << 4) +#define AT91_MCI_DTOMUL_256 (3 << 4) +#define AT91_MCI_DTOMUL_1K (4 << 4) +#define AT91_MCI_DTOMUL_4K (5 << 4) +#define AT91_MCI_DTOMUL_64K (6 << 4) +#define AT91_MCI_DTOMUL_1M (7 << 4) + +#define AT91_MCI_SDCR 0x0c /* SD Card Register */ +#define AT91_MCI_SDCSEL (3 << 0) /* SD Card Selector */ +#define AT91_MCI_SDCBUS (1 << 7) /* 1-bit or 4-bit bus */ + +#define AT91_MCI_ARGR 0x10 /* Argument Register */ + +#define AT91_MCI_CMDR 0x14 /* Command Register */ +#define AT91_MCI_CMDNB (0x3f << 0) /* Command Number */ +#define AT91_MCI_RSPTYP (3 << 6) /* Response Type */ +#define AT91_MCI_RSPTYP_NONE (0 << 6) +#define AT91_MCI_RSPTYP_48 (1 << 6) +#define AT91_MCI_RSPTYP_136 (2 << 6) +#define AT91_MCI_SPCMD (7 << 8) /* Special Command */ +#define AT91_MCI_SPCMD_NONE (0 << 8) +#define AT91_MCI_SPCMD_INIT (1 << 8) +#define AT91_MCI_SPCMD_SYNC (2 << 8) +#define AT91_MCI_SPCMD_ICMD (4 << 8) +#define AT91_MCI_SPCMD_IRESP (5 << 8) +#define AT91_MCI_OPDCMD (1 << 11) /* Open Drain Command */ +#define AT91_MCI_MAXLAT (1 << 12) /* Max Latency for Command to Response */ +#define AT91_MCI_TRCMD (3 << 16) /* Transfer Command */ +#define AT91_MCI_TRCMD_NONE (0 << 16) +#define AT91_MCI_TRCMD_START (1 << 16) +#define AT91_MCI_TRCMD_STOP (2 << 16) +#define AT91_MCI_TRDIR (1 << 18) /* Transfer Direction */ +#define AT91_MCI_TRTYP (3 << 19) /* Transfer Type */ +#define AT91_MCI_TRTYP_BLOCK (0 << 19) +#define AT91_MCI_TRTYP_MULTIPLE (1 << 19) +#define AT91_MCI_TRTYP_STREAM (2 << 19) +#define AT91_MCI_TRTYP_SDIO_BYTE (4 << 19) +#define AT91_MCI_TRTYP_SDIO_BLOCK (5 << 19) + +#define AT91_MCI_BLKR 0x18 /* Block Register */ +#define AT91_MCI_BLKR_BCNT(n) ((0xffff & (n)) << 0) /* Block count */ +#define AT91_MCI_BLKR_BLKLEN(n) ((0xffff & (n)) << 16) /* Block length */ + +#define AT91_MCI_RSPR(n) (0x20 + ((n) * 4)) /* Response Registers 0-3 */ +#define AT91_MCR_RDR 0x30 /* Receive Data Register */ +#define AT91_MCR_TDR 0x34 /* Transmit Data Register */ + +#define AT91_MCI_SR 0x40 /* Status Register */ +#define AT91_MCI_CMDRDY (1 << 0) /* Command Ready */ +#define AT91_MCI_RXRDY (1 << 1) /* Receiver Ready */ +#define AT91_MCI_TXRDY (1 << 2) /* Transmit Ready */ +#define AT91_MCI_BLKE (1 << 3) /* Data Block Ended */ +#define AT91_MCI_DTIP (1 << 4) /* Data Transfer in Progress */ +#define AT91_MCI_NOTBUSY (1 << 5) /* Data Not Busy */ +#define AT91_MCI_ENDRX (1 << 6) /* End of RX Buffer */ +#define AT91_MCI_ENDTX (1 << 7) /* End fo TX Buffer */ +#define AT91_MCI_SDIOIRQA (1 << 8) /* SDIO Interrupt for Slot A */ +#define AT91_MCI_SDIOIRQB (1 << 9) /* SDIO Interrupt for Slot B */ +#define AT91_MCI_RXBUFF (1 << 14) /* RX Buffer Full */ +#define AT91_MCI_TXBUFE (1 << 15) /* TX Buffer Empty */ +#define AT91_MCI_RINDE (1 << 16) /* Response Index Error */ +#define AT91_MCI_RDIRE (1 << 17) /* Response Direction Error */ +#define AT91_MCI_RCRCE (1 << 18) /* Response CRC Error */ +#define AT91_MCI_RENDE (1 << 19) /* Response End Bit Error */ +#define AT91_MCI_RTOE (1 << 20) /* Response Time-out Error */ +#define AT91_MCI_DCRCE (1 << 21) /* Data CRC Error */ +#define AT91_MCI_DTOE (1 << 22) /* Data Time-out Error */ +#define AT91_MCI_OVRE (1 << 30) /* Overrun */ +#define AT91_MCI_UNRE (1 << 31) /* Underrun */ + +#define AT91_MCI_IER 0x44 /* Interrupt Enable Register */ +#define AT91_MCI_IDR 0x48 /* Interrupt Disable Register */ +#define AT91_MCI_IMR 0x4c /* Interrupt Mask Register */ + +#endif diff --git a/trunk/drivers/mmc/host/dw_mmc-exynos.c b/trunk/drivers/mmc/host/dw_mmc-exynos.c index 4d50da618166..660bbc528862 100644 --- a/trunk/drivers/mmc/host/dw_mmc-exynos.c +++ b/trunk/drivers/mmc/host/dw_mmc-exynos.c @@ -208,7 +208,7 @@ static unsigned long exynos5250_dwmmc_caps[4] = { MMC_CAP_CMD23, }; -static const struct dw_mci_drv_data exynos5250_drv_data = { +static struct dw_mci_drv_data exynos5250_drv_data = { .caps = exynos5250_dwmmc_caps, .init = dw_mci_exynos_priv_init, .setup_clock = dw_mci_exynos_setup_clock, @@ -220,14 +220,14 @@ static const struct dw_mci_drv_data exynos5250_drv_data = { static const struct of_device_id dw_mci_exynos_match[] = { { .compatible = "samsung,exynos5250-dw-mshc", - .data = &exynos5250_drv_data, }, + .data = (void *)&exynos5250_drv_data, }, {}, }; -MODULE_DEVICE_TABLE(of, dw_mci_exynos_match); +MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match); int dw_mci_exynos_probe(struct platform_device *pdev) { - const struct dw_mci_drv_data *drv_data; + struct dw_mci_drv_data *drv_data; const struct of_device_id *match; match = of_match_node(dw_mci_exynos_match, pdev->dev.of_node); diff --git a/trunk/drivers/mmc/host/dw_mmc-pci.c b/trunk/drivers/mmc/host/dw_mmc-pci.c index 53a09cbb2c7c..edb37e9135ae 100644 --- a/trunk/drivers/mmc/host/dw_mmc-pci.c +++ b/trunk/drivers/mmc/host/dw_mmc-pci.c @@ -134,7 +134,7 @@ static struct pci_driver dw_mci_pci_driver = { .name = "dw_mmc_pci", .id_table = dw_mci_pci_id, .probe = dw_mci_pci_probe, - .remove = __devexit_p(dw_mci_pci_remove), + .remove = dw_mci_pci_remove, .driver = { .pm = &dw_mci_pci_pmops }, diff --git a/trunk/drivers/mmc/host/dw_mmc-pltfm.c b/trunk/drivers/mmc/host/dw_mmc-pltfm.c index 4e133709e33d..c960ca7ffbe6 100644 --- a/trunk/drivers/mmc/host/dw_mmc-pltfm.c +++ b/trunk/drivers/mmc/host/dw_mmc-pltfm.c @@ -24,7 +24,7 @@ #include "dw_mmc.h" int dw_mci_pltfm_register(struct platform_device *pdev, - const struct dw_mci_drv_data *drv_data) + struct dw_mci_drv_data *drv_data) { struct dw_mci *host; struct resource *regs; @@ -50,8 +50,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev, if (!host->regs) return -ENOMEM; - if (drv_data && drv_data->init) { - ret = drv_data->init(host); + if (host->drv_data->init) { + ret = host->drv_data->init(host); if (ret) return ret; } @@ -119,8 +119,7 @@ static const struct of_device_id dw_mci_pltfm_match[] = { MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match); static struct platform_driver dw_mci_pltfm_driver = { - .probe = dw_mci_pltfm_probe, - .remove = __devexit_p(dw_mci_pltfm_remove), + .remove = __exit_p(dw_mci_pltfm_remove), .driver = { .name = "dw_mmc", .of_match_table = of_match_ptr(dw_mci_pltfm_match), @@ -128,7 +127,18 @@ static struct platform_driver dw_mci_pltfm_driver = { }, }; -module_platform_driver(dw_mci_pltfm_driver); +static int __init dw_mci_init(void) +{ + return platform_driver_probe(&dw_mci_pltfm_driver, dw_mci_pltfm_probe); +} + +static void __exit dw_mci_exit(void) +{ + platform_driver_unregister(&dw_mci_pltfm_driver); +} + +module_init(dw_mci_init); +module_exit(dw_mci_exit); MODULE_DESCRIPTION("DW Multimedia Card Interface driver"); MODULE_AUTHOR("NXP Semiconductor VietNam"); diff --git a/trunk/drivers/mmc/host/dw_mmc-pltfm.h b/trunk/drivers/mmc/host/dw_mmc-pltfm.h index 2ac37b81de4d..301f24541fc2 100644 --- a/trunk/drivers/mmc/host/dw_mmc-pltfm.h +++ b/trunk/drivers/mmc/host/dw_mmc-pltfm.h @@ -13,7 +13,7 @@ #define _DW_MMC_PLTFM_H_ extern int dw_mci_pltfm_register(struct platform_device *pdev, - const struct dw_mci_drv_data *drv_data); + struct dw_mci_drv_data *drv_data); extern int __devexit dw_mci_pltfm_remove(struct platform_device *pdev); extern const struct dev_pm_ops dw_mci_pltfm_pmops; diff --git a/trunk/drivers/mmc/host/dw_mmc.c b/trunk/drivers/mmc/host/dw_mmc.c index 323c5022c2ca..c2828f35c3b8 100644 --- a/trunk/drivers/mmc/host/dw_mmc.c +++ b/trunk/drivers/mmc/host/dw_mmc.c @@ -232,7 +232,6 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) { struct mmc_data *data; struct dw_mci_slot *slot = mmc_priv(mmc); - const struct dw_mci_drv_data *drv_data = slot->host->drv_data; u32 cmdr; cmd->error = -EINPROGRESS; @@ -262,8 +261,8 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) cmdr |= SDMMC_CMD_DAT_WR; } - if (drv_data && drv_data->prepare_command) - drv_data->prepare_command(slot->host, &cmdr); + if (slot->host->drv_data->prepare_command) + slot->host->drv_data->prepare_command(slot->host, &cmdr); return cmdr; } @@ -435,7 +434,7 @@ static int dw_mci_idmac_init(struct dw_mci *host) return 0; } -static const struct dw_mci_dma_ops dw_mci_idmac_ops = { +static struct dw_mci_dma_ops dw_mci_idmac_ops = { .init = dw_mci_idmac_init, .start = dw_mci_idmac_start_dma, .stop = dw_mci_idmac_stop_dma, @@ -617,13 +616,13 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg) cmd, arg, cmd_status); } -static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit) +static void dw_mci_setup_bus(struct dw_mci_slot *slot) { struct dw_mci *host = slot->host; u32 div; u32 clk_en_a; - if (slot->clock != host->current_speed || force_clkinit) { + if (slot->clock != host->current_speed) { div = host->bus_hz / slot->clock; if (host->bus_hz % slot->clock && host->bus_hz > slot->clock) /* @@ -683,6 +682,9 @@ static void __dw_mci_start_request(struct dw_mci *host, if (host->pdata->select_slot) host->pdata->select_slot(slot->id); + /* Slot specific timing and width adjustment */ + dw_mci_setup_bus(slot); + host->cur_slot = slot; host->mrq = mrq; @@ -770,19 +772,21 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct dw_mci_slot *slot = mmc_priv(mmc); - const struct dw_mci_drv_data *drv_data = slot->host->drv_data; u32 regs; + /* set default 1 bit mode */ + slot->ctype = SDMMC_CTYPE_1BIT; + switch (ios->bus_width) { + case MMC_BUS_WIDTH_1: + slot->ctype = SDMMC_CTYPE_1BIT; + break; case MMC_BUS_WIDTH_4: slot->ctype = SDMMC_CTYPE_4BIT; break; case MMC_BUS_WIDTH_8: slot->ctype = SDMMC_CTYPE_8BIT; break; - default: - /* set default 1 bit mode */ - slot->ctype = SDMMC_CTYPE_1BIT; } regs = mci_readl(slot->host, UHS_REG); @@ -803,11 +807,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) slot->clock = ios->clock; } - if (drv_data && drv_data->set_ios) - drv_data->set_ios(slot->host, ios); - - /* Slot specific timing and width adjustment */ - dw_mci_setup_bus(slot, false); + if (slot->host->drv_data->set_ios) + slot->host->drv_data->set_ios(slot->host, ios); switch (ios->power_mode) { case MMC_POWER_UP: @@ -1814,7 +1815,6 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) { struct mmc_host *mmc; struct dw_mci_slot *slot; - const struct dw_mci_drv_data *drv_data = host->drv_data; int ctrl_id, ret; u8 bus_width; @@ -1847,9 +1847,6 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) if (host->pdata->caps) mmc->caps = host->pdata->caps; - if (host->pdata->pm_caps) - mmc->pm_caps = host->pdata->pm_caps; - if (host->dev->of_node) { ctrl_id = of_alias_get_id(host->dev->of_node, "mshc"); if (ctrl_id < 0) @@ -1857,8 +1854,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) } else { ctrl_id = to_platform_device(host->dev)->id; } - if (drv_data && drv_data->caps) - mmc->caps |= drv_data->caps[ctrl_id]; + if (host->drv_data && host->drv_data->caps) + mmc->caps |= host->drv_data->caps[ctrl_id]; if (host->pdata->caps2) mmc->caps2 = host->pdata->caps2; @@ -1870,10 +1867,10 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) else bus_width = 1; - if (drv_data && drv_data->setup_bus) { + if (host->drv_data->setup_bus) { struct device_node *slot_np; slot_np = dw_mci_of_find_slot_node(host->dev, slot->id); - ret = drv_data->setup_bus(host, slot_np, bus_width); + ret = host->drv_data->setup_bus(host, slot_np, bus_width); if (ret) goto err_setup_bus; } @@ -1911,7 +1908,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) #endif /* CONFIG_MMC_DW_IDMAC */ } - host->vmmc = devm_regulator_get(mmc_dev(mmc), "vmmc"); + host->vmmc = regulator_get(mmc_dev(mmc), "vmmc"); if (IS_ERR(host->vmmc)) { pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc)); host->vmmc = NULL; @@ -1960,7 +1957,7 @@ static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id) static void dw_mci_init_dma(struct dw_mci *host) { /* Alloc memory for sg translation */ - host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE, + host->sg_cpu = dma_alloc_coherent(host->dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL); if (!host->sg_cpu) { dev_err(host->dev, "%s: could not alloc DMA memory\n", @@ -1971,7 +1968,7 @@ static void dw_mci_init_dma(struct dw_mci *host) /* Determine which DMA interface to use */ #ifdef CONFIG_MMC_DW_IDMAC host->dma_ops = &dw_mci_idmac_ops; - dev_info(host->dev, "Using internal DMA controller.\n"); + dev_info(&host->dev, "Using internal DMA controller.\n"); #endif if (!host->dma_ops) @@ -2038,7 +2035,6 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) struct dw_mci_board *pdata; struct device *dev = host->dev; struct device_node *np = dev->of_node; - const struct dw_mci_drv_data *drv_data = host->drv_data; int idx, ret; pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); @@ -2066,18 +2062,12 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms); - if (drv_data && drv_data->parse_dt) { - ret = drv_data->parse_dt(host); + if (host->drv_data->parse_dt) { + ret = host->drv_data->parse_dt(host); if (ret) return ERR_PTR(ret); } - if (of_find_property(np, "keep-power-in-suspend", NULL)) - pdata->pm_caps |= MMC_PM_KEEP_POWER; - - if (of_find_property(np, "enable-sdio-wakeup", NULL)) - pdata->pm_caps |= MMC_PM_WAKE_SDIO_IRQ; - return pdata; } @@ -2090,7 +2080,6 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) int dw_mci_probe(struct dw_mci *host) { - const struct dw_mci_drv_data *drv_data = host->drv_data; int width, i, ret = 0; u32 fifo_size; int init_slots = 0; @@ -2109,24 +2098,26 @@ int dw_mci_probe(struct dw_mci *host) return -ENODEV; } - host->biu_clk = devm_clk_get(host->dev, "biu"); + host->biu_clk = clk_get(host->dev, "biu"); if (IS_ERR(host->biu_clk)) { dev_dbg(host->dev, "biu clock not available\n"); } else { ret = clk_prepare_enable(host->biu_clk); if (ret) { dev_err(host->dev, "failed to enable biu clock\n"); + clk_put(host->biu_clk); return ret; } } - host->ciu_clk = devm_clk_get(host->dev, "ciu"); + host->ciu_clk = clk_get(host->dev, "ciu"); if (IS_ERR(host->ciu_clk)) { dev_dbg(host->dev, "ciu clock not available\n"); } else { ret = clk_prepare_enable(host->ciu_clk); if (ret) { dev_err(host->dev, "failed to enable ciu clock\n"); + clk_put(host->ciu_clk); goto err_clk_biu; } } @@ -2136,8 +2127,8 @@ int dw_mci_probe(struct dw_mci *host) else host->bus_hz = clk_get_rate(host->ciu_clk); - if (drv_data && drv_data->setup_clock) { - ret = drv_data->setup_clock(host); + if (host->drv_data->setup_clock) { + ret = host->drv_data->setup_clock(host); if (ret) { dev_err(host->dev, "implementation specific clock setup failed\n"); @@ -2228,8 +2219,7 @@ int dw_mci_probe(struct dw_mci *host) if (!host->card_workqueue) goto err_dmaunmap; INIT_WORK(&host->card_work, dw_mci_work_routine_card); - ret = devm_request_irq(host->dev, host->irq, dw_mci_interrupt, - host->irq_flags, "dw-mci", host); + ret = request_irq(host->irq, dw_mci_interrupt, host->irq_flags, "dw-mci", host); if (ret) goto err_workqueue; @@ -2238,21 +2228,6 @@ int dw_mci_probe(struct dw_mci *host) else host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1; - /* - * Enable interrupts for command done, data over, data empty, card det, - * receive ready and error such as transmit, receive timeout, crc error - */ - mci_writel(host, RINTSTS, 0xFFFFFFFF); - mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | - SDMMC_INT_TXDR | SDMMC_INT_RXDR | - DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); - mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ - - dev_info(host->dev, "DW MMC controller at irq %d, " - "%d bit host data width, " - "%u deep fifo\n", - host->irq, width, fifo_size); - /* We need at least one slot to succeed */ for (i = 0; i < host->num_slots; i++) { ret = dw_mci_init_slot(host, i); @@ -2267,7 +2242,7 @@ int dw_mci_probe(struct dw_mci *host) } else { dev_dbg(host->dev, "attempted to initialize %d slots, " "but failed on all\n", host->num_slots); - goto err_workqueue; + goto err_init_slot; } /* @@ -2282,29 +2257,52 @@ int dw_mci_probe(struct dw_mci *host) else host->data_offset = DATA_240A_OFFSET; + /* + * Enable interrupts for command done, data over, data empty, card det, + * receive ready and error such as transmit, receive timeout, crc error + */ + mci_writel(host, RINTSTS, 0xFFFFFFFF); + mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | + SDMMC_INT_TXDR | SDMMC_INT_RXDR | + DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); + mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ + + dev_info(host->dev, "DW MMC controller at irq %d, " + "%d bit host data width, " + "%u deep fifo\n", + host->irq, width, fifo_size); if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO) dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n"); return 0; +err_init_slot: + free_irq(host->irq, host); + err_workqueue: destroy_workqueue(host->card_workqueue); err_dmaunmap: if (host->use_dma && host->dma_ops->exit) host->dma_ops->exit(host); + dma_free_coherent(host->dev, PAGE_SIZE, + host->sg_cpu, host->sg_dma); - if (host->vmmc) + if (host->vmmc) { regulator_disable(host->vmmc); + regulator_put(host->vmmc); + } err_clk_ciu: - if (!IS_ERR(host->ciu_clk)) + if (!IS_ERR(host->ciu_clk)) { clk_disable_unprepare(host->ciu_clk); - + clk_put(host->ciu_clk); + } err_clk_biu: - if (!IS_ERR(host->biu_clk)) + if (!IS_ERR(host->biu_clk)) { clk_disable_unprepare(host->biu_clk); - + clk_put(host->biu_clk); + } return ret; } EXPORT_SYMBOL(dw_mci_probe); @@ -2326,19 +2324,24 @@ void dw_mci_remove(struct dw_mci *host) mci_writel(host, CLKENA, 0); mci_writel(host, CLKSRC, 0); + free_irq(host->irq, host); destroy_workqueue(host->card_workqueue); + dma_free_coherent(host->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); if (host->use_dma && host->dma_ops->exit) host->dma_ops->exit(host); - if (host->vmmc) + if (host->vmmc) { regulator_disable(host->vmmc); + regulator_put(host->vmmc); + } if (!IS_ERR(host->ciu_clk)) clk_disable_unprepare(host->ciu_clk); - if (!IS_ERR(host->biu_clk)) clk_disable_unprepare(host->biu_clk); + clk_put(host->ciu_clk); + clk_put(host->biu_clk); } EXPORT_SYMBOL(dw_mci_remove); @@ -2402,11 +2405,6 @@ int dw_mci_resume(struct dw_mci *host) struct dw_mci_slot *slot = host->slot[i]; if (!slot) continue; - if (slot->mmc->pm_flags & MMC_PM_KEEP_POWER) { - dw_mci_set_ios(slot->mmc, &slot->mmc->ios); - dw_mci_setup_bus(slot, true); - } - ret = mmc_resume_host(host->slot[i]->mmc); if (ret < 0) return ret; diff --git a/trunk/drivers/mmc/host/mxcmmc.c b/trunk/drivers/mmc/host/mxcmmc.c index 29e680f193a0..565c2e4fac75 100644 --- a/trunk/drivers/mmc/host/mxcmmc.c +++ b/trunk/drivers/mmc/host/mxcmmc.c @@ -240,7 +240,7 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) return 0; for_each_sg(data->sg, sg, data->sg_len, i) { - if (sg->offset & 3 || sg->length & 3 || sg->length < 512) { + if (sg->offset & 3 || sg->length & 3) { host->do_dma = 0; return 0; } @@ -1134,4 +1134,4 @@ module_platform_driver(mxcmci_driver); MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver"); MODULE_AUTHOR("Sascha Hauer, Pengutronix"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:mxc-mmc"); +MODULE_ALIAS("platform:imx-mmc"); diff --git a/trunk/drivers/mmc/host/mxs-mmc.c b/trunk/drivers/mmc/host/mxs-mmc.c index 206fe499ded5..80d1e6d4b0ae 100644 --- a/trunk/drivers/mmc/host/mxs-mmc.c +++ b/trunk/drivers/mmc/host/mxs-mmc.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #define DRIVER_NAME "mxs-mmc" @@ -592,13 +593,13 @@ static int mxs_mmc_probe(struct platform_device *pdev) struct mxs_mmc_host *host; struct mmc_host *mmc; struct resource *iores, *dmares; + struct mxs_mmc_platform_data *pdata; struct pinctrl *pinctrl; int ret = 0, irq_err, irq_dma; dma_cap_mask_t mask; struct regulator *reg_vmmc; enum of_gpio_flags flags; struct mxs_ssp *ssp; - u32 bus_width = 0; iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); @@ -681,15 +682,25 @@ static int mxs_mmc_probe(struct platform_device *pdev) mmc->caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL; - of_property_read_u32(np, "bus-width", &bus_width); - if (bus_width == 4) - mmc->caps |= MMC_CAP_4_BIT_DATA; - else if (bus_width == 8) - mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; - host->wp_gpio = of_get_named_gpio_flags(np, "wp-gpios", 0, &flags); - - if (flags & OF_GPIO_ACTIVE_LOW) - host->wp_inverted = 1; + pdata = mmc_dev(host->mmc)->platform_data; + if (!pdata) { + u32 bus_width = 0; + of_property_read_u32(np, "bus-width", &bus_width); + if (bus_width == 4) + mmc->caps |= MMC_CAP_4_BIT_DATA; + else if (bus_width == 8) + mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; + host->wp_gpio = of_get_named_gpio_flags(np, "wp-gpios", 0, + &flags); + if (flags & OF_GPIO_ACTIVE_LOW) + host->wp_inverted = 1; + } else { + if (pdata->flags & SLOTF_8_BIT_CAPABLE) + mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; + if (pdata->flags & SLOTF_4_BIT_CAPABLE) + mmc->caps |= MMC_CAP_4_BIT_DATA; + host->wp_gpio = pdata->wp_gpio; + } mmc->f_min = 400000; mmc->f_max = 288000000; diff --git a/trunk/drivers/mmc/host/omap_hsmmc.c b/trunk/drivers/mmc/host/omap_hsmmc.c index d0a912fbad3b..54bfd0cc106b 100644 --- a/trunk/drivers/mmc/host/omap_hsmmc.c +++ b/trunk/drivers/mmc/host/omap_hsmmc.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -63,7 +62,6 @@ #define VS18 (1 << 26) #define VS30 (1 << 25) -#define HSS (1 << 21) #define SDVS18 (0x5 << 9) #define SDVS30 (0x6 << 9) #define SDVS33 (0x7 << 9) @@ -80,17 +78,28 @@ #define CLKD_SHIFT 6 #define DTO_MASK 0x000F0000 #define DTO_SHIFT 16 +#define INT_EN_MASK 0x307F0033 +#define BWR_ENABLE (1 << 4) +#define BRR_ENABLE (1 << 5) +#define DTO_ENABLE (1 << 20) #define INIT_STREAM (1 << 1) #define DP_SELECT (1 << 21) #define DDIR (1 << 4) -#define DMAE 0x1 +#define DMA_EN 0x1 #define MSBS (1 << 5) #define BCE (1 << 1) #define FOUR_BIT (1 << 1) -#define HSPE (1 << 2) #define DDR (1 << 19) #define DW8 (1 << 5) +#define CC 0x1 +#define TC 0x02 #define OD 0x1 +#define ERR (1 << 15) +#define CMD_TIMEOUT (1 << 16) +#define DATA_TIMEOUT (1 << 20) +#define CMD_CRC (1 << 17) +#define DATA_CRC (1 << 21) +#define CARD_ERR (1 << 28) #define STAT_CLEAR 0xFFFFFFFF #define INIT_STREAM_CMD 0x00000000 #define DUAL_VOLT_OCR_BIT 7 @@ -99,26 +108,6 @@ #define SOFTRESET (1 << 1) #define RESETDONE (1 << 0) -/* Interrupt masks for IE and ISE register */ -#define CC_EN (1 << 0) -#define TC_EN (1 << 1) -#define BWR_EN (1 << 4) -#define BRR_EN (1 << 5) -#define ERR_EN (1 << 15) -#define CTO_EN (1 << 16) -#define CCRC_EN (1 << 17) -#define CEB_EN (1 << 18) -#define CIE_EN (1 << 19) -#define DTO_EN (1 << 20) -#define DCRC_EN (1 << 21) -#define DEB_EN (1 << 22) -#define CERR_EN (1 << 28) -#define BADA_EN (1 << 29) - -#define INT_EN_MASK (BADA_EN | CERR_EN | DEB_EN | DCRC_EN |\ - DTO_EN | CIE_EN | CEB_EN | CCRC_EN | CTO_EN | \ - BRR_EN | BWR_EN | TC_EN | CC_EN) - #define MMC_AUTOSUSPEND_DELAY 100 #define MMC_TIMEOUT_MS 20 #define OMAP_MMC_MIN_CLOCK 400000 @@ -189,8 +178,7 @@ struct omap_hsmmc_host { static int omap_hsmmc_card_detect(struct device *dev, int slot) { - struct omap_hsmmc_host *host = dev_get_drvdata(dev); - struct omap_mmc_platform_data *mmc = host->pdata; + struct omap_mmc_platform_data *mmc = dev->platform_data; /* NOTE: assumes card detect signal is active-low */ return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); @@ -198,8 +186,7 @@ static int omap_hsmmc_card_detect(struct device *dev, int slot) static int omap_hsmmc_get_wp(struct device *dev, int slot) { - struct omap_hsmmc_host *host = dev_get_drvdata(dev); - struct omap_mmc_platform_data *mmc = host->pdata; + struct omap_mmc_platform_data *mmc = dev->platform_data; /* NOTE: assumes write protect signal is active-high */ return gpio_get_value_cansleep(mmc->slots[0].gpio_wp); @@ -207,8 +194,7 @@ static int omap_hsmmc_get_wp(struct device *dev, int slot) static int omap_hsmmc_get_cover_state(struct device *dev, int slot) { - struct omap_hsmmc_host *host = dev_get_drvdata(dev); - struct omap_mmc_platform_data *mmc = host->pdata; + struct omap_mmc_platform_data *mmc = dev->platform_data; /* NOTE: assumes card detect signal is active-low */ return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); @@ -218,8 +204,7 @@ static int omap_hsmmc_get_cover_state(struct device *dev, int slot) static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) { - struct omap_hsmmc_host *host = dev_get_drvdata(dev); - struct omap_mmc_platform_data *mmc = host->pdata; + struct omap_mmc_platform_data *mmc = dev->platform_data; disable_irq(mmc->slots[0].card_detect_irq); return 0; @@ -227,8 +212,7 @@ static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) static int omap_hsmmc_resume_cdirq(struct device *dev, int slot) { - struct omap_hsmmc_host *host = dev_get_drvdata(dev); - struct omap_mmc_platform_data *mmc = host->pdata; + struct omap_mmc_platform_data *mmc = dev->platform_data; enable_irq(mmc->slots[0].card_detect_irq); return 0; @@ -313,7 +297,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) reg = regulator_get(host->dev, "vmmc"); if (IS_ERR(reg)) { - dev_err(host->dev, "vmmc regulator missing\n"); + dev_dbg(host->dev, "vmmc regulator missing\n"); return PTR_ERR(reg); } else { mmc_slot(host).set_power = omap_hsmmc_set_power; @@ -466,13 +450,13 @@ static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host, unsigned int irq_mask; if (host->use_dma) - irq_mask = INT_EN_MASK & ~(BRR_EN | BWR_EN); + irq_mask = INT_EN_MASK & ~(BRR_ENABLE | BWR_ENABLE); else irq_mask = INT_EN_MASK; /* Disable timeout for erases */ if (cmd->opcode == MMC_ERASE) - irq_mask &= ~DTO_EN; + irq_mask &= ~DTO_ENABLE; OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); OMAP_HSMMC_WRITE(host->base, ISE, irq_mask); @@ -505,7 +489,6 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host) struct mmc_ios *ios = &host->mmc->ios; unsigned long regval; unsigned long timeout; - unsigned long clkdiv; dev_vdbg(mmc_dev(host->mmc), "Set clock to %uHz\n", ios->clock); @@ -513,8 +496,7 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host) regval = OMAP_HSMMC_READ(host->base, SYSCTL); regval = regval & ~(CLKD_MASK | DTO_MASK); - clkdiv = calc_divisor(host, ios); - regval = regval | (clkdiv << 6) | (DTO << 16); + regval = regval | (calc_divisor(host, ios) << 6) | (DTO << 16); OMAP_HSMMC_WRITE(host->base, SYSCTL, regval); OMAP_HSMMC_WRITE(host->base, SYSCTL, OMAP_HSMMC_READ(host->base, SYSCTL) | ICE); @@ -525,27 +507,6 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host) && time_before(jiffies, timeout)) cpu_relax(); - /* - * Enable High-Speed Support - * Pre-Requisites - * - Controller should support High-Speed-Enable Bit - * - Controller should not be using DDR Mode - * - Controller should advertise that it supports High Speed - * in capabilities register - * - MMC/SD clock coming out of controller > 25MHz - */ - if ((mmc_slot(host).features & HSMMC_HAS_HSPE_SUPPORT) && - (ios->timing != MMC_TIMING_UHS_DDR50) && - ((OMAP_HSMMC_READ(host->base, CAPA) & HSS) == HSS)) { - regval = OMAP_HSMMC_READ(host->base, HCTL); - if (clkdiv && (clk_get_rate(host->fclk)/clkdiv) > 25000000) - regval |= HSPE; - else - regval &= ~HSPE; - - OMAP_HSMMC_WRITE(host->base, HCTL, regval); - } - omap_hsmmc_start_clock(host); } @@ -710,8 +671,8 @@ static void send_init_stream(struct omap_hsmmc_host *host) OMAP_HSMMC_WRITE(host->base, CMD, INIT_STREAM_CMD); timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS); - while ((reg != CC_EN) && time_before(jiffies, timeout)) - reg = OMAP_HSMMC_READ(host->base, STAT) & CC_EN; + while ((reg != CC) && time_before(jiffies, timeout)) + reg = OMAP_HSMMC_READ(host->base, STAT) & CC; OMAP_HSMMC_WRITE(host->base, CON, OMAP_HSMMC_READ(host->base, CON) & ~INIT_STREAM); @@ -802,7 +763,7 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, } if (host->use_dma) - cmdreg |= DMAE; + cmdreg |= DMA_EN; host->req_in_progress = 1; @@ -1002,20 +963,16 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host, __func__); } -static void hsmmc_command_incomplete(struct omap_hsmmc_host *host, - int err, int end_cmd) +static void hsmmc_command_incomplete(struct omap_hsmmc_host *host, int err) { - if (end_cmd) { - omap_hsmmc_reset_controller_fsm(host, SRC); - if (host->cmd) - host->cmd->error = err; - } + omap_hsmmc_reset_controller_fsm(host, SRC); + host->cmd->error = err; if (host->data) { omap_hsmmc_reset_controller_fsm(host, SRD); omap_hsmmc_dma_cleanup(host, err); - } else if (host->mrq && host->mrq->cmd) - host->mrq->cmd->error = err; + } + } static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status) @@ -1026,25 +983,23 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status) data = host->data; dev_vdbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status); - if (status & ERR_EN) { + if (status & ERR) { omap_hsmmc_dbg_report_irq(host, status); + if (status & (CMD_TIMEOUT | DATA_TIMEOUT)) + hsmmc_command_incomplete(host, -ETIMEDOUT); + else if (status & (CMD_CRC | DATA_CRC)) + hsmmc_command_incomplete(host, -EILSEQ); - if (status & (CTO_EN | CCRC_EN)) - end_cmd = 1; - if (status & (CTO_EN | DTO_EN)) - hsmmc_command_incomplete(host, -ETIMEDOUT, end_cmd); - else if (status & (CCRC_EN | DCRC_EN)) - hsmmc_command_incomplete(host, -EILSEQ, end_cmd); - + end_cmd = 1; if (host->data || host->response_busy) { - end_trans = !end_cmd; + end_trans = 1; host->response_busy = 0; } } - if (end_cmd || ((status & CC_EN) && host->cmd)) + if (end_cmd || ((status & CC) && host->cmd)) omap_hsmmc_cmd_done(host, host->cmd); - if ((end_trans || (status & TC_EN)) && host->mrq) + if ((end_trans || (status & TC)) && host->mrq) omap_hsmmc_xfer_done(host, data); } @@ -1141,7 +1096,7 @@ static int omap_hsmmc_switch_opcond(struct omap_hsmmc_host *host, int vdd) return 0; err: - dev_err(mmc_dev(host->mmc), "Unable to switch operating voltage\n"); + dev_dbg(mmc_dev(host->mmc), "Unable to switch operating voltage\n"); return ret; } @@ -1400,7 +1355,7 @@ omap_hsmmc_prepare_data(struct omap_hsmmc_host *host, struct mmc_request *req) if (host->use_dma) { ret = omap_hsmmc_start_dma_transfer(host, req); if (ret != 0) { - dev_err(mmc_dev(host->mmc), "MMC start dma failure\n"); + dev_dbg(mmc_dev(host->mmc), "MMC start dma failure\n"); return ret; } } @@ -1718,7 +1673,7 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) { struct omap_mmc_platform_data *pdata; struct device_node *np = dev->of_node; - u32 bus_width, max_freq; + u32 bus_width; pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) @@ -1745,12 +1700,6 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) if (of_find_property(np, "ti,needs-special-reset", NULL)) pdata->slots[0].features |= HSMMC_HAS_UPDATED_RESET; - if (!of_property_read_u32(np, "max-frequency", &max_freq)) - pdata->max_freq = max_freq; - - if (of_find_property(np, "ti,needs-special-hs-handling", NULL)) - pdata->slots[0].features |= HSMMC_HAS_HSPE_SUPPORT; - return pdata; } #else @@ -1771,7 +1720,6 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) const struct of_device_id *match; dma_cap_mask_t mask; unsigned tx_req, rx_req; - struct pinctrl *pinctrl; match = of_match_device(of_match_ptr(omap_mmc_of_match), &pdev->dev); if (match) { @@ -1868,6 +1816,7 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) * MMC can still work without debounce clock. */ if (IS_ERR(host->dbclk)) { + dev_warn(mmc_dev(host->mmc), "Failed to get debounce clk\n"); host->dbclk = NULL; } else if (clk_prepare_enable(host->dbclk) != 0) { dev_warn(mmc_dev(host->mmc), "Failed to enable debounce clk\n"); @@ -1935,13 +1884,13 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) ret = request_irq(host->irq, omap_hsmmc_irq, 0, mmc_hostname(mmc), host); if (ret) { - dev_err(mmc_dev(host->mmc), "Unable to grab HSMMC IRQ\n"); + dev_dbg(mmc_dev(host->mmc), "Unable to grab HSMMC IRQ\n"); goto err_irq; } if (pdata->init != NULL) { if (pdata->init(&pdev->dev) != 0) { - dev_err(mmc_dev(host->mmc), + dev_dbg(mmc_dev(host->mmc), "Unable to configure MMC IRQs\n"); goto err_irq_cd_init; } @@ -1964,7 +1913,7 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, mmc_hostname(mmc), host); if (ret) { - dev_err(mmc_dev(host->mmc), + dev_dbg(mmc_dev(host->mmc), "Unable to grab MMC CD IRQ\n"); goto err_irq_cd; } @@ -1974,11 +1923,6 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) omap_hsmmc_disable_irq(host); - pinctrl = devm_pinctrl_get_select_default(&pdev->dev); - if (IS_ERR(pinctrl)) - dev_warn(&pdev->dev, - "pins are not configured from the driver\n"); - omap_hsmmc_protect_card(host); mmc_add_host(mmc); @@ -2065,9 +2009,9 @@ static int __devexit omap_hsmmc_remove(struct platform_device *pdev) clk_put(host->dbclk); } - omap_hsmmc_gpio_free(host->pdata); - iounmap(host->base); mmc_free_host(host->mmc); + iounmap(host->base); + omap_hsmmc_gpio_free(pdev->dev.platform_data); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res) @@ -2078,25 +2022,6 @@ static int __devexit omap_hsmmc_remove(struct platform_device *pdev) } #ifdef CONFIG_PM -static int omap_hsmmc_prepare(struct device *dev) -{ - struct omap_hsmmc_host *host = dev_get_drvdata(dev); - - if (host->pdata->suspend) - return host->pdata->suspend(dev, host->slot_id); - - return 0; -} - -static void omap_hsmmc_complete(struct device *dev) -{ - struct omap_hsmmc_host *host = dev_get_drvdata(dev); - - if (host->pdata->resume) - host->pdata->resume(dev, host->slot_id); - -} - static int omap_hsmmc_suspend(struct device *dev) { int ret = 0; @@ -2110,10 +2035,23 @@ static int omap_hsmmc_suspend(struct device *dev) pm_runtime_get_sync(host->dev); host->suspended = 1; + if (host->pdata->suspend) { + ret = host->pdata->suspend(dev, host->slot_id); + if (ret) { + dev_dbg(dev, "Unable to handle MMC board" + " level suspend\n"); + host->suspended = 0; + return ret; + } + } ret = mmc_suspend_host(host->mmc); if (ret) { host->suspended = 0; + if (host->pdata->resume) { + if (host->pdata->resume(dev, host->slot_id)) + dev_dbg(dev, "Unmask interrupt failed\n"); + } goto err; } @@ -2150,6 +2088,12 @@ static int omap_hsmmc_resume(struct device *dev) if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) omap_hsmmc_conf_bus_power(host); + if (host->pdata->resume) { + ret = host->pdata->resume(dev, host->slot_id); + if (ret) + dev_dbg(dev, "Unmask interrupt failed\n"); + } + omap_hsmmc_protect_card(host); /* Notify the core to resume the host */ @@ -2165,10 +2109,8 @@ static int omap_hsmmc_resume(struct device *dev) } #else -#define omap_hsmmc_prepare NULL -#define omap_hsmmc_complete NULL #define omap_hsmmc_suspend NULL -#define omap_hsmmc_resume NULL +#define omap_hsmmc_resume NULL #endif static int omap_hsmmc_runtime_suspend(struct device *dev) @@ -2196,8 +2138,6 @@ static int omap_hsmmc_runtime_resume(struct device *dev) static struct dev_pm_ops omap_hsmmc_dev_pm_ops = { .suspend = omap_hsmmc_suspend, .resume = omap_hsmmc_resume, - .prepare = omap_hsmmc_prepare, - .complete = omap_hsmmc_complete, .runtime_suspend = omap_hsmmc_runtime_suspend, .runtime_resume = omap_hsmmc_runtime_resume, }; diff --git a/trunk/drivers/mmc/host/sdhci-dove.c b/trunk/drivers/mmc/host/sdhci-dove.c index e6214480bc98..90140eb03e36 100644 --- a/trunk/drivers/mmc/host/sdhci-dove.c +++ b/trunk/drivers/mmc/host/sdhci-dove.c @@ -19,30 +19,19 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include -#include -#include -#include #include +#include #include -#include #include "sdhci-pltfm.h" struct sdhci_dove_priv { struct clk *clk; - int gpio_cd; }; -static irqreturn_t sdhci_dove_carddetect_irq(int irq, void *data) -{ - struct sdhci_host *host = data; - - tasklet_schedule(&host->card_tasklet); - return IRQ_HANDLED; -} - static u16 sdhci_dove_readw(struct sdhci_host *host, int reg) { u16 ret; @@ -60,25 +49,16 @@ static u16 sdhci_dove_readw(struct sdhci_host *host, int reg) static u32 sdhci_dove_readl(struct sdhci_host *host, int reg) { - struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); - struct sdhci_dove_priv *priv = pltfm_host->priv; u32 ret; - ret = readl(host->ioaddr + reg); - switch (reg) { case SDHCI_CAPABILITIES: + ret = readl(host->ioaddr + reg); /* Mask the support for 3.0V */ ret &= ~SDHCI_CAN_VDD_300; break; - case SDHCI_PRESENT_STATE: - if (gpio_is_valid(priv->gpio_cd)) { - if (gpio_get_value(priv->gpio_cd) == 0) - ret |= SDHCI_CARD_PRESENT; - else - ret &= ~SDHCI_CARD_PRESENT; - } - break; + default: + ret = readl(host->ioaddr + reg); } return ret; } @@ -104,77 +84,30 @@ static int __devinit sdhci_dove_probe(struct platform_device *pdev) struct sdhci_dove_priv *priv; int ret; + ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata); + if (ret) + goto sdhci_dove_register_fail; + priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_dove_priv), GFP_KERNEL); if (!priv) { dev_err(&pdev->dev, "unable to allocate private data"); - return -ENOMEM; - } - - priv->clk = devm_clk_get(&pdev->dev, NULL); - - if (pdev->dev.of_node) { - priv->gpio_cd = of_get_named_gpio(pdev->dev.of_node, - "cd-gpios", 0); - } else { - priv->gpio_cd = -EINVAL; - } - - if (gpio_is_valid(priv->gpio_cd)) { - ret = gpio_request(priv->gpio_cd, "sdhci-cd"); - if (ret) { - dev_err(&pdev->dev, "card detect gpio request failed: %d\n", - ret); - return ret; - } - gpio_direction_input(priv->gpio_cd); - } - - host = sdhci_pltfm_init(pdev, &sdhci_dove_pdata); - if (IS_ERR(host)) { - ret = PTR_ERR(host); - goto err_sdhci_pltfm_init; + ret = -ENOMEM; + goto sdhci_dove_allocate_fail; } + host = platform_get_drvdata(pdev); pltfm_host = sdhci_priv(host); pltfm_host->priv = priv; + priv->clk = clk_get(&pdev->dev, NULL); if (!IS_ERR(priv->clk)) clk_prepare_enable(priv->clk); - - sdhci_get_of_property(pdev); - - ret = sdhci_add_host(host); - if (ret) - goto err_sdhci_add; - - /* - * We must request the IRQ after sdhci_add_host(), as the tasklet only - * gets setup in sdhci_add_host() and we oops. - */ - if (gpio_is_valid(priv->gpio_cd)) { - ret = request_irq(gpio_to_irq(priv->gpio_cd), - sdhci_dove_carddetect_irq, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, - mmc_hostname(host->mmc), host); - if (ret) { - dev_err(&pdev->dev, "card detect irq request failed: %d\n", - ret); - goto err_request_irq; - } - } - return 0; -err_request_irq: - sdhci_remove_host(host, 0); -err_sdhci_add: - if (!IS_ERR(priv->clk)) - clk_disable_unprepare(priv->clk); - sdhci_pltfm_free(pdev); -err_sdhci_pltfm_init: - if (gpio_is_valid(priv->gpio_cd)) - gpio_free(priv->gpio_cd); +sdhci_dove_allocate_fail: + sdhci_pltfm_unregister(pdev); +sdhci_dove_register_fail: return ret; } @@ -184,17 +117,14 @@ static int __devexit sdhci_dove_remove(struct platform_device *pdev) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_dove_priv *priv = pltfm_host->priv; - sdhci_pltfm_unregister(pdev); - - if (gpio_is_valid(priv->gpio_cd)) { - free_irq(gpio_to_irq(priv->gpio_cd), host); - gpio_free(priv->gpio_cd); + if (priv->clk) { + if (!IS_ERR(priv->clk)) { + clk_disable_unprepare(priv->clk); + clk_put(priv->clk); + } + devm_kfree(&pdev->dev, priv->clk); } - - if (!IS_ERR(priv->clk)) - clk_disable_unprepare(priv->clk); - - return 0; + return sdhci_pltfm_unregister(pdev); } static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = { diff --git a/trunk/drivers/mmc/host/sdhci-esdhc-imx.c b/trunk/drivers/mmc/host/sdhci-esdhc-imx.c index 1849461c39ee..effc2acfe778 100644 --- a/trunk/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/trunk/drivers/mmc/host/sdhci-esdhc-imx.c @@ -456,10 +456,10 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev) pltfm_host = sdhci_priv(host); - imx_data = devm_kzalloc(&pdev->dev, sizeof(*imx_data), GFP_KERNEL); + imx_data = kzalloc(sizeof(struct pltfm_imx_data), GFP_KERNEL); if (!imx_data) { err = -ENOMEM; - goto free_sdhci; + goto err_imx_data; } if (of_id) @@ -470,19 +470,19 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev) imx_data->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); if (IS_ERR(imx_data->clk_ipg)) { err = PTR_ERR(imx_data->clk_ipg); - goto free_sdhci; + goto err_clk_get; } imx_data->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); if (IS_ERR(imx_data->clk_ahb)) { err = PTR_ERR(imx_data->clk_ahb); - goto free_sdhci; + goto err_clk_get; } imx_data->clk_per = devm_clk_get(&pdev->dev, "per"); if (IS_ERR(imx_data->clk_per)) { err = PTR_ERR(imx_data->clk_per); - goto free_sdhci; + goto err_clk_get; } pltfm_host->clk = imx_data->clk_per; @@ -494,7 +494,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev) imx_data->pinctrl = devm_pinctrl_get_select_default(&pdev->dev); if (IS_ERR(imx_data->pinctrl)) { err = PTR_ERR(imx_data->pinctrl); - goto disable_clk; + goto pin_err; } host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; @@ -519,7 +519,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev) if (!host->mmc->parent->platform_data) { dev_err(mmc_dev(host->mmc), "no board data!\n"); err = -EINVAL; - goto disable_clk; + goto no_board_data; } imx_data->boarddata = *((struct esdhc_platform_data *) host->mmc->parent->platform_data); @@ -527,8 +527,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev) /* write_protect */ if (boarddata->wp_type == ESDHC_WP_GPIO) { - err = devm_gpio_request_one(&pdev->dev, boarddata->wp_gpio, - GPIOF_IN, "ESDHC_WP"); + err = gpio_request_one(boarddata->wp_gpio, GPIOF_IN, "ESDHC_WP"); if (err) { dev_warn(mmc_dev(host->mmc), "no write-protect pin available!\n"); @@ -544,21 +543,19 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev) switch (boarddata->cd_type) { case ESDHC_CD_GPIO: - err = devm_gpio_request_one(&pdev->dev, boarddata->cd_gpio, - GPIOF_IN, "ESDHC_CD"); + err = gpio_request_one(boarddata->cd_gpio, GPIOF_IN, "ESDHC_CD"); if (err) { dev_err(mmc_dev(host->mmc), "no card-detect pin available!\n"); - goto disable_clk; + goto no_card_detect_pin; } - err = devm_request_irq(&pdev->dev, - gpio_to_irq(boarddata->cd_gpio), cd_irq, + err = request_irq(gpio_to_irq(boarddata->cd_gpio), cd_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, mmc_hostname(host->mmc), host); if (err) { dev_err(mmc_dev(host->mmc), "request irq error\n"); - goto disable_clk; + goto no_card_detect_irq; } /* fall through */ @@ -577,15 +574,27 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev) err = sdhci_add_host(host); if (err) - goto disable_clk; + goto err_add_host; return 0; -disable_clk: +err_add_host: + if (gpio_is_valid(boarddata->cd_gpio)) + free_irq(gpio_to_irq(boarddata->cd_gpio), host); +no_card_detect_irq: + if (gpio_is_valid(boarddata->cd_gpio)) + gpio_free(boarddata->cd_gpio); + if (gpio_is_valid(boarddata->wp_gpio)) + gpio_free(boarddata->wp_gpio); +no_card_detect_pin: +no_board_data: +pin_err: clk_disable_unprepare(imx_data->clk_per); clk_disable_unprepare(imx_data->clk_ipg); clk_disable_unprepare(imx_data->clk_ahb); -free_sdhci: +err_clk_get: + kfree(imx_data); +err_imx_data: sdhci_pltfm_free(pdev); return err; } @@ -595,14 +604,25 @@ static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev) struct sdhci_host *host = platform_get_drvdata(pdev); struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct pltfm_imx_data *imx_data = pltfm_host->priv; + struct esdhc_platform_data *boarddata = &imx_data->boarddata; int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff); sdhci_remove_host(host, dead); + if (gpio_is_valid(boarddata->wp_gpio)) + gpio_free(boarddata->wp_gpio); + + if (gpio_is_valid(boarddata->cd_gpio)) { + free_irq(gpio_to_irq(boarddata->cd_gpio), host); + gpio_free(boarddata->cd_gpio); + } + clk_disable_unprepare(imx_data->clk_per); clk_disable_unprepare(imx_data->clk_ipg); clk_disable_unprepare(imx_data->clk_ahb); + kfree(imx_data); + sdhci_pltfm_free(pdev); return 0; diff --git a/trunk/drivers/mmc/host/sdhci-of-esdhc.c b/trunk/drivers/mmc/host/sdhci-of-esdhc.c index 60de2eeb39b1..ae5fcbfa1eef 100644 --- a/trunk/drivers/mmc/host/sdhci-of-esdhc.c +++ b/trunk/drivers/mmc/host/sdhci-of-esdhc.c @@ -22,7 +22,6 @@ #include "sdhci-esdhc.h" #define VENDOR_V_22 0x12 -#define VENDOR_V_23 0x13 static u32 esdhc_readl(struct sdhci_host *host, int reg) { u32 ret; @@ -86,18 +85,6 @@ static u8 esdhc_readb(struct sdhci_host *host, int reg) return ret; } -static void esdhc_writel(struct sdhci_host *host, u32 val, int reg) -{ - /* - * Enable IRQSTATEN[BGESEN] is just to set IRQSTAT[BGE] - * when SYSCTL[RSTD]) is set for some special operations. - * No any impact other operation. - */ - if (reg == SDHCI_INT_ENABLE) - val |= SDHCI_INT_BLK_GAP; - sdhci_be32bs_writel(host, val, reg); -} - static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) { if (reg == SDHCI_BLOCK_SIZE) { @@ -134,41 +121,6 @@ static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) sdhci_be32bs_writeb(host, val, reg); } -/* - * For Abort or Suspend after Stop at Block Gap, ignore the ADMA - * error(IRQSTAT[ADMAE]) if both Transfer Complete(IRQSTAT[TC]) - * and Block Gap Event(IRQSTAT[BGE]) are also set. - * For Continue, apply soft reset for data(SYSCTL[RSTD]); - * and re-issue the entire read transaction from beginning. - */ -static void esdhci_of_adma_workaround(struct sdhci_host *host, u32 intmask) -{ - u32 tmp; - bool applicable; - dma_addr_t dmastart; - dma_addr_t dmanow; - - tmp = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS); - tmp = (tmp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; - - applicable = (intmask & SDHCI_INT_DATA_END) && - (intmask & SDHCI_INT_BLK_GAP) && - (tmp == VENDOR_V_23); - if (!applicable) - return; - - host->data->error = 0; - dmastart = sg_dma_address(host->data->sg); - dmanow = dmastart + host->data->bytes_xfered; - /* - * Force update to the next DMA block boundary. - */ - dmanow = (dmanow & ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1)) + - SDHCI_DEFAULT_BOUNDARY_SIZE; - host->data->bytes_xfered = dmanow - dmastart; - sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS); -} - static int esdhc_of_enable_dma(struct sdhci_host *host) { setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP); @@ -217,36 +169,21 @@ static void esdhc_of_resume(struct sdhci_host *host) } #endif -static void esdhc_of_platform_init(struct sdhci_host *host) -{ - u32 vvn; - - vvn = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS); - vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; - if (vvn == VENDOR_V_22) - host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; - - if (vvn > VENDOR_V_22) - host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ; -} - static struct sdhci_ops sdhci_esdhc_ops = { .read_l = esdhc_readl, .read_w = esdhc_readw, .read_b = esdhc_readb, - .write_l = esdhc_writel, + .write_l = sdhci_be32bs_writel, .write_w = esdhc_writew, .write_b = esdhc_writeb, .set_clock = esdhc_of_set_clock, .enable_dma = esdhc_of_enable_dma, .get_max_clock = esdhc_of_get_max_clock, .get_min_clock = esdhc_of_get_min_clock, - .platform_init = esdhc_of_platform_init, #ifdef CONFIG_PM .platform_suspend = esdhc_of_suspend, .platform_resume = esdhc_of_resume, #endif - .adma_workaround = esdhci_of_adma_workaround, }; static struct sdhci_pltfm_data sdhci_esdhc_pdata = { diff --git a/trunk/drivers/mmc/host/sdhci-pci.c b/trunk/drivers/mmc/host/sdhci-pci.c index 0777fad997ba..4bb74b042a06 100644 --- a/trunk/drivers/mmc/host/sdhci-pci.c +++ b/trunk/drivers/mmc/host/sdhci-pci.c @@ -114,7 +114,6 @@ static int ricoh_mmc_probe_slot(struct sdhci_pci_slot *slot) SDHCI_TIMEOUT_CLK_UNIT | SDHCI_CAN_VDD_330 | - SDHCI_CAN_DO_HISPD | SDHCI_CAN_DO_SDMA; return 0; } @@ -1197,7 +1196,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( return ERR_PTR(-ENODEV); } - if (pci_resource_len(pdev, bar) < 0x100) { + if (pci_resource_len(pdev, bar) != 0x100) { dev_err(&pdev->dev, "Invalid iomem size. You may " "experience problems.\n"); } diff --git a/trunk/drivers/mmc/host/sdhci-pltfm.c b/trunk/drivers/mmc/host/sdhci-pltfm.c index d4283ef5917a..65551a9709cc 100644 --- a/trunk/drivers/mmc/host/sdhci-pltfm.c +++ b/trunk/drivers/mmc/host/sdhci-pltfm.c @@ -78,9 +78,6 @@ void sdhci_get_of_property(struct platform_device *pdev) if (of_get_property(np, "broken-cd", NULL)) host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION; - if (of_get_property(np, "no-1-8-v", NULL)) - host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V; - if (of_device_is_compatible(np, "fsl,p2020-rev1-esdhc")) host->quirks |= SDHCI_QUIRK_BROKEN_DMA; @@ -92,12 +89,6 @@ void sdhci_get_of_property(struct platform_device *pdev) clk = of_get_property(np, "clock-frequency", &size); if (clk && size == sizeof(*clk) && *clk) pltfm_host->clock = be32_to_cpup(clk); - - if (of_find_property(np, "keep-power-in-suspend", NULL)) - host->mmc->pm_caps |= MMC_PM_KEEP_POWER; - - if (of_find_property(np, "enable-sdio-wakeup", NULL)) - host->mmc->pm_caps |= MMC_PM_WAKE_SDIO_IRQ; } } #else @@ -159,13 +150,6 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev, goto err_remap; } - /* - * Some platforms need to probe the controller to be able to - * determine which caps should be used. - */ - if (host->ops && host->ops->platform_init) - host->ops->platform_init(host); - platform_set_drvdata(pdev, host); return host; diff --git a/trunk/drivers/mmc/host/sdhci-pxav3.c b/trunk/drivers/mmc/host/sdhci-pxav3.c index 60829c92bcfd..e918a2bb3af1 100644 --- a/trunk/drivers/mmc/host/sdhci-pxav3.c +++ b/trunk/drivers/mmc/host/sdhci-pxav3.c @@ -163,18 +163,10 @@ static int pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs) return 0; } -static u32 pxav3_get_max_clock(struct sdhci_host *host) -{ - struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); - - return clk_get_rate(pltfm_host->clk); -} - static struct sdhci_ops pxav3_sdhci_ops = { .platform_reset_exit = pxav3_set_private_registers, .set_uhs_signaling = pxav3_set_uhs_signaling, .platform_send_init_74_clocks = pxav3_gen_init_74_clocks, - .get_max_clock = pxav3_get_max_clock, }; #ifdef CONFIG_OF @@ -257,8 +249,7 @@ static int __devinit sdhci_pxav3_probe(struct platform_device *pdev) host->quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC - | SDHCI_QUIRK_32BIT_ADMA_SIZE - | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN; + | SDHCI_QUIRK_32BIT_ADMA_SIZE; /* enable 1/8V DDR capable */ host->mmc->caps |= MMC_CAP_1_8V_DDR; @@ -280,8 +271,6 @@ static int __devinit sdhci_pxav3_probe(struct platform_device *pdev) if (pdata->quirks) host->quirks |= pdata->quirks; - if (pdata->quirks2) - host->quirks2 |= pdata->quirks2; if (pdata->host_caps) host->mmc->caps |= pdata->host_caps; if (pdata->host_caps2) diff --git a/trunk/drivers/mmc/host/sdhci-s3c.c b/trunk/drivers/mmc/host/sdhci-s3c.c index 82b7a7ad4217..2903949594c6 100644 --- a/trunk/drivers/mmc/host/sdhci-s3c.c +++ b/trunk/drivers/mmc/host/sdhci-s3c.c @@ -24,7 +24,6 @@ #include #include #include -#include #include @@ -58,7 +57,6 @@ struct sdhci_s3c { int ext_cd_irq; int ext_cd_gpio; int *gpios; - struct pinctrl *pctrl; struct clk *clk_io; struct clk *clk_bus[MAX_BUS_CLK]; @@ -213,8 +211,8 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock) if (ourhost->cur_clk != best_src) { struct clk *clk = ourhost->clk_bus[best_src]; - clk_prepare_enable(clk); - clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); + clk_enable(clk); + clk_disable(ourhost->clk_bus[ourhost->cur_clk]); /* turn clock off to card before changing clock source */ writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); @@ -375,27 +373,18 @@ static struct sdhci_ops sdhci_s3c_ops = { static void sdhci_s3c_notify_change(struct platform_device *dev, int state) { struct sdhci_host *host = platform_get_drvdata(dev); -#ifdef CONFIG_PM_RUNTIME - struct sdhci_s3c *sc = sdhci_priv(host); -#endif unsigned long flags; if (host) { spin_lock_irqsave(&host->lock, flags); if (state) { dev_dbg(&dev->dev, "card inserted.\n"); -#ifdef CONFIG_PM_RUNTIME - clk_prepare_enable(sc->clk_io); -#endif host->flags &= ~SDHCI_DEVICE_DEAD; host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION; } else { dev_dbg(&dev->dev, "card removed.\n"); host->flags |= SDHCI_DEVICE_DEAD; host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; -#ifdef CONFIG_PM_RUNTIME - clk_disable_unprepare(sc->clk_io); -#endif } tasklet_schedule(&host->card_tasklet); spin_unlock_irqrestore(&host->lock, flags); @@ -417,7 +406,7 @@ static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc) struct s3c_sdhci_platdata *pdata = sc->pdata; struct device *dev = &sc->pdev->dev; - if (devm_gpio_request(dev, pdata->ext_cd_gpio, "SDHCI EXT CD") == 0) { + if (gpio_request(pdata->ext_cd_gpio, "SDHCI EXT CD") == 0) { sc->ext_cd_gpio = pdata->ext_cd_gpio; sc->ext_cd_irq = gpio_to_irq(pdata->ext_cd_gpio); if (sc->ext_cd_irq && @@ -460,12 +449,12 @@ static int __devinit sdhci_s3c_parse_dt(struct device *dev, return -ENOMEM; /* get the card detection method */ - if (of_get_property(node, "broken-cd", NULL)) { + if (of_get_property(node, "broken-cd", 0)) { pdata->cd_type = S3C_SDHCI_CD_NONE; goto setup_bus; } - if (of_get_property(node, "non-removable", NULL)) { + if (of_get_property(node, "non-removable", 0)) { pdata->cd_type = S3C_SDHCI_CD_PERMANENT; goto setup_bus; } @@ -488,9 +477,8 @@ static int __devinit sdhci_s3c_parse_dt(struct device *dev, return -EINVAL; } - /* assuming internal card detect that will be configured by pinctrl */ - pdata->cd_type = S3C_SDHCI_CD_INTERNAL; - goto setup_bus; + dev_info(dev, "assuming no card detect line available\n"); + pdata->cd_type = S3C_SDHCI_CD_NONE; found_cd: if (pdata->cd_type == S3C_SDHCI_CD_GPIO) { @@ -499,7 +487,7 @@ static int __devinit sdhci_s3c_parse_dt(struct device *dev, if (of_get_property(node, "cd-inverted", NULL)) pdata->ext_cd_gpio_invert = 1; } else if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { - ret = devm_gpio_request(dev, gpio, "sdhci-cd"); + ret = gpio_request(gpio, "sdhci-cd"); if (ret) { dev_err(dev, "card detect gpio request failed\n"); return -EINVAL; @@ -508,28 +496,33 @@ static int __devinit sdhci_s3c_parse_dt(struct device *dev, } setup_bus: - if (!IS_ERR(ourhost->pctrl)) - return 0; - /* get the gpios for command, clock and data lines */ for (cnt = 0; cnt < NUM_GPIOS(pdata->max_width); cnt++) { gpio = of_get_gpio(node, cnt); if (!gpio_is_valid(gpio)) { dev_err(dev, "invalid gpio[%d]\n", cnt); - return -EINVAL; + goto err_free_dt_cd_gpio; } ourhost->gpios[cnt] = gpio; } for (cnt = 0; cnt < NUM_GPIOS(pdata->max_width); cnt++) { - ret = devm_gpio_request(dev, ourhost->gpios[cnt], "sdhci-gpio"); + ret = gpio_request(ourhost->gpios[cnt], "sdhci-gpio"); if (ret) { dev_err(dev, "gpio[%d] request failed\n", cnt); - return -EINVAL; + goto err_free_dt_gpios; } } return 0; + + err_free_dt_gpios: + while (--cnt >= 0) + gpio_free(ourhost->gpios[cnt]); + err_free_dt_cd_gpio: + if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) + gpio_free(ourhost->ext_cd_gpio); + return -EINVAL; } #else static int __devinit sdhci_s3c_parse_dt(struct device *dev, @@ -586,15 +579,13 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) { ret = -ENOMEM; - goto err_pdata_io_clk; + goto err_pdata; } - sc->pctrl = devm_pinctrl_get_select_default(&pdev->dev); - if (pdev->dev.of_node) { ret = sdhci_s3c_parse_dt(&pdev->dev, host, pdata); if (ret) - goto err_pdata_io_clk; + goto err_pdata; } else { memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata)); sc->ext_cd_gpio = -1; /* invalid gpio number */ @@ -612,11 +603,11 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) if (IS_ERR(sc->clk_io)) { dev_err(dev, "failed to get io clock\n"); ret = PTR_ERR(sc->clk_io); - goto err_pdata_io_clk; + goto err_io_clk; } /* enable the local io clock and keep it running for the moment. */ - clk_prepare_enable(sc->clk_io); + clk_enable(sc->clk_io); for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) { struct clk *clk; @@ -647,7 +638,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) } #ifndef CONFIG_PM_RUNTIME - clk_prepare_enable(sc->clk_bus[sc->cur_clk]); + clk_enable(sc->clk_bus[sc->cur_clk]); #endif res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -756,14 +747,13 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) sdhci_s3c_setup_card_detect_gpio(sc); #ifdef CONFIG_PM_RUNTIME - if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) - clk_disable_unprepare(sc->clk_io); + clk_disable(sc->clk_io); #endif return 0; err_req_regs: #ifndef CONFIG_PM_RUNTIME - clk_disable_unprepare(sc->clk_bus[sc->cur_clk]); + clk_disable(sc->clk_bus[sc->cur_clk]); #endif for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { if (sc->clk_bus[ptr]) { @@ -772,10 +762,16 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) } err_no_busclks: - clk_disable_unprepare(sc->clk_io); + clk_disable(sc->clk_io); clk_put(sc->clk_io); - err_pdata_io_clk: + err_io_clk: + for (ptr = 0; ptr < NUM_GPIOS(sc->pdata->max_width); ptr++) + gpio_free(sc->gpios[ptr]); + if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) + gpio_free(sc->ext_cd_gpio); + + err_pdata: sdhci_free_host(host); return ret; @@ -794,9 +790,11 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) if (sc->ext_cd_irq) free_irq(sc->ext_cd_irq, sc); + if (gpio_is_valid(sc->ext_cd_gpio)) + gpio_free(sc->ext_cd_gpio); + #ifdef CONFIG_PM_RUNTIME - if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) - clk_prepare_enable(sc->clk_io); + clk_enable(sc->clk_io); #endif sdhci_remove_host(host, 1); @@ -804,16 +802,21 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); #ifndef CONFIG_PM_RUNTIME - clk_disable_unprepare(sc->clk_bus[sc->cur_clk]); + clk_disable(sc->clk_bus[sc->cur_clk]); #endif for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { if (sc->clk_bus[ptr]) { clk_put(sc->clk_bus[ptr]); } } - clk_disable_unprepare(sc->clk_io); + clk_disable(sc->clk_io); clk_put(sc->clk_io); + if (pdev->dev.of_node) { + for (ptr = 0; ptr < NUM_GPIOS(sc->pdata->max_width); ptr++) + gpio_free(sc->gpios[ptr]); + } + sdhci_free_host(host); platform_set_drvdata(pdev, NULL); @@ -846,8 +849,8 @@ static int sdhci_s3c_runtime_suspend(struct device *dev) ret = sdhci_runtime_suspend_host(host); - clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); - clk_disable_unprepare(busclk); + clk_disable(ourhost->clk_bus[ourhost->cur_clk]); + clk_disable(busclk); return ret; } @@ -858,8 +861,8 @@ static int sdhci_s3c_runtime_resume(struct device *dev) struct clk *busclk = ourhost->clk_io; int ret; - clk_prepare_enable(busclk); - clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]); + clk_enable(busclk); + clk_enable(ourhost->clk_bus[ourhost->cur_clk]); ret = sdhci_runtime_resume_host(host); return ret; } diff --git a/trunk/drivers/mmc/host/sdhci-spear.c b/trunk/drivers/mmc/host/sdhci-spear.c index 87a700944b7d..6be89c032deb 100644 --- a/trunk/drivers/mmc/host/sdhci-spear.c +++ b/trunk/drivers/mmc/host/sdhci-spear.c @@ -146,11 +146,6 @@ static int __devinit sdhci_probe(struct platform_device *pdev) goto put_clk; } - ret = clk_set_rate(sdhci->clk, 50000000); - if (ret) - dev_dbg(&pdev->dev, "Error setting desired clk, clk=%lu\n", - clk_get_rate(sdhci->clk)); - if (np) { sdhci->data = sdhci_probe_config_dt(pdev); if (IS_ERR(sdhci->data)) { @@ -302,7 +297,7 @@ static int sdhci_suspend(struct device *dev) ret = sdhci_suspend_host(host); if (!ret) - clk_disable(sdhci->clk); + clk_disable_unprepare(sdhci->clk); return ret; } @@ -313,7 +308,7 @@ static int sdhci_resume(struct device *dev) struct spear_sdhci *sdhci = dev_get_platdata(dev); int ret; - ret = clk_enable(sdhci->clk); + ret = clk_prepare_enable(sdhci->clk); if (ret) { dev_dbg(dev, "Resume: Error enabling clock\n"); return ret; diff --git a/trunk/drivers/mmc/host/sdhci.c b/trunk/drivers/mmc/host/sdhci.c index 6f0bfc0c8c9c..7922adb42386 100644 --- a/trunk/drivers/mmc/host/sdhci.c +++ b/trunk/drivers/mmc/host/sdhci.c @@ -1315,19 +1315,16 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) */ if ((host->flags & SDHCI_NEEDS_RETUNING) && !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) { - if (mmc->card) { - /* eMMC uses cmd21 but sd and sdio use cmd19 */ - tuning_opcode = - mmc->card->type == MMC_TYPE_MMC ? - MMC_SEND_TUNING_BLOCK_HS200 : - MMC_SEND_TUNING_BLOCK; - spin_unlock_irqrestore(&host->lock, flags); - sdhci_execute_tuning(mmc, tuning_opcode); - spin_lock_irqsave(&host->lock, flags); - - /* Restore original mmc_request structure */ - host->mrq = mrq; - } + /* eMMC uses cmd21 while sd and sdio use cmd19 */ + tuning_opcode = mmc->card->type == MMC_TYPE_MMC ? + MMC_SEND_TUNING_BLOCK_HS200 : + MMC_SEND_TUNING_BLOCK; + spin_unlock_irqrestore(&host->lock, flags); + sdhci_execute_tuning(mmc, tuning_opcode); + spin_lock_irqsave(&host->lock, flags); + + /* Restore original mmc_request structure */ + host->mrq = mrq; } if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23)) @@ -1618,7 +1615,7 @@ static int sdhci_do_3_3v_signal_voltage_switch(struct sdhci_host *host, sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); if (host->vqmmc) { - ret = regulator_set_voltage(host->vqmmc, 2700000, 3600000); + ret = regulator_set_voltage(host->vqmmc, 3300000, 3300000); if (ret) { pr_warning("%s: Switching to 3.3V signalling voltage " " failed\n", mmc_hostname(host->mmc)); @@ -1662,7 +1659,7 @@ static int sdhci_do_1_8v_signal_voltage_switch(struct sdhci_host *host, */ if (host->vqmmc) ret = regulator_set_voltage(host->vqmmc, - 1700000, 1950000); + 1800000, 1800000); else ret = 0; @@ -1994,11 +1991,30 @@ static void sdhci_enable_preset_value(struct mmc_host *mmc, bool enable) sdhci_runtime_pm_put(host); } -static void sdhci_card_event(struct mmc_host *mmc) +static const struct mmc_host_ops sdhci_ops = { + .request = sdhci_request, + .set_ios = sdhci_set_ios, + .get_ro = sdhci_get_ro, + .hw_reset = sdhci_hw_reset, + .enable_sdio_irq = sdhci_enable_sdio_irq, + .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, + .execute_tuning = sdhci_execute_tuning, + .enable_preset_value = sdhci_enable_preset_value, +}; + +/*****************************************************************************\ + * * + * Tasklets * + * * +\*****************************************************************************/ + +static void sdhci_tasklet_card(unsigned long param) { - struct sdhci_host *host = mmc_priv(mmc); + struct sdhci_host *host; unsigned long flags; + host = (struct sdhci_host*)param; + spin_lock_irqsave(&host->lock, flags); /* Check host->mrq first in case we are runtime suspended */ @@ -2017,31 +2033,6 @@ static void sdhci_card_event(struct mmc_host *mmc) } spin_unlock_irqrestore(&host->lock, flags); -} - -static const struct mmc_host_ops sdhci_ops = { - .request = sdhci_request, - .set_ios = sdhci_set_ios, - .get_ro = sdhci_get_ro, - .hw_reset = sdhci_hw_reset, - .enable_sdio_irq = sdhci_enable_sdio_irq, - .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, - .execute_tuning = sdhci_execute_tuning, - .enable_preset_value = sdhci_enable_preset_value, - .card_event = sdhci_card_event, -}; - -/*****************************************************************************\ - * * - * Tasklets * - * * -\*****************************************************************************/ - -static void sdhci_tasklet_card(unsigned long param) -{ - struct sdhci_host *host = (struct sdhci_host*)param; - - sdhci_card_event(host->mmc); mmc_detect_change(host->mmc, msecs_to_jiffies(200)); } @@ -2288,8 +2279,6 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) pr_err("%s: ADMA error\n", mmc_hostname(host->mmc)); sdhci_show_adma_error(host); host->data->error = -EIO; - if (host->ops->adma_workaround) - host->ops->adma_workaround(host, intmask); } if (host->data->error) @@ -2848,9 +2837,6 @@ int sdhci_add_host(struct sdhci_host *host) if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) mmc->caps |= MMC_CAP_4_BIT_DATA; - if (host->quirks2 & SDHCI_QUIRK2_HOST_NO_CMD23) - mmc->caps &= ~MMC_CAP_CMD23; - if (caps[0] & SDHCI_CAN_DO_HISPD) mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; @@ -2860,22 +2846,13 @@ int sdhci_add_host(struct sdhci_host *host) /* If vqmmc regulator and no 1.8V signalling, then there's no UHS */ host->vqmmc = regulator_get(mmc_dev(mmc), "vqmmc"); - if (IS_ERR_OR_NULL(host->vqmmc)) { - if (PTR_ERR(host->vqmmc) < 0) { - pr_info("%s: no vqmmc regulator found\n", - mmc_hostname(mmc)); - host->vqmmc = NULL; - } - } else { - regulator_enable(host->vqmmc); - if (!regulator_is_supported_voltage(host->vqmmc, 1700000, - 1950000)) - caps[1] &= ~(SDHCI_SUPPORT_SDR104 | - SDHCI_SUPPORT_SDR50 | - SDHCI_SUPPORT_DDR50); + if (IS_ERR(host->vqmmc)) { + pr_info("%s: no vqmmc regulator found\n", mmc_hostname(mmc)); + host->vqmmc = NULL; } - - if (host->quirks2 & SDHCI_QUIRK2_NO_1_8_V) + else if (regulator_is_supported_voltage(host->vqmmc, 1800000, 1800000)) + regulator_enable(host->vqmmc); + else caps[1] &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_DDR50); @@ -2927,24 +2904,24 @@ int sdhci_add_host(struct sdhci_host *host) ocr_avail = 0; host->vmmc = regulator_get(mmc_dev(mmc), "vmmc"); - if (IS_ERR_OR_NULL(host->vmmc)) { - if (PTR_ERR(host->vmmc) < 0) { - pr_info("%s: no vmmc regulator found\n", - mmc_hostname(mmc)); - host->vmmc = NULL; - } - } + if (IS_ERR(host->vmmc)) { + pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc)); + host->vmmc = NULL; + } else + regulator_enable(host->vmmc); #ifdef CONFIG_REGULATOR if (host->vmmc) { - ret = regulator_is_supported_voltage(host->vmmc, 2700000, - 3600000); + ret = regulator_is_supported_voltage(host->vmmc, 3300000, + 3300000); if ((ret <= 0) || (!(caps[0] & SDHCI_CAN_VDD_330))) caps[0] &= ~SDHCI_CAN_VDD_330; + ret = regulator_is_supported_voltage(host->vmmc, 3000000, + 3000000); if ((ret <= 0) || (!(caps[0] & SDHCI_CAN_VDD_300))) caps[0] &= ~SDHCI_CAN_VDD_300; - ret = regulator_is_supported_voltage(host->vmmc, 1700000, - 1950000); + ret = regulator_is_supported_voltage(host->vmmc, 1800000, + 1800000); if ((ret <= 0) || (!(caps[0] & SDHCI_CAN_VDD_180))) caps[0] &= ~SDHCI_CAN_VDD_180; } diff --git a/trunk/drivers/mmc/host/sdhci.h b/trunk/drivers/mmc/host/sdhci.h index a6d69b7bdea2..97653ea8942b 100644 --- a/trunk/drivers/mmc/host/sdhci.h +++ b/trunk/drivers/mmc/host/sdhci.h @@ -120,7 +120,6 @@ #define SDHCI_SIGNAL_ENABLE 0x38 #define SDHCI_INT_RESPONSE 0x00000001 #define SDHCI_INT_DATA_END 0x00000002 -#define SDHCI_INT_BLK_GAP 0x00000004 #define SDHCI_INT_DMA_END 0x00000008 #define SDHCI_INT_SPACE_AVAIL 0x00000010 #define SDHCI_INT_DATA_AVAIL 0x00000020 @@ -147,8 +146,7 @@ #define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \ SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \ SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \ - SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR | \ - SDHCI_INT_BLK_GAP) + SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR) #define SDHCI_INT_ALL_MASK ((unsigned int)-1) #define SDHCI_ACMD12_ERR 0x3C @@ -280,8 +278,6 @@ struct sdhci_ops { void (*hw_reset)(struct sdhci_host *host); void (*platform_suspend)(struct sdhci_host *host); void (*platform_resume)(struct sdhci_host *host); - void (*adma_workaround)(struct sdhci_host *host, u32 intmask); - void (*platform_init)(struct sdhci_host *host); }; #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS diff --git a/trunk/drivers/mmc/host/sh_mmcif.c b/trunk/drivers/mmc/host/sh_mmcif.c index ae795233a1d6..11d2bc3b51d5 100644 --- a/trunk/drivers/mmc/host/sh_mmcif.c +++ b/trunk/drivers/mmc/host/sh_mmcif.c @@ -1104,6 +1104,7 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id) { struct sh_mmcif_host *host = dev_id; struct mmc_request *mrq = host->mrq; + struct mmc_data *data = mrq->data; cancel_delayed_work_sync(&host->timeout_work); @@ -1151,14 +1152,13 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id) case MMCIF_WAIT_FOR_READ_END: case MMCIF_WAIT_FOR_WRITE_END: if (host->sd_error) - mrq->data->error = sh_mmcif_error_manage(host); + data->error = sh_mmcif_error_manage(host); break; default: BUG(); } if (host->wait_for != MMCIF_WAIT_FOR_STOP) { - struct mmc_data *data = mrq->data; if (!mrq->cmd->error && data && !data->error) data->bytes_xfered = data->blocks * data->blksz; @@ -1231,6 +1231,10 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) host->sd_error = true; dev_dbg(&host->pd->dev, "int err state = %08x\n", state); } + if (host->state == STATE_IDLE) { + dev_info(&host->pd->dev, "Spurious IRQ status 0x%x", state); + return IRQ_HANDLED; + } if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) { if (!host->dma_active) return IRQ_WAKE_THREAD; @@ -1306,6 +1310,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev) struct sh_mmcif_plat_data *pd = pdev->dev.platform_data; struct resource *res; void __iomem *reg; + char clk_name[8]; irq[0] = platform_get_irq(pdev, 0); irq[1] = platform_get_irq(pdev, 1); @@ -1355,10 +1360,11 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); host->power = false; - host->hclk = clk_get(&pdev->dev, NULL); + snprintf(clk_name, sizeof(clk_name), "mmc%d", pdev->id); + host->hclk = clk_get(&pdev->dev, clk_name); if (IS_ERR(host->hclk)) { ret = PTR_ERR(host->hclk); - dev_err(&pdev->dev, "cannot get clock: %d\n", ret); + dev_err(&pdev->dev, "cannot get clock \"%s\": %d\n", clk_name, ret); goto eclkget; } ret = sh_mmcif_clk_update(host); @@ -1460,9 +1466,9 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); - clk_disable(host->hclk); mmc_free_host(host->mmc); pm_runtime_put_sync(&pdev->dev); + clk_disable(host->hclk); pm_runtime_disable(&pdev->dev); return 0; diff --git a/trunk/drivers/mmc/host/sh_mobile_sdhi.c b/trunk/drivers/mmc/host/sh_mobile_sdhi.c index d6ff8531fb35..0bdc146178db 100644 --- a/trunk/drivers/mmc/host/sh_mobile_sdhi.c +++ b/trunk/drivers/mmc/host/sh_mobile_sdhi.c @@ -123,6 +123,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev) struct tmio_mmc_data *mmc_data; struct sh_mobile_sdhi_info *p = pdev->dev.platform_data; struct tmio_mmc_host *host; + char clk_name[8]; int irq, ret, i = 0; bool multiplexed_isr = true; @@ -143,10 +144,11 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev) } } - priv->clk = clk_get(&pdev->dev, NULL); + snprintf(clk_name, sizeof(clk_name), "sdhi%d", pdev->id); + priv->clk = clk_get(&pdev->dev, clk_name); if (IS_ERR(priv->clk)) { + dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); ret = PTR_ERR(priv->clk); - dev_err(&pdev->dev, "cannot get clock: %d\n", ret); goto eclkget; } @@ -248,7 +250,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev) dev_info(&pdev->dev, "%s base at 0x%08lx clock rate %u MHz\n", mmc_hostname(host->mmc), (unsigned long) (platform_get_resource(pdev, IORESOURCE_MEM, 0)->start), - host->mmc->f_max / 1000000); + mmc_data->hclk / 1000000); return ret; diff --git a/trunk/drivers/mmc/host/vub300.c b/trunk/drivers/mmc/host/vub300.c index cb9f361c03ab..d5655a63eda4 100644 --- a/trunk/drivers/mmc/host/vub300.c +++ b/trunk/drivers/mmc/host/vub300.c @@ -2362,7 +2362,6 @@ static int vub300_probe(struct usb_interface *interface, error1: usb_free_urb(command_out_urb); error0: - usb_put_dev(udev); return retval; } diff --git a/trunk/drivers/mmc/host/wmt-sdmmc.c b/trunk/drivers/mmc/host/wmt-sdmmc.c deleted file mode 100644 index 5ba4605e4f80..000000000000 --- a/trunk/drivers/mmc/host/wmt-sdmmc.c +++ /dev/null @@ -1,1029 +0,0 @@ -/* - * WM8505/WM8650 SD/MMC Host Controller - * - * Copyright (C) 2010 Tony Prisk - * Copyright (C) 2008 WonderMedia Technologies, Inc. - * - * 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 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include - - -#define DRIVER_NAME "wmt-sdhc" - - -/* MMC/SD controller registers */ -#define SDMMC_CTLR 0x00 -#define SDMMC_CMD 0x01 -#define SDMMC_RSPTYPE 0x02 -#define SDMMC_ARG 0x04 -#define SDMMC_BUSMODE 0x08 -#define SDMMC_BLKLEN 0x0C -#define SDMMC_BLKCNT 0x0E -#define SDMMC_RSP 0x10 -#define SDMMC_CBCR 0x20 -#define SDMMC_INTMASK0 0x24 -#define SDMMC_INTMASK1 0x25 -#define SDMMC_STS0 0x28 -#define SDMMC_STS1 0x29 -#define SDMMC_STS2 0x2A -#define SDMMC_STS3 0x2B -#define SDMMC_RSPTIMEOUT 0x2C -#define SDMMC_CLK 0x30 /* VT8500 only */ -#define SDMMC_EXTCTRL 0x34 -#define SDMMC_SBLKLEN 0x38 -#define SDMMC_DMATIMEOUT 0x3C - - -/* SDMMC_CTLR bit fields */ -#define CTLR_CMD_START 0x01 -#define CTLR_CMD_WRITE 0x04 -#define CTLR_FIFO_RESET 0x08 - -/* SDMMC_BUSMODE bit fields */ -#define BM_SPI_MODE 0x01 -#define BM_FOURBIT_MODE 0x02 -#define BM_EIGHTBIT_MODE 0x04 -#define BM_SD_OFF 0x10 -#define BM_SPI_CS 0x20 -#define BM_SD_POWER 0x40 -#define BM_SOFT_RESET 0x80 -#define BM_ONEBIT_MASK 0xFD - -/* SDMMC_BLKLEN bit fields */ -#define BLKL_CRCERR_ABORT 0x0800 -#define BLKL_CD_POL_HIGH 0x1000 -#define BLKL_GPI_CD 0x2000 -#define BLKL_DATA3_CD 0x4000 -#define BLKL_INT_ENABLE 0x8000 - -/* SDMMC_INTMASK0 bit fields */ -#define INT0_MBLK_TRAN_DONE_INT_EN 0x10 -#define INT0_BLK_TRAN_DONE_INT_EN 0x20 -#define INT0_CD_INT_EN 0x40 -#define INT0_DI_INT_EN 0x80 - -/* SDMMC_INTMASK1 bit fields */ -#define INT1_CMD_RES_TRAN_DONE_INT_EN 0x02 -#define INT1_CMD_RES_TOUT_INT_EN 0x04 -#define INT1_MBLK_AUTO_STOP_INT_EN 0x08 -#define INT1_DATA_TOUT_INT_EN 0x10 -#define INT1_RESCRC_ERR_INT_EN 0x20 -#define INT1_RCRC_ERR_INT_EN 0x40 -#define INT1_WCRC_ERR_INT_EN 0x80 - -/* SDMMC_STS0 bit fields */ -#define STS0_WRITE_PROTECT 0x02 -#define STS0_CD_DATA3 0x04 -#define STS0_CD_GPI 0x08 -#define STS0_MBLK_DONE 0x10 -#define STS0_BLK_DONE 0x20 -#define STS0_CARD_DETECT 0x40 -#define STS0_DEVICE_INS 0x80 - -/* SDMMC_STS1 bit fields */ -#define STS1_SDIO_INT 0x01 -#define STS1_CMDRSP_DONE 0x02 -#define STS1_RSP_TIMEOUT 0x04 -#define STS1_AUTOSTOP_DONE 0x08 -#define STS1_DATA_TIMEOUT 0x10 -#define STS1_RSP_CRC_ERR 0x20 -#define STS1_RCRC_ERR 0x40 -#define STS1_WCRC_ERR 0x80 - -/* SDMMC_STS2 bit fields */ -#define STS2_CMD_RES_BUSY 0x10 -#define STS2_DATARSP_BUSY 0x20 -#define STS2_DIS_FORCECLK 0x80 - - -/* MMC/SD DMA Controller Registers */ -#define SDDMA_GCR 0x100 -#define SDDMA_IER 0x104 -#define SDDMA_ISR 0x108 -#define SDDMA_DESPR 0x10C -#define SDDMA_RBR 0x110 -#define SDDMA_DAR 0x114 -#define SDDMA_BAR 0x118 -#define SDDMA_CPR 0x11C -#define SDDMA_CCR 0x120 - - -/* SDDMA_GCR bit fields */ -#define DMA_GCR_DMA_EN 0x00000001 -#define DMA_GCR_SOFT_RESET 0x00000100 - -/* SDDMA_IER bit fields */ -#define DMA_IER_INT_EN 0x00000001 - -/* SDDMA_ISR bit fields */ -#define DMA_ISR_INT_STS 0x00000001 - -/* SDDMA_RBR bit fields */ -#define DMA_RBR_FORMAT 0x40000000 -#define DMA_RBR_END 0x80000000 - -/* SDDMA_CCR bit fields */ -#define DMA_CCR_RUN 0x00000080 -#define DMA_CCR_IF_TO_PERIPHERAL 0x00000000 -#define DMA_CCR_PERIPHERAL_TO_IF 0x00400000 - -/* SDDMA_CCR event status */ -#define DMA_CCR_EVT_NO_STATUS 0x00000000 -#define DMA_CCR_EVT_UNDERRUN 0x00000001 -#define DMA_CCR_EVT_OVERRUN 0x00000002 -#define DMA_CCR_EVT_DESP_READ 0x00000003 -#define DMA_CCR_EVT_DATA_RW 0x00000004 -#define DMA_CCR_EVT_EARLY_END 0x00000005 -#define DMA_CCR_EVT_SUCCESS 0x0000000F - -#define PDMA_READ 0x00 -#define PDMA_WRITE 0x01 - -#define WMT_SD_POWER_OFF 0 -#define WMT_SD_POWER_ON 1 - -struct wmt_dma_descriptor { - u32 flags; - u32 data_buffer_addr; - u32 branch_addr; - u32 reserved1; -}; - -struct wmt_mci_caps { - unsigned int f_min; - unsigned int f_max; - u32 ocr_avail; - u32 caps; - u32 max_seg_size; - u32 max_segs; - u32 max_blk_size; -}; - -struct wmt_mci_priv { - struct mmc_host *mmc; - void __iomem *sdmmc_base; - - int irq_regular; - int irq_dma; - - void *dma_desc_buffer; - dma_addr_t dma_desc_device_addr; - - struct completion cmdcomp; - struct completion datacomp; - - struct completion *comp_cmd; - struct completion *comp_dma; - - struct mmc_request *req; - struct mmc_command *cmd; - - struct clk *clk_sdmmc; - struct device *dev; - - u8 power_inverted; - u8 cd_inverted; -}; - -static void wmt_set_sd_power(struct wmt_mci_priv *priv, int enable) -{ - u32 reg_tmp; - if (enable) { - if (priv->power_inverted) { - reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE); - writeb(reg_tmp | BM_SD_OFF, - priv->sdmmc_base + SDMMC_BUSMODE); - } else { - reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE); - writeb(reg_tmp & (~BM_SD_OFF), - priv->sdmmc_base + SDMMC_BUSMODE); - } - } else { - if (priv->power_inverted) { - reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE); - writeb(reg_tmp & (~BM_SD_OFF), - priv->sdmmc_base + SDMMC_BUSMODE); - } else { - reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE); - writeb(reg_tmp | BM_SD_OFF, - priv->sdmmc_base + SDMMC_BUSMODE); - } - } -} - -static void wmt_mci_read_response(struct mmc_host *mmc) -{ - struct wmt_mci_priv *priv; - int idx1, idx2; - u8 tmp_resp; - u32 response; - - priv = mmc_priv(mmc); - - for (idx1 = 0; idx1 < 4; idx1++) { - response = 0; - for (idx2 = 0; idx2 < 4; idx2++) { - if ((idx1 == 3) && (idx2 == 3)) - tmp_resp = readb(priv->sdmmc_base + SDMMC_RSP); - else - tmp_resp = readb(priv->sdmmc_base + SDMMC_RSP + - (idx1*4) + idx2 + 1); - response |= (tmp_resp << (idx2 * 8)); - } - priv->cmd->resp[idx1] = cpu_to_be32(response); - } -} - -static void wmt_mci_start_command(struct wmt_mci_priv *priv) -{ - u32 reg_tmp; - - reg_tmp = readb(priv->sdmmc_base + SDMMC_CTLR); - writeb(reg_tmp | CTLR_CMD_START, priv->sdmmc_base + SDMMC_CTLR); -} - -static int wmt_mci_send_command(struct mmc_host *mmc, u8 command, u8 cmdtype, - u32 arg, u8 rsptype) -{ - struct wmt_mci_priv *priv; - u32 reg_tmp; - - priv = mmc_priv(mmc); - - /* write command, arg, resptype registers */ - writeb(command, priv->sdmmc_base + SDMMC_CMD); - writel(arg, priv->sdmmc_base + SDMMC_ARG); - writeb(rsptype, priv->sdmmc_base + SDMMC_RSPTYPE); - - /* reset response FIFO */ - reg_tmp = readb(priv->sdmmc_base + SDMMC_CTLR); - writeb(reg_tmp | CTLR_FIFO_RESET, priv->sdmmc_base + SDMMC_CTLR); - - /* ensure clock enabled - VT3465 */ - wmt_set_sd_power(priv, WMT_SD_POWER_ON); - - /* clear status bits */ - writeb(0xFF, priv->sdmmc_base + SDMMC_STS0); - writeb(0xFF, priv->sdmmc_base + SDMMC_STS1); - writeb(0xFF, priv->sdmmc_base + SDMMC_STS2); - writeb(0xFF, priv->sdmmc_base + SDMMC_STS3); - - /* set command type */ - reg_tmp = readb(priv->sdmmc_base + SDMMC_CTLR); - writeb((reg_tmp & 0x0F) | (cmdtype << 4), - priv->sdmmc_base + SDMMC_CTLR); - - return 0; -} - -static void wmt_mci_disable_dma(struct wmt_mci_priv *priv) -{ - writel(DMA_ISR_INT_STS, priv->sdmmc_base + SDDMA_ISR); - writel(0, priv->sdmmc_base + SDDMA_IER); -} - -static void wmt_complete_data_request(struct wmt_mci_priv *priv) -{ - struct mmc_request *req; - req = priv->req; - - req->data->bytes_xfered = req->data->blksz * req->data->blocks; - - /* unmap the DMA pages used for write data */ - if (req->data->flags & MMC_DATA_WRITE) - dma_unmap_sg(mmc_dev(priv->mmc), req->data->sg, - req->data->sg_len, DMA_TO_DEVICE); - else - dma_unmap_sg(mmc_dev(priv->mmc), req->data->sg, - req->data->sg_len, DMA_FROM_DEVICE); - - /* Check if the DMA ISR returned a data error */ - if ((req->cmd->error) || (req->data->error)) - mmc_request_done(priv->mmc, req); - else { - wmt_mci_read_response(priv->mmc); - if (!req->data->stop) { - /* single-block read/write requests end here */ - mmc_request_done(priv->mmc, req); - } else { - /* - * we change the priv->cmd variable so the response is - * stored in the stop struct rather than the original - * calling command struct - */ - priv->comp_cmd = &priv->cmdcomp; - init_completion(priv->comp_cmd); - priv->cmd = req->data->stop; - wmt_mci_send_command(priv->mmc, req->data->stop->opcode, - 7, req->data->stop->arg, 9); - wmt_mci_start_command(priv); - } - } -} - -static irqreturn_t wmt_mci_dma_isr(int irq_num, void *data) -{ - struct mmc_host *mmc; - struct wmt_mci_priv *priv; - - int status; - - priv = (struct wmt_mci_priv *)data; - mmc = priv->mmc; - - status = readl(priv->sdmmc_base + SDDMA_CCR) & 0x0F; - - if (status != DMA_CCR_EVT_SUCCESS) { - dev_err(priv->dev, "DMA Error: Status = %d\n", status); - priv->req->data->error = -ETIMEDOUT; - complete(priv->comp_dma); - return IRQ_HANDLED; - } - - priv->req->data->error = 0; - - wmt_mci_disable_dma(priv); - - complete(priv->comp_dma); - - if (priv->comp_cmd) { - if (completion_done(priv->comp_cmd)) { - /* - * if the command (regular) interrupt has already - * completed, finish off the request otherwise we wait - * for the command interrupt and finish from there. - */ - wmt_complete_data_request(priv); - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t wmt_mci_regular_isr(int irq_num, void *data) -{ - struct wmt_mci_priv *priv; - u32 status0; - u32 status1; - u32 status2; - u32 reg_tmp; - int cmd_done; - - priv = (struct wmt_mci_priv *)data; - cmd_done = 0; - status0 = readb(priv->sdmmc_base + SDMMC_STS0); - status1 = readb(priv->sdmmc_base + SDMMC_STS1); - status2 = readb(priv->sdmmc_base + SDMMC_STS2); - - /* Check for card insertion */ - reg_tmp = readb(priv->sdmmc_base + SDMMC_INTMASK0); - if ((reg_tmp & INT0_DI_INT_EN) && (status0 & STS0_DEVICE_INS)) { - mmc_detect_change(priv->mmc, 0); - if (priv->cmd) - priv->cmd->error = -ETIMEDOUT; - if (priv->comp_cmd) - complete(priv->comp_cmd); - if (priv->comp_dma) { - wmt_mci_disable_dma(priv); - complete(priv->comp_dma); - } - writeb(STS0_DEVICE_INS, priv->sdmmc_base + SDMMC_STS0); - return IRQ_HANDLED; - } - - if ((!priv->req->data) || - ((priv->req->data->stop) && (priv->cmd == priv->req->data->stop))) { - /* handle non-data & stop_transmission requests */ - if (status1 & STS1_CMDRSP_DONE) { - priv->cmd->error = 0; - cmd_done = 1; - } else if ((status1 & STS1_RSP_TIMEOUT) || - (status1 & STS1_DATA_TIMEOUT)) { - priv->cmd->error = -ETIMEDOUT; - cmd_done = 1; - } - - if (cmd_done) { - priv->comp_cmd = NULL; - - if (!priv->cmd->error) - wmt_mci_read_response(priv->mmc); - - priv->cmd = NULL; - - mmc_request_done(priv->mmc, priv->req); - } - } else { - /* handle data requests */ - if (status1 & STS1_CMDRSP_DONE) { - if (priv->cmd) - priv->cmd->error = 0; - if (priv->comp_cmd) - complete(priv->comp_cmd); - } - - if ((status1 & STS1_RSP_TIMEOUT) || - (status1 & STS1_DATA_TIMEOUT)) { - if (priv->cmd) - priv->cmd->error = -ETIMEDOUT; - if (priv->comp_cmd) - complete(priv->comp_cmd); - if (priv->comp_dma) { - wmt_mci_disable_dma(priv); - complete(priv->comp_dma); - } - } - - if (priv->comp_dma) { - /* - * If the dma interrupt has already completed, finish - * off the request; otherwise we wait for the DMA - * interrupt and finish from there. - */ - if (completion_done(priv->comp_dma)) - wmt_complete_data_request(priv); - } - } - - writeb(status0, priv->sdmmc_base + SDMMC_STS0); - writeb(status1, priv->sdmmc_base + SDMMC_STS1); - writeb(status2, priv->sdmmc_base + SDMMC_STS2); - - return IRQ_HANDLED; -} - -static void wmt_reset_hardware(struct mmc_host *mmc) -{ - struct wmt_mci_priv *priv; - u32 reg_tmp; - - priv = mmc_priv(mmc); - - /* reset controller */ - reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE); - writeb(reg_tmp | BM_SOFT_RESET, priv->sdmmc_base + SDMMC_BUSMODE); - - /* reset response FIFO */ - reg_tmp = readb(priv->sdmmc_base + SDMMC_CTLR); - writeb(reg_tmp | CTLR_FIFO_RESET, priv->sdmmc_base + SDMMC_CTLR); - - /* enable GPI pin to detect card */ - writew(BLKL_INT_ENABLE | BLKL_GPI_CD, priv->sdmmc_base + SDMMC_BLKLEN); - - /* clear interrupt status */ - writeb(0xFF, priv->sdmmc_base + SDMMC_STS0); - writeb(0xFF, priv->sdmmc_base + SDMMC_STS1); - - /* setup interrupts */ - writeb(INT0_CD_INT_EN | INT0_DI_INT_EN, priv->sdmmc_base + - SDMMC_INTMASK0); - writeb(INT1_DATA_TOUT_INT_EN | INT1_CMD_RES_TRAN_DONE_INT_EN | - INT1_CMD_RES_TOUT_INT_EN, priv->sdmmc_base + SDMMC_INTMASK1); - - /* set the DMA timeout */ - writew(8191, priv->sdmmc_base + SDMMC_DMATIMEOUT); - - /* auto clock freezing enable */ - reg_tmp = readb(priv->sdmmc_base + SDMMC_STS2); - writeb(reg_tmp | STS2_DIS_FORCECLK, priv->sdmmc_base + SDMMC_STS2); - - /* set a default clock speed of 400Khz */ - clk_set_rate(priv->clk_sdmmc, 400000); -} - -static int wmt_dma_init(struct mmc_host *mmc) -{ - struct wmt_mci_priv *priv; - - priv = mmc_priv(mmc); - - writel(DMA_GCR_SOFT_RESET, priv->sdmmc_base + SDDMA_GCR); - writel(DMA_GCR_DMA_EN, priv->sdmmc_base + SDDMA_GCR); - if ((readl(priv->sdmmc_base + SDDMA_GCR) & DMA_GCR_DMA_EN) != 0) - return 0; - else - return 1; -} - -static void wmt_dma_init_descriptor(struct wmt_dma_descriptor *desc, - u16 req_count, u32 buffer_addr, u32 branch_addr, int end) -{ - desc->flags = 0x40000000 | req_count; - if (end) - desc->flags |= 0x80000000; - desc->data_buffer_addr = buffer_addr; - desc->branch_addr = branch_addr; -} - -static void wmt_dma_config(struct mmc_host *mmc, u32 descaddr, u8 dir) -{ - struct wmt_mci_priv *priv; - u32 reg_tmp; - - priv = mmc_priv(mmc); - - /* Enable DMA Interrupts */ - writel(DMA_IER_INT_EN, priv->sdmmc_base + SDDMA_IER); - - /* Write DMA Descriptor Pointer Register */ - writel(descaddr, priv->sdmmc_base + SDDMA_DESPR); - - writel(0x00, priv->sdmmc_base + SDDMA_CCR); - - if (dir == PDMA_WRITE) { - reg_tmp = readl(priv->sdmmc_base + SDDMA_CCR); - writel(reg_tmp & DMA_CCR_IF_TO_PERIPHERAL, priv->sdmmc_base + - SDDMA_CCR); - } else { - reg_tmp = readl(priv->sdmmc_base + SDDMA_CCR); - writel(reg_tmp | DMA_CCR_PERIPHERAL_TO_IF, priv->sdmmc_base + - SDDMA_CCR); - } -} - -static void wmt_dma_start(struct wmt_mci_priv *priv) -{ - u32 reg_tmp; - - reg_tmp = readl(priv->sdmmc_base + SDDMA_CCR); - writel(reg_tmp | DMA_CCR_RUN, priv->sdmmc_base + SDDMA_CCR); -} - -static void wmt_mci_request(struct mmc_host *mmc, struct mmc_request *req) -{ - struct wmt_mci_priv *priv; - struct wmt_dma_descriptor *desc; - u8 command; - u8 cmdtype; - u32 arg; - u8 rsptype; - u32 reg_tmp; - - struct scatterlist *sg; - int i; - int sg_cnt; - int offset; - u32 dma_address; - int desc_cnt; - - priv = mmc_priv(mmc); - priv->req = req; - - /* - * Use the cmd variable to pass a pointer to the resp[] structure - * This is required on multi-block requests to pass the pointer to the - * stop command - */ - priv->cmd = req->cmd; - - command = req->cmd->opcode; - arg = req->cmd->arg; - rsptype = mmc_resp_type(req->cmd); - cmdtype = 0; - - /* rsptype=7 only valid for SPI commands - should be =2 for SD */ - if (rsptype == 7) - rsptype = 2; - /* rsptype=21 is R1B, convert for controller */ - if (rsptype == 21) - rsptype = 9; - - if (!req->data) { - wmt_mci_send_command(mmc, command, cmdtype, arg, rsptype); - wmt_mci_start_command(priv); - /* completion is now handled in the regular_isr() */ - } - if (req->data) { - priv->comp_cmd = &priv->cmdcomp; - init_completion(priv->comp_cmd); - - wmt_dma_init(mmc); - - /* set controller data length */ - reg_tmp = readw(priv->sdmmc_base + SDMMC_BLKLEN); - writew((reg_tmp & 0xF800) | (req->data->blksz - 1), - priv->sdmmc_base + SDMMC_BLKLEN); - - /* set controller block count */ - writew(req->data->blocks, priv->sdmmc_base + SDMMC_BLKCNT); - - desc = (struct wmt_dma_descriptor *)priv->dma_desc_buffer; - - if (req->data->flags & MMC_DATA_WRITE) { - sg_cnt = dma_map_sg(mmc_dev(mmc), req->data->sg, - req->data->sg_len, DMA_TO_DEVICE); - cmdtype = 1; - if (req->data->blocks > 1) - cmdtype = 3; - } else { - sg_cnt = dma_map_sg(mmc_dev(mmc), req->data->sg, - req->data->sg_len, DMA_FROM_DEVICE); - cmdtype = 2; - if (req->data->blocks > 1) - cmdtype = 4; - } - - dma_address = priv->dma_desc_device_addr + 16; - desc_cnt = 0; - - for_each_sg(req->data->sg, sg, sg_cnt, i) { - offset = 0; - while (offset < sg_dma_len(sg)) { - wmt_dma_init_descriptor(desc, req->data->blksz, - sg_dma_address(sg)+offset, - dma_address, 0); - desc++; - desc_cnt++; - offset += req->data->blksz; - dma_address += 16; - if (desc_cnt == req->data->blocks) - break; - } - } - desc--; - desc->flags |= 0x80000000; - - if (req->data->flags & MMC_DATA_WRITE) - wmt_dma_config(mmc, priv->dma_desc_device_addr, - PDMA_WRITE); - else - wmt_dma_config(mmc, priv->dma_desc_device_addr, - PDMA_READ); - - wmt_mci_send_command(mmc, command, cmdtype, arg, rsptype); - - priv->comp_dma = &priv->datacomp; - init_completion(priv->comp_dma); - - wmt_dma_start(priv); - wmt_mci_start_command(priv); - } -} - -static void wmt_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -{ - struct wmt_mci_priv *priv; - u32 reg_tmp; - - priv = mmc_priv(mmc); - - if (ios->power_mode == MMC_POWER_UP) { - wmt_reset_hardware(mmc); - - wmt_set_sd_power(priv, WMT_SD_POWER_ON); - } - if (ios->power_mode == MMC_POWER_OFF) - wmt_set_sd_power(priv, WMT_SD_POWER_OFF); - - if (ios->clock != 0) - clk_set_rate(priv->clk_sdmmc, ios->clock); - - switch (ios->bus_width) { - case MMC_BUS_WIDTH_8: - reg_tmp = readb(priv->sdmmc_base + SDMMC_EXTCTRL); - writeb(reg_tmp | 0x04, priv->sdmmc_base + SDMMC_EXTCTRL); - break; - case MMC_BUS_WIDTH_4: - reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE); - writeb(reg_tmp | BM_FOURBIT_MODE, priv->sdmmc_base + - SDMMC_BUSMODE); - - reg_tmp = readb(priv->sdmmc_base + SDMMC_EXTCTRL); - writeb(reg_tmp & 0xFB, priv->sdmmc_base + SDMMC_EXTCTRL); - break; - case MMC_BUS_WIDTH_1: - reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE); - writeb(reg_tmp & BM_ONEBIT_MASK, priv->sdmmc_base + - SDMMC_BUSMODE); - - reg_tmp = readb(priv->sdmmc_base + SDMMC_EXTCTRL); - writeb(reg_tmp & 0xFB, priv->sdmmc_base + SDMMC_EXTCTRL); - break; - } -} - -static int wmt_mci_get_ro(struct mmc_host *mmc) -{ - struct wmt_mci_priv *priv = mmc_priv(mmc); - - return !(readb(priv->sdmmc_base + SDMMC_STS0) & STS0_WRITE_PROTECT); -} - -static int wmt_mci_get_cd(struct mmc_host *mmc) -{ - struct wmt_mci_priv *priv = mmc_priv(mmc); - u32 cd = (readb(priv->sdmmc_base + SDMMC_STS0) & STS0_CD_GPI) >> 3; - - return !(cd ^ priv->cd_inverted); -} - -static struct mmc_host_ops wmt_mci_ops = { - .request = wmt_mci_request, - .set_ios = wmt_mci_set_ios, - .get_ro = wmt_mci_get_ro, - .get_cd = wmt_mci_get_cd, -}; - -/* Controller capabilities */ -static struct wmt_mci_caps wm8505_caps = { - .f_min = 390425, - .f_max = 50000000, - .ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34, - .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | - MMC_CAP_SD_HIGHSPEED, - .max_seg_size = 65024, - .max_segs = 128, - .max_blk_size = 2048, -}; - -static struct of_device_id wmt_mci_dt_ids[] = { - { .compatible = "wm,wm8505-sdhc", .data = &wm8505_caps }, - { /* Sentinel */ }, -}; - -static int __devinit wmt_mci_probe(struct platform_device *pdev) -{ - struct mmc_host *mmc; - struct wmt_mci_priv *priv; - struct device_node *np = pdev->dev.of_node; - const struct of_device_id *of_id = - of_match_device(wmt_mci_dt_ids, &pdev->dev); - const struct wmt_mci_caps *wmt_caps = of_id->data; - int ret; - int regular_irq, dma_irq; - - if (!of_id || !of_id->data) { - dev_err(&pdev->dev, "Controller capabilities data missing\n"); - return -EFAULT; - } - - if (!np) { - dev_err(&pdev->dev, "Missing SDMMC description in devicetree\n"); - return -EFAULT; - } - - regular_irq = irq_of_parse_and_map(np, 0); - dma_irq = irq_of_parse_and_map(np, 1); - - if (!regular_irq || !dma_irq) { - dev_err(&pdev->dev, "Getting IRQs failed!\n"); - ret = -ENXIO; - goto fail1; - } - - mmc = mmc_alloc_host(sizeof(struct wmt_mci_priv), &pdev->dev); - if (!mmc) { - dev_err(&pdev->dev, "Failed to allocate mmc_host\n"); - ret = -ENOMEM; - goto fail1; - } - - mmc->ops = &wmt_mci_ops; - mmc->f_min = wmt_caps->f_min; - mmc->f_max = wmt_caps->f_max; - mmc->ocr_avail = wmt_caps->ocr_avail; - mmc->caps = wmt_caps->caps; - - mmc->max_seg_size = wmt_caps->max_seg_size; - mmc->max_segs = wmt_caps->max_segs; - mmc->max_blk_size = wmt_caps->max_blk_size; - - mmc->max_req_size = (16*512*mmc->max_segs); - mmc->max_blk_count = mmc->max_req_size / 512; - - priv = mmc_priv(mmc); - priv->mmc = mmc; - priv->dev = &pdev->dev; - - priv->power_inverted = 0; - priv->cd_inverted = 0; - - if (of_get_property(np, "sdon-inverted", NULL)) - priv->power_inverted = 1; - if (of_get_property(np, "cd-inverted", NULL)) - priv->cd_inverted = 1; - - priv->sdmmc_base = of_iomap(np, 0); - if (!priv->sdmmc_base) { - dev_err(&pdev->dev, "Failed to map IO space\n"); - ret = -ENOMEM; - goto fail2; - } - - priv->irq_regular = regular_irq; - priv->irq_dma = dma_irq; - - ret = request_irq(regular_irq, wmt_mci_regular_isr, 0, "sdmmc", priv); - if (ret) { - dev_err(&pdev->dev, "Register regular IRQ fail\n"); - goto fail3; - } - - ret = request_irq(dma_irq, wmt_mci_dma_isr, 32, "sdmmc", priv); - if (ret) { - dev_err(&pdev->dev, "Register DMA IRQ fail\n"); - goto fail4; - } - - /* alloc some DMA buffers for descriptors/transfers */ - priv->dma_desc_buffer = dma_alloc_coherent(&pdev->dev, - mmc->max_blk_count * 16, - &priv->dma_desc_device_addr, - 208); - if (!priv->dma_desc_buffer) { - dev_err(&pdev->dev, "DMA alloc fail\n"); - ret = -EPERM; - goto fail5; - } - - platform_set_drvdata(pdev, mmc); - - priv->clk_sdmmc = of_clk_get(np, 0); - if (IS_ERR(priv->clk_sdmmc)) { - dev_err(&pdev->dev, "Error getting clock\n"); - ret = PTR_ERR(priv->clk_sdmmc); - goto fail5; - } - - clk_prepare_enable(priv->clk_sdmmc); - - /* configure the controller to a known 'ready' state */ - wmt_reset_hardware(mmc); - - mmc_add_host(mmc); - - dev_info(&pdev->dev, "WMT SDHC Controller initialized\n"); - - return 0; -fail5: - free_irq(dma_irq, priv); -fail4: - free_irq(regular_irq, priv); -fail3: - iounmap(priv->sdmmc_base); -fail2: - mmc_free_host(mmc); -fail1: - return ret; -} - -static int __devexit wmt_mci_remove(struct platform_device *pdev) -{ - struct mmc_host *mmc; - struct wmt_mci_priv *priv; - struct resource *res; - u32 reg_tmp; - - mmc = platform_get_drvdata(pdev); - priv = mmc_priv(mmc); - - /* reset SD controller */ - reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE); - writel(reg_tmp | BM_SOFT_RESET, priv->sdmmc_base + SDMMC_BUSMODE); - reg_tmp = readw(priv->sdmmc_base + SDMMC_BLKLEN); - writew(reg_tmp & ~(0xA000), priv->sdmmc_base + SDMMC_BLKLEN); - writeb(0xFF, priv->sdmmc_base + SDMMC_STS0); - writeb(0xFF, priv->sdmmc_base + SDMMC_STS1); - - /* release the dma buffers */ - dma_free_coherent(&pdev->dev, priv->mmc->max_blk_count * 16, - priv->dma_desc_buffer, priv->dma_desc_device_addr); - - mmc_remove_host(mmc); - - free_irq(priv->irq_regular, priv); - free_irq(priv->irq_dma, priv); - - iounmap(priv->sdmmc_base); - - clk_disable_unprepare(priv->clk_sdmmc); - clk_put(priv->clk_sdmmc); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, res->end - res->start + 1); - - mmc_free_host(mmc); - - platform_set_drvdata(pdev, NULL); - - dev_info(&pdev->dev, "WMT MCI device removed\n"); - - return 0; -} - -#ifdef CONFIG_PM -static int wmt_mci_suspend(struct device *dev) -{ - u32 reg_tmp; - struct platform_device *pdev = to_platform_device(dev); - struct mmc_host *mmc = platform_get_drvdata(pdev); - struct wmt_mci_priv *priv; - int ret; - - if (!mmc) - return 0; - - priv = mmc_priv(mmc); - ret = mmc_suspend_host(mmc); - - if (!ret) { - reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE); - writeb(reg_tmp | BM_SOFT_RESET, priv->sdmmc_base + - SDMMC_BUSMODE); - - reg_tmp = readw(priv->sdmmc_base + SDMMC_BLKLEN); - writew(reg_tmp & 0x5FFF, priv->sdmmc_base + SDMMC_BLKLEN); - - writeb(0xFF, priv->sdmmc_base + SDMMC_STS0); - writeb(0xFF, priv->sdmmc_base + SDMMC_STS1); - - clk_disable(priv->clk_sdmmc); - } - return ret; -} - -static int wmt_mci_resume(struct device *dev) -{ - u32 reg_tmp; - struct platform_device *pdev = to_platform_device(dev); - struct mmc_host *mmc = platform_get_drvdata(pdev); - struct wmt_mci_priv *priv; - int ret = 0; - - if (mmc) { - priv = mmc_priv(mmc); - clk_enable(priv->clk_sdmmc); - - reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE); - writeb(reg_tmp | BM_SOFT_RESET, priv->sdmmc_base + - SDMMC_BUSMODE); - - reg_tmp = readw(priv->sdmmc_base + SDMMC_BLKLEN); - writew(reg_tmp | (BLKL_GPI_CD | BLKL_INT_ENABLE), - priv->sdmmc_base + SDMMC_BLKLEN); - - reg_tmp = readb(priv->sdmmc_base + SDMMC_INTMASK0); - writeb(reg_tmp | INT0_DI_INT_EN, priv->sdmmc_base + - SDMMC_INTMASK0); - - ret = mmc_resume_host(mmc); - } - - return ret; -} - -static const struct dev_pm_ops wmt_mci_pm = { - .suspend = wmt_mci_suspend, - .resume = wmt_mci_resume, -}; - -#define wmt_mci_pm_ops (&wmt_mci_pm) - -#else /* !CONFIG_PM */ - -#define wmt_mci_pm_ops NULL - -#endif - -static struct platform_driver wmt_mci_driver = { - .probe = wmt_mci_probe, - .remove = __exit_p(wmt_mci_remove), - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - .pm = wmt_mci_pm_ops, - .of_match_table = wmt_mci_dt_ids, - }, -}; - -module_platform_driver(wmt_mci_driver); - -MODULE_DESCRIPTION("Wondermedia MMC/SD Driver"); -MODULE_AUTHOR("Tony Prisk"); -MODULE_LICENSE("GPL v2"); -MODULE_DEVICE_TABLE(of, wmt_mci_dt_ids); diff --git a/trunk/drivers/mtd/devices/slram.c b/trunk/drivers/mtd/devices/slram.c index 5a5cd2ace4a6..8f52fc858e48 100644 --- a/trunk/drivers/mtd/devices/slram.c +++ b/trunk/drivers/mtd/devices/slram.c @@ -240,7 +240,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength) if (*(szlength) != '+') { devlength = simple_strtoul(szlength, &buffer, 0); - devlength = handle_unit(devlength, buffer); + devlength = handle_unit(devlength, buffer) - devstart; if (devlength < devstart) goto err_out; diff --git a/trunk/drivers/mtd/mtdcore.c b/trunk/drivers/mtd/mtdcore.c index ec794a72975d..374c46dff7dd 100644 --- a/trunk/drivers/mtd/mtdcore.c +++ b/trunk/drivers/mtd/mtdcore.c @@ -1077,8 +1077,7 @@ EXPORT_SYMBOL_GPL(mtd_writev); * until the request succeeds or until the allocation size falls below * the system page size. This attempts to make sure it does not adversely * impact system performance, so when allocating more than one page, we - * ask the memory allocator to avoid re-trying, swapping, writing back - * or performing I/O. + * ask the memory allocator to avoid re-trying. * * Note, this function also makes sure that the allocated buffer is aligned to * the MTD device's min. I/O unit, i.e. the "mtd->writesize" value. @@ -1092,8 +1091,7 @@ EXPORT_SYMBOL_GPL(mtd_writev); */ void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size) { - gfp_t flags = __GFP_NOWARN | __GFP_WAIT | - __GFP_NORETRY | __GFP_NO_KSWAPD; + gfp_t flags = __GFP_NOWARN | __GFP_WAIT | __GFP_NORETRY; size_t min_alloc = max_t(size_t, mtd->writesize, PAGE_SIZE); void *kbuf; diff --git a/trunk/drivers/mtd/nand/atmel_nand.c b/trunk/drivers/mtd/nand/atmel_nand.c index 92623ac2015a..914455783302 100644 --- a/trunk/drivers/mtd/nand/atmel_nand.c +++ b/trunk/drivers/mtd/nand/atmel_nand.c @@ -41,7 +41,6 @@ #include #include #include -#include #include @@ -1371,7 +1370,6 @@ static int __init atmel_nand_probe(struct platform_device *pdev) struct resource *mem; struct mtd_part_parser_data ppdata = {}; int res; - struct pinctrl *pinctrl; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { @@ -1416,13 +1414,6 @@ static int __init atmel_nand_probe(struct platform_device *pdev) nand_chip->IO_ADDR_W = host->io_base; nand_chip->cmd_ctrl = atmel_nand_cmd_ctrl; - pinctrl = devm_pinctrl_get_select_default(&pdev->dev); - if (IS_ERR(pinctrl)) { - dev_err(host->dev, "Failed to request pinctrl\n"); - res = PTR_ERR(pinctrl); - goto err_ecc_ioremap; - } - if (gpio_is_valid(host->board.rdy_pin)) { res = gpio_request(host->board.rdy_pin, "nand_rdy"); if (res < 0) { diff --git a/trunk/drivers/mtd/nand/nand_base.c b/trunk/drivers/mtd/nand/nand_base.c index 1a03b7f673ce..ec6841d8e956 100644 --- a/trunk/drivers/mtd/nand/nand_base.c +++ b/trunk/drivers/mtd/nand/nand_base.c @@ -2983,15 +2983,13 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, /* * Field definitions are in the following datasheets: * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32) - * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44) + * New style (6 byte ID): Samsung K9GAG08U0F (p.44) * Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22) * - * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung - * ID to decide what to do. + * Check for ID length, cell type, and Hynix/Samsung ID to decide what + * to do. */ - if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG && - (chip->cellinfo & NAND_CI_CELLTYPE_MSK) && - id_data[5] != 0x00) { + if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) { /* Calc pagesize */ mtd->writesize = 2048 << (extid & 0x03); extid >>= 2; diff --git a/trunk/drivers/mtd/ofpart.c b/trunk/drivers/mtd/ofpart.c index d9127e2ed808..64be8f0848b0 100644 --- a/trunk/drivers/mtd/ofpart.c +++ b/trunk/drivers/mtd/ofpart.c @@ -121,7 +121,7 @@ static int parse_ofoldpart_partitions(struct mtd_info *master, nr_parts = plen / sizeof(part[0]); *pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL); - if (!*pparts) + if (!pparts) return -ENOMEM; names = of_get_property(dp, "partition-names", &plen); diff --git a/trunk/drivers/mtd/onenand/onenand_base.c b/trunk/drivers/mtd/onenand/onenand_base.c index b3f41f200622..7153e0d27101 100644 --- a/trunk/drivers/mtd/onenand/onenand_base.c +++ b/trunk/drivers/mtd/onenand/onenand_base.c @@ -3694,7 +3694,7 @@ static int flexonenand_check_blocks_erased(struct mtd_info *mtd, int start, int * flexonenand_set_boundary - Writes the SLC boundary * @param mtd - mtd info structure */ -static int flexonenand_set_boundary(struct mtd_info *mtd, int die, +int flexonenand_set_boundary(struct mtd_info *mtd, int die, int boundary, int lock) { struct onenand_chip *this = mtd->priv; diff --git a/trunk/drivers/mtd/ubi/wl.c b/trunk/drivers/mtd/ubi/wl.c index 2144f611196e..da7b44998b40 100644 --- a/trunk/drivers/mtd/ubi/wl.c +++ b/trunk/drivers/mtd/ubi/wl.c @@ -498,7 +498,7 @@ struct ubi_wl_entry *ubi_wl_get_fm_peb(struct ubi_device *ubi, int anchor) * @ubi: UBI device description object * * This function returns a physical eraseblock in case of success and a - * negative error code in case of failure. + * negative error code in case of failure. Might sleep. */ static int __wl_get_peb(struct ubi_device *ubi) { @@ -540,6 +540,13 @@ static int __wl_get_peb(struct ubi_device *ubi) * ubi_wl_get_peb() after removing e from the pool. */ prot_queue_add(ubi, e); #endif + err = ubi_self_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset, + ubi->peb_size - ubi->vid_hdr_aloffset); + if (err) { + ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum); + return err; + } + return e->pnum; } @@ -672,30 +679,17 @@ static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) #else static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) { - struct ubi_wl_entry *e; - - e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); - self_check_in_wl_tree(ubi, e, &ubi->free); - rb_erase(&e->u.rb, &ubi->free); - - return e; + return find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); } int ubi_wl_get_peb(struct ubi_device *ubi) { - int peb, err; + int peb; spin_lock(&ubi->wl_lock); peb = __wl_get_peb(ubi); spin_unlock(&ubi->wl_lock); - err = ubi_self_check_all_ff(ubi, peb, ubi->vid_hdr_aloffset, - ubi->peb_size - ubi->vid_hdr_aloffset); - if (err) { - ubi_err("new PEB %d does not contain all 0xFF bytes", peb); - return err; - } - return peb; } #endif diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index a7d47350ea4b..b2530b002125 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -1379,8 +1379,6 @@ static void bond_compute_features(struct bonding *bond) struct net_device *bond_dev = bond->dev; netdev_features_t vlan_features = BOND_VLAN_FEATURES; unsigned short max_hard_header_len = ETH_HLEN; - unsigned int gso_max_size = GSO_MAX_SIZE; - u16 gso_max_segs = GSO_MAX_SEGS; int i; unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE; @@ -1396,16 +1394,11 @@ static void bond_compute_features(struct bonding *bond) dst_release_flag &= slave->dev->priv_flags; if (slave->dev->hard_header_len > max_hard_header_len) max_hard_header_len = slave->dev->hard_header_len; - - gso_max_size = min(gso_max_size, slave->dev->gso_max_size); - gso_max_segs = min(gso_max_segs, slave->dev->gso_max_segs); } done: bond_dev->vlan_features = vlan_features; bond_dev->hard_header_len = max_hard_header_len; - bond_dev->gso_max_segs = gso_max_segs; - netif_set_gso_max_size(bond_dev, gso_max_size); flags = bond_dev->priv_flags & ~IFF_XMIT_DST_RELEASE; bond_dev->priv_flags = flags | dst_release_flag; @@ -3459,28 +3452,6 @@ static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count) /*-------------------------- Device entry points ----------------------------*/ -static void bond_work_init_all(struct bonding *bond) -{ - INIT_DELAYED_WORK(&bond->mcast_work, - bond_resend_igmp_join_requests_delayed); - INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor); - INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor); - if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) - INIT_DELAYED_WORK(&bond->arp_work, bond_activebackup_arp_mon); - else - INIT_DELAYED_WORK(&bond->arp_work, bond_loadbalance_arp_mon); - INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler); -} - -static void bond_work_cancel_all(struct bonding *bond) -{ - cancel_delayed_work_sync(&bond->mii_work); - cancel_delayed_work_sync(&bond->arp_work); - cancel_delayed_work_sync(&bond->alb_work); - cancel_delayed_work_sync(&bond->ad_work); - cancel_delayed_work_sync(&bond->mcast_work); -} - static int bond_open(struct net_device *bond_dev) { struct bonding *bond = netdev_priv(bond_dev); @@ -3503,27 +3474,41 @@ static int bond_open(struct net_device *bond_dev) } read_unlock(&bond->lock); - bond_work_init_all(bond); + INIT_DELAYED_WORK(&bond->mcast_work, bond_resend_igmp_join_requests_delayed); if (bond_is_lb(bond)) { /* bond_alb_initialize must be called before the timer * is started. */ - if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) + if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) { + /* something went wrong - fail the open operation */ return -ENOMEM; + } + + INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor); queue_delayed_work(bond->wq, &bond->alb_work, 0); } - if (bond->params.miimon) /* link check interval, in milliseconds. */ + if (bond->params.miimon) { /* link check interval, in milliseconds. */ + INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor); queue_delayed_work(bond->wq, &bond->mii_work, 0); + } if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ + if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) + INIT_DELAYED_WORK(&bond->arp_work, + bond_activebackup_arp_mon); + else + INIT_DELAYED_WORK(&bond->arp_work, + bond_loadbalance_arp_mon); + queue_delayed_work(bond->wq, &bond->arp_work, 0); if (bond->params.arp_validate) bond->recv_probe = bond_arp_rcv; } if (bond->params.mode == BOND_MODE_8023AD) { + INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler); queue_delayed_work(bond->wq, &bond->ad_work, 0); /* register to receive LACPDUs */ bond->recv_probe = bond_3ad_lacpdu_recv; @@ -3538,10 +3523,34 @@ static int bond_close(struct net_device *bond_dev) struct bonding *bond = netdev_priv(bond_dev); write_lock_bh(&bond->lock); + bond->send_peer_notif = 0; + write_unlock_bh(&bond->lock); - bond_work_cancel_all(bond); + if (bond->params.miimon) { /* link check interval, in milliseconds. */ + cancel_delayed_work_sync(&bond->mii_work); + } + + if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ + cancel_delayed_work_sync(&bond->arp_work); + } + + switch (bond->params.mode) { + case BOND_MODE_8023AD: + cancel_delayed_work_sync(&bond->ad_work); + break; + case BOND_MODE_TLB: + case BOND_MODE_ALB: + cancel_delayed_work_sync(&bond->alb_work); + break; + default: + break; + } + + if (delayed_work_pending(&bond->mcast_work)) + cancel_delayed_work_sync(&bond->mcast_work); + if (bond_is_lb(bond)) { /* Must be called only after all * slaves have been released @@ -4420,6 +4429,26 @@ static void bond_setup(struct net_device *bond_dev) bond_dev->features |= bond_dev->hw_features; } +static void bond_work_cancel_all(struct bonding *bond) +{ + if (bond->params.miimon && delayed_work_pending(&bond->mii_work)) + cancel_delayed_work_sync(&bond->mii_work); + + if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work)) + cancel_delayed_work_sync(&bond->arp_work); + + if (bond->params.mode == BOND_MODE_ALB && + delayed_work_pending(&bond->alb_work)) + cancel_delayed_work_sync(&bond->alb_work); + + if (bond->params.mode == BOND_MODE_8023AD && + delayed_work_pending(&bond->ad_work)) + cancel_delayed_work_sync(&bond->ad_work); + + if (delayed_work_pending(&bond->mcast_work)) + cancel_delayed_work_sync(&bond->mcast_work); +} + /* * Destroy a bonding device. * Must be under rtnl_lock when this function is called. @@ -4670,13 +4699,12 @@ static int bond_check_params(struct bond_params *params) arp_ip_count++) { /* not complete check, but should be good enough to catch mistakes */ - __be32 ip = in_aton(arp_ip_target[arp_ip_count]); - if (!isdigit(arp_ip_target[arp_ip_count][0]) || - ip == 0 || ip == htonl(INADDR_BROADCAST)) { + if (!isdigit(arp_ip_target[arp_ip_count][0])) { pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n", arp_ip_target[arp_ip_count]); arp_interval = 0; } else { + __be32 ip = in_aton(arp_ip_target[arp_ip_count]); arp_target[arp_ip_count] = ip; } } diff --git a/trunk/drivers/net/bonding/bond_sysfs.c b/trunk/drivers/net/bonding/bond_sysfs.c index 1877ed7ca086..dc15d248443f 100644 --- a/trunk/drivers/net/bonding/bond_sysfs.c +++ b/trunk/drivers/net/bonding/bond_sysfs.c @@ -513,8 +513,6 @@ static ssize_t bonding_store_arp_interval(struct device *d, int new_value, ret = count; struct bonding *bond = to_bond(d); - if (!rtnl_trylock()) - return restart_syscall(); if (sscanf(buf, "%d", &new_value) != 1) { pr_err("%s: no arp_interval value specified.\n", bond->dev->name); @@ -541,6 +539,10 @@ static ssize_t bonding_store_arp_interval(struct device *d, pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", bond->dev->name, bond->dev->name); bond->params.miimon = 0; + if (delayed_work_pending(&bond->mii_work)) { + cancel_delayed_work(&bond->mii_work); + flush_workqueue(bond->wq); + } } if (!bond->params.arp_targets[0]) { pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", @@ -552,12 +554,19 @@ static ssize_t bonding_store_arp_interval(struct device *d, * timer will get fired off when the open function * is called. */ - cancel_delayed_work_sync(&bond->mii_work); - queue_delayed_work(bond->wq, &bond->arp_work, 0); + if (!delayed_work_pending(&bond->arp_work)) { + if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) + INIT_DELAYED_WORK(&bond->arp_work, + bond_activebackup_arp_mon); + else + INIT_DELAYED_WORK(&bond->arp_work, + bond_loadbalance_arp_mon); + + queue_delayed_work(bond->wq, &bond->arp_work, 0); + } } out: - rtnl_unlock(); return ret; } static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR, @@ -953,8 +962,6 @@ static ssize_t bonding_store_miimon(struct device *d, int new_value, ret = count; struct bonding *bond = to_bond(d); - if (!rtnl_trylock()) - return restart_syscall(); if (sscanf(buf, "%d", &new_value) != 1) { pr_err("%s: no miimon value specified.\n", bond->dev->name); @@ -986,6 +993,10 @@ static ssize_t bonding_store_miimon(struct device *d, bond->params.arp_validate = BOND_ARP_VALIDATE_NONE; } + if (delayed_work_pending(&bond->arp_work)) { + cancel_delayed_work(&bond->arp_work); + flush_workqueue(bond->wq); + } } if (bond->dev->flags & IFF_UP) { @@ -994,12 +1005,15 @@ static ssize_t bonding_store_miimon(struct device *d, * timer will get fired off when the open function * is called. */ - cancel_delayed_work_sync(&bond->arp_work); - queue_delayed_work(bond->wq, &bond->mii_work, 0); + if (!delayed_work_pending(&bond->mii_work)) { + INIT_DELAYED_WORK(&bond->mii_work, + bond_mii_monitor); + queue_delayed_work(bond->wq, + &bond->mii_work, 0); + } } } out: - rtnl_unlock(); return ret; } static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, @@ -1046,7 +1060,7 @@ static ssize_t bonding_store_primary(struct device *d, goto out; } - sscanf(buf, "%15s", ifname); /* IFNAMSIZ */ + sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ /* check to see if we are clearing primary */ if (!strlen(ifname) || buf[0] == '\n') { @@ -1223,7 +1237,7 @@ static ssize_t bonding_store_active_slave(struct device *d, goto out; } - sscanf(buf, "%15s", ifname); /* IFNAMSIZ */ + sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ /* check to see if we are clearing active */ if (!strlen(ifname) || buf[0] == '\n') { @@ -1568,7 +1582,6 @@ static ssize_t bonding_store_slaves_active(struct device *d, goto out; } - read_lock(&bond->lock); bond_for_each_slave(bond, slave, i) { if (!bond_is_active_slave(slave)) { if (new_value) @@ -1577,7 +1590,6 @@ static ssize_t bonding_store_slaves_active(struct device *d, slave->inactive = 1; } } - read_unlock(&bond->lock); out: return ret; } diff --git a/trunk/drivers/net/can/flexcan.c b/trunk/drivers/net/can/flexcan.c index a412bf6d73ef..c78ecfca1e45 100644 --- a/trunk/drivers/net/can/flexcan.c +++ b/trunk/drivers/net/can/flexcan.c @@ -144,22 +144,9 @@ #define FLEXCAN_MB_CODE_MASK (0xf0ffffff) -/* - * FLEXCAN hardware feature flags - * - * Below is some version info we got: - * SOC Version IP-Version Glitch- [TR]WRN_INT - * Filter? connected? - * MX25 FlexCAN2 03.00.00.00 no no - * MX28 FlexCAN2 03.00.04.00 yes yes - * MX35 FlexCAN2 03.00.00.00 no no - * MX53 FlexCAN2 03.00.00.00 yes no - * MX6s FlexCAN3 10.00.12.00 yes yes - * - * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. - */ +/* FLEXCAN hardware feature flags */ #define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */ -#define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */ +#define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* Broken error state handling */ /* Structure of the message buffer */ struct flexcan_mb { @@ -218,7 +205,7 @@ static struct flexcan_devtype_data fsl_p1010_devtype_data = { }; static struct flexcan_devtype_data fsl_imx28_devtype_data; static struct flexcan_devtype_data fsl_imx6q_devtype_data = { - .features = FLEXCAN_HAS_V10_FEATURES, + .features = FLEXCAN_HAS_V10_FEATURES | FLEXCAN_HAS_BROKEN_ERR_STATE, }; static const struct can_bittiming_const flexcan_bittiming_const = { diff --git a/trunk/drivers/net/can/sja1000/peak_pci.c b/trunk/drivers/net/can/sja1000/peak_pci.c index 6525dbcca4e3..f5b82aeb2540 100644 --- a/trunk/drivers/net/can/sja1000/peak_pci.c +++ b/trunk/drivers/net/can/sja1000/peak_pci.c @@ -30,10 +30,9 @@ #include "sja1000.h" -MODULE_AUTHOR("Stephane Grosjean "); +MODULE_AUTHOR("Wolfgang Grandegger "); MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCI family cards"); MODULE_SUPPORTED_DEVICE("PEAK PCAN PCI/PCIe/PCIeC miniPCI CAN cards"); -MODULE_SUPPORTED_DEVICE("PEAK PCAN miniPCIe/cPCI PC/104+ PCI/104e CAN Cards"); MODULE_LICENSE("GPL v2"); #define DRV_NAME "peak_pci" @@ -65,11 +64,7 @@ struct peak_pci_chan { #define PEAK_PCI_DEVICE_ID 0x0001 /* for PCI/PCIe slot cards */ #define PEAK_PCIEC_DEVICE_ID 0x0002 /* for ExpressCard slot cards */ #define PEAK_PCIE_DEVICE_ID 0x0003 /* for nextgen PCIe slot cards */ -#define PEAK_CPCI_DEVICE_ID 0x0004 /* for nextgen cPCI slot cards */ -#define PEAK_MPCI_DEVICE_ID 0x0005 /* for nextgen miniPCI slot cards */ -#define PEAK_PC_104P_DEVICE_ID 0x0006 /* PCAN-PC/104+ cards */ -#define PEAK_PCI_104E_DEVICE_ID 0x0007 /* PCAN-PCI/104 Express cards */ -#define PEAK_MPCIE_DEVICE_ID 0x0008 /* The miniPCIe slot cards */ +#define PEAK_MPCI_DEVICE_ID 0x0008 /* The miniPCI slot cards */ #define PEAK_PCI_CHAN_MAX 4 @@ -81,10 +76,6 @@ static DEFINE_PCI_DEVICE_TABLE(peak_pci_tbl) = { {PEAK_PCI_VENDOR_ID, PEAK_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, {PEAK_PCI_VENDOR_ID, PEAK_PCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, {PEAK_PCI_VENDOR_ID, PEAK_MPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, - {PEAK_PCI_VENDOR_ID, PEAK_MPCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, - {PEAK_PCI_VENDOR_ID, PEAK_PC_104P_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, - {PEAK_PCI_VENDOR_ID, PEAK_PCI_104E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, - {PEAK_PCI_VENDOR_ID, PEAK_CPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, #ifdef CONFIG_CAN_PEAK_PCIEC {PEAK_PCI_VENDOR_ID, PEAK_PCIEC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, #endif diff --git a/trunk/drivers/net/can/usb/peak_usb/pcan_usb.c b/trunk/drivers/net/can/usb/peak_usb/pcan_usb.c index 25723d8ee201..86f26a1ede4c 100644 --- a/trunk/drivers/net/can/usb/peak_usb/pcan_usb.c +++ b/trunk/drivers/net/can/usb/peak_usb/pcan_usb.c @@ -519,10 +519,8 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n, mc->pdev->dev.can.state = new_state; if (status_len & PCAN_USB_STATUSLEN_TIMESTAMP) { - struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb); - peak_usb_get_ts_tv(&mc->pdev->time_ref, mc->ts16, &tv); - hwts->hwtstamp = timeval_to_ktime(tv); + skb->tstamp = timeval_to_ktime(tv); } netif_rx(skb); @@ -607,7 +605,6 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len) struct sk_buff *skb; struct can_frame *cf; struct timeval tv; - struct skb_shared_hwtstamps *hwts; skb = alloc_can_skb(mc->netdev, &cf); if (!skb) @@ -655,8 +652,7 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len) /* convert timestamp into kernel time */ peak_usb_get_ts_tv(&mc->pdev->time_ref, mc->ts16, &tv); - hwts = skb_hwtstamps(skb); - hwts->hwtstamp = timeval_to_ktime(tv); + skb->tstamp = timeval_to_ktime(tv); /* push the skb */ netif_rx(skb); diff --git a/trunk/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/trunk/drivers/net/can/usb/peak_usb/pcan_usb_pro.c index 30d79bfa5b10..e1626d92511a 100644 --- a/trunk/drivers/net/can/usb/peak_usb/pcan_usb_pro.c +++ b/trunk/drivers/net/can/usb/peak_usb/pcan_usb_pro.c @@ -532,7 +532,6 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if, struct can_frame *can_frame; struct sk_buff *skb; struct timeval tv; - struct skb_shared_hwtstamps *hwts; skb = alloc_can_skb(netdev, &can_frame); if (!skb) @@ -550,8 +549,7 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if, memcpy(can_frame->data, rx->data, can_frame->can_dlc); peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(rx->ts32), &tv); - hwts = skb_hwtstamps(skb); - hwts->hwtstamp = timeval_to_ktime(tv); + skb->tstamp = timeval_to_ktime(tv); netif_rx(skb); netdev->stats.rx_packets++; @@ -572,7 +570,6 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if, u8 err_mask = 0; struct sk_buff *skb; struct timeval tv; - struct skb_shared_hwtstamps *hwts; /* nothing should be sent while in BUS_OFF state */ if (dev->can.state == CAN_STATE_BUS_OFF) @@ -667,8 +664,7 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if, dev->can.state = new_state; peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(er->ts32), &tv); - hwts = skb_hwtstamps(skb); - hwts->hwtstamp = timeval_to_ktime(tv); + skb->tstamp = timeval_to_ktime(tv); netif_rx(skb); netdev->stats.rx_packets++; netdev->stats.rx_bytes += can_frame->can_dlc; diff --git a/trunk/drivers/net/ethernet/8390/ne.c b/trunk/drivers/net/ethernet/8390/ne.c index 47618e505355..d04911d33b64 100644 --- a/trunk/drivers/net/ethernet/8390/ne.c +++ b/trunk/drivers/net/ethernet/8390/ne.c @@ -813,7 +813,6 @@ static int __init ne_drv_probe(struct platform_device *pdev) dev->irq = irq[this_dev]; dev->mem_end = bad[this_dev]; } - SET_NETDEV_DEV(dev, &pdev->dev); err = do_ne_probe(dev); if (err) { free_netdev(dev); diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 6e5bdd1a31d9..c65295dded39 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -1702,7 +1702,7 @@ static int bnx2x_set_eee(struct net_device *dev, struct ethtool_eee *edata) SHMEM_EEE_ADV_STATUS_SHIFT); if ((advertised != (eee_cfg & SHMEM_EEE_ADV_STATUS_MASK))) { DP(BNX2X_MSG_ETHTOOL, - "Direct manipulation of EEE advertisement is not supported\n"); + "Direct manipulation of EEE advertisment is not supported\n"); return -EINVAL; } diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index f6cfdc6cf20f..e2e45ee5df33 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -137,16 +137,7 @@ #define LINK_20GTFD LINK_STATUS_SPEED_AND_DUPLEX_20GTFD #define LINK_20GXFD LINK_STATUS_SPEED_AND_DUPLEX_20GXFD -#define LINK_UPDATE_MASK \ - (LINK_STATUS_SPEED_AND_DUPLEX_MASK | \ - LINK_STATUS_LINK_UP | \ - LINK_STATUS_PHYSICAL_LINK_FLAG | \ - LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | \ - LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | \ - LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | \ - LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | \ - LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | \ - LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE) + #define SFP_EEPROM_CON_TYPE_ADDR 0x2 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 @@ -3304,21 +3295,6 @@ static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port) DEFAULT_PHY_DEV_ADDR); } -static void bnx2x_xgxs_specific_func(struct bnx2x_phy *phy, - struct link_params *params, - u32 action) -{ - struct bnx2x *bp = params->bp; - switch (action) { - case PHY_INIT: - /* Set correct devad */ - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + params->port*0x18, 0); - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18, - phy->def_md_devad); - break; - } -} - static void bnx2x_xgxs_deassert(struct link_params *params) { struct bnx2x *bp = params->bp; @@ -3333,8 +3309,10 @@ static void bnx2x_xgxs_deassert(struct link_params *params) REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); udelay(500); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); - bnx2x_xgxs_specific_func(¶ms->phy[INT_PHY], params, - PHY_INIT); + + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + port*0x18, 0); + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, + params->phy[INT_PHY].def_md_devad); } static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy, @@ -3567,11 +3545,14 @@ static void bnx2x_warpcore_set_lpi_passthrough(struct bnx2x_phy *phy, static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) { - u16 lane, i, cl72_ctrl, an_adv = 0; - u16 ucode_ver; + u16 val16 = 0, lane, i; struct bnx2x *bp = params->bp; static struct bnx2x_reg_set reg_set[] = { {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7}, + {MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 0}, + {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0}, + {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0xff}, + {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0x5555}, {MDIO_PMA_DEVAD, MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0}, {MDIO_WC_DEVAD, MDIO_WC_REG_RX66_CONTROL, 0x7415}, {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190}, @@ -3584,19 +3565,12 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, reg_set[i].val); - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &cl72_ctrl); - cl72_ctrl &= 0xf8ff; - cl72_ctrl |= 0x3800; - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, cl72_ctrl); - /* Check adding advertisement for 1G KX */ if (((vars->line_speed == SPEED_AUTO_NEG) && (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || (vars->line_speed == SPEED_1000)) { u32 addr = MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2; - an_adv |= (1<<5); + val16 |= (1<<5); /* Enable CL37 1G Parallel Detect */ bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, addr, 0x1); @@ -3606,14 +3580,11 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) || (vars->line_speed == SPEED_10000)) { /* Check adding advertisement for 10G KR */ - an_adv |= (1<<7); + val16 |= (1<<7); /* Enable 10G Parallel Detect */ - CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, - MDIO_AER_BLOCK_AER_REG, 0); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 1); - bnx2x_set_aer_mmd(params, phy); + DP(NETIF_MSG_LINK, "Advertize 10G\n"); } @@ -3633,7 +3604,7 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, /* Advertised speeds */ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, an_adv); + MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16); /* Advertised and set FEC (Forward Error Correction) */ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, @@ -3657,10 +3628,9 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, /* Set KR Autoneg Work-Around flag for Warpcore version older than D108 */ bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_UC_INFO_B1_VERSION, &ucode_ver); - if (ucode_ver < 0xd108) { - DP(NETIF_MSG_LINK, "Enable AN KR work-around. WC ver:0x%x\n", - ucode_ver); + MDIO_WC_REG_UC_INFO_B1_VERSION, &val16); + if (val16 < 0xd108) { + DP(NETIF_MSG_LINK, "Enable AN KR work-around\n"); vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY; } bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, @@ -3681,16 +3651,21 @@ static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u16 val16, i, lane; + u16 i; static struct bnx2x_reg_set reg_set[] = { /* Disable Autoneg */ {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7}, + {MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 0}, {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0x3f00}, {MDIO_AN_DEVAD, MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0}, {MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0}, {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL3_UP1, 0x1}, {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, 0xa}, + /* Disable CL36 PCS Tx */ + {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0}, + /* Double Wide Single Data Rate @ pll rate */ + {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF}, /* Leave cl72 training enable, needed for KR */ {MDIO_PMA_DEVAD, MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150, @@ -3701,24 +3676,11 @@ static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, reg_set[i].val); - lane = bnx2x_get_warpcore_lane(phy, params); - /* Global registers */ - CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, - MDIO_AER_BLOCK_AER_REG, 0); - /* Disable CL36 PCS Tx */ - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16); - val16 &= ~(0x0011 << lane); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16); + /* Leave CL72 enabled */ + bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, + 0x3800); - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16); - val16 |= (0x0303 << (lane << 1)); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16); - /* Restore AER */ - bnx2x_set_aer_mmd(params, phy); /* Set speed via PMA/PMD register */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040); @@ -4341,7 +4303,7 @@ static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy, struct link_params *params) { struct bnx2x *bp = params->bp; - u16 val16, lane; + u16 val16; bnx2x_sfp_e3_set_transmitter(params, phy, 0); bnx2x_set_mdio_clk(bp, params->chip_id, params->port); bnx2x_set_aer_mmd(params, phy); @@ -4378,30 +4340,6 @@ static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy, MDIO_WC_REG_XGXSBLK1_LANECTRL2, val16 & 0xff00); - lane = bnx2x_get_warpcore_lane(phy, params); - /* Disable CL36 PCS Tx */ - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16); - val16 |= (0x11 << lane); - if (phy->flags & FLAGS_WC_DUAL_MODE) - val16 |= (0x22 << lane); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16); - - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16); - val16 &= ~(0x0303 << (lane << 1)); - val16 |= (0x0101 << (lane << 1)); - if (phy->flags & FLAGS_WC_DUAL_MODE) { - val16 &= ~(0x0c0c << (lane << 1)); - val16 |= (0x0404 << (lane << 1)); - } - - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16); - /* Restore AER */ - bnx2x_set_aer_mmd(params, phy); - } static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy, @@ -6358,7 +6296,15 @@ static int bnx2x_update_link_down(struct link_params *params, vars->mac_type = MAC_TYPE_NONE; /* Update shared memory */ - vars->link_status &= ~LINK_UPDATE_MASK; + vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK | + LINK_STATUS_LINK_UP | + LINK_STATUS_PHYSICAL_LINK_FLAG | + LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | + LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | + LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | + LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | + LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | + LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE); vars->line_speed = 0; bnx2x_update_mng(params, vars->link_status); @@ -6506,7 +6452,6 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed; u8 active_external_phy = INT_PHY; vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG; - vars->link_status &= ~LINK_UPDATE_MASK; for (phy_index = INT_PHY; phy_index < params->num_phys; phy_index++) { phy_vars[phy_index].flow_ctrl = 0; @@ -7634,7 +7579,7 @@ static void bnx2x_warpcore_power_module(struct link_params *params, static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, struct link_params *params, u16 addr, u8 byte_cnt, - u8 *o_buf, u8 is_init) + u8 *o_buf) { int rc = 0; u8 i, j = 0, cnt = 0; @@ -7651,10 +7596,10 @@ static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, /* 4 byte aligned address */ addr32 = addr & (~0x3); do { - if ((!is_init) && (cnt == I2C_WA_PWR_ITER)) { + if (cnt == I2C_WA_PWR_ITER) { bnx2x_warpcore_power_module(params, phy, 0); /* Note that 100us are not enough here */ - usleep_range(1000, 2000); + usleep_range(1000,1000); bnx2x_warpcore_power_module(params, phy, 1); } rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt, @@ -7774,7 +7719,7 @@ int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr, - byte_cnt, o_buf, 0); + byte_cnt, o_buf); break; } return rc; @@ -7978,7 +7923,6 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, { u8 val; - int rc; struct bnx2x *bp = params->bp; u16 timeout; /* Initialization time after hot-plug may take up to 300ms for @@ -7986,14 +7930,8 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, */ for (timeout = 0; timeout < 60; timeout++) { - if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) - rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, - params, 1, - 1, &val, 1); - else - rc = bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, - &val); - if (rc == 0) { + if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val) + == 0) { DP(NETIF_MSG_LINK, "SFP+ module initialization took %d ms\n", timeout * 5); @@ -8001,8 +7939,7 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, } usleep_range(5000, 10000); } - rc = bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val); - return rc; + return -EINVAL; } static void bnx2x_8727_power_module(struct bnx2x *bp, @@ -9941,7 +9878,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, else rc = bnx2x_8483x_disable_eee(phy, params, vars); if (rc) { - DP(NETIF_MSG_LINK, "Failed to set EEE advertisement\n"); + DP(NETIF_MSG_LINK, "Failed to set EEE advertisment\n"); return rc; } } else { @@ -11056,7 +10993,7 @@ static struct bnx2x_phy phy_xgxs = { .format_fw_ver = (format_fw_ver_t)NULL, .hw_reset = (hw_reset_t)NULL, .set_link_led = (set_link_led_t)NULL, - .phy_specific_func = (phy_specific_func_t)bnx2x_xgxs_specific_func + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_warpcore = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT, @@ -11528,11 +11465,6 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, phy->media_type = ETH_PHY_BASE_T; break; case PORT_HW_CFG_NET_SERDES_IF_XFI: - phy->supported &= (SUPPORTED_1000baseT_Full | - SUPPORTED_10000baseT_Full | - SUPPORTED_FIBRE | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); phy->media_type = ETH_PHY_XFP_FIBER; break; case PORT_HW_CFG_NET_SERDES_IF_SFI: @@ -12987,7 +12919,7 @@ static u8 bnx2x_analyze_link_error(struct link_params *params, DP(NETIF_MSG_LINK, "Analyze TX Fault\n"); break; default: - DP(NETIF_MSG_LINK, "Analyze UNKNOWN\n"); + DP(NETIF_MSG_LINK, "Analyze UNKOWN\n"); } DP(NETIF_MSG_LINK, "Link changed:[%x %x]->%x\n", vars->link_up, old_status, status); diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 01611b33a93d..d5648fc666bd 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -6794,9 +6794,8 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) bnx2x_init_block(bp, BLOCK_DORQ, init_phase); - bnx2x_init_block(bp, BLOCK_BRB1, init_phase); - if (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) { + bnx2x_init_block(bp, BLOCK_BRB1, init_phase); if (IS_MF(bp)) low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246); @@ -9545,13 +9544,10 @@ static int __devinit bnx2x_prev_unload_common(struct bnx2x *bp) */ static void __devinit bnx2x_prev_interrupted_dmae(struct bnx2x *bp) { - if (!CHIP_IS_E1x(bp)) { - u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS); - if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) { - BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing"); - REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, - 1 << BP_FUNC(bp)); - } + u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) { + BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing"); + REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, 1 << BP_FUNC(bp)); } } @@ -11906,15 +11902,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, /* disable FCOE L2 queue for E1x */ if (CHIP_IS_E1x(bp)) bp->flags |= NO_FCOE_FLAG; - /* disable FCOE for 57840 device, until FW supports it */ - switch (ent->driver_data) { - case BCM57840_O: - case BCM57840_4_10: - case BCM57840_2_20: - case BCM57840_MFO: - case BCM57840_MF: - bp->flags |= NO_FCOE_FLAG; - } + #endif diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 378988b5709a..a4da893ac1e1 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -251,8 +251,6 @@ struct adapter_params { unsigned char rev; /* chip revision */ unsigned char offload; - unsigned char bypass; - unsigned int ofldq_wr_cred; }; @@ -644,23 +642,6 @@ extern int dbfifo_int_thresh; #define for_each_port(adapter, iter) \ for (iter = 0; iter < (adapter)->params.nports; ++iter) -static inline int is_bypass(struct adapter *adap) -{ - return adap->params.bypass; -} - -static inline int is_bypass_device(int device) -{ - /* this should be set based upon device capabilities */ - switch (device) { - case 0x440b: - case 0x440c: - return 1; - default: - return 0; - } -} - static inline unsigned int core_ticks_per_usec(const struct adapter *adap) { return adap->params.vpd.cclk / 1000; diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 0df1284df497..604f4f87f550 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3415,6 +3415,16 @@ static int adap_init0_config(struct adapter *adapter, int reset) "mismatch: [fini] csum=%#x, computed csum=%#x\n", finicsum, cfcsum); + /* + * If we're a pure NIC driver then disable all offloading facilities. + * This will allow the firmware to optimize aspects of the hardware + * configuration which will result in improved performance. + */ + caps_cmd.ofldcaps = 0; + caps_cmd.iscsicaps = 0; + caps_cmd.rdmacaps = 0; + caps_cmd.fcoecaps = 0; + /* * And now tell the firmware to use the configuration we just loaded. */ @@ -3503,6 +3513,18 @@ static int adap_init0_no_config(struct adapter *adapter, int reset) if (ret < 0) goto bye; +#ifndef CONFIG_CHELSIO_T4_OFFLOAD + /* + * If we're a pure NIC driver then disable all offloading facilities. + * This will allow the firmware to optimize aspects of the hardware + * configuration which will result in improved performance. + */ + caps_cmd.ofldcaps = 0; + caps_cmd.iscsicaps = 0; + caps_cmd.rdmacaps = 0; + caps_cmd.fcoecaps = 0; +#endif + if (caps_cmd.niccaps & htons(FW_CAPS_CONFIG_NIC_VM)) { if (!vf_acls) caps_cmd.niccaps ^= htons(FW_CAPS_CONFIG_NIC_VM); @@ -3723,7 +3745,6 @@ static int adap_init0(struct adapter *adap) u32 v, port_vec; enum dev_state state; u32 params[7], val[7]; - struct fw_caps_config_cmd caps_cmd; int reset = 1, j; /* @@ -3877,9 +3898,6 @@ static int adap_init0(struct adapter *adap) goto bye; } - if (is_bypass_device(adap->pdev->device)) - adap->params.bypass = 1; - /* * Grab some of our basic fundamental operating parameters. */ @@ -3922,12 +3940,13 @@ static int adap_init0(struct adapter *adap) adap->tids.aftid_end = val[1]; } +#ifdef CONFIG_CHELSIO_T4_OFFLOAD /* * Get device capabilities so we can determine what resources we need * to manage. */ memset(&caps_cmd, 0, sizeof(caps_cmd)); - caps_cmd.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | + caps_cmd.op_to_write = htonl(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) | FW_CMD_REQUEST | FW_CMD_READ); caps_cmd.retval_len16 = htonl(FW_LEN16(caps_cmd)); ret = t4_wr_mbox(adap, adap->mbox, &caps_cmd, sizeof(caps_cmd), @@ -3972,6 +3991,15 @@ static int adap_init0(struct adapter *adap) adap->vres.ddp.size = val[4] - val[3] + 1; adap->params.ofldq_wr_cred = val[5]; + params[0] = FW_PARAM_PFVF(ETHOFLD_START); + params[1] = FW_PARAM_PFVF(ETHOFLD_END); + ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 2, + params, val); + if ((val[0] != val[1]) && (ret >= 0)) { + adap->tids.uotid_base = val[0]; + adap->tids.nuotids = val[1] - val[0] + 1; + } + adap->params.offload = 1; } if (caps_cmd.rdmacaps) { @@ -4020,6 +4048,7 @@ static int adap_init0(struct adapter *adap) } #undef FW_PARAM_PFVF #undef FW_PARAM_DEV +#endif /* CONFIG_CHELSIO_T4_OFFLOAD */ /* * These are finalized by FW initialization, load their values now. diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h index 39bec73ff87c..1b899fea1a91 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h +++ b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h @@ -102,9 +102,6 @@ struct tid_info { unsigned int ftid_base; unsigned int aftid_base; unsigned int aftid_end; - /* Server filter region */ - unsigned int sftid_base; - unsigned int nsftids; spinlock_t atid_lock ____cacheline_aligned_in_smp; union aopen_entry *afree; diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 730ae2cfa49e..32eec15fe4c2 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -2519,7 +2519,6 @@ int t4_fw_bye(struct adapter *adap, unsigned int mbox) { struct fw_bye_cmd c; - memset(&c, 0, sizeof(c)); INIT_CMD(c, BYE, WRITE); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); } @@ -2536,7 +2535,6 @@ int t4_early_init(struct adapter *adap, unsigned int mbox) { struct fw_initialize_cmd c; - memset(&c, 0, sizeof(c)); INIT_CMD(c, INITIALIZE, WRITE); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); } @@ -2553,7 +2551,6 @@ int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset) { struct fw_reset_cmd c; - memset(&c, 0, sizeof(c)); INIT_CMD(c, RESET, WRITE); c.val = htonl(reset); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); @@ -2831,7 +2828,7 @@ int t4_fixup_host_params(struct adapter *adap, unsigned int page_size, HOSTPAGESIZEPF7(sge_hps)); t4_set_reg_field(adap, SGE_CONTROL, - INGPADBOUNDARY_MASK | + INGPADBOUNDARY(INGPADBOUNDARY_MASK) | EGRSTATUSPAGESIZE_MASK, INGPADBOUNDARY(fl_align_log - 5) | EGRSTATUSPAGESIZE(stat_len != 64)); @@ -3281,7 +3278,6 @@ int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid, { struct fw_vi_enable_cmd c; - memset(&c, 0, sizeof(c)); c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST | FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid)); c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED | FW_LEN16(c)); diff --git a/trunk/drivers/net/ethernet/freescale/gianfar.c b/trunk/drivers/net/ethernet/freescale/gianfar.c index 19ac096cb07b..1d03dcdd5e56 100644 --- a/trunk/drivers/net/ethernet/freescale/gianfar.c +++ b/trunk/drivers/net/ethernet/freescale/gianfar.c @@ -1353,11 +1353,8 @@ static int gfar_restore(struct device *dev) struct gfar_private *priv = dev_get_drvdata(dev); struct net_device *ndev = priv->ndev; - if (!netif_running(ndev)) { - netif_device_attach(ndev); - + if (!netif_running(ndev)) return 0; - } gfar_init_bds(ndev); init_registers(ndev); diff --git a/trunk/drivers/net/ethernet/freescale/gianfar_ptp.c b/trunk/drivers/net/ethernet/freescale/gianfar_ptp.c index 2e5daee0438a..b9db0e040563 100644 --- a/trunk/drivers/net/ethernet/freescale/gianfar_ptp.c +++ b/trunk/drivers/net/ethernet/freescale/gianfar_ptp.c @@ -478,7 +478,7 @@ static int gianfar_ptp_probe(struct platform_device *dev) pr_err("no resource\n"); goto no_resource; } - if (request_resource(&iomem_resource, etsects->rsrc)) { + if (request_resource(&ioport_resource, etsects->rsrc)) { pr_err("resource busy\n"); goto no_resource; } diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 116f0e901bee..56b20d17d0e4 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -2673,9 +2673,6 @@ static int ixgbe_get_ts_info(struct net_device *dev, case ixgbe_mac_X540: case ixgbe_mac_82599EB: info->so_timestamping = - SOF_TIMESTAMPING_TX_SOFTWARE | - SOF_TIMESTAMPING_RX_SOFTWARE | - SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_RAW_HARDWARE; diff --git a/trunk/drivers/net/ethernet/jme.c b/trunk/drivers/net/ethernet/jme.c index 60ac46f4ac08..f8064df10cc4 100644 --- a/trunk/drivers/net/ethernet/jme.c +++ b/trunk/drivers/net/ethernet/jme.c @@ -1860,14 +1860,10 @@ jme_open(struct net_device *netdev) jme_clear_pm(jme); JME_NAPI_ENABLE(jme); - tasklet_init(&jme->linkch_task, jme_link_change_tasklet, - (unsigned long) jme); - tasklet_init(&jme->txclean_task, jme_tx_clean_tasklet, - (unsigned long) jme); - tasklet_init(&jme->rxclean_task, jme_rx_clean_tasklet, - (unsigned long) jme); - tasklet_init(&jme->rxempty_task, jme_rx_empty_tasklet, - (unsigned long) jme); + tasklet_enable(&jme->linkch_task); + tasklet_enable(&jme->txclean_task); + tasklet_hi_enable(&jme->rxclean_task); + tasklet_hi_enable(&jme->rxempty_task); rc = jme_request_irq(jme); if (rc) @@ -1952,10 +1948,10 @@ jme_close(struct net_device *netdev) JME_NAPI_DISABLE(jme); - tasklet_kill(&jme->linkch_task); - tasklet_kill(&jme->txclean_task); - tasklet_kill(&jme->rxclean_task); - tasklet_kill(&jme->rxempty_task); + tasklet_disable(&jme->linkch_task); + tasklet_disable(&jme->txclean_task); + tasklet_disable(&jme->rxclean_task); + tasklet_disable(&jme->rxempty_task); jme_disable_rx_engine(jme); jme_disable_tx_engine(jme); @@ -3083,6 +3079,22 @@ jme_init_one(struct pci_dev *pdev, tasklet_init(&jme->pcc_task, jme_pcc_tasklet, (unsigned long) jme); + tasklet_init(&jme->linkch_task, + jme_link_change_tasklet, + (unsigned long) jme); + tasklet_init(&jme->txclean_task, + jme_tx_clean_tasklet, + (unsigned long) jme); + tasklet_init(&jme->rxclean_task, + jme_rx_clean_tasklet, + (unsigned long) jme); + tasklet_init(&jme->rxempty_task, + jme_rx_empty_tasklet, + (unsigned long) jme); + tasklet_disable_nosync(&jme->linkch_task); + tasklet_disable_nosync(&jme->txclean_task); + tasklet_disable_nosync(&jme->rxclean_task); + tasklet_disable_nosync(&jme->rxempty_task); jme->dpi.cur = PCC_P1; jme->reg_ghc = 0; diff --git a/trunk/drivers/net/ethernet/marvell/skge.c b/trunk/drivers/net/ethernet/marvell/skge.c index d19a143aa5a8..9b9c2ac5c4c2 100644 --- a/trunk/drivers/net/ethernet/marvell/skge.c +++ b/trunk/drivers/net/ethernet/marvell/skge.c @@ -4026,7 +4026,7 @@ static void __devexit skge_remove(struct pci_dev *pdev) dev0 = hw->dev[0]; unregister_netdev(dev0); - tasklet_kill(&hw->phy_task); + tasklet_disable(&hw->phy_task); spin_lock_irq(&hw->hw_lock); hw->intr_mask = 0; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c b/trunk/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c index b799ab12a291..5d36795877cb 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c @@ -237,7 +237,7 @@ static int mlx4_en_dcbnl_ieee_setmaxrate(struct net_device *dev, if (err) return err; - memcpy(priv->maxrate, tmp, sizeof(priv->maxrate)); + memcpy(priv->maxrate, tmp, sizeof(*priv->maxrate)); return 0; } diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/trunk/drivers/net/ethernet/mellanox/mlx4/en_tx.c index b35094c590ba..c10e3a6de09f 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/en_tx.c @@ -143,6 +143,7 @@ void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv, mlx4_bf_free(mdev->dev, &ring->bf); mlx4_qp_remove(mdev->dev, &ring->qp); mlx4_qp_free(mdev->dev, &ring->qp); + mlx4_qp_release_range(mdev->dev, ring->qpn, 1); mlx4_en_unmap_buffer(&ring->wqres.buf); mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size); kfree(ring->bounce_buf); @@ -711,7 +712,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) if (bounce) tx_desc = mlx4_en_bounce_to_desc(priv, ring, index, desc_size); - if (ring->bf_enabled && desc_size <= MAX_BF && !bounce && !vlan_tx_tag_present(skb)) { + if (ring->bf_enabled && desc_size <= MAX_BF && !bounce && !vlan_tag) { *(__be32 *) (&tx_desc->ctrl.vlan_tag) |= cpu_to_be32(ring->doorbell_qpn); op_own |= htonl((bf_index & 0xffff) << 8); /* Ensure new descirptor hits memory diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/eq.c b/trunk/drivers/net/ethernet/mellanox/mlx4/eq.c index b84a88bc44dc..51c764901ad2 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/eq.c @@ -329,6 +329,9 @@ int set_and_calc_slave_port_state(struct mlx4_dev *dev, int slave, ctx = &priv->mfunc.master.slave_state[slave]; spin_lock_irqsave(&ctx->lock, flags); + mlx4_dbg(dev, "%s: slave: %d, current state: %d new event :%d\n", + __func__, slave, cur_state, event); + switch (cur_state) { case SLAVE_PORT_DOWN: if (MLX4_PORT_STATE_DEV_EVENT_PORT_UP == event) @@ -363,6 +366,9 @@ int set_and_calc_slave_port_state(struct mlx4_dev *dev, int slave, goto out; } ret = mlx4_get_slave_port_state(dev, slave, port); + mlx4_dbg(dev, "%s: slave: %d, current state: %d new event" + " :%d gen_event: %d\n", + __func__, slave, cur_state, event, *gen_event); out: spin_unlock_irqrestore(&ctx->lock, flags); @@ -837,18 +843,6 @@ static void __iomem *mlx4_get_eq_uar(struct mlx4_dev *dev, struct mlx4_eq *eq) return priv->eq_table.uar_map[index] + 0x800 + 8 * (eq->eqn % 4); } -static void mlx4_unmap_uar(struct mlx4_dev *dev) -{ - struct mlx4_priv *priv = mlx4_priv(dev); - int i; - - for (i = 0; i < mlx4_num_eq_uar(dev); ++i) - if (priv->eq_table.uar_map[i]) { - iounmap(priv->eq_table.uar_map[i]); - priv->eq_table.uar_map[i] = NULL; - } -} - static int mlx4_create_eq(struct mlx4_dev *dev, int nent, u8 intr, struct mlx4_eq *eq) { @@ -1213,7 +1207,6 @@ int mlx4_init_eq_table(struct mlx4_dev *dev) mlx4_free_irqs(dev); err_out_bitmap: - mlx4_unmap_uar(dev); mlx4_bitmap_cleanup(&priv->eq_table.bitmap); err_out_free: @@ -1238,7 +1231,10 @@ void mlx4_cleanup_eq_table(struct mlx4_dev *dev) if (!mlx4_is_slave(dev)) mlx4_unmap_clr_int(dev); - mlx4_unmap_uar(dev); + for (i = 0; i < mlx4_num_eq_uar(dev); ++i) + if (priv->eq_table.uar_map[i]) + iounmap(priv->eq_table.uar_map[i]); + mlx4_bitmap_cleanup(&priv->eq_table.bitmap); kfree(priv->eq_table.uar_map); diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/main.c b/trunk/drivers/net/ethernet/mellanox/mlx4/main.c index 2aa80afd98d2..80df2ab0177c 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/main.c @@ -1405,10 +1405,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) unmap_bf_area(dev); err_close: - if (mlx4_is_slave(dev)) - mlx4_slave_exit(dev); - else - mlx4_CLOSE_HCA(dev, 0); + mlx4_close_hca(dev); err_free_icm: if (!mlx4_is_slave(dev)) diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index b05705f50f0f..926c911c0ac4 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -330,6 +330,9 @@ static void update_pkey_index(struct mlx4_dev *dev, int slave, new_index = priv->virt2phys_pkey[slave][port - 1][orig_index]; *(u8 *)(inbox->buf + 35) = new_index; + + mlx4_dbg(dev, "port = %d, orig pkey index = %d, " + "new pkey index = %d\n", port, orig_index, new_index); } static void update_gid(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *inbox, @@ -348,6 +351,9 @@ static void update_gid(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *inbox, if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH) qp_ctx->alt_path.mgid_index = slave & 0x7F; } + + mlx4_dbg(dev, "slave %d, new gid index: 0x%x ", + slave, qp_ctx->pri_path.mgid_index); } static int mpt_mask(struct mlx4_dev *dev) diff --git a/trunk/drivers/net/ethernet/micrel/ksz884x.c b/trunk/drivers/net/ethernet/micrel/ksz884x.c index 69e01977a1dd..318fee91c79d 100644 --- a/trunk/drivers/net/ethernet/micrel/ksz884x.c +++ b/trunk/drivers/net/ethernet/micrel/ksz884x.c @@ -5407,8 +5407,8 @@ static int netdev_close(struct net_device *dev) /* Delay for receive task to stop scheduling itself. */ msleep(2000 / HZ); - tasklet_kill(&hw_priv->rx_tasklet); - tasklet_kill(&hw_priv->tx_tasklet); + tasklet_disable(&hw_priv->rx_tasklet); + tasklet_disable(&hw_priv->tx_tasklet); free_irq(dev->irq, hw_priv->dev); transmit_cleanup(hw_priv, 0); @@ -5459,10 +5459,8 @@ static int prepare_hardware(struct net_device *dev) rc = request_irq(dev->irq, netdev_intr, IRQF_SHARED, dev->name, dev); if (rc) return rc; - tasklet_init(&hw_priv->rx_tasklet, rx_proc_task, - (unsigned long) hw_priv); - tasklet_init(&hw_priv->tx_tasklet, tx_proc_task, - (unsigned long) hw_priv); + tasklet_enable(&hw_priv->rx_tasklet); + tasklet_enable(&hw_priv->tx_tasklet); hw->promiscuous = 0; hw->all_multi = 0; @@ -7035,6 +7033,16 @@ static int __devinit pcidev_init(struct pci_dev *pdev, spin_lock_init(&hw_priv->hwlock); mutex_init(&hw_priv->lock); + /* tasklet is enabled. */ + tasklet_init(&hw_priv->rx_tasklet, rx_proc_task, + (unsigned long) hw_priv); + tasklet_init(&hw_priv->tx_tasklet, tx_proc_task, + (unsigned long) hw_priv); + + /* tasklet_enable will decrement the atomic counter. */ + tasklet_disable(&hw_priv->rx_tasklet); + tasklet_disable(&hw_priv->tx_tasklet); + for (i = 0; i < TOTAL_PORT_NUM; i++) init_waitqueue_head(&hw_priv->counter[i].counter); diff --git a/trunk/drivers/net/ethernet/nxp/lpc_eth.c b/trunk/drivers/net/ethernet/nxp/lpc_eth.c index af8b4142088c..53743f7a2ca9 100644 --- a/trunk/drivers/net/ethernet/nxp/lpc_eth.c +++ b/trunk/drivers/net/ethernet/nxp/lpc_eth.c @@ -1524,7 +1524,6 @@ static int lpc_eth_drv_remove(struct platform_device *pdev) pldat->dma_buff_base_p); free_irq(ndev->irq, ndev); iounmap(pldat->net_base); - mdiobus_unregister(pldat->mii_bus); mdiobus_free(pldat->mii_bus); clk_disable(pldat->clk); clk_put(pldat->clk); diff --git a/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index 4c4fe5b1a29a..b2a94d02a521 100644 --- a/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -338,6 +338,26 @@ static void pch_gbe_wait_clr_bit(void *reg, u32 bit) pr_err("Error: busy bit is not cleared\n"); } +/** + * pch_gbe_wait_clr_bit_irq - Wait to clear a bit for interrupt context + * @reg: Pointer of register + * @busy: Busy bit + */ +static int pch_gbe_wait_clr_bit_irq(void *reg, u32 bit) +{ + u32 tmp; + int ret = -1; + /* wait busy */ + tmp = 20; + while ((ioread32(reg) & bit) && --tmp) + udelay(5); + if (!tmp) + pr_err("Error: busy bit is not cleared\n"); + else + ret = 0; + return ret; +} + /** * pch_gbe_mac_mar_set - Set MAC address register * @hw: Pointer to the HW structure @@ -389,20 +409,15 @@ static void pch_gbe_mac_reset_hw(struct pch_gbe_hw *hw) return; } -static void pch_gbe_disable_mac_rx(struct pch_gbe_hw *hw) +static void pch_gbe_mac_reset_rx(struct pch_gbe_hw *hw) { - u32 rctl; - /* Disables Receive MAC */ - rctl = ioread32(&hw->reg->MAC_RX_EN); - iowrite32((rctl & ~PCH_GBE_MRE_MAC_RX_EN), &hw->reg->MAC_RX_EN); -} - -static void pch_gbe_enable_mac_rx(struct pch_gbe_hw *hw) -{ - u32 rctl; - /* Enables Receive MAC */ - rctl = ioread32(&hw->reg->MAC_RX_EN); - iowrite32((rctl | PCH_GBE_MRE_MAC_RX_EN), &hw->reg->MAC_RX_EN); + /* Read the MAC addresses. and store to the private data */ + pch_gbe_mac_read_mac_addr(hw); + iowrite32(PCH_GBE_RX_RST, &hw->reg->RESET); + pch_gbe_wait_clr_bit_irq(&hw->reg->RESET, PCH_GBE_RX_RST); + /* Setup the MAC addresses */ + pch_gbe_mac_mar_set(hw, hw->mac.addr, 0); + return; } /** @@ -898,7 +913,7 @@ static void pch_gbe_setup_rctl(struct pch_gbe_adapter *adapter) static void pch_gbe_configure_rx(struct pch_gbe_adapter *adapter) { struct pch_gbe_hw *hw = &adapter->hw; - u32 rdba, rdlen, rxdma; + u32 rdba, rdlen, rctl, rxdma; pr_debug("dma adr = 0x%08llx size = 0x%08x\n", (unsigned long long)adapter->rx_ring->dma, @@ -906,7 +921,9 @@ static void pch_gbe_configure_rx(struct pch_gbe_adapter *adapter) pch_gbe_mac_force_mac_fc(hw); - pch_gbe_disable_mac_rx(hw); + /* Disables Receive MAC */ + rctl = ioread32(&hw->reg->MAC_RX_EN); + iowrite32((rctl & ~PCH_GBE_MRE_MAC_RX_EN), &hw->reg->MAC_RX_EN); /* Disables Receive DMA */ rxdma = ioread32(&hw->reg->DMA_CTRL); @@ -1299,17 +1316,38 @@ void pch_gbe_update_stats(struct pch_gbe_adapter *adapter) spin_unlock_irqrestore(&adapter->stats_lock, flags); } -static void pch_gbe_disable_dma_rx(struct pch_gbe_hw *hw) +static void pch_gbe_stop_receive(struct pch_gbe_adapter *adapter) { + struct pch_gbe_hw *hw = &adapter->hw; u32 rxdma; + u16 value; + int ret; /* Disable Receive DMA */ rxdma = ioread32(&hw->reg->DMA_CTRL); rxdma &= ~PCH_GBE_RX_DMA_EN; iowrite32(rxdma, &hw->reg->DMA_CTRL); + /* Wait Rx DMA BUS is IDLE */ + ret = pch_gbe_wait_clr_bit_irq(&hw->reg->RX_DMA_ST, PCH_GBE_IDLE_CHECK); + if (ret) { + /* Disable Bus master */ + pci_read_config_word(adapter->pdev, PCI_COMMAND, &value); + value &= ~PCI_COMMAND_MASTER; + pci_write_config_word(adapter->pdev, PCI_COMMAND, value); + /* Stop Receive */ + pch_gbe_mac_reset_rx(hw); + /* Enable Bus master */ + value |= PCI_COMMAND_MASTER; + pci_write_config_word(adapter->pdev, PCI_COMMAND, value); + } else { + /* Stop Receive */ + pch_gbe_mac_reset_rx(hw); + } + /* reprogram multicast address register after reset */ + pch_gbe_set_multi(adapter->netdev); } -static void pch_gbe_enable_dma_rx(struct pch_gbe_hw *hw) +static void pch_gbe_start_receive(struct pch_gbe_hw *hw) { u32 rxdma; @@ -1317,6 +1355,9 @@ static void pch_gbe_enable_dma_rx(struct pch_gbe_hw *hw) rxdma = ioread32(&hw->reg->DMA_CTRL); rxdma |= PCH_GBE_RX_DMA_EN; iowrite32(rxdma, &hw->reg->DMA_CTRL); + /* Enables Receive */ + iowrite32(PCH_GBE_MRE_MAC_RX_EN, &hw->reg->MAC_RX_EN); + return; } /** @@ -1352,7 +1393,7 @@ static irqreturn_t pch_gbe_intr(int irq, void *data) int_en = ioread32(&hw->reg->INT_EN); iowrite32((int_en & ~PCH_GBE_INT_RX_FIFO_ERR), &hw->reg->INT_EN); - pch_gbe_disable_dma_rx(&adapter->hw); + pch_gbe_stop_receive(adapter); int_st |= ioread32(&hw->reg->INT_ST); int_st = int_st & ioread32(&hw->reg->INT_EN); } @@ -1930,12 +1971,12 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter) struct net_device *netdev = adapter->netdev; struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring; struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring; - int err = -EINVAL; + int err; /* Ensure we have a valid MAC */ if (!is_valid_ether_addr(adapter->hw.mac.addr)) { pr_err("Error: Invalid MAC address\n"); - goto out; + return -EINVAL; } /* hardware has been reset, we need to reload some things */ @@ -1948,19 +1989,18 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter) err = pch_gbe_request_irq(adapter); if (err) { - pr_err("Error: can't bring device up - irq request failed\n"); - goto out; + pr_err("Error: can't bring device up\n"); + return err; } err = pch_gbe_alloc_rx_buffers_pool(adapter, rx_ring, rx_ring->count); if (err) { - pr_err("Error: can't bring device up - alloc rx buffers pool failed\n"); - goto freeirq; + pr_err("Error: can't bring device up\n"); + return err; } pch_gbe_alloc_tx_buffers(adapter, tx_ring); pch_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count); adapter->tx_queue_len = netdev->tx_queue_len; - pch_gbe_enable_dma_rx(&adapter->hw); - pch_gbe_enable_mac_rx(&adapter->hw); + pch_gbe_start_receive(&adapter->hw); mod_timer(&adapter->watchdog_timer, jiffies); @@ -1969,11 +2009,6 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter) netif_start_queue(adapter->netdev); return 0; - -freeirq: - pch_gbe_free_irq(adapter); -out: - return err; } /** @@ -2370,6 +2405,7 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget) int work_done = 0; bool poll_end_flag = false; bool cleaned = false; + u32 int_en; pr_debug("budget : %d\n", budget); @@ -2386,13 +2422,19 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget) if (poll_end_flag) { napi_complete(napi); + if (adapter->rx_stop_flag) { + adapter->rx_stop_flag = false; + pch_gbe_start_receive(&adapter->hw); + } pch_gbe_irq_enable(adapter); - } - - if (adapter->rx_stop_flag) { - adapter->rx_stop_flag = false; - pch_gbe_enable_dma_rx(&adapter->hw); - } + } else + if (adapter->rx_stop_flag) { + adapter->rx_stop_flag = false; + pch_gbe_start_receive(&adapter->hw); + int_en = ioread32(&adapter->hw.reg->INT_EN); + iowrite32((int_en | PCH_GBE_INT_RX_FIFO_ERR), + &adapter->hw.reg->INT_EN); + } pr_debug("poll_end_flag : %d work_done : %d budget : %d\n", poll_end_flag, work_done, budget); diff --git a/trunk/drivers/net/ethernet/qlogic/qla3xxx.c b/trunk/drivers/net/ethernet/qlogic/qla3xxx.c index 6407d0d77e81..df09b1cb742f 100644 --- a/trunk/drivers/net/ethernet/qlogic/qla3xxx.c +++ b/trunk/drivers/net/ethernet/qlogic/qla3xxx.c @@ -2525,13 +2525,6 @@ static int ql_alloc_net_req_rsp_queues(struct ql3_adapter *qdev) qdev->req_q_size = (u32) (NUM_REQ_Q_ENTRIES * sizeof(struct ob_mac_iocb_req)); - qdev->rsp_q_size = NUM_RSP_Q_ENTRIES * sizeof(struct net_rsp_iocb); - - /* The barrier is required to ensure request and response queue - * addr writes to the registers. - */ - wmb(); - qdev->req_q_virt_addr = pci_alloc_consistent(qdev->pdev, (size_t) qdev->req_q_size, @@ -2543,6 +2536,8 @@ static int ql_alloc_net_req_rsp_queues(struct ql3_adapter *qdev) return -ENOMEM; } + qdev->rsp_q_size = NUM_RSP_Q_ENTRIES * sizeof(struct net_rsp_iocb); + qdev->rsp_q_virt_addr = pci_alloc_consistent(qdev->pdev, (size_t) qdev->rsp_q_size, diff --git a/trunk/drivers/net/ethernet/realtek/8139cp.c b/trunk/drivers/net/ethernet/realtek/8139cp.c index 609125a249d9..1c818254b7be 100644 --- a/trunk/drivers/net/ethernet/realtek/8139cp.c +++ b/trunk/drivers/net/ethernet/realtek/8139cp.c @@ -979,6 +979,17 @@ static void cp_init_hw (struct cp_private *cp) cpw32_f (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0))); cpw32_f (MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4))); + cpw32_f(HiTxRingAddr, 0); + cpw32_f(HiTxRingAddr + 4, 0); + + ring_dma = cp->ring_dma; + cpw32_f(RxRingAddr, ring_dma & 0xffffffff); + cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16); + + ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE; + cpw32_f(TxRingAddr, ring_dma & 0xffffffff); + cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16); + cp_start_hw(cp); cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */ @@ -992,17 +1003,6 @@ static void cp_init_hw (struct cp_private *cp) cpw8(Config5, cpr8(Config5) & PMEStatus); - cpw32_f(HiTxRingAddr, 0); - cpw32_f(HiTxRingAddr + 4, 0); - - ring_dma = cp->ring_dma; - cpw32_f(RxRingAddr, ring_dma & 0xffffffff); - cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16); - - ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE; - cpw32_f(TxRingAddr, ring_dma & 0xffffffff); - cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16); - cpw16(MultiIntr, 0); cpw8_f(Cfg9346, Cfg9346_Lock); @@ -1060,22 +1060,17 @@ static int cp_init_rings (struct cp_private *cp) static int cp_alloc_rings (struct cp_private *cp) { - struct device *d = &cp->pdev->dev; void *mem; - int rc; - mem = dma_alloc_coherent(d, CP_RING_BYTES, &cp->ring_dma, GFP_KERNEL); + mem = dma_alloc_coherent(&cp->pdev->dev, CP_RING_BYTES, + &cp->ring_dma, GFP_KERNEL); if (!mem) return -ENOMEM; cp->rx_ring = mem; cp->tx_ring = &cp->rx_ring[CP_RX_RING_SIZE]; - rc = cp_init_rings(cp); - if (rc < 0) - dma_free_coherent(d, CP_RING_BYTES, cp->rx_ring, cp->ring_dma); - - return rc; + return cp_init_rings(cp); } static void cp_clean_rings (struct cp_private *cp) diff --git a/trunk/drivers/net/ethernet/realtek/r8169.c b/trunk/drivers/net/ethernet/realtek/r8169.c index 927aa33d4349..e7ff886e8047 100644 --- a/trunk/drivers/net/ethernet/realtek/r8169.c +++ b/trunk/drivers/net/ethernet/realtek/r8169.c @@ -3827,8 +3827,6 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) void __iomem *ioaddr = tp->mmio_addr; switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_25: - case RTL_GIGA_MAC_VER_26: case RTL_GIGA_MAC_VER_29: case RTL_GIGA_MAC_VER_30: case RTL_GIGA_MAC_VER_32: @@ -4521,9 +4519,6 @@ static void rtl_set_rx_mode(struct net_device *dev) mc_filter[1] = swab32(data); } - if (tp->mac_version == RTL_GIGA_MAC_VER_35) - mc_filter[1] = mc_filter[0] = 0xffffffff; - RTL_W32(MAR0 + 4, mc_filter[1]); RTL_W32(MAR0 + 0, mc_filter[0]); diff --git a/trunk/drivers/net/ethernet/sis/sis900.c b/trunk/drivers/net/ethernet/sis/sis900.c index edf5edb13140..fb9f6b38511f 100644 --- a/trunk/drivers/net/ethernet/sis/sis900.c +++ b/trunk/drivers/net/ethernet/sis/sis900.c @@ -2479,7 +2479,7 @@ static int sis900_resume(struct pci_dev *pci_dev) netif_start_queue(net_dev); /* Workaround for EDB */ - sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED); + sis900_set_mode(ioaddr, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED); /* Enable all known interrupts by setting the interrupt mask. */ sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE); diff --git a/trunk/drivers/net/ethernet/smsc/smsc911x.c b/trunk/drivers/net/ethernet/smsc/smsc911x.c index c53c0f4e2ce3..62d1baf111ea 100644 --- a/trunk/drivers/net/ethernet/smsc/smsc911x.c +++ b/trunk/drivers/net/ethernet/smsc/smsc911x.c @@ -2110,7 +2110,7 @@ static void __devinit smsc911x_read_mac_address(struct net_device *dev) static int __devinit smsc911x_init(struct net_device *dev) { struct smsc911x_data *pdata = netdev_priv(dev); - unsigned int byte_test, mask; + unsigned int byte_test; unsigned int to = 100; SMSC_TRACE(pdata, probe, "Driver Parameters:"); @@ -2130,22 +2130,9 @@ static int __devinit smsc911x_init(struct net_device *dev) /* * poll the READY bit in PMT_CTRL. Any other access to the device is * forbidden while this bit isn't set. Try for 100ms - * - * Note that this test is done before the WORD_SWAP register is - * programmed. So in some configurations the READY bit is at 16 before - * WORD_SWAP is written to. This issue is worked around by waiting - * until either bit 0 or bit 16 gets set in PMT_CTRL. - * - * SMSC has confirmed that checking bit 16 (marked as reserved in - * the datasheet) is fine since these bits "will either never be set - * or can only go high after READY does (so also indicate the device - * is ready)". */ - - mask = PMT_CTRL_READY_ | swahw32(PMT_CTRL_READY_); - while (!(smsc911x_reg_read(pdata, PMT_CTRL) & mask) && --to) + while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to) udelay(1000); - if (to == 0) { pr_err("Device not READY in 100ms aborting\n"); return -ENODEV; diff --git a/trunk/drivers/net/ethernet/ti/Kconfig b/trunk/drivers/net/ethernet/ti/Kconfig index 2c41894d5472..b26cbda5efa9 100644 --- a/trunk/drivers/net/ethernet/ti/Kconfig +++ b/trunk/drivers/net/ethernet/ti/Kconfig @@ -5,7 +5,7 @@ config NET_VENDOR_TI bool "Texas Instruments (TI) devices" default y - depends on PCI || EISA || AR7 || (ARM && (ARCH_DAVINCI || ARCH_OMAP3 || SOC_AM33XX)) + depends on PCI || EISA || AR7 || (ARM && (ARCH_DAVINCI || ARCH_OMAP3)) ---help--- If you have a network (Ethernet) card belonging to this class, say Y and read the Ethernet-HOWTO, available from diff --git a/trunk/drivers/net/ethernet/tile/tilegx.c b/trunk/drivers/net/ethernet/tile/tilegx.c index 66e025ad5df1..4e2a1628484d 100644 --- a/trunk/drivers/net/ethernet/tile/tilegx.c +++ b/trunk/drivers/net/ethernet/tile/tilegx.c @@ -917,7 +917,7 @@ static int tile_net_setup_interrupts(struct net_device *dev) ingress_irq = rc; tile_irq_activate(ingress_irq, TILE_IRQ_PERCPU); rc = request_irq(ingress_irq, tile_net_handle_ingress_irq, - 0, "tile_net", NULL); + 0, NULL, NULL); if (rc != 0) { netdev_err(dev, "request_irq failed: %d\n", rc); destroy_irq(ingress_irq); @@ -1334,11 +1334,11 @@ static int tso_count_edescs(struct sk_buff *skb) { struct skb_shared_info *sh = skb_shinfo(skb); unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); - unsigned int data_len = skb->len - sh_len; + unsigned int data_len = skb->data_len + skb->hdr_len - sh_len; unsigned int p_len = sh->gso_size; long f_id = -1; /* id of the current fragment */ - long f_size = skb_headlen(skb) - sh_len; /* current fragment size */ - long f_used = 0; /* bytes used from the current fragment */ + long f_size = skb->hdr_len; /* size of the current fragment */ + long f_used = sh_len; /* bytes used from the current fragment */ long n; /* size of the current piece of payload */ int num_edescs = 0; int segment; @@ -1353,7 +1353,7 @@ static int tso_count_edescs(struct sk_buff *skb) /* Advance as needed. */ while (f_used >= f_size) { f_id++; - f_size = skb_frag_size(&sh->frags[f_id]); + f_size = sh->frags[f_id].size; f_used = 0; } @@ -1384,13 +1384,13 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, struct iphdr *ih; struct tcphdr *th; unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); - unsigned int data_len = skb->len - sh_len; + unsigned int data_len = skb->data_len + skb->hdr_len - sh_len; unsigned char *data = skb->data; unsigned int ih_off, th_off, p_len; unsigned int isum_seed, tsum_seed, id, seq; long f_id = -1; /* id of the current fragment */ - long f_size = skb_headlen(skb) - sh_len; /* current fragment size */ - long f_used = 0; /* bytes used from the current fragment */ + long f_size = skb->hdr_len; /* size of the current fragment */ + long f_used = sh_len; /* bytes used from the current fragment */ long n; /* size of the current piece of payload */ int segment; @@ -1405,7 +1405,7 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, isum_seed = ((0xFFFF - ih->check) + (0xFFFF - ih->tot_len) + (0xFFFF - ih->id)); - tsum_seed = th->check + (0xFFFF ^ htons(skb->len)); + tsum_seed = th->check + (0xFFFF ^ htons(sh_len + data_len)); id = ntohs(ih->id); seq = ntohl(th->seq); @@ -1444,7 +1444,7 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, /* Advance as needed. */ while (f_used >= f_size) { f_id++; - f_size = skb_frag_size(&sh->frags[f_id]); + f_size = sh->frags[f_id].size; f_used = 0; } @@ -1478,14 +1478,14 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, struct tile_net_priv *priv = netdev_priv(dev); struct skb_shared_info *sh = skb_shinfo(skb); unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); - unsigned int data_len = skb->len - sh_len; + unsigned int data_len = skb->data_len + skb->hdr_len - sh_len; unsigned int p_len = sh->gso_size; gxio_mpipe_edesc_t edesc_head = { { 0 } }; gxio_mpipe_edesc_t edesc_body = { { 0 } }; long f_id = -1; /* id of the current fragment */ - long f_size = skb_headlen(skb) - sh_len; /* current fragment size */ - long f_used = 0; /* bytes used from the current fragment */ - void *f_data = skb->data + sh_len; + long f_size = skb->hdr_len; /* size of the current fragment */ + long f_used = sh_len; /* bytes used from the current fragment */ + void *f_data = skb->data; long n; /* size of the current piece of payload */ unsigned long tx_packets = 0, tx_bytes = 0; unsigned int csum_start; @@ -1516,18 +1516,15 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, /* Egress the payload. */ while (p_used < p_len) { - void *va; /* Advance as needed. */ while (f_used >= f_size) { f_id++; - f_size = skb_frag_size(&sh->frags[f_id]); - f_data = tile_net_frag_buf(&sh->frags[f_id]); + f_size = sh->frags[f_id].size; f_used = 0; + f_data = tile_net_frag_buf(&sh->frags[f_id]); } - va = f_data + f_used; - /* Use bytes from the current fragment. */ n = p_len - p_used; if (n > f_size - f_used) @@ -1536,7 +1533,7 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, p_used += n; /* Egress a piece of the payload. */ - edesc_body.va = va_to_tile_io_addr(va); + edesc_body.va = va_to_tile_io_addr(f_data) + f_used; edesc_body.xfer_size = n; edesc_body.bound = !(p_used < p_len); gxio_mpipe_equeue_put_at(equeue, edesc_body, slot); diff --git a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index a788501e978e..0793299bd39e 100644 --- a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -894,8 +894,6 @@ static irqreturn_t axienet_rx_irq(int irq, void *_ndev) return IRQ_HANDLED; } -static void axienet_dma_err_handler(unsigned long data); - /** * axienet_open - Driver open routine. * @ndev: Pointer to net_device structure @@ -944,10 +942,6 @@ static int axienet_open(struct net_device *ndev) phy_start(lp->phy_dev); } - /* Enable tasklets for Axi DMA error handling */ - tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler, - (unsigned long) lp); - /* Enable interrupts for Axi DMA Tx */ ret = request_irq(lp->tx_irq, axienet_tx_irq, 0, ndev->name, ndev); if (ret) @@ -956,7 +950,8 @@ static int axienet_open(struct net_device *ndev) ret = request_irq(lp->rx_irq, axienet_rx_irq, 0, ndev->name, ndev); if (ret) goto err_rx_irq; - + /* Enable tasklets for Axi DMA error handling */ + tasklet_enable(&lp->dma_err_tasklet); return 0; err_rx_irq: @@ -965,7 +960,6 @@ static int axienet_open(struct net_device *ndev) if (lp->phy_dev) phy_disconnect(lp->phy_dev); lp->phy_dev = NULL; - tasklet_kill(&lp->dma_err_tasklet); dev_err(lp->dev, "request_irq() failed\n"); return ret; } @@ -996,7 +990,7 @@ static int axienet_stop(struct net_device *ndev) axienet_setoptions(ndev, lp->options & ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN)); - tasklet_kill(&lp->dma_err_tasklet); + tasklet_disable(&lp->dma_err_tasklet); free_irq(lp->tx_irq, ndev); free_irq(lp->rx_irq, ndev); @@ -1619,6 +1613,10 @@ static int __devinit axienet_of_probe(struct platform_device *op) goto err_iounmap_2; } + tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler, + (unsigned long) lp); + tasklet_disable(&lp->dma_err_tasklet); + return 0; err_iounmap_2: diff --git a/trunk/drivers/net/ethernet/xscale/ixp4xx_eth.c b/trunk/drivers/net/ethernet/xscale/ixp4xx_eth.c index 477d6729b17f..98934bdf6acf 100644 --- a/trunk/drivers/net/ethernet/xscale/ixp4xx_eth.c +++ b/trunk/drivers/net/ethernet/xscale/ixp4xx_eth.c @@ -1102,12 +1102,10 @@ static int init_queues(struct port *port) { int i; - if (!ports_open) { - dma_pool = dma_pool_create(DRV_NAME, &port->netdev->dev, - POOL_ALLOC_SIZE, 32, 0); - if (!dma_pool) + if (!ports_open) + if (!(dma_pool = dma_pool_create(DRV_NAME, NULL, + POOL_ALLOC_SIZE, 32, 0))) return -ENOMEM; - } if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL, &port->desc_tab_phys))) diff --git a/trunk/drivers/net/irda/sir_dev.c b/trunk/drivers/net/irda/sir_dev.c index 43e9ab4f4d7e..5039f08f5a5b 100644 --- a/trunk/drivers/net/irda/sir_dev.c +++ b/trunk/drivers/net/irda/sir_dev.c @@ -222,7 +222,7 @@ static void sirdev_config_fsm(struct work_struct *work) break; case SIRDEV_STATE_DONGLE_SPEED: - if (dev->dongle_drv->set_speed) { + if (dev->dongle_drv->reset) { ret = dev->dongle_drv->set_speed(dev, fsm->param); if (ret < 0) { fsm->result = ret; diff --git a/trunk/drivers/net/phy/Kconfig b/trunk/drivers/net/phy/Kconfig index 961f0b293913..983bbf4d5ef6 100644 --- a/trunk/drivers/net/phy/Kconfig +++ b/trunk/drivers/net/phy/Kconfig @@ -15,11 +15,6 @@ if PHYLIB comment "MII PHY device drivers" -config AT803X_PHY - tristate "Drivers for Atheros AT803X PHYs" - ---help--- - Currently supports the AT8030 and AT8035 model - config AMD_PHY tristate "Drivers for the AMD PHYs" ---help--- diff --git a/trunk/drivers/net/phy/Makefile b/trunk/drivers/net/phy/Makefile index 9645e389a58d..426674debae4 100644 --- a/trunk/drivers/net/phy/Makefile +++ b/trunk/drivers/net/phy/Makefile @@ -25,7 +25,6 @@ obj-$(CONFIG_STE10XP) += ste10Xp.o obj-$(CONFIG_MICREL_PHY) += micrel.o obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o -obj-$(CONFIG_AT803X_PHY) += at803x.o obj-$(CONFIG_AMD_PHY) += amd.o obj-$(CONFIG_MDIO_BUS_MUX) += mdio-mux.o obj-$(CONFIG_MDIO_BUS_MUX_GPIO) += mdio-mux-gpio.o diff --git a/trunk/drivers/net/phy/at803x.c b/trunk/drivers/net/phy/at803x.c deleted file mode 100644 index 45cbc10de01c..000000000000 --- a/trunk/drivers/net/phy/at803x.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * drivers/net/phy/at803x.c - * - * Driver for Atheros 803x PHY - * - * Author: Matus Ujhelyi - * - * 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 -#include -#include -#include -#include - -#define AT803X_INTR_ENABLE 0x12 -#define AT803X_INTR_STATUS 0x13 -#define AT803X_WOL_ENABLE 0x01 -#define AT803X_DEVICE_ADDR 0x03 -#define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C -#define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B -#define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A -#define AT803X_MMD_ACCESS_CONTROL 0x0D -#define AT803X_MMD_ACCESS_CONTROL_DATA 0x0E -#define AT803X_FUNC_DATA 0x4003 - -MODULE_DESCRIPTION("Atheros 803x PHY driver"); -MODULE_AUTHOR("Matus Ujhelyi"); -MODULE_LICENSE("GPL"); - -static void at803x_set_wol_mac_addr(struct phy_device *phydev) -{ - struct net_device *ndev = phydev->attached_dev; - const u8 *mac; - unsigned int i, offsets[] = { - AT803X_LOC_MAC_ADDR_32_47_OFFSET, - AT803X_LOC_MAC_ADDR_16_31_OFFSET, - AT803X_LOC_MAC_ADDR_0_15_OFFSET, - }; - - if (!ndev) - return; - - mac = (const u8 *) ndev->dev_addr; - - if (!is_valid_ether_addr(mac)) - return; - - for (i = 0; i < 3; i++) { - phy_write(phydev, AT803X_MMD_ACCESS_CONTROL, - AT803X_DEVICE_ADDR); - phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA, - offsets[i]); - phy_write(phydev, AT803X_MMD_ACCESS_CONTROL, - AT803X_FUNC_DATA); - phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA, - mac[(i * 2) + 1] | (mac[(i * 2)] << 8)); - } -} - -static int at803x_config_init(struct phy_device *phydev) -{ - int val; - u32 features; - int status; - - features = SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_AUI | - SUPPORTED_FIBRE | SUPPORTED_BNC; - - val = phy_read(phydev, MII_BMSR); - if (val < 0) - return val; - - if (val & BMSR_ANEGCAPABLE) - features |= SUPPORTED_Autoneg; - if (val & BMSR_100FULL) - features |= SUPPORTED_100baseT_Full; - if (val & BMSR_100HALF) - features |= SUPPORTED_100baseT_Half; - if (val & BMSR_10FULL) - features |= SUPPORTED_10baseT_Full; - if (val & BMSR_10HALF) - features |= SUPPORTED_10baseT_Half; - - if (val & BMSR_ESTATEN) { - val = phy_read(phydev, MII_ESTATUS); - if (val < 0) - return val; - - if (val & ESTATUS_1000_TFULL) - features |= SUPPORTED_1000baseT_Full; - if (val & ESTATUS_1000_THALF) - features |= SUPPORTED_1000baseT_Half; - } - - phydev->supported = features; - phydev->advertising = features; - - /* enable WOL */ - at803x_set_wol_mac_addr(phydev); - status = phy_write(phydev, AT803X_INTR_ENABLE, AT803X_WOL_ENABLE); - status = phy_read(phydev, AT803X_INTR_STATUS); - - return 0; -} - -/* ATHEROS 8035 */ -static struct phy_driver at8035_driver = { - .phy_id = 0x004dd072, - .name = "Atheros 8035 ethernet", - .phy_id_mask = 0xffffffef, - .config_init = at803x_config_init, - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_aneg = &genphy_config_aneg, - .read_status = &genphy_read_status, - .driver = { - .owner = THIS_MODULE, - }, -}; - -/* ATHEROS 8030 */ -static struct phy_driver at8030_driver = { - .phy_id = 0x004dd076, - .name = "Atheros 8030 ethernet", - .phy_id_mask = 0xffffffef, - .config_init = at803x_config_init, - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_aneg = &genphy_config_aneg, - .read_status = &genphy_read_status, - .driver = { - .owner = THIS_MODULE, - }, -}; - -static int __init atheros_init(void) -{ - int ret; - - ret = phy_driver_register(&at8035_driver); - if (ret) - goto err1; - - ret = phy_driver_register(&at8030_driver); - if (ret) - goto err2; - - return 0; - -err2: - phy_driver_unregister(&at8035_driver); -err1: - return ret; -} - -static void __exit atheros_exit(void) -{ - phy_driver_unregister(&at8035_driver); - phy_driver_unregister(&at8030_driver); -} - -module_init(atheros_init); -module_exit(atheros_exit); - -static struct mdio_device_id __maybe_unused atheros_tbl[] = { - { 0x004dd076, 0xffffffef }, - { 0x004dd072, 0xffffffef }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, atheros_tbl); diff --git a/trunk/drivers/net/phy/mdio-gpio.c b/trunk/drivers/net/phy/mdio-gpio.c index 2ed1140df3e9..899274f2f9b1 100644 --- a/trunk/drivers/net/phy/mdio-gpio.c +++ b/trunk/drivers/net/phy/mdio-gpio.c @@ -185,20 +185,17 @@ static int __devinit mdio_gpio_probe(struct platform_device *pdev) { struct mdio_gpio_platform_data *pdata; struct mii_bus *new_bus; - int ret, bus_id; + int ret; - if (pdev->dev.of_node) { + if (pdev->dev.of_node) pdata = mdio_gpio_of_get_data(pdev); - bus_id = of_alias_get_id(pdev->dev.of_node, "mdio-gpio"); - } else { + else pdata = pdev->dev.platform_data; - bus_id = pdev->id; - } if (!pdata) return -ENODEV; - new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, bus_id); + new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, pdev->id); if (!new_bus) return -ENODEV; diff --git a/trunk/drivers/net/team/team.c b/trunk/drivers/net/team/team.c index ad86660fb8f9..d44cca327588 100644 --- a/trunk/drivers/net/team/team.c +++ b/trunk/drivers/net/team/team.c @@ -1794,12 +1794,10 @@ static void team_setup(struct net_device *dev) dev->features |= NETIF_F_LLTX; dev->features |= NETIF_F_GRO; - dev->hw_features = TEAM_VLAN_FEATURES | - NETIF_F_HW_VLAN_TX | + dev->hw_features = NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; - dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_HW_CSUM); dev->features |= dev->hw_features; } diff --git a/trunk/drivers/net/team/team_mode_broadcast.c b/trunk/drivers/net/team/team_mode_broadcast.c index c5db428e73fa..9db0171e9366 100644 --- a/trunk/drivers/net/team/team_mode_broadcast.c +++ b/trunk/drivers/net/team/team_mode_broadcast.c @@ -29,8 +29,8 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb) if (last) { skb2 = skb_clone(skb, GFP_ATOMIC); if (skb2) { - ret = !team_dev_queue_xmit(team, last, - skb2); + ret = team_dev_queue_xmit(team, last, + skb2); if (!sum_ret) sum_ret = ret; } @@ -39,7 +39,7 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb) } } if (last) { - ret = !team_dev_queue_xmit(team, last, skb); + ret = team_dev_queue_xmit(team, last, skb); if (!sum_ret) sum_ret = ret; } diff --git a/trunk/drivers/net/usb/cdc_eem.c b/trunk/drivers/net/usb/cdc_eem.c index 08d55b6bf272..c81e278629ff 100644 --- a/trunk/drivers/net/usb/cdc_eem.c +++ b/trunk/drivers/net/usb/cdc_eem.c @@ -31,7 +31,6 @@ #include #include #include -#include /* @@ -93,7 +92,7 @@ static int eem_bind(struct usbnet *dev, struct usb_interface *intf) /* no jumbogram (16K) support for now */ - dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN + VLAN_HLEN; + dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN; dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; return 0; diff --git a/trunk/drivers/net/usb/cdc_ether.c b/trunk/drivers/net/usb/cdc_ether.c index d0129827602b..a03de7197049 100644 --- a/trunk/drivers/net/usb/cdc_ether.c +++ b/trunk/drivers/net/usb/cdc_ether.c @@ -592,32 +592,6 @@ static const struct usb_device_id products [] = { .driver_info = 0, }, -/* Novatel USB551L and MC551 - handled by qmi_wwan */ -{ - .match_flags = USB_DEVICE_ID_MATCH_VENDOR - | USB_DEVICE_ID_MATCH_PRODUCT - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = NOVATEL_VENDOR_ID, - .idProduct = 0xB001, - .bInterfaceClass = USB_CLASS_COMM, - .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, - .bInterfaceProtocol = USB_CDC_PROTO_NONE, - .driver_info = 0, -}, - -/* Novatel E362 - handled by qmi_wwan */ -{ - .match_flags = USB_DEVICE_ID_MATCH_VENDOR - | USB_DEVICE_ID_MATCH_PRODUCT - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = NOVATEL_VENDOR_ID, - .idProduct = 0x9010, - .bInterfaceClass = USB_CLASS_COMM, - .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, - .bInterfaceProtocol = USB_CDC_PROTO_NONE, - .driver_info = 0, -}, - /* * WHITELIST!!! * @@ -630,6 +604,21 @@ static const struct usb_device_id products [] = { * because of bugs/quirks in a given product (like Zaurus, above). */ { + /* Novatel USB551L */ + /* This match must come *before* the generic CDC-ETHER match so that + * we get FLAG_WWAN set on the device, since it's descriptors are + * generic CDC-ETHER. + */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = NOVATEL_VENDOR_ID, + .idProduct = 0xB001, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, + .bInterfaceProtocol = USB_CDC_PROTO_NONE, + .driver_info = (unsigned long)&wwan_info, +}, { /* ZTE (Vodafone) K3805-Z */ .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT diff --git a/trunk/drivers/net/usb/cdc_ncm.c b/trunk/drivers/net/usb/cdc_ncm.c index 74fab1a40156..4cd582a4f625 100644 --- a/trunk/drivers/net/usb/cdc_ncm.c +++ b/trunk/drivers/net/usb/cdc_ncm.c @@ -540,12 +540,10 @@ static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf) (ctx->ether_desc == NULL) || (ctx->control != intf)) goto error; - /* claim data interface, if different from control */ - if (ctx->data != ctx->control) { - temp = usb_driver_claim_interface(driver, ctx->data, dev); - if (temp) - goto error; - } + /* claim interfaces, if any */ + temp = usb_driver_claim_interface(driver, ctx->data, dev); + if (temp) + goto error; iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber; @@ -625,10 +623,6 @@ static void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf) tasklet_kill(&ctx->bh); - /* handle devices with combined control and data interface */ - if (ctx->control == ctx->data) - ctx->data = NULL; - /* disconnect master --> disconnect slave */ if (intf == ctx->control && ctx->data) { usb_set_intfdata(ctx->data, NULL); @@ -1251,14 +1245,6 @@ static const struct usb_device_id cdc_devs[] = { .driver_info = (unsigned long) &wwan_info, }, - /* Huawei NCM devices disguised as vendor specific */ - { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x16), - .driver_info = (unsigned long)&wwan_info, - }, - { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46), - .driver_info = (unsigned long)&wwan_info, - }, - /* Generic CDC-NCM devices */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), diff --git a/trunk/drivers/net/usb/ipheth.c b/trunk/drivers/net/usb/ipheth.c index 534d8becbbdc..a28a983d465e 100644 --- a/trunk/drivers/net/usb/ipheth.c +++ b/trunk/drivers/net/usb/ipheth.c @@ -62,7 +62,6 @@ #define USB_PRODUCT_IPAD 0x129a #define USB_PRODUCT_IPHONE_4_VZW 0x129c #define USB_PRODUCT_IPHONE_4S 0x12a0 -#define USB_PRODUCT_IPHONE_5 0x12a8 #define IPHETH_USBINTF_CLASS 255 #define IPHETH_USBINTF_SUBCLASS 253 @@ -114,10 +113,6 @@ static struct usb_device_id ipheth_table[] = { USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4S, IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, IPHETH_USBINTF_PROTO) }, - { USB_DEVICE_AND_INTERFACE_INFO( - USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_5, - IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, - IPHETH_USBINTF_PROTO) }, { } }; MODULE_DEVICE_TABLE(usb, ipheth_table); diff --git a/trunk/drivers/net/usb/qmi_wwan.c b/trunk/drivers/net/usb/qmi_wwan.c index 1ea91f4237f0..6883c371c59f 100644 --- a/trunk/drivers/net/usb/qmi_wwan.c +++ b/trunk/drivers/net/usb/qmi_wwan.c @@ -369,74 +369,18 @@ static const struct usb_device_id products[] = { USB_VENDOR_AND_INTERFACE_INFO(0x106c, USB_CLASS_VENDOR_SPEC, 0xf1, 0xff), .driver_info = (unsigned long)&qmi_wwan_info, }, - { /* Novatel USB551L and MC551 */ - USB_DEVICE_AND_INTERFACE_INFO(0x1410, 0xb001, - USB_CLASS_COMM, - USB_CDC_SUBCLASS_ETHERNET, - USB_CDC_PROTO_NONE), - .driver_info = (unsigned long)&qmi_wwan_info, - }, - { /* Novatel E362 */ - USB_DEVICE_AND_INTERFACE_INFO(0x1410, 0x9010, - USB_CLASS_COMM, - USB_CDC_SUBCLASS_ETHERNET, - USB_CDC_PROTO_NONE), - .driver_info = (unsigned long)&qmi_wwan_info, - }, /* 3. Combined interface devices matching on interface number */ - {QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */ - {QMI_FIXED_INTF(0x19d2, 0x0002, 1)}, - {QMI_FIXED_INTF(0x19d2, 0x0012, 1)}, - {QMI_FIXED_INTF(0x19d2, 0x0017, 3)}, - {QMI_FIXED_INTF(0x19d2, 0x0021, 4)}, - {QMI_FIXED_INTF(0x19d2, 0x0025, 1)}, - {QMI_FIXED_INTF(0x19d2, 0x0031, 4)}, - {QMI_FIXED_INTF(0x19d2, 0x0042, 4)}, - {QMI_FIXED_INTF(0x19d2, 0x0049, 5)}, - {QMI_FIXED_INTF(0x19d2, 0x0052, 4)}, {QMI_FIXED_INTF(0x19d2, 0x0055, 1)}, /* ZTE (Vodafone) K3520-Z */ - {QMI_FIXED_INTF(0x19d2, 0x0058, 4)}, {QMI_FIXED_INTF(0x19d2, 0x0063, 4)}, /* ZTE (Vodafone) K3565-Z */ {QMI_FIXED_INTF(0x19d2, 0x0104, 4)}, /* ZTE (Vodafone) K4505-Z */ - {QMI_FIXED_INTF(0x19d2, 0x0113, 5)}, - {QMI_FIXED_INTF(0x19d2, 0x0118, 5)}, - {QMI_FIXED_INTF(0x19d2, 0x0121, 5)}, - {QMI_FIXED_INTF(0x19d2, 0x0123, 4)}, - {QMI_FIXED_INTF(0x19d2, 0x0124, 5)}, - {QMI_FIXED_INTF(0x19d2, 0x0125, 6)}, - {QMI_FIXED_INTF(0x19d2, 0x0126, 5)}, - {QMI_FIXED_INTF(0x19d2, 0x0130, 1)}, - {QMI_FIXED_INTF(0x19d2, 0x0133, 3)}, - {QMI_FIXED_INTF(0x19d2, 0x0141, 5)}, {QMI_FIXED_INTF(0x19d2, 0x0157, 5)}, /* ZTE MF683 */ - {QMI_FIXED_INTF(0x19d2, 0x0158, 3)}, {QMI_FIXED_INTF(0x19d2, 0x0167, 4)}, /* ZTE MF820D */ - {QMI_FIXED_INTF(0x19d2, 0x0168, 4)}, - {QMI_FIXED_INTF(0x19d2, 0x0176, 3)}, - {QMI_FIXED_INTF(0x19d2, 0x0178, 3)}, - {QMI_FIXED_INTF(0x19d2, 0x0191, 4)}, /* ZTE EuFi890 */ - {QMI_FIXED_INTF(0x19d2, 0x0199, 1)}, /* ZTE MF820S */ - {QMI_FIXED_INTF(0x19d2, 0x0200, 1)}, - {QMI_FIXED_INTF(0x19d2, 0x0257, 3)}, /* ZTE MF821 */ {QMI_FIXED_INTF(0x19d2, 0x0326, 4)}, /* ZTE MF821D */ {QMI_FIXED_INTF(0x19d2, 0x1008, 4)}, /* ZTE (Vodafone) K3570-Z */ {QMI_FIXED_INTF(0x19d2, 0x1010, 4)}, /* ZTE (Vodafone) K3571-Z */ - {QMI_FIXED_INTF(0x19d2, 0x1012, 4)}, {QMI_FIXED_INTF(0x19d2, 0x1018, 3)}, /* ZTE (Vodafone) K5006-Z */ - {QMI_FIXED_INTF(0x19d2, 0x1021, 2)}, - {QMI_FIXED_INTF(0x19d2, 0x1245, 4)}, - {QMI_FIXED_INTF(0x19d2, 0x1247, 4)}, - {QMI_FIXED_INTF(0x19d2, 0x1252, 4)}, - {QMI_FIXED_INTF(0x19d2, 0x1254, 4)}, - {QMI_FIXED_INTF(0x19d2, 0x1255, 3)}, - {QMI_FIXED_INTF(0x19d2, 0x1255, 4)}, - {QMI_FIXED_INTF(0x19d2, 0x1256, 4)}, - {QMI_FIXED_INTF(0x19d2, 0x1401, 2)}, {QMI_FIXED_INTF(0x19d2, 0x1402, 2)}, /* ZTE MF60 */ - {QMI_FIXED_INTF(0x19d2, 0x1424, 2)}, - {QMI_FIXED_INTF(0x19d2, 0x1425, 2)}, - {QMI_FIXED_INTF(0x19d2, 0x1426, 2)}, /* ZTE MF91 */ {QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */ {QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)}, /* Sierra Wireless MC7700 */ {QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */ diff --git a/trunk/drivers/net/usb/smsc95xx.c b/trunk/drivers/net/usb/smsc95xx.c index 362cb8cfeb92..7479a5761d0d 100644 --- a/trunk/drivers/net/usb/smsc95xx.c +++ b/trunk/drivers/net/usb/smsc95xx.c @@ -184,7 +184,7 @@ static int smsc95xx_mdio_read(struct net_device *netdev, int phy_id, int idx) /* set the address, index & direction (read from PHY) */ phy_id &= dev->mii.phy_id_mask; idx &= dev->mii.reg_num_mask; - addr = (phy_id << 11) | (idx << 6) | MII_READ_ | MII_BUSY_; + addr = (phy_id << 11) | (idx << 6) | MII_READ_; ret = smsc95xx_write_reg(dev, MII_ADDR, addr); check_warn_goto_done(ret, "Error writing MII_ADDR"); @@ -221,7 +221,7 @@ static void smsc95xx_mdio_write(struct net_device *netdev, int phy_id, int idx, /* set the address, index & direction (write to PHY) */ phy_id &= dev->mii.phy_id_mask; idx &= dev->mii.reg_num_mask; - addr = (phy_id << 11) | (idx << 6) | MII_WRITE_ | MII_BUSY_; + addr = (phy_id << 11) | (idx << 6) | MII_WRITE_; ret = smsc95xx_write_reg(dev, MII_ADDR, addr); check_warn_goto_done(ret, "Error writing MII_ADDR"); @@ -1344,7 +1344,6 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev, } else { u32 csum_preamble = smsc95xx_calc_csum_preamble(skb); skb_push(skb, 4); - cpu_to_le32s(&csum_preamble); memcpy(skb->data, &csum_preamble, 4); } } diff --git a/trunk/drivers/net/usb/usbnet.c b/trunk/drivers/net/usb/usbnet.c index edb81ed06950..f9819d10b1f9 100644 --- a/trunk/drivers/net/usb/usbnet.c +++ b/trunk/drivers/net/usb/usbnet.c @@ -359,12 +359,10 @@ static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb, void usbnet_defer_kevent (struct usbnet *dev, int work) { set_bit (work, &dev->flags); - if (!schedule_work (&dev->kevent)) { - if (net_ratelimit()) - netdev_err(dev->net, "kevent %d may have been dropped\n", work); - } else { + if (!schedule_work (&dev->kevent)) + netdev_err(dev->net, "kevent %d may have been dropped\n", work); + else netdev_dbg(dev->net, "kevent %d scheduled\n", work); - } } EXPORT_SYMBOL_GPL(usbnet_defer_kevent); @@ -1160,7 +1158,6 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, usb_anchor_urb(urb, &dev->deferred); /* no use to process more packets */ netif_stop_queue(net); - usb_put_urb(urb); spin_unlock_irqrestore(&dev->txq.lock, flags); netdev_dbg(dev->net, "Delaying transmission for resumption\n"); goto deferred; @@ -1313,8 +1310,6 @@ void usbnet_disconnect (struct usb_interface *intf) cancel_work_sync(&dev->kevent); - usb_scuttle_anchored_urbs(&dev->deferred); - if (dev->driver_info->unbind) dev->driver_info->unbind (dev, intf); diff --git a/trunk/drivers/net/vmxnet3/vmxnet3_drv.c b/trunk/drivers/net/vmxnet3/vmxnet3_drv.c index 0ae1bcc6da73..ce9d4f2c9776 100644 --- a/trunk/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/trunk/drivers/net/vmxnet3/vmxnet3_drv.c @@ -744,43 +744,28 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; - u32 buf_size; - - buf_offset = 0; - len = skb_frag_size(frag); - while (len) { - tbi = tq->buf_info + tq->tx_ring.next2fill; - if (len < VMXNET3_MAX_TX_BUF_SIZE) { - buf_size = len; - dw2 |= len; - } else { - buf_size = VMXNET3_MAX_TX_BUF_SIZE; - /* spec says that for TxDesc.len, 0 == 2^14 */ - } - tbi->map_type = VMXNET3_MAP_PAGE; - tbi->dma_addr = skb_frag_dma_map(&adapter->pdev->dev, frag, - buf_offset, buf_size, - DMA_TO_DEVICE); - tbi->len = buf_size; + tbi = tq->buf_info + tq->tx_ring.next2fill; + tbi->map_type = VMXNET3_MAP_PAGE; + tbi->dma_addr = skb_frag_dma_map(&adapter->pdev->dev, frag, + 0, skb_frag_size(frag), + DMA_TO_DEVICE); - gdesc = tq->tx_ring.base + tq->tx_ring.next2fill; - BUG_ON(gdesc->txd.gen == tq->tx_ring.gen); + tbi->len = skb_frag_size(frag); - gdesc->txd.addr = cpu_to_le64(tbi->dma_addr); - gdesc->dword[2] = cpu_to_le32(dw2); - gdesc->dword[3] = 0; + gdesc = tq->tx_ring.base + tq->tx_ring.next2fill; + BUG_ON(gdesc->txd.gen == tq->tx_ring.gen); - dev_dbg(&adapter->netdev->dev, - "txd[%u]: 0x%llu %u %u\n", - tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr), - le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]); - vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring); - dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT; + gdesc->txd.addr = cpu_to_le64(tbi->dma_addr); + gdesc->dword[2] = cpu_to_le32(dw2 | skb_frag_size(frag)); + gdesc->dword[3] = 0; - len -= buf_size; - buf_offset += buf_size; - } + dev_dbg(&adapter->netdev->dev, + "txd[%u]: 0x%llu %u %u\n", + tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr), + le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]); + vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring); + dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT; } ctx->eop_txd = gdesc; @@ -901,18 +886,6 @@ vmxnet3_prepare_tso(struct sk_buff *skb, } } -static int txd_estimate(const struct sk_buff *skb) -{ - int count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) + 1; - int i; - - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; - - count += VMXNET3_TXD_NEEDED(skb_frag_size(frag)); - } - return count; -} /* * Transmits a pkt thru a given tq @@ -941,7 +914,9 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, union Vmxnet3_GenericDesc tempTxDesc; #endif - count = txd_estimate(skb); + /* conservatively estimate # of descriptors to use */ + count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) + + skb_shinfo(skb)->nr_frags + 1; ctx.ipv4 = (vlan_get_protocol(skb) == cpu_to_be16(ETH_P_IP)); diff --git a/trunk/drivers/net/vxlan.c b/trunk/drivers/net/vxlan.c index 8b5c61917076..607976c00162 100644 --- a/trunk/drivers/net/vxlan.c +++ b/trunk/drivers/net/vxlan.c @@ -1,5 +1,5 @@ /* - * VXLAN: Virtual eXtensible Local Area Network + * VXLAN: Virtual eXtensiable Local Area Network * * Copyright (c) 2012 Vyatta Inc. * @@ -50,8 +50,8 @@ #define VXLAN_N_VID (1u << 24) #define VXLAN_VID_MASK (VXLAN_N_VID - 1) -/* IP header + UDP + VXLAN + Ethernet header */ -#define VXLAN_HEADROOM (20 + 8 + 8 + 14) +/* VLAN + IP header + UDP + VXLAN */ +#define VXLAN_HEADROOM (4 + 20 + 8 + 8) #define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags required value. */ @@ -816,7 +816,7 @@ static void vxlan_cleanup(unsigned long arg) = container_of(p, struct vxlan_fdb, hlist); unsigned long timeout; - if (f->state & NUD_PERMANENT) + if (f->state == NUD_PERMANENT) continue; timeout = f->used + vxlan->age_interval * HZ; @@ -1102,10 +1102,6 @@ static int vxlan_newlink(struct net *net, struct net_device *dev, if (!tb[IFLA_MTU]) dev->mtu = lowerdev->mtu - VXLAN_HEADROOM; - - /* update header length based on lower device */ - dev->hard_header_len = lowerdev->hard_header_len + - VXLAN_HEADROOM; } if (data[IFLA_VXLAN_TOS]) diff --git a/trunk/drivers/net/wan/ixp4xx_hss.c b/trunk/drivers/net/wan/ixp4xx_hss.c index 760776b3d66c..3f575afd8cfc 100644 --- a/trunk/drivers/net/wan/ixp4xx_hss.c +++ b/trunk/drivers/net/wan/ixp4xx_hss.c @@ -969,12 +969,10 @@ static int init_hdlc_queues(struct port *port) { int i; - if (!ports_open) { - dma_pool = dma_pool_create(DRV_NAME, &port->netdev->dev, - POOL_ALLOC_SIZE, 32, 0); - if (!dma_pool) + if (!ports_open) + if (!(dma_pool = dma_pool_create(DRV_NAME, NULL, + POOL_ALLOC_SIZE, 32, 0))) return -ENOMEM; - } if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL, &port->desc_tab_phys))) @@ -1365,7 +1363,7 @@ static int __devinit hss_init_one(struct platform_device *pdev) platform_set_drvdata(pdev, port); - netdev_info(dev, "initialized\n"); + netdev_info(dev, "HSS-%i\n", port->id); return 0; err_free_netdev: diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index 6f7cf49eff4d..89bf94d4d8a1 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -534,107 +534,107 @@ static const u32 ar9300_2p2_baseband_core[][2] = { static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, - {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, - {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, - {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402}, - {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404}, - {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, - {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, - {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, - {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, - {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, - {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, - {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, - {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, - {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, - {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861}, - {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81}, - {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83}, - {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84}, - {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3}, - {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5}, - {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9}, - {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb}, - {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, - {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, - {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, - {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, - {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, - {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, - {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202}, + {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400}, + {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402}, + {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404}, + {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603}, + {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02}, + {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04}, + {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20}, + {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20}, + {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22}, + {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24}, + {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640}, + {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660}, + {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861}, + {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81}, + {0x0000a54c, 0x5a08442e, 0x5a08442e, 0x47001a83, 0x47001a83}, + {0x0000a550, 0x5e0a4431, 0x5e0a4431, 0x4a001c84, 0x4a001c84}, + {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3}, + {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5}, + {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9}, + {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb}, + {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, + {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, + {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, + {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, + {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, + {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, + {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, - {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, - {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, - {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402}, - {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404}, - {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, - {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, - {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, - {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, - {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, - {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, - {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, - {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, - {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, - {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861}, - {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81}, - {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83}, - {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84}, - {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3}, - {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5}, - {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9}, - {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb}, - {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, - {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, - {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, - {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, - {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, - {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, - {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a590, 0x15800028, 0x15800028, 0x0f800202, 0x0f800202}, + {0x0000a594, 0x1b80002b, 0x1b80002b, 0x12800400, 0x12800400}, + {0x0000a598, 0x1f820028, 0x1f820028, 0x16800402, 0x16800402}, + {0x0000a59c, 0x2582002b, 0x2582002b, 0x19800404, 0x19800404}, + {0x0000a5a0, 0x2a84002a, 0x2a84002a, 0x1c800603, 0x1c800603}, + {0x0000a5a4, 0x2e86002a, 0x2e86002a, 0x21800a02, 0x21800a02}, + {0x0000a5a8, 0x3382202d, 0x3382202d, 0x25800a04, 0x25800a04}, + {0x0000a5ac, 0x3884202c, 0x3884202c, 0x28800a20, 0x28800a20}, + {0x0000a5b0, 0x3c86202c, 0x3c86202c, 0x2c800e20, 0x2c800e20}, + {0x0000a5b4, 0x4188202d, 0x4188202d, 0x30800e22, 0x30800e22}, + {0x0000a5b8, 0x4586402d, 0x4586402d, 0x34800e24, 0x34800e24}, + {0x0000a5bc, 0x4986222d, 0x4986222d, 0x38801640, 0x38801640}, + {0x0000a5c0, 0x4d862231, 0x4d862231, 0x3c801660, 0x3c801660}, + {0x0000a5c4, 0x50882231, 0x50882231, 0x3f801861, 0x3f801861}, + {0x0000a5c8, 0x5688422e, 0x5688422e, 0x43801a81, 0x43801a81}, + {0x0000a5cc, 0x5a88442e, 0x5a88442e, 0x47801a83, 0x47801a83}, + {0x0000a5d0, 0x5e8a4431, 0x5e8a4431, 0x4a801c84, 0x4a801c84}, + {0x0000a5d4, 0x648a4432, 0x648a4432, 0x4e801ce3, 0x4e801ce3}, + {0x0000a5d8, 0x688a4434, 0x688a4434, 0x52801ce5, 0x52801ce5}, + {0x0000a5dc, 0x6c8a6434, 0x6c8a6434, 0x56801ce9, 0x56801ce9}, + {0x0000a5e0, 0x6f8a6633, 0x6f8a6633, 0x5a801ceb, 0x5a801ceb}, + {0x0000a5e4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, + {0x0000a5e8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, + {0x0000a5ec, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, + {0x0000a5f0, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, + {0x0000a5f4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, + {0x0000a5f8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, + {0x0000a5fc, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000}, - {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501}, - {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501}, - {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03}, - {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04}, - {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04}, - {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, - {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, - {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, - {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, - {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, - {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, - {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, + {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, + {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, + {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, + {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000}, + {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501}, + {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501}, + {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03}, + {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, + {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04}, + {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, + {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, + {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, + {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, + {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, + {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, - {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, - {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, + {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, + {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, + {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, + {0x00016048, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, + {0x00016448, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, + {0x00016848, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, }; diff --git a/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c b/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c index f5dda84176c3..924c4616c3d9 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -38,7 +38,6 @@ static struct usb_device_id ath9k_hif_usb_ids[] = { { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */ { USB_DEVICE(0x040D, 0x3801) }, /* VIA */ { USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */ - { USB_DEVICE(0x0cf3, 0xb002) }, /* Ubiquiti WifiStation */ { USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */ { USB_DEVICE(0x0cf3, 0x7015), diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.c b/trunk/drivers/net/wireless/ath/ath9k/hw.c index 1829b445d0b0..8e1559aba495 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.c @@ -1456,7 +1456,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) switch (type) { case ATH9K_RESET_POWER_ON: ret = ath9k_hw_set_reset_power_on(ah); - if (ret) + if (!ret) ah->reset_power_on = true; break; case ATH9K_RESET_WARM: diff --git a/trunk/drivers/net/wireless/ath/ath9k/xmit.c b/trunk/drivers/net/wireless/ath/ath9k/xmit.c index 741918a2027b..378bd70256b2 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/xmit.c +++ b/trunk/drivers/net/wireless/ath/ath9k/xmit.c @@ -312,7 +312,6 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) } bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); - bf->bf_next = NULL; list_del(&bf->list); spin_unlock_bh(&sc->tx.txbuflock); @@ -394,7 +393,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0, seq_first; u32 ba[WME_BA_BMP_SIZE >> 5]; int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; - bool rc_update = true, isba; + bool rc_update = true; struct ieee80211_tx_rate rates[4]; struct ath_frame_info *fi; int nframes; @@ -438,17 +437,13 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; tid = ATH_AN_2_TID(an, tidno); seq_first = tid->seq_start; - isba = ts->ts_flags & ATH9K_TX_BA; /* * The hardware occasionally sends a tx status for the wrong TID. * In this case, the BA status cannot be considered valid and all * subframes need to be retransmitted - * - * Only BlockAcks have a TID and therefore normal Acks cannot be - * checked */ - if (isba && tidno != ts->tid) + if (tidno != ts->tid) txok = false; isaggr = bf_isaggr(bf); @@ -1779,7 +1774,6 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, list_add_tail(&bf->list, &bf_head); bf->bf_state.bf_type = 0; - bf->bf_next = NULL; bf->bf_lastbf = bf; ath_tx_fill_desc(sc, bf, txq, fi->framelen); ath_tx_txqaddbuf(sc, txq, &bf_head, false); diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c index c5a99c8c8168..73730e94e0ac 100644 --- a/trunk/drivers/net/wireless/b43/main.c +++ b/trunk/drivers/net/wireless/b43/main.c @@ -5404,8 +5404,6 @@ static void b43_bcma_remove(struct bcma_device *core) cancel_work_sync(&wldev->restart_work); B43_WARN_ON(!wl); - if (!wldev->fw.ucode.data) - return; /* NULL if firmware never loaded */ if (wl->current_dev == wldev && wl->hw_registred) { b43_leds_stop(wldev); ieee80211_unregister_hw(wl->hw); @@ -5480,8 +5478,6 @@ static void b43_ssb_remove(struct ssb_device *sdev) cancel_work_sync(&wldev->restart_work); B43_WARN_ON(!wl); - if (!wldev->fw.ucode.data) - return; /* NULL if firmware never loaded */ if (wl->current_dev == wldev && wl->hw_registred) { b43_leds_stop(wldev); ieee80211_unregister_hw(wl->hw); diff --git a/trunk/drivers/net/wireless/b43legacy/pio.c b/trunk/drivers/net/wireless/b43legacy/pio.c index 282eedec675e..192251adf986 100644 --- a/trunk/drivers/net/wireless/b43legacy/pio.c +++ b/trunk/drivers/net/wireless/b43legacy/pio.c @@ -382,7 +382,7 @@ static void cancel_transfers(struct b43legacy_pioqueue *queue) { struct b43legacy_pio_txpacket *packet, *tmp_packet; - tasklet_kill(&queue->txtask); + tasklet_disable(&queue->txtask); list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list) free_txpacket(packet, 0); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 7a6dfdc67b6c..a2b4b1e71017 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -1339,7 +1339,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo, } ret = brcmf_bus_start(dev); - if (ret) { + if (ret == -ENOLINK) { brcmf_dbg(ERROR, "dongle is not responding\n"); brcmf_detach(dev); goto fail; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 481345c23ded..c1abaa6db59e 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -3569,7 +3569,7 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy, if (!request || !request->n_ssids || !request->n_match_sets) { WL_ERR("Invalid sched scan req!! n_ssids:%d\n", - request ? request->n_ssids : 0); + request->n_ssids); return -EINVAL; } @@ -3972,7 +3972,7 @@ brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg, u8 *iovar_ie_buf; u8 *curr_ie_buf; u8 *mgmt_ie_buf = NULL; - int mgmt_ie_buf_len; + u32 mgmt_ie_buf_len = 0; u32 *mgmt_ie_len = 0; u32 del_add_ie_buf_len = 0; u32 total_ie_buf_len = 0; @@ -3982,7 +3982,7 @@ brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg, struct parsed_vndr_ie_info *vndrie_info; s32 i; u8 *ptr; - int remained_buf_len; + u32 remained_buf_len; WL_TRACE("bssidx %d, pktflag : 0x%02X\n", bssidx, pktflag); iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); @@ -4401,7 +4401,7 @@ static s32 brcmf_mode_to_nl80211_iftype(s32 mode) static void brcmf_wiphy_pno_params(struct wiphy *wiphy) { -#ifndef CONFIG_BRCMISCAN +#ifndef CONFIG_BRCMFISCAN /* scheduled scan settings */ wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT; wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT; @@ -4606,13 +4606,12 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, struct brcmf_cfg80211_profile *profile = cfg->profile; struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); struct wiphy *wiphy = cfg_to_wiphy(cfg); - struct ieee80211_channel *notify_channel = NULL; + struct brcmf_channel_info_le channel_le; + struct ieee80211_channel *notify_channel; struct ieee80211_supported_band *band; - struct brcmf_bss_info_le *bi; u32 freq; s32 err = 0; u32 target_channel; - u8 *buf; WL_TRACE("Enter\n"); @@ -4620,22 +4619,11 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, memcpy(profile->bssid, e->addr, ETH_ALEN); brcmf_update_bss_info(cfg); - buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); - if (buf == NULL) { - err = -ENOMEM; - goto done; - } + brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le, + sizeof(channel_le)); - /* data sent to dongle has to be little endian */ - *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX); - err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX); - - if (err) - goto done; - - bi = (struct brcmf_bss_info_le *)(buf + 4); - target_channel = bi->ctl_ch ? bi->ctl_ch : - CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); + target_channel = le32_to_cpu(channel_le.target_channel); + WL_CONN("Roamed to channel %d\n", target_channel); if (target_channel <= CH_MAX_2G_CHANNEL) band = wiphy->bands[IEEE80211_BAND_2GHZ]; @@ -4645,8 +4633,6 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, freq = ieee80211_channel_to_frequency(target_channel, band->band); notify_channel = ieee80211_get_channel(wiphy, freq); -done: - kfree(buf); cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid, conn_info->req_ie, conn_info->req_ie_len, conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); @@ -5200,6 +5186,41 @@ brcmf_cfg80211_event(struct net_device *ndev, schedule_work(&cfg->event_work); } +static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype) +{ + s32 infra = 0; + s32 err = 0; + + switch (iftype) { + case NL80211_IFTYPE_MONITOR: + case NL80211_IFTYPE_WDS: + WL_ERR("type (%d) : currently we do not support this mode\n", + iftype); + err = -EINVAL; + return err; + case NL80211_IFTYPE_ADHOC: + infra = 0; + break; + case NL80211_IFTYPE_STATION: + infra = 1; + break; + case NL80211_IFTYPE_AP: + infra = 1; + break; + default: + err = -EINVAL; + WL_ERR("invalid type (%d)\n", iftype); + return err; + } + err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra); + if (err) { + WL_ERR("WLC_SET_INFRA error (%d)\n", err); + return err; + } + + return 0; +} + static s32 brcmf_dongle_eventmsg(struct net_device *ndev) { /* Room for "event_msgs" + '\0' + bitvec */ @@ -5418,8 +5439,7 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) WL_BEACON_TIMEOUT); if (err) goto default_conf_out; - err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype, - NULL, NULL); + err = brcmf_dongle_mode(ndev, wdev->iftype); if (err && err != -EINPROGRESS) goto default_conf_out; err = brcmf_dongle_probecap(cfg); diff --git a/trunk/drivers/net/wireless/ipw2x00/ipw2200.c b/trunk/drivers/net/wireless/ipw2x00/ipw2200.c index 768bf612533e..935120fc8c93 100644 --- a/trunk/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/trunk/drivers/net/wireless/ipw2x00/ipw2200.c @@ -10472,7 +10472,7 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv, } else len = src->len; - dst = alloc_skb(len + sizeof(*rt_hdr) + sizeof(u16)*2, GFP_ATOMIC); + dst = alloc_skb(len + sizeof(*rt_hdr), GFP_ATOMIC); if (!dst) continue; diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/devices.c b/trunk/drivers/net/wireless/iwlwifi/dvm/devices.c index da5862064195..349c205d5f62 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/devices.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/devices.c @@ -518,7 +518,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, * See iwlagn_mac_channel_switch. */ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - struct iwl6000_channel_switch_cmd *cmd; + struct iwl6000_channel_switch_cmd cmd; u32 switch_time_in_usec, ucode_switch_time; u16 ch; u32 tsf_low; @@ -527,25 +527,18 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, struct ieee80211_vif *vif = ctx->vif; struct iwl_host_cmd hcmd = { .id = REPLY_CHANNEL_SWITCH, - .len = { sizeof(*cmd), }, + .len = { sizeof(cmd), }, .flags = CMD_SYNC, - .dataflags[0] = IWL_HCMD_DFL_NOCOPY, + .data = { &cmd, }, }; - int err; - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) - return -ENOMEM; - - hcmd.data[0] = cmd; - cmd->band = priv->band == IEEE80211_BAND_2GHZ; + cmd.band = priv->band == IEEE80211_BAND_2GHZ; ch = ch_switch->channel->hw_value; IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", ctx->active.channel, ch); - cmd->channel = cpu_to_le16(ch); - cmd->rxon_flags = ctx->staging.flags; - cmd->rxon_filter_flags = ctx->staging.filter_flags; + cmd.channel = cpu_to_le16(ch); + cmd.rxon_flags = ctx->staging.flags; + cmd.rxon_filter_flags = ctx->staging.filter_flags; switch_count = ch_switch->count; tsf_low = ch_switch->timestamp & 0x0ffffffff; /* @@ -561,25 +554,23 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, switch_count = 0; } if (switch_count <= 1) - cmd->switch_time = cpu_to_le32(priv->ucode_beacon_time); + cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); else { switch_time_in_usec = vif->bss_conf.beacon_int * switch_count * TIME_UNIT; ucode_switch_time = iwl_usecs_to_beacons(priv, switch_time_in_usec, beacon_interval); - cmd->switch_time = iwl_add_beacon_time(priv, - priv->ucode_beacon_time, - ucode_switch_time, - beacon_interval); + cmd.switch_time = iwl_add_beacon_time(priv, + priv->ucode_beacon_time, + ucode_switch_time, + beacon_interval); } IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", - cmd->switch_time); - cmd->expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; + cmd.switch_time); + cmd.expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; - err = iwl_dvm_send_cmd(priv, &hcmd); - kfree(cmd); - return err; + return iwl_dvm_send_cmd(priv, &hcmd); } struct iwl_lib_ops iwl6000_lib = { diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c index 2d9eee93c743..ff8162d4c454 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -521,7 +521,7 @@ static void iwlagn_mac_tx(struct ieee80211_hw *hw, ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); if (iwlagn_tx_skb(priv, control->sta, skb)) - ieee80211_free_txskb(hw, skb); + dev_kfree_skb_any(skb); } static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, @@ -1354,20 +1354,6 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, vif_priv->ctx = ctx; ctx->vif = vif; - /* - * In SNIFFER device type, the firmware reports the FCS to - * the host, rather than snipping it off. Unfortunately, - * mac80211 doesn't (yet) provide a per-packet flag for - * this, so that we have to set the hardware flag based - * on the interfaces added. As the monitor interface can - * only be present by itself, and will be removed before - * other interfaces are added, this is safe. - */ - if (vif->type == NL80211_IFTYPE_MONITOR) - priv->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS; - else - priv->hw->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS; - err = iwl_setup_interface(priv, ctx); if (!err || reset) goto out; diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/main.c b/trunk/drivers/net/wireless/iwlwifi/dvm/main.c index 408132cf83c1..7ff3f1430678 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/main.c @@ -2114,7 +2114,7 @@ static void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) info = IEEE80211_SKB_CB(skb); iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); - ieee80211_free_txskb(priv->hw, skb); + dev_kfree_skb_any(skb); } static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c b/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c index 2830ea290502..10896393e5a0 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c @@ -1012,12 +1012,12 @@ static void iwl_calc_basic_rates(struct iwl_priv *priv, * As a consequence, it's not as complicated as it sounds, just add * any lower rates to the ACK rate bitmap. */ - if (IWL_RATE_11M_INDEX < lowest_present_cck) - cck |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE; - if (IWL_RATE_5M_INDEX < lowest_present_cck) - cck |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE; - if (IWL_RATE_2M_INDEX < lowest_present_cck) - cck |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE; + if (IWL_RATE_11M_INDEX < lowest_present_ofdm) + ofdm |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE; + if (IWL_RATE_5M_INDEX < lowest_present_ofdm) + ofdm |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE; + if (IWL_RATE_2M_INDEX < lowest_present_ofdm) + ofdm |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE; /* 1M already there or needed so always add */ cck |= IWL_RATE_1M_MASK >> IWL_FIRST_CCK_RATE; diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c b/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c index bb69f8f90b3b..17c8e5d82681 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c @@ -321,14 +321,6 @@ static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority) dma_map_page(trans->dev, page, 0, PAGE_SIZE << trans_pcie->rx_page_order, DMA_FROM_DEVICE); - if (dma_mapping_error(trans->dev, rxb->page_dma)) { - rxb->page = NULL; - spin_lock_irqsave(&rxq->lock, flags); - list_add(&rxb->list, &rxq->rx_used); - spin_unlock_irqrestore(&rxq->lock, flags); - __free_pages(page, trans_pcie->rx_page_order); - return; - } /* dma address must be no more than 36 bits */ BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); /* and also 256 byte aligned! */ @@ -496,19 +488,8 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, dma_map_page(trans->dev, rxb->page, 0, PAGE_SIZE << trans_pcie->rx_page_order, DMA_FROM_DEVICE); - if (dma_mapping_error(trans->dev, rxb->page_dma)) { - /* - * free the page(s) as well to not break - * the invariant that the items on the used - * list have no page(s) - */ - __free_pages(rxb->page, trans_pcie->rx_page_order); - rxb->page = NULL; - list_add_tail(&rxb->list, &rxq->rx_used); - } else { - list_add_tail(&rxb->list, &rxq->rx_free); - rxq->free_count++; - } + list_add_tail(&rxb->list, &rxq->rx_free); + rxq->free_count++; } else list_add_tail(&rxb->list, &rxq->rx_used); spin_unlock_irqrestore(&rxq->lock, flags); diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c b/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c index 79a4ddc002d3..105e3af3c621 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -480,12 +480,20 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + u16 rd_ptr, wr_ptr; + int n_bd = trans_pcie->txq[txq_id].q.n_bd; if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) { WARN_ONCE(1, "queue %d not used", txq_id); return; } + rd_ptr = iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) & (n_bd - 1); + wr_ptr = iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id)); + + WARN_ONCE(rd_ptr != wr_ptr, "queue %d isn't empty: [%d,%d]", + txq_id, rd_ptr, wr_ptr); + iwl_txq_set_inactive(trans, txq_id); IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); } diff --git a/trunk/drivers/net/wireless/mwifiex/cfg80211.c b/trunk/drivers/net/wireless/mwifiex/cfg80211.c index 780d3e168297..0679458a1bac 100644 --- a/trunk/drivers/net/wireless/mwifiex/cfg80211.c +++ b/trunk/drivers/net/wireless/mwifiex/cfg80211.c @@ -1825,6 +1825,8 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, return -EBUSY; } + priv->scan_request = request; + priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL); if (!priv->user_scan_cfg) { @@ -1832,8 +1834,6 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, return -ENOMEM; } - priv->scan_request = request; - priv->user_scan_cfg->num_ssids = request->n_ssids; priv->user_scan_cfg->ssid_list = request->ssids; @@ -1870,9 +1870,6 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, ret = mwifiex_scan_networks(priv, priv->user_scan_cfg); if (ret) { dev_err(priv->adapter->dev, "scan failed: %d\n", ret); - priv->scan_request = NULL; - kfree(priv->user_scan_cfg); - priv->user_scan_cfg = NULL; return ret; } diff --git a/trunk/drivers/net/wireless/mwifiex/cmdevt.c b/trunk/drivers/net/wireless/mwifiex/cmdevt.c index ae9010ed58de..8d465107f52b 100644 --- a/trunk/drivers/net/wireless/mwifiex/cmdevt.c +++ b/trunk/drivers/net/wireless/mwifiex/cmdevt.c @@ -890,6 +890,9 @@ mwifiex_cmd_timeout_func(unsigned long function_context) return; } cmd_node = adapter->curr_cmd; + if (cmd_node->wait_q_enabled) + adapter->cmd_wait_q.status = -ETIMEDOUT; + if (cmd_node) { adapter->dbg.timeout_cmd_id = adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index]; @@ -935,14 +938,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context) dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n", adapter->ps_mode, adapter->ps_state); - - if (cmd_node->wait_q_enabled) { - adapter->cmd_wait_q.status = -ETIMEDOUT; - wake_up_interruptible(&adapter->cmd_wait_q.wait); - mwifiex_cancel_pending_ioctl(adapter); - /* reset cmd_sent flag to unblock new commands */ - adapter->cmd_sent = false; - } } if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) mwifiex_init_fw_complete(adapter); diff --git a/trunk/drivers/net/wireless/mwifiex/scan.c b/trunk/drivers/net/wireless/mwifiex/scan.c index 9171aaedbccd..00b658d3b6ec 100644 --- a/trunk/drivers/net/wireless/mwifiex/scan.c +++ b/trunk/drivers/net/wireless/mwifiex/scan.c @@ -1843,18 +1843,21 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, struct cfg80211_ssid *req_ssid) { struct mwifiex_adapter *adapter = priv->adapter; - int ret; + int ret = 0; struct mwifiex_user_scan_cfg *scan_cfg; + if (!req_ssid) + return -1; + if (adapter->scan_processing) { - dev_err(adapter->dev, "cmd: Scan already in process...\n"); - return -EBUSY; + dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); + return ret; } if (priv->scan_block) { - dev_err(adapter->dev, + dev_dbg(adapter->dev, "cmd: Scan is blocked during association...\n"); - return -EBUSY; + return ret; } scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL); diff --git a/trunk/drivers/net/wireless/mwifiex/sdio.c b/trunk/drivers/net/wireless/mwifiex/sdio.c index 82cf0fa2d9f6..fc8a9bfa1248 100644 --- a/trunk/drivers/net/wireless/mwifiex/sdio.c +++ b/trunk/drivers/net/wireless/mwifiex/sdio.c @@ -161,6 +161,7 @@ static int mwifiex_sdio_suspend(struct device *dev) struct sdio_mmc_card *card; struct mwifiex_adapter *adapter; mmc_pm_flag_t pm_flag = 0; + int hs_actived = 0; int i; int ret = 0; @@ -187,14 +188,12 @@ static int mwifiex_sdio_suspend(struct device *dev) adapter = card->adapter; /* Enable the Host Sleep */ - if (!mwifiex_enable_hs(adapter)) { - dev_err(adapter->dev, "cmd: failed to suspend\n"); - return -EFAULT; + hs_actived = mwifiex_enable_hs(adapter); + if (hs_actived) { + pr_debug("cmd: suspend with MMC_PM_KEEP_POWER\n"); + ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); } - dev_dbg(adapter->dev, "cmd: suspend with MMC_PM_KEEP_POWER\n"); - ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); - /* Indicate device suspended */ adapter->is_suspended = true; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2500usb.c b/trunk/drivers/net/wireless/rt2x00/rt2500usb.c index 6b2e1e431dd2..a12e84f892be 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1988,7 +1988,6 @@ static struct usb_driver rt2500usb_driver = { .disconnect = rt2x00usb_disconnect, .suspend = rt2x00usb_suspend, .resume = rt2x00usb_resume, - .reset_resume = rt2x00usb_resume, .disable_hub_initiated_lpm = 1, }; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c index 59474ae0aec0..01dc8891070c 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2449,7 +2449,7 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev) /* * Check if temperature compensation is supported. */ - if (tssi_bounds[4] == 0xff || step == 0xff) + if (tssi_bounds[4] == 0xff) return 0; /* diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800usb.c b/trunk/drivers/net/wireless/rt2x00/rt2800usb.c index 3b8fb5a603f2..c9e9370eb789 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800usb.c @@ -1282,7 +1282,6 @@ static struct usb_driver rt2800usb_driver = { .disconnect = rt2x00usb_disconnect, .suspend = rt2x00usb_suspend, .resume = rt2x00usb_resume, - .reset_resume = rt2x00usb_resume, .disable_hub_initiated_lpm = 1, }; diff --git a/trunk/drivers/net/wireless/rt2x00/rt73usb.c b/trunk/drivers/net/wireless/rt2x00/rt73usb.c index 24eec66e9fd2..e5eb43b3eee7 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt73usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt73usb.c @@ -2535,7 +2535,6 @@ static struct usb_driver rt73usb_driver = { .disconnect = rt2x00usb_disconnect, .suspend = rt2x00usb_suspend, .resume = rt2x00usb_resume, - .reset_resume = rt2x00usb_resume, .disable_hub_initiated_lpm = 1, }; diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index b7e6607e6b6d..9970c2b1b199 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -297,7 +297,6 @@ static struct usb_device_id rtl8192c_usb_ids[] = { /*=== Customer ID ===*/ /****** 8188CU ********/ {RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/ - {RTL_USB_DEVICE(0x050d, 0x11f2, rtl92cu_hal_cfg)}, /*Belkin - ISY*/ {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ diff --git a/trunk/drivers/net/wireless/rtlwifi/usb.c b/trunk/drivers/net/wireless/rtlwifi/usb.c index e3ea4b346889..030beb45d8b0 100644 --- a/trunk/drivers/net/wireless/rtlwifi/usb.c +++ b/trunk/drivers/net/wireless/rtlwifi/usb.c @@ -673,7 +673,7 @@ static int rtl_usb_start(struct ieee80211_hw *hw) set_hal_start(rtlhal); /* Start bulk IN */ - err = _rtl_usb_receive(hw); + _rtl_usb_receive(hw); } return err; diff --git a/trunk/drivers/net/xen-netfront.c b/trunk/drivers/net/xen-netfront.c index fc24eb9b3948..caa011008cd0 100644 --- a/trunk/drivers/net/xen-netfront.c +++ b/trunk/drivers/net/xen-netfront.c @@ -452,85 +452,29 @@ static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev, /* Grant backend access to each skb fragment page. */ for (i = 0; i < frags; i++) { skb_frag_t *frag = skb_shinfo(skb)->frags + i; - struct page *page = skb_frag_page(frag); - len = skb_frag_size(frag); - offset = frag->page_offset; - - /* Data must not cross a page boundary. */ - BUG_ON(len + offset > PAGE_SIZE<> PAGE_SHIFT; - offset &= ~PAGE_MASK; - - while (len > 0) { - unsigned long bytes; - - BUG_ON(offset >= PAGE_SIZE); - - bytes = PAGE_SIZE - offset; - if (bytes > len) - bytes = len; - - tx->flags |= XEN_NETTXF_more_data; - - id = get_id_from_freelist(&np->tx_skb_freelist, - np->tx_skbs); - np->tx_skbs[id].skb = skb_get(skb); - tx = RING_GET_REQUEST(&np->tx, prod++); - tx->id = id; - ref = gnttab_claim_grant_reference(&np->gref_tx_head); - BUG_ON((signed short)ref < 0); - - mfn = pfn_to_mfn(page_to_pfn(page)); - gnttab_grant_foreign_access_ref(ref, - np->xbdev->otherend_id, - mfn, GNTMAP_readonly); + tx->flags |= XEN_NETTXF_more_data; - tx->gref = np->grant_tx_ref[id] = ref; - tx->offset = offset; - tx->size = bytes; - tx->flags = 0; + id = get_id_from_freelist(&np->tx_skb_freelist, np->tx_skbs); + np->tx_skbs[id].skb = skb_get(skb); + tx = RING_GET_REQUEST(&np->tx, prod++); + tx->id = id; + ref = gnttab_claim_grant_reference(&np->gref_tx_head); + BUG_ON((signed short)ref < 0); - offset += bytes; - len -= bytes; + mfn = pfn_to_mfn(page_to_pfn(skb_frag_page(frag))); + gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id, + mfn, GNTMAP_readonly); - /* Next frame */ - if (offset == PAGE_SIZE && len) { - BUG_ON(!PageCompound(page)); - page++; - offset = 0; - } - } + tx->gref = np->grant_tx_ref[id] = ref; + tx->offset = frag->page_offset; + tx->size = skb_frag_size(frag); + tx->flags = 0; } np->tx.req_prod_pvt = prod; } -/* - * Count how many ring slots are required to send the frags of this - * skb. Each frag might be a compound page. - */ -static int xennet_count_skb_frag_slots(struct sk_buff *skb) -{ - int i, frags = skb_shinfo(skb)->nr_frags; - int pages = 0; - - for (i = 0; i < frags; i++) { - skb_frag_t *frag = skb_shinfo(skb)->frags + i; - unsigned long size = skb_frag_size(frag); - unsigned long offset = frag->page_offset; - - /* Skip unused frames from start of page */ - offset &= ~PAGE_MASK; - - pages += PFN_UP(offset + size); - } - - return pages; -} - static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned short id; @@ -543,23 +487,23 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) grant_ref_t ref; unsigned long mfn; int notify; - int slots; + int frags = skb_shinfo(skb)->nr_frags; unsigned int offset = offset_in_page(data); unsigned int len = skb_headlen(skb); unsigned long flags; - slots = DIV_ROUND_UP(offset + len, PAGE_SIZE) + - xennet_count_skb_frag_slots(skb); - if (unlikely(slots > MAX_SKB_FRAGS + 1)) { - net_alert_ratelimited( - "xennet: skb rides the rocket: %d slots\n", slots); + frags += DIV_ROUND_UP(offset + len, PAGE_SIZE); + if (unlikely(frags > MAX_SKB_FRAGS + 1)) { + printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n", + frags); + dump_stack(); goto drop; } spin_lock_irqsave(&np->tx_lock, flags); if (unlikely(!netif_carrier_ok(dev) || - (slots > 1 && !xennet_can_sg(dev)) || + (frags > 1 && !xennet_can_sg(dev)) || netif_needs_gso(skb, netif_skb_features(skb)))) { spin_unlock_irqrestore(&np->tx_lock, flags); goto drop; diff --git a/trunk/drivers/nfc/pn533.c b/trunk/drivers/nfc/pn533.c index 30ae18a03a9c..97c440a8cd61 100644 --- a/trunk/drivers/nfc/pn533.c +++ b/trunk/drivers/nfc/pn533.c @@ -698,14 +698,13 @@ static void pn533_wq_cmd(struct work_struct *work) cmd = list_first_entry(&dev->cmd_queue, struct pn533_cmd, queue); - list_del(&cmd->queue); - mutex_unlock(&dev->cmd_lock); __pn533_send_cmd_frame_async(dev, cmd->out_frame, cmd->in_frame, cmd->in_frame_len, cmd->cmd_complete, cmd->arg, cmd->flags); + list_del(&cmd->queue); kfree(cmd); } @@ -1679,14 +1678,11 @@ static void pn533_deactivate_target(struct nfc_dev *nfc_dev, static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, u8 *params, int params_len) { + struct pn533_cmd_jump_dep *cmd; struct pn533_cmd_jump_dep_response *resp; struct nfc_target nfc_target; u8 target_gt_len; int rc; - struct pn533_cmd_jump_dep *cmd = (struct pn533_cmd_jump_dep *)arg; - u8 active = cmd->active; - - kfree(arg); if (params_len == -ENOENT) { nfc_dev_dbg(&dev->interface->dev, ""); @@ -1708,6 +1704,7 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, } resp = (struct pn533_cmd_jump_dep_response *) params; + cmd = (struct pn533_cmd_jump_dep *) arg; rc = resp->status & PN533_CMD_RET_MASK; if (rc != PN533_CMD_RET_SUCCESS) { nfc_dev_err(&dev->interface->dev, @@ -1737,7 +1734,7 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, if (rc == 0) rc = nfc_dep_link_is_up(dev->nfc_dev, dev->nfc_dev->targets[0].idx, - !active, NFC_RF_INITIATOR); + !cmd->active, NFC_RF_INITIATOR); return 0; } @@ -1822,8 +1819,12 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, dev->in_maxlen, pn533_in_dep_link_up_complete, cmd, GFP_KERNEL); - if (rc < 0) - kfree(cmd); + if (rc) + goto out; + + +out: + kfree(cmd); return rc; } @@ -2077,12 +2078,8 @@ static int pn533_transceive(struct nfc_dev *nfc_dev, static int pn533_tm_send_complete(struct pn533 *dev, void *arg, u8 *params, int params_len) { - struct sk_buff *skb_out = arg; - nfc_dev_dbg(&dev->interface->dev, "%s", __func__); - dev_kfree_skb(skb_out); - if (params_len < 0) { nfc_dev_err(&dev->interface->dev, "Error %d when sending data", @@ -2120,7 +2117,7 @@ static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb) rc = pn533_send_cmd_frame_async(dev, out_frame, dev->in_frame, dev->in_maxlen, pn533_tm_send_complete, - skb, GFP_KERNEL); + NULL, GFP_KERNEL); if (rc) { nfc_dev_err(&dev->interface->dev, "Error %d when trying to send data", rc); diff --git a/trunk/drivers/pci/bus.c b/trunk/drivers/pci/bus.c index a543746fb354..6241fd05bd41 100644 --- a/trunk/drivers/pci/bus.c +++ b/trunk/drivers/pci/bus.c @@ -320,7 +320,10 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), } else next = dev->bus_list.next; + /* Run device routines with the device locked */ + device_lock(&dev->dev); retval = cb(dev, userdata); + device_unlock(&dev->dev); if (retval) break; } diff --git a/trunk/drivers/pci/pci-driver.c b/trunk/drivers/pci/pci-driver.c index 6c94fc9489e7..94c6e2aa03d6 100644 --- a/trunk/drivers/pci/pci-driver.c +++ b/trunk/drivers/pci/pci-driver.c @@ -398,8 +398,6 @@ static void pci_device_shutdown(struct device *dev) struct pci_dev *pci_dev = to_pci_dev(dev); struct pci_driver *drv = pci_dev->driver; - pm_runtime_resume(dev); - if (drv && drv->shutdown) drv->shutdown(pci_dev); pci_msi_shutdown(pci_dev); @@ -410,6 +408,16 @@ static void pci_device_shutdown(struct device *dev) * continue to do DMA */ pci_disable_device(pci_dev); + + /* + * Devices may be enabled to wake up by runtime PM, but they need not + * be supposed to wake up the system from its "power off" state (e.g. + * ACPI S5). Therefore disable wakeup for all devices that aren't + * supposed to wake up the system at this point. The state argument + * will be ignored by pci_enable_wake(). + */ + if (!device_may_wakeup(dev)) + pci_enable_wake(pci_dev, PCI_UNKNOWN, false); } #ifdef CONFIG_PM diff --git a/trunk/drivers/pci/pci-sysfs.c b/trunk/drivers/pci/pci-sysfs.c index f39378d9da15..02d107b15281 100644 --- a/trunk/drivers/pci/pci-sysfs.c +++ b/trunk/drivers/pci/pci-sysfs.c @@ -458,6 +458,40 @@ boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf) } struct device_attribute vga_attr = __ATTR_RO(boot_vga); +static void +pci_config_pm_runtime_get(struct pci_dev *pdev) +{ + struct device *dev = &pdev->dev; + struct device *parent = dev->parent; + + if (parent) + pm_runtime_get_sync(parent); + pm_runtime_get_noresume(dev); + /* + * pdev->current_state is set to PCI_D3cold during suspending, + * so wait until suspending completes + */ + pm_runtime_barrier(dev); + /* + * Only need to resume devices in D3cold, because config + * registers are still accessible for devices suspended but + * not in D3cold. + */ + if (pdev->current_state == PCI_D3cold) + pm_runtime_resume(dev); +} + +static void +pci_config_pm_runtime_put(struct pci_dev *pdev) +{ + struct device *dev = &pdev->dev; + struct device *parent = dev->parent; + + pm_runtime_put(dev); + if (parent) + pm_runtime_put_sync(parent); +} + static ssize_t pci_read_config(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index aabf64798bda..54858838f098 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -1858,38 +1858,6 @@ bool pci_dev_run_wake(struct pci_dev *dev) } EXPORT_SYMBOL_GPL(pci_dev_run_wake); -void pci_config_pm_runtime_get(struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - struct device *parent = dev->parent; - - if (parent) - pm_runtime_get_sync(parent); - pm_runtime_get_noresume(dev); - /* - * pdev->current_state is set to PCI_D3cold during suspending, - * so wait until suspending completes - */ - pm_runtime_barrier(dev); - /* - * Only need to resume devices in D3cold, because config - * registers are still accessible for devices suspended but - * not in D3cold. - */ - if (pdev->current_state == PCI_D3cold) - pm_runtime_resume(dev); -} - -void pci_config_pm_runtime_put(struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - struct device *parent = dev->parent; - - pm_runtime_put(dev); - if (parent) - pm_runtime_put_sync(parent); -} - /** * pci_pm_init - Initialize PM functions of given PCI device * @dev: PCI device to handle. diff --git a/trunk/drivers/pci/pci.h b/trunk/drivers/pci/pci.h index fd92aab9904b..bacbcba69cf3 100644 --- a/trunk/drivers/pci/pci.h +++ b/trunk/drivers/pci/pci.h @@ -72,8 +72,6 @@ extern void pci_disable_enabled_device(struct pci_dev *dev); extern int pci_finish_runtime_suspend(struct pci_dev *dev); extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); extern void pci_wakeup_bus(struct pci_bus *bus); -extern void pci_config_pm_runtime_get(struct pci_dev *dev); -extern void pci_config_pm_runtime_put(struct pci_dev *dev); extern void pci_pm_init(struct pci_dev *dev); extern void platform_pci_wakeup_init(struct pci_dev *dev); extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_core.c b/trunk/drivers/pci/pcie/aer/aerdrv_core.c index af4e31cd3a3b..06bad96af415 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv_core.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv_core.c @@ -213,7 +213,6 @@ static int report_error_detected(struct pci_dev *dev, void *data) struct aer_broadcast_data *result_data; result_data = (struct aer_broadcast_data *) data; - device_lock(&dev->dev); dev->error_state = result_data->state; if (!dev->driver || @@ -232,14 +231,12 @@ static int report_error_detected(struct pci_dev *dev, void *data) dev->driver ? "no AER-aware driver" : "no driver"); } - goto out; + return 0; } err_handler = dev->driver->err_handler; vote = err_handler->error_detected(dev, result_data->state); result_data->result = merge_result(result_data->result, vote); -out: - device_unlock(&dev->dev); return 0; } @@ -250,17 +247,14 @@ static int report_mmio_enabled(struct pci_dev *dev, void *data) struct aer_broadcast_data *result_data; result_data = (struct aer_broadcast_data *) data; - device_lock(&dev->dev); if (!dev->driver || !dev->driver->err_handler || !dev->driver->err_handler->mmio_enabled) - goto out; + return 0; err_handler = dev->driver->err_handler; vote = err_handler->mmio_enabled(dev); result_data->result = merge_result(result_data->result, vote); -out: - device_unlock(&dev->dev); return 0; } @@ -271,17 +265,14 @@ static int report_slot_reset(struct pci_dev *dev, void *data) struct aer_broadcast_data *result_data; result_data = (struct aer_broadcast_data *) data; - device_lock(&dev->dev); if (!dev->driver || !dev->driver->err_handler || !dev->driver->err_handler->slot_reset) - goto out; + return 0; err_handler = dev->driver->err_handler; vote = err_handler->slot_reset(dev); result_data->result = merge_result(result_data->result, vote); -out: - device_unlock(&dev->dev); return 0; } @@ -289,18 +280,15 @@ static int report_resume(struct pci_dev *dev, void *data) { const struct pci_error_handlers *err_handler; - device_lock(&dev->dev); dev->error_state = pci_channel_io_normal; if (!dev->driver || !dev->driver->err_handler || !dev->driver->err_handler->resume) - goto out; + return 0; err_handler = dev->driver->err_handler; err_handler->resume(dev); -out: - device_unlock(&dev->dev); return 0; } diff --git a/trunk/drivers/pci/pcie/portdrv_core.c b/trunk/drivers/pci/pcie/portdrv_core.c index ed129b414624..d03a7a39b2d8 100644 --- a/trunk/drivers/pci/pcie/portdrv_core.c +++ b/trunk/drivers/pci/pcie/portdrv_core.c @@ -272,8 +272,7 @@ static int get_port_device_capability(struct pci_dev *dev) } /* Hot-Plug Capable */ - if ((cap_mask & PCIE_PORT_SERVICE_HP) && - dev->pcie_flags_reg & PCI_EXP_FLAGS_SLOT) { + if (cap_mask & PCIE_PORT_SERVICE_HP) { pcie_capability_read_dword(dev, PCI_EXP_SLTCAP, ®32); if (reg32 & PCI_EXP_SLTCAP_HPC) { services |= PCIE_PORT_SERVICE_HP; diff --git a/trunk/drivers/pci/proc.c b/trunk/drivers/pci/proc.c index 9b8505ccc56d..eb907a8faf2a 100644 --- a/trunk/drivers/pci/proc.c +++ b/trunk/drivers/pci/proc.c @@ -76,8 +76,6 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp if (!access_ok(VERIFY_WRITE, buf, cnt)) return -EINVAL; - pci_config_pm_runtime_get(dev); - if ((pos & 1) && cnt) { unsigned char val; pci_user_read_config_byte(dev, pos, &val); @@ -123,8 +121,6 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp cnt--; } - pci_config_pm_runtime_put(dev); - *ppos = pos; return nbytes; } @@ -150,8 +146,6 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof if (!access_ok(VERIFY_READ, buf, cnt)) return -EINVAL; - pci_config_pm_runtime_get(dev); - if ((pos & 1) && cnt) { unsigned char val; __get_user(val, buf); @@ -197,8 +191,6 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof cnt--; } - pci_config_pm_runtime_put(dev); - *ppos = pos; i_size_write(ino, dp->size); return nbytes; diff --git a/trunk/drivers/pinctrl/Kconfig b/trunk/drivers/pinctrl/Kconfig index 390ab69ea569..7bf914df6e91 100644 --- a/trunk/drivers/pinctrl/Kconfig +++ b/trunk/drivers/pinctrl/Kconfig @@ -26,15 +26,6 @@ config DEBUG_PINCTRL help Say Y here to add some extra checks and diagnostics to PINCTRL calls. -config PINCTRL_AT91 - bool "AT91 pinctrl driver" - depends on OF - depends on ARCH_AT91 - select PINMUX - select PINCONF - help - Say Y here to enable the at91 pinctrl driver - config PINCTRL_BCM2835 bool select PINMUX @@ -96,18 +87,21 @@ config PINCTRL_MMP2 bool "MMP2 pin controller driver" depends on ARCH_MMP select PINCTRL_PXA3xx + select PINCONF config PINCTRL_MXS bool - select PINMUX - select PINCONF config PINCTRL_IMX23 bool + select PINMUX + select PINCONF select PINCTRL_MXS config PINCTRL_IMX28 bool + select PINMUX + select PINCONF select PINCTRL_MXS config PINCTRL_NOMADIK @@ -132,11 +126,13 @@ config PINCTRL_PXA168 bool "PXA168 pin controller driver" depends on ARCH_MMP select PINCTRL_PXA3xx + select PINCONF config PINCTRL_PXA910 bool "PXA910 pin controller driver" depends on ARCH_MMP select PINCTRL_PXA3xx + select PINCONF config PINCTRL_SINGLE tristate "One-register-per-pin type device tree based pinctrl driver" @@ -147,21 +143,23 @@ config PINCTRL_SINGLE This selects the device tree based generic pinctrl driver. config PINCTRL_SIRF - bool "CSR SiRFprimaII/SiRFmarco pin controller driver" - depends on ARCH_SIRF + bool "CSR SiRFprimaII pin controller driver" + depends on ARCH_PRIMA2 select PINMUX config PINCTRL_TEGRA bool - select PINMUX - select PINCONF config PINCTRL_TEGRA20 bool + select PINMUX + select PINCONF select PINCTRL_TEGRA config PINCTRL_TEGRA30 bool + select PINMUX + select PINCONF select PINCTRL_TEGRA config PINCTRL_U300 @@ -180,17 +178,35 @@ config PINCTRL_COH901 ports of 8 GPIO pins each. config PINCTRL_SAMSUNG - bool - depends on OF && GPIOLIB + bool "Samsung pinctrl driver" select PINMUX select PINCONF config PINCTRL_EXYNOS4 bool "Pinctrl driver data for Exynos4 SoC" - depends on OF && GPIOLIB select PINCTRL_SAMSUNG -source "drivers/pinctrl/mvebu/Kconfig" +config PINCTRL_MVEBU + bool + depends on ARCH_MVEBU + select PINMUX + select PINCONF + +config PINCTRL_DOVE + bool + select PINCTRL_MVEBU + +config PINCTRL_KIRKWOOD + bool + select PINCTRL_MVEBU + +config PINCTRL_ARMADA_370 + bool + select PINCTRL_MVEBU + +config PINCTRL_ARMADA_XP + bool + select PINCTRL_MVEBU source "drivers/pinctrl/spear/Kconfig" diff --git a/trunk/drivers/pinctrl/Makefile b/trunk/drivers/pinctrl/Makefile index f95f5ed923be..f395ba5cec25 100644 --- a/trunk/drivers/pinctrl/Makefile +++ b/trunk/drivers/pinctrl/Makefile @@ -9,7 +9,6 @@ ifeq ($(CONFIG_OF),y) obj-$(CONFIG_PINCTRL) += devicetree.o endif obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o -obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o obj-$(CONFIG_PINCTRL_IMX35) += pinctrl-imx35.o @@ -37,8 +36,12 @@ obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o obj-$(CONFIG_PINCTRL_EXYNOS4) += pinctrl-exynos.o +obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o +obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o +obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o +obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o +obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o -obj-$(CONFIG_PLAT_ORION) += mvebu/ obj-$(CONFIG_PLAT_SPEAR) += spear/ diff --git a/trunk/drivers/pinctrl/core.c b/trunk/drivers/pinctrl/core.c index 5cdee8669ea3..0f1ec9e8ff14 100644 --- a/trunk/drivers/pinctrl/core.c +++ b/trunk/drivers/pinctrl/core.c @@ -345,62 +345,6 @@ void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev, } EXPORT_SYMBOL_GPL(pinctrl_add_gpio_ranges); -struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname, - struct pinctrl_gpio_range *range) -{ - struct pinctrl_dev *pctldev = get_pinctrl_dev_from_devname(devname); - - /* - * If we can't find this device, let's assume that is because - * it has not probed yet, so the driver trying to register this - * range need to defer probing. - */ - if (!pctldev) - return ERR_PTR(-EPROBE_DEFER); - - pinctrl_add_gpio_range(pctldev, range); - return pctldev; -} -EXPORT_SYMBOL_GPL(pinctrl_find_and_add_gpio_range); - -/** - * pinctrl_find_gpio_range_from_pin() - locate the GPIO range for a pin - * @pctldev: the pin controller device to look in - * @pin: a controller-local number to find the range for - */ -struct pinctrl_gpio_range * -pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev, - unsigned int pin) -{ - struct pinctrl_gpio_range *range = NULL; - - /* Loop over the ranges */ - list_for_each_entry(range, &pctldev->gpio_ranges, node) { - /* Check if we're in the valid range */ - if (pin >= range->pin_base && - pin < range->pin_base + range->npins) { - return range; - } - } - - return NULL; -} -EXPORT_SYMBOL_GPL(pinctrl_find_gpio_range_from_pin); - -/** - * pinctrl_remove_gpio_range() - remove a range of GPIOs fro a pin controller - * @pctldev: pin controller device to remove the range from - * @range: the GPIO range to remove - */ -void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range) -{ - mutex_lock(&pinctrl_mutex); - list_del(&range->node); - mutex_unlock(&pinctrl_mutex); -} -EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range); - /** * pinctrl_get_group_selector() - returns the group selector for a group * @pctldev: the pin controller handling the group @@ -619,8 +563,6 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map) return -EPROBE_DEFER; } - setting->dev_name = map->dev_name; - switch (map->type) { case PIN_MAP_TYPE_MUX_GROUP: ret = pinmux_map_to_setting(map, setting); @@ -1119,10 +1061,8 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) seq_printf(s, "group: %s\n", gname); for (i = 0; i < num_pins; i++) { pname = pin_get_name(pctldev, pins[i]); - if (WARN_ON(!pname)) { - mutex_unlock(&pinctrl_mutex); + if (WARN_ON(!pname)) return -EINVAL; - } seq_printf(s, "pin %d (%s)\n", pins[i], pname); } seq_puts(s, "\n"); diff --git a/trunk/drivers/pinctrl/core.h b/trunk/drivers/pinctrl/core.h index 12f5694f3d5d..1f40ff68a8c4 100644 --- a/trunk/drivers/pinctrl/core.h +++ b/trunk/drivers/pinctrl/core.h @@ -105,14 +105,12 @@ struct pinctrl_setting_configs { * @type: the type of setting * @pctldev: pin control device handling to be programmed. Not used for * PIN_MAP_TYPE_DUMMY_STATE. - * @dev_name: the name of the device using this state * @data: Data specific to the setting type */ struct pinctrl_setting { struct list_head node; enum pinctrl_map_type type; struct pinctrl_dev *pctldev; - const char *dev_name; union { struct pinctrl_setting_mux mux; struct pinctrl_setting_configs configs; diff --git a/trunk/drivers/pinctrl/devicetree.c b/trunk/drivers/pinctrl/devicetree.c index fe2d1af7cfa0..fcb1de45473c 100644 --- a/trunk/drivers/pinctrl/devicetree.c +++ b/trunk/drivers/pinctrl/devicetree.c @@ -106,17 +106,6 @@ static struct pinctrl_dev *find_pinctrl_by_of_node(struct device_node *np) return NULL; } -struct pinctrl_dev *of_pinctrl_get(struct device_node *np) -{ - struct pinctrl_dev *pctldev; - - pctldev = find_pinctrl_by_of_node(np); - if (!pctldev) - return NULL; - - return pctldev; -} - static int dt_to_map_one_config(struct pinctrl *p, const char *statename, struct device_node *np_config) { diff --git a/trunk/drivers/pinctrl/mvebu/Kconfig b/trunk/drivers/pinctrl/mvebu/Kconfig deleted file mode 100644 index 366fa541ee91..000000000000 --- a/trunk/drivers/pinctrl/mvebu/Kconfig +++ /dev/null @@ -1,24 +0,0 @@ -if PLAT_ORION - -config PINCTRL_MVEBU - bool - select PINMUX - select PINCONF - -config PINCTRL_DOVE - bool - select PINCTRL_MVEBU - -config PINCTRL_KIRKWOOD - bool - select PINCTRL_MVEBU - -config PINCTRL_ARMADA_370 - bool - select PINCTRL_MVEBU - -config PINCTRL_ARMADA_XP - bool - select PINCTRL_MVEBU - -endif diff --git a/trunk/drivers/pinctrl/mvebu/Makefile b/trunk/drivers/pinctrl/mvebu/Makefile deleted file mode 100644 index 37c253297af0..000000000000 --- a/trunk/drivers/pinctrl/mvebu/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o -obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o -obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o -obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o -obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o diff --git a/trunk/drivers/pinctrl/pinconf-generic.c b/trunk/drivers/pinctrl/pinconf-generic.c index 833a36458157..33fbaeaa65dd 100644 --- a/trunk/drivers/pinctrl/pinconf-generic.c +++ b/trunk/drivers/pinctrl/pinconf-generic.c @@ -41,7 +41,6 @@ struct pin_config_item conf_items[] = { PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL), PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL), PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL), - PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_DISABLE, "input schmitt disabled", NULL), PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL), PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "time units"), PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector"), diff --git a/trunk/drivers/pinctrl/pinconf.c b/trunk/drivers/pinctrl/pinconf.c index baee2cc46a17..43f474cdc110 100644 --- a/trunk/drivers/pinctrl/pinconf.c +++ b/trunk/drivers/pinctrl/pinconf.c @@ -537,6 +537,8 @@ static int pinconf_groups_show(struct seq_file *s, void *what) seq_puts(s, "Pin config settings per pin group\n"); seq_puts(s, "Format: group (name): configs\n"); + mutex_lock(&pinctrl_mutex); + while (selector < ngroups) { const char *gname = pctlops->get_group_name(pctldev, selector); @@ -547,6 +549,8 @@ static int pinconf_groups_show(struct seq_file *s, void *what) selector++; } + mutex_unlock(&pinctrl_mutex); + return 0; } diff --git a/trunk/drivers/pinctrl/mvebu/pinctrl-armada-370.c b/trunk/drivers/pinctrl/pinctrl-armada-370.c similarity index 100% rename from trunk/drivers/pinctrl/mvebu/pinctrl-armada-370.c rename to trunk/drivers/pinctrl/pinctrl-armada-370.c diff --git a/trunk/drivers/pinctrl/mvebu/pinctrl-armada-xp.c b/trunk/drivers/pinctrl/pinctrl-armada-xp.c similarity index 100% rename from trunk/drivers/pinctrl/mvebu/pinctrl-armada-xp.c rename to trunk/drivers/pinctrl/pinctrl-armada-xp.c diff --git a/trunk/drivers/pinctrl/pinctrl-at91.c b/trunk/drivers/pinctrl/pinctrl-at91.c deleted file mode 100644 index c5e757157183..000000000000 --- a/trunk/drivers/pinctrl/pinctrl-at91.c +++ /dev/null @@ -1,1634 +0,0 @@ -/* - * at91 pinctrl driver based on at91 pinmux core - * - * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD - * - * Under GPLv2 only - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -/* Since we request GPIOs from ourself */ -#include - -#include - -#include -#include - -#include "core.h" - -#define MAX_NB_GPIO_PER_BANK 32 - -struct at91_pinctrl_mux_ops; - -struct at91_gpio_chip { - struct gpio_chip chip; - struct pinctrl_gpio_range range; - struct at91_gpio_chip *next; /* Bank sharing same clock */ - int pioc_hwirq; /* PIO bank interrupt identifier on AIC */ - int pioc_virq; /* PIO bank Linux virtual interrupt */ - int pioc_idx; /* PIO bank index */ - void __iomem *regbase; /* PIO bank virtual address */ - struct clk *clock; /* associated clock */ - struct irq_domain *domain; /* associated irq domain */ - struct at91_pinctrl_mux_ops *ops; /* ops */ -}; - -#define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip) - -static struct at91_gpio_chip *gpio_chips[MAX_GPIO_BANKS]; - -static int gpio_banks; - -#define PULL_UP (1 << 0) -#define MULTI_DRIVE (1 << 1) -#define DEGLITCH (1 << 2) -#define PULL_DOWN (1 << 3) -#define DIS_SCHMIT (1 << 4) -#define DEBOUNCE (1 << 16) -#define DEBOUNCE_VAL_SHIFT 17 -#define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT) - -/** - * struct at91_pmx_func - describes AT91 pinmux functions - * @name: the name of this specific function - * @groups: corresponding pin groups - * @ngroups: the number of groups - */ -struct at91_pmx_func { - const char *name; - const char **groups; - unsigned ngroups; -}; - -enum at91_mux { - AT91_MUX_GPIO = 0, - AT91_MUX_PERIPH_A = 1, - AT91_MUX_PERIPH_B = 2, - AT91_MUX_PERIPH_C = 3, - AT91_MUX_PERIPH_D = 4, -}; - -/** - * struct at91_pmx_pin - describes an At91 pin mux - * @bank: the bank of the pin - * @pin: the pin number in the @bank - * @mux: the mux mode : gpio or periph_x of the pin i.e. alternate function. - * @conf: the configuration of the pin: PULL_UP, MULTIDRIVE etc... - */ -struct at91_pmx_pin { - uint32_t bank; - uint32_t pin; - enum at91_mux mux; - unsigned long conf; -}; - -/** - * struct at91_pin_group - describes an At91 pin group - * @name: the name of this specific pin group - * @pins_conf: the mux mode for each pin in this group. The size of this - * array is the same as pins. - * @pins: an array of discrete physical pins used in this group, taken - * from the driver-local pin enumeration space - * @npins: the number of pins in this group array, i.e. the number of - * elements in .pins so we can iterate over that array - */ -struct at91_pin_group { - const char *name; - struct at91_pmx_pin *pins_conf; - unsigned int *pins; - unsigned npins; -}; - -/** - * struct at91_pinctrl_mux_ops - describes an At91 mux ops group - * on new IP with support for periph C and D the way to mux in - * periph A and B has changed - * So provide the right call back - * if not present means the IP does not support it - * @get_periph: return the periph mode configured - * @mux_A_periph: mux as periph A - * @mux_B_periph: mux as periph B - * @mux_C_periph: mux as periph C - * @mux_D_periph: mux as periph D - * @get_deglitch: get deglitch status - * @set_deglitch: enable/disable deglitch - * @get_debounce: get debounce status - * @set_debounce: enable/disable debounce - * @get_pulldown: get pulldown status - * @set_pulldown: enable/disable pulldown - * @get_schmitt_trig: get schmitt trigger status - * @disable_schmitt_trig: disable schmitt trigger - * @irq_type: return irq type - */ -struct at91_pinctrl_mux_ops { - enum at91_mux (*get_periph)(void __iomem *pio, unsigned mask); - void (*mux_A_periph)(void __iomem *pio, unsigned mask); - void (*mux_B_periph)(void __iomem *pio, unsigned mask); - void (*mux_C_periph)(void __iomem *pio, unsigned mask); - void (*mux_D_periph)(void __iomem *pio, unsigned mask); - bool (*get_deglitch)(void __iomem *pio, unsigned pin); - void (*set_deglitch)(void __iomem *pio, unsigned mask, bool in_on); - bool (*get_debounce)(void __iomem *pio, unsigned pin, u32 *div); - void (*set_debounce)(void __iomem *pio, unsigned mask, bool in_on, u32 div); - bool (*get_pulldown)(void __iomem *pio, unsigned pin); - void (*set_pulldown)(void __iomem *pio, unsigned mask, bool in_on); - bool (*get_schmitt_trig)(void __iomem *pio, unsigned pin); - void (*disable_schmitt_trig)(void __iomem *pio, unsigned mask); - /* irq */ - int (*irq_type)(struct irq_data *d, unsigned type); -}; - -static int gpio_irq_type(struct irq_data *d, unsigned type); -static int alt_gpio_irq_type(struct irq_data *d, unsigned type); - -struct at91_pinctrl { - struct device *dev; - struct pinctrl_dev *pctl; - - int nbanks; - - uint32_t *mux_mask; - int nmux; - - struct at91_pmx_func *functions; - int nfunctions; - - struct at91_pin_group *groups; - int ngroups; - - struct at91_pinctrl_mux_ops *ops; -}; - -static const inline struct at91_pin_group *at91_pinctrl_find_group_by_name( - const struct at91_pinctrl *info, - const char *name) -{ - const struct at91_pin_group *grp = NULL; - int i; - - for (i = 0; i < info->ngroups; i++) { - if (strcmp(info->groups[i].name, name)) - continue; - - grp = &info->groups[i]; - dev_dbg(info->dev, "%s: %d 0:%d\n", name, grp->npins, grp->pins[0]); - break; - } - - return grp; -} - -static int at91_get_groups_count(struct pinctrl_dev *pctldev) -{ - struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - - return info->ngroups; -} - -static const char *at91_get_group_name(struct pinctrl_dev *pctldev, - unsigned selector) -{ - struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - - return info->groups[selector].name; -} - -static int at91_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, - const unsigned **pins, - unsigned *npins) -{ - struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - - if (selector >= info->ngroups) - return -EINVAL; - - *pins = info->groups[selector].pins; - *npins = info->groups[selector].npins; - - return 0; -} - -static void at91_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, - unsigned offset) -{ - seq_printf(s, "%s", dev_name(pctldev->dev)); -} - -static int at91_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np, - struct pinctrl_map **map, unsigned *num_maps) -{ - struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - const struct at91_pin_group *grp; - struct pinctrl_map *new_map; - struct device_node *parent; - int map_num = 1; - int i; - - /* - * first find the group of this node and check if we need create - * config maps for pins - */ - grp = at91_pinctrl_find_group_by_name(info, np->name); - if (!grp) { - dev_err(info->dev, "unable to find group for node %s\n", - np->name); - return -EINVAL; - } - - map_num += grp->npins; - new_map = devm_kzalloc(pctldev->dev, sizeof(*new_map) * map_num, GFP_KERNEL); - if (!new_map) - return -ENOMEM; - - *map = new_map; - *num_maps = map_num; - - /* create mux map */ - parent = of_get_parent(np); - if (!parent) { - kfree(new_map); - return -EINVAL; - } - new_map[0].type = PIN_MAP_TYPE_MUX_GROUP; - new_map[0].data.mux.function = parent->name; - new_map[0].data.mux.group = np->name; - of_node_put(parent); - - /* create config map */ - new_map++; - for (i = 0; i < grp->npins; i++) { - new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN; - new_map[i].data.configs.group_or_pin = - pin_get_name(pctldev, grp->pins[i]); - new_map[i].data.configs.configs = &grp->pins_conf[i].conf; - new_map[i].data.configs.num_configs = 1; - } - - dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n", - (*map)->data.mux.function, (*map)->data.mux.group, map_num); - - return 0; -} - -static void at91_dt_free_map(struct pinctrl_dev *pctldev, - struct pinctrl_map *map, unsigned num_maps) -{ -} - -static struct pinctrl_ops at91_pctrl_ops = { - .get_groups_count = at91_get_groups_count, - .get_group_name = at91_get_group_name, - .get_group_pins = at91_get_group_pins, - .pin_dbg_show = at91_pin_dbg_show, - .dt_node_to_map = at91_dt_node_to_map, - .dt_free_map = at91_dt_free_map, -}; - -static void __iomem * pin_to_controller(struct at91_pinctrl *info, - unsigned int bank) -{ - return gpio_chips[bank]->regbase; -} - -static inline int pin_to_bank(unsigned pin) -{ - return pin /= MAX_NB_GPIO_PER_BANK; -} - -static unsigned pin_to_mask(unsigned int pin) -{ - return 1 << pin; -} - -static void at91_mux_disable_interrupt(void __iomem *pio, unsigned mask) -{ - writel_relaxed(mask, pio + PIO_IDR); -} - -static unsigned at91_mux_get_pullup(void __iomem *pio, unsigned pin) -{ - return (readl_relaxed(pio + PIO_PUSR) >> pin) & 0x1; -} - -static void at91_mux_set_pullup(void __iomem *pio, unsigned mask, bool on) -{ - writel_relaxed(mask, pio + (on ? PIO_PUER : PIO_PUDR)); -} - -static unsigned at91_mux_get_multidrive(void __iomem *pio, unsigned pin) -{ - return (readl_relaxed(pio + PIO_MDSR) >> pin) & 0x1; -} - -static void at91_mux_set_multidrive(void __iomem *pio, unsigned mask, bool on) -{ - writel_relaxed(mask, pio + (on ? PIO_MDER : PIO_MDDR)); -} - -static void at91_mux_set_A_periph(void __iomem *pio, unsigned mask) -{ - writel_relaxed(mask, pio + PIO_ASR); -} - -static void at91_mux_set_B_periph(void __iomem *pio, unsigned mask) -{ - writel_relaxed(mask, pio + PIO_BSR); -} - -static void at91_mux_pio3_set_A_periph(void __iomem *pio, unsigned mask) -{ - - writel_relaxed(readl_relaxed(pio + PIO_ABCDSR1) & ~mask, - pio + PIO_ABCDSR1); - writel_relaxed(readl_relaxed(pio + PIO_ABCDSR2) & ~mask, - pio + PIO_ABCDSR2); -} - -static void at91_mux_pio3_set_B_periph(void __iomem *pio, unsigned mask) -{ - writel_relaxed(readl_relaxed(pio + PIO_ABCDSR1) | mask, - pio + PIO_ABCDSR1); - writel_relaxed(readl_relaxed(pio + PIO_ABCDSR2) & ~mask, - pio + PIO_ABCDSR2); -} - -static void at91_mux_pio3_set_C_periph(void __iomem *pio, unsigned mask) -{ - writel_relaxed(readl_relaxed(pio + PIO_ABCDSR1) & ~mask, pio + PIO_ABCDSR1); - writel_relaxed(readl_relaxed(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2); -} - -static void at91_mux_pio3_set_D_periph(void __iomem *pio, unsigned mask) -{ - writel_relaxed(readl_relaxed(pio + PIO_ABCDSR1) | mask, pio + PIO_ABCDSR1); - writel_relaxed(readl_relaxed(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2); -} - -static enum at91_mux at91_mux_pio3_get_periph(void __iomem *pio, unsigned mask) -{ - unsigned select; - - if (readl_relaxed(pio + PIO_PSR) & mask) - return AT91_MUX_GPIO; - - select = !!(readl_relaxed(pio + PIO_ABCDSR1) & mask); - select |= (!!(readl_relaxed(pio + PIO_ABCDSR2) & mask) << 1); - - return select + 1; -} - -static enum at91_mux at91_mux_get_periph(void __iomem *pio, unsigned mask) -{ - unsigned select; - - if (readl_relaxed(pio + PIO_PSR) & mask) - return AT91_MUX_GPIO; - - select = readl_relaxed(pio + PIO_ABSR) & mask; - - return select + 1; -} - -static bool at91_mux_get_deglitch(void __iomem *pio, unsigned pin) -{ - return (__raw_readl(pio + PIO_IFSR) >> pin) & 0x1; -} - -static void at91_mux_set_deglitch(void __iomem *pio, unsigned mask, bool is_on) -{ - __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR)); -} - -static void at91_mux_pio3_set_deglitch(void __iomem *pio, unsigned mask, bool is_on) -{ - if (is_on) - __raw_writel(mask, pio + PIO_IFSCDR); - at91_mux_set_deglitch(pio, mask, is_on); -} - -static bool at91_mux_pio3_get_debounce(void __iomem *pio, unsigned pin, u32 *div) -{ - *div = __raw_readl(pio + PIO_SCDR); - - return (__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1; -} - -static void at91_mux_pio3_set_debounce(void __iomem *pio, unsigned mask, - bool is_on, u32 div) -{ - if (is_on) { - __raw_writel(mask, pio + PIO_IFSCER); - __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR); - __raw_writel(mask, pio + PIO_IFER); - } else { - __raw_writel(mask, pio + PIO_IFDR); - } -} - -static bool at91_mux_pio3_get_pulldown(void __iomem *pio, unsigned pin) -{ - return (__raw_readl(pio + PIO_PPDSR) >> pin) & 0x1; -} - -static void at91_mux_pio3_set_pulldown(void __iomem *pio, unsigned mask, bool is_on) -{ - __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR)); -} - -static void at91_mux_pio3_disable_schmitt_trig(void __iomem *pio, unsigned mask) -{ - __raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT); -} - -static bool at91_mux_pio3_get_schmitt_trig(void __iomem *pio, unsigned pin) -{ - return (__raw_readl(pio + PIO_SCHMITT) >> pin) & 0x1; -} - -static struct at91_pinctrl_mux_ops at91rm9200_ops = { - .get_periph = at91_mux_get_periph, - .mux_A_periph = at91_mux_set_A_periph, - .mux_B_periph = at91_mux_set_B_periph, - .get_deglitch = at91_mux_get_deglitch, - .set_deglitch = at91_mux_set_deglitch, - .irq_type = gpio_irq_type, -}; - -static struct at91_pinctrl_mux_ops at91sam9x5_ops = { - .get_periph = at91_mux_pio3_get_periph, - .mux_A_periph = at91_mux_pio3_set_A_periph, - .mux_B_periph = at91_mux_pio3_set_B_periph, - .mux_C_periph = at91_mux_pio3_set_C_periph, - .mux_D_periph = at91_mux_pio3_set_D_periph, - .get_deglitch = at91_mux_get_deglitch, - .set_deglitch = at91_mux_pio3_set_deglitch, - .get_debounce = at91_mux_pio3_get_debounce, - .set_debounce = at91_mux_pio3_set_debounce, - .get_pulldown = at91_mux_pio3_get_pulldown, - .set_pulldown = at91_mux_pio3_set_pulldown, - .get_schmitt_trig = at91_mux_pio3_get_schmitt_trig, - .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig, - .irq_type = alt_gpio_irq_type, -}; - -static void at91_pin_dbg(const struct device *dev, const struct at91_pmx_pin *pin) -{ - if (pin->mux) { - dev_dbg(dev, "pio%c%d configured as periph%c with conf = 0x%lu\n", - pin->bank + 'A', pin->pin, pin->mux - 1 + 'A', pin->conf); - } else { - dev_dbg(dev, "pio%c%d configured as gpio with conf = 0x%lu\n", - pin->bank + 'A', pin->pin, pin->conf); - } -} - -static int pin_check_config(struct at91_pinctrl *info, const char* name, - int index, const struct at91_pmx_pin *pin) -{ - int mux; - - /* check if it's a valid config */ - if (pin->bank >= info->nbanks) { - dev_err(info->dev, "%s: pin conf %d bank_id %d >= nbanks %d\n", - name, index, pin->bank, info->nbanks); - return -EINVAL; - } - - if (pin->pin >= MAX_NB_GPIO_PER_BANK) { - dev_err(info->dev, "%s: pin conf %d pin_bank_id %d >= %d\n", - name, index, pin->pin, MAX_NB_GPIO_PER_BANK); - return -EINVAL; - } - - if (!pin->mux) - return 0; - - mux = pin->mux - 1; - - if (mux >= info->nmux) { - dev_err(info->dev, "%s: pin conf %d mux_id %d >= nmux %d\n", - name, index, mux, info->nmux); - return -EINVAL; - } - - if (!(info->mux_mask[pin->bank * info->nmux + mux] & 1 << pin->pin)) { - dev_err(info->dev, "%s: pin conf %d mux_id %d not supported for pio%c%d\n", - name, index, mux, pin->bank + 'A', pin->pin); - return -EINVAL; - } - - return 0; -} - -static void at91_mux_gpio_disable(void __iomem *pio, unsigned mask) -{ - writel_relaxed(mask, pio + PIO_PDR); -} - -static void at91_mux_gpio_enable(void __iomem *pio, unsigned mask, bool input) -{ - writel_relaxed(mask, pio + PIO_PER); - writel_relaxed(mask, pio + (input ? PIO_ODR : PIO_OER)); -} - -static int at91_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, - unsigned group) -{ - struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - const struct at91_pmx_pin *pins_conf = info->groups[group].pins_conf; - const struct at91_pmx_pin *pin; - uint32_t npins = info->groups[group].npins; - int i, ret; - unsigned mask; - void __iomem *pio; - - dev_dbg(info->dev, "enable function %s group %s\n", - info->functions[selector].name, info->groups[group].name); - - /* first check that all the pins of the group are valid with a valid - * paramter */ - for (i = 0; i < npins; i++) { - pin = &pins_conf[i]; - ret = pin_check_config(info, info->groups[group].name, i, pin); - if (ret) - return ret; - } - - for (i = 0; i < npins; i++) { - pin = &pins_conf[i]; - at91_pin_dbg(info->dev, pin); - pio = pin_to_controller(info, pin->bank); - mask = pin_to_mask(pin->pin); - at91_mux_disable_interrupt(pio, mask); - switch(pin->mux) { - case AT91_MUX_GPIO: - at91_mux_gpio_enable(pio, mask, 1); - break; - case AT91_MUX_PERIPH_A: - info->ops->mux_A_periph(pio, mask); - break; - case AT91_MUX_PERIPH_B: - info->ops->mux_B_periph(pio, mask); - break; - case AT91_MUX_PERIPH_C: - if (!info->ops->mux_C_periph) - return -EINVAL; - info->ops->mux_C_periph(pio, mask); - break; - case AT91_MUX_PERIPH_D: - if (!info->ops->mux_D_periph) - return -EINVAL; - info->ops->mux_D_periph(pio, mask); - break; - } - if (pin->mux) - at91_mux_gpio_disable(pio, mask); - } - - return 0; -} - -static void at91_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector, - unsigned group) -{ - struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - const struct at91_pmx_pin *pins_conf = info->groups[group].pins_conf; - const struct at91_pmx_pin *pin; - uint32_t npins = info->groups[group].npins; - int i; - unsigned mask; - void __iomem *pio; - - for (i = 0; i < npins; i++) { - pin = &pins_conf[i]; - at91_pin_dbg(info->dev, pin); - pio = pin_to_controller(info, pin->bank); - mask = pin_to_mask(pin->pin); - at91_mux_gpio_enable(pio, mask, 1); - } -} - -static int at91_pmx_get_funcs_count(struct pinctrl_dev *pctldev) -{ - struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - - return info->nfunctions; -} - -static const char *at91_pmx_get_func_name(struct pinctrl_dev *pctldev, - unsigned selector) -{ - struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - - return info->functions[selector].name; -} - -static int at91_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector, - const char * const **groups, - unsigned * const num_groups) -{ - struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - - *groups = info->functions[selector].groups; - *num_groups = info->functions[selector].ngroups; - - return 0; -} - -static int at91_gpio_request_enable(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, - unsigned offset) -{ - struct at91_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); - struct at91_gpio_chip *at91_chip; - struct gpio_chip *chip; - unsigned mask; - - if (!range) { - dev_err(npct->dev, "invalid range\n"); - return -EINVAL; - } - if (!range->gc) { - dev_err(npct->dev, "missing GPIO chip in range\n"); - return -EINVAL; - } - chip = range->gc; - at91_chip = container_of(chip, struct at91_gpio_chip, chip); - - dev_dbg(npct->dev, "enable pin %u as GPIO\n", offset); - - mask = 1 << (offset - chip->base); - - dev_dbg(npct->dev, "enable pin %u as PIO%c%d 0x%x\n", - offset, 'A' + range->id, offset - chip->base, mask); - - writel_relaxed(mask, at91_chip->regbase + PIO_PER); - - return 0; -} - -static void at91_gpio_disable_free(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, - unsigned offset) -{ - struct at91_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); - - dev_dbg(npct->dev, "disable pin %u as GPIO\n", offset); - /* Set the pin to some default state, GPIO is usually default */ -} - -static struct pinmux_ops at91_pmx_ops = { - .get_functions_count = at91_pmx_get_funcs_count, - .get_function_name = at91_pmx_get_func_name, - .get_function_groups = at91_pmx_get_groups, - .enable = at91_pmx_enable, - .disable = at91_pmx_disable, - .gpio_request_enable = at91_gpio_request_enable, - .gpio_disable_free = at91_gpio_disable_free, -}; - -static int at91_pinconf_get(struct pinctrl_dev *pctldev, - unsigned pin_id, unsigned long *config) -{ - struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - void __iomem *pio; - unsigned pin; - int div; - - dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__, __LINE__, pin_id, *config); - pio = pin_to_controller(info, pin_to_bank(pin_id)); - pin = pin_id % MAX_NB_GPIO_PER_BANK; - - if (at91_mux_get_multidrive(pio, pin)) - *config |= MULTI_DRIVE; - - if (at91_mux_get_pullup(pio, pin)) - *config |= PULL_UP; - - if (info->ops->get_deglitch && info->ops->get_deglitch(pio, pin)) - *config |= DEGLITCH; - if (info->ops->get_debounce && info->ops->get_debounce(pio, pin, &div)) - *config |= DEBOUNCE | (div << DEBOUNCE_VAL_SHIFT); - if (info->ops->get_pulldown && info->ops->get_pulldown(pio, pin)) - *config |= PULL_DOWN; - if (info->ops->get_schmitt_trig && info->ops->get_schmitt_trig(pio, pin)) - *config |= DIS_SCHMIT; - - return 0; -} - -static int at91_pinconf_set(struct pinctrl_dev *pctldev, - unsigned pin_id, unsigned long config) -{ - struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - unsigned mask; - void __iomem *pio; - - dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__, __LINE__, pin_id, config); - pio = pin_to_controller(info, pin_to_bank(pin_id)); - mask = pin_to_mask(pin_id % MAX_NB_GPIO_PER_BANK); - - if (config & PULL_UP && config & PULL_DOWN) - return -EINVAL; - - at91_mux_set_pullup(pio, mask, config & PULL_UP); - at91_mux_set_multidrive(pio, mask, config & MULTI_DRIVE); - if (info->ops->set_deglitch) - info->ops->set_deglitch(pio, mask, config & DEGLITCH); - if (info->ops->set_debounce) - info->ops->set_debounce(pio, mask, config & DEBOUNCE, - (config & DEBOUNCE_VAL) >> DEBOUNCE_VAL_SHIFT); - if (info->ops->set_pulldown) - info->ops->set_pulldown(pio, mask, config & PULL_DOWN); - if (info->ops->disable_schmitt_trig && config & DIS_SCHMIT) - info->ops->disable_schmitt_trig(pio, mask); - - return 0; -} - -static void at91_pinconf_dbg_show(struct pinctrl_dev *pctldev, - struct seq_file *s, unsigned pin_id) -{ - -} - -static void at91_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, - struct seq_file *s, unsigned group) -{ -} - -static struct pinconf_ops at91_pinconf_ops = { - .pin_config_get = at91_pinconf_get, - .pin_config_set = at91_pinconf_set, - .pin_config_dbg_show = at91_pinconf_dbg_show, - .pin_config_group_dbg_show = at91_pinconf_group_dbg_show, -}; - -static struct pinctrl_desc at91_pinctrl_desc = { - .pctlops = &at91_pctrl_ops, - .pmxops = &at91_pmx_ops, - .confops = &at91_pinconf_ops, - .owner = THIS_MODULE, -}; - -static const char *gpio_compat = "atmel,at91rm9200-gpio"; - -static void __devinit at91_pinctrl_child_count(struct at91_pinctrl *info, - struct device_node *np) -{ - struct device_node *child; - - for_each_child_of_node(np, child) { - if (of_device_is_compatible(child, gpio_compat)) { - info->nbanks++; - } else { - info->nfunctions++; - info->ngroups += of_get_child_count(child); - } - } -} - -static int __devinit at91_pinctrl_mux_mask(struct at91_pinctrl *info, - struct device_node *np) -{ - int ret = 0; - int size; - const const __be32 *list; - - list = of_get_property(np, "atmel,mux-mask", &size); - if (!list) { - dev_err(info->dev, "can not read the mux-mask of %d\n", size); - return -EINVAL; - } - - size /= sizeof(*list); - if (!size || size % info->nbanks) { - dev_err(info->dev, "wrong mux mask array should be by %d\n", info->nbanks); - return -EINVAL; - } - info->nmux = size / info->nbanks; - - info->mux_mask = devm_kzalloc(info->dev, sizeof(u32) * size, GFP_KERNEL); - if (!info->mux_mask) { - dev_err(info->dev, "could not alloc mux_mask\n"); - return -ENOMEM; - } - - ret = of_property_read_u32_array(np, "atmel,mux-mask", - info->mux_mask, size); - if (ret) - dev_err(info->dev, "can not read the mux-mask of %d\n", size); - return ret; -} - -static int __devinit at91_pinctrl_parse_groups(struct device_node *np, - struct at91_pin_group *grp, - struct at91_pinctrl *info, - u32 index) -{ - struct at91_pmx_pin *pin; - int size; - const const __be32 *list; - int i, j; - - dev_dbg(info->dev, "group(%d): %s\n", index, np->name); - - /* Initialise group */ - grp->name = np->name; - - /* - * the binding format is atmel,pins = , - * do sanity check and calculate pins number - */ - list = of_get_property(np, "atmel,pins", &size); - /* we do not check return since it's safe node passed down */ - size /= sizeof(*list); - if (!size || size % 4) { - dev_err(info->dev, "wrong pins number or pins and configs should be by 4\n"); - return -EINVAL; - } - - grp->npins = size / 4; - pin = grp->pins_conf = devm_kzalloc(info->dev, grp->npins * sizeof(struct at91_pmx_pin), - GFP_KERNEL); - grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), - GFP_KERNEL); - if (!grp->pins_conf || !grp->pins) - return -ENOMEM; - - for (i = 0, j = 0; i < size; i += 4, j++) { - pin->bank = be32_to_cpu(*list++); - pin->pin = be32_to_cpu(*list++); - grp->pins[j] = pin->bank * MAX_NB_GPIO_PER_BANK + pin->pin; - pin->mux = be32_to_cpu(*list++); - pin->conf = be32_to_cpu(*list++); - - at91_pin_dbg(info->dev, pin); - pin++; - } - - return 0; -} - -static int __devinit at91_pinctrl_parse_functions(struct device_node *np, - struct at91_pinctrl *info, u32 index) -{ - struct device_node *child; - struct at91_pmx_func *func; - struct at91_pin_group *grp; - int ret; - static u32 grp_index; - u32 i = 0; - - dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name); - - func = &info->functions[index]; - - /* Initialise function */ - func->name = np->name; - func->ngroups = of_get_child_count(np); - if (func->ngroups <= 0) { - dev_err(info->dev, "no groups defined\n"); - return -EINVAL; - } - func->groups = devm_kzalloc(info->dev, - func->ngroups * sizeof(char *), GFP_KERNEL); - if (!func->groups) - return -ENOMEM; - - for_each_child_of_node(np, child) { - func->groups[i] = child->name; - grp = &info->groups[grp_index++]; - ret = at91_pinctrl_parse_groups(child, grp, info, i++); - if (ret) - return ret; - } - - return 0; -} - -static struct of_device_id at91_pinctrl_of_match[] __devinitdata = { - { .compatible = "atmel,at91sam9x5-pinctrl", .data = &at91sam9x5_ops }, - { .compatible = "atmel,at91rm9200-pinctrl", .data = &at91rm9200_ops }, - { /* sentinel */ } -}; - -static int __devinit at91_pinctrl_probe_dt(struct platform_device *pdev, - struct at91_pinctrl *info) -{ - int ret = 0; - int i, j; - uint32_t *tmp; - struct device_node *np = pdev->dev.of_node; - struct device_node *child; - - if (!np) - return -ENODEV; - - info->dev = &pdev->dev; - info->ops = (struct at91_pinctrl_mux_ops*) - of_match_device(at91_pinctrl_of_match, &pdev->dev)->data; - at91_pinctrl_child_count(info, np); - - if (info->nbanks < 1) { - dev_err(&pdev->dev, "you need to specify atleast one gpio-controller\n"); - return -EINVAL; - } - - ret = at91_pinctrl_mux_mask(info, np); - if (ret) - return ret; - - dev_dbg(&pdev->dev, "nmux = %d\n", info->nmux); - - dev_dbg(&pdev->dev, "mux-mask\n"); - tmp = info->mux_mask; - for (i = 0; i < info->nbanks; i++) { - for (j = 0; j < info->nmux; j++, tmp++) { - dev_dbg(&pdev->dev, "%d:%d\t0x%x\n", i, j, tmp[0]); - } - } - - dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions); - dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups); - info->functions = devm_kzalloc(&pdev->dev, info->nfunctions * sizeof(struct at91_pmx_func), - GFP_KERNEL); - if (!info->functions) - return -ENOMEM; - - info->groups = devm_kzalloc(&pdev->dev, info->ngroups * sizeof(struct at91_pin_group), - GFP_KERNEL); - if (!info->groups) - return -ENOMEM; - - dev_dbg(&pdev->dev, "nbanks = %d\n", info->nbanks); - dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions); - dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups); - - i = 0; - - for_each_child_of_node(np, child) { - if (of_device_is_compatible(child, gpio_compat)) - continue; - ret = at91_pinctrl_parse_functions(child, info, i++); - if (ret) { - dev_err(&pdev->dev, "failed to parse function\n"); - return ret; - } - } - - return 0; -} - -static int __devinit at91_pinctrl_probe(struct platform_device *pdev) -{ - struct at91_pinctrl *info; - struct pinctrl_pin_desc *pdesc; - int ret, i, j ,k; - - info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); - if (!info) - return -ENOMEM; - - ret = at91_pinctrl_probe_dt(pdev, info); - if (ret) - return ret; - - /* - * We need all the GPIO drivers to probe FIRST, or we will not be able - * to obtain references to the struct gpio_chip * for them, and we - * need this to proceed. - */ - for (i = 0; i < info->nbanks; i++) { - if (!gpio_chips[i]) { - dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i); - devm_kfree(&pdev->dev, info); - return -EPROBE_DEFER; - } - } - - at91_pinctrl_desc.name = dev_name(&pdev->dev); - at91_pinctrl_desc.npins = info->nbanks * MAX_NB_GPIO_PER_BANK; - at91_pinctrl_desc.pins = pdesc = - devm_kzalloc(&pdev->dev, sizeof(*pdesc) * at91_pinctrl_desc.npins, GFP_KERNEL); - - if (!at91_pinctrl_desc.pins) - return -ENOMEM; - - for (i = 0 , k = 0; i < info->nbanks; i++) { - for (j = 0; j < MAX_NB_GPIO_PER_BANK; j++, k++) { - pdesc->number = k; - pdesc->name = kasprintf(GFP_KERNEL, "pio%c%d", i + 'A', j); - pdesc++; - } - } - - platform_set_drvdata(pdev, info); - info->pctl = pinctrl_register(&at91_pinctrl_desc, &pdev->dev, info); - - if (!info->pctl) { - dev_err(&pdev->dev, "could not register AT91 pinctrl driver\n"); - ret = -EINVAL; - goto err; - } - - /* We will handle a range of GPIO pins */ - for (i = 0; i < info->nbanks; i++) - pinctrl_add_gpio_range(info->pctl, &gpio_chips[i]->range); - - dev_info(&pdev->dev, "initialized AT91 pinctrl driver\n"); - - return 0; - -err: - return ret; -} - -static int __devexit at91_pinctrl_remove(struct platform_device *pdev) -{ - struct at91_pinctrl *info = platform_get_drvdata(pdev); - - pinctrl_unregister(info->pctl); - - return 0; -} - -static int at91_gpio_request(struct gpio_chip *chip, unsigned offset) -{ - /* - * Map back to global GPIO space and request muxing, the direction - * parameter does not matter for this controller. - */ - int gpio = chip->base + offset; - int bank = chip->base / chip->ngpio; - - dev_dbg(chip->dev, "%s:%d pio%c%d(%d)\n", __func__, __LINE__, - 'A' + bank, offset, gpio); - - return pinctrl_request_gpio(gpio); -} - -static void at91_gpio_free(struct gpio_chip *chip, unsigned offset) -{ - int gpio = chip->base + offset; - - pinctrl_free_gpio(gpio); -} - -static int at91_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -{ - struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); - void __iomem *pio = at91_gpio->regbase; - unsigned mask = 1 << offset; - - writel_relaxed(mask, pio + PIO_ODR); - return 0; -} - -static int at91_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); - void __iomem *pio = at91_gpio->regbase; - unsigned mask = 1 << offset; - u32 pdsr; - - pdsr = readl_relaxed(pio + PIO_PDSR); - return (pdsr & mask) != 0; -} - -static void at91_gpio_set(struct gpio_chip *chip, unsigned offset, - int val) -{ - struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); - void __iomem *pio = at91_gpio->regbase; - unsigned mask = 1 << offset; - - writel_relaxed(mask, pio + (val ? PIO_SODR : PIO_CODR)); -} - -static int at91_gpio_direction_output(struct gpio_chip *chip, unsigned offset, - int val) -{ - struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); - void __iomem *pio = at91_gpio->regbase; - unsigned mask = 1 << offset; - - writel_relaxed(mask, pio + (val ? PIO_SODR : PIO_CODR)); - writel_relaxed(mask, pio + PIO_OER); - - return 0; -} - -static int at91_gpio_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); - int virq; - - if (offset < chip->ngpio) - virq = irq_create_mapping(at91_gpio->domain, offset); - else - virq = -ENXIO; - - dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n", - chip->label, offset + chip->base, virq); - return virq; -} - -#ifdef CONFIG_DEBUG_FS -static void at91_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) -{ - enum at91_mux mode; - int i; - struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); - void __iomem *pio = at91_gpio->regbase; - - for (i = 0; i < chip->ngpio; i++) { - unsigned pin = chip->base + i; - unsigned mask = pin_to_mask(pin); - const char *gpio_label; - u32 pdsr; - - gpio_label = gpiochip_is_requested(chip, i); - if (!gpio_label) - continue; - mode = at91_gpio->ops->get_periph(pio, mask); - seq_printf(s, "[%s] GPIO%s%d: ", - gpio_label, chip->label, i); - if (mode == AT91_MUX_GPIO) { - pdsr = readl_relaxed(pio + PIO_PDSR); - - seq_printf(s, "[gpio] %s\n", - pdsr & mask ? - "set" : "clear"); - } else { - seq_printf(s, "[periph %c]\n", - mode + 'A' - 1); - } - } -} -#else -#define at91_gpio_dbg_show NULL -#endif - -/* Several AIC controller irqs are dispatched through this GPIO handler. - * To use any AT91_PIN_* as an externally triggered IRQ, first call - * at91_set_gpio_input() then maybe enable its glitch filter. - * Then just request_irq() with the pin ID; it works like any ARM IRQ - * handler. - * First implementation always triggers on rising and falling edges - * whereas the newer PIO3 can be additionally configured to trigger on - * level, edge with any polarity. - * - * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after - * configuring them with at91_set_a_periph() or at91_set_b_periph(). - * IRQ0..IRQ6 should be configurable, e.g. level vs edge triggering. - */ - -static void gpio_irq_mask(struct irq_data *d) -{ - struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); - void __iomem *pio = at91_gpio->regbase; - unsigned mask = 1 << d->hwirq; - - if (pio) - writel_relaxed(mask, pio + PIO_IDR); -} - -static void gpio_irq_unmask(struct irq_data *d) -{ - struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); - void __iomem *pio = at91_gpio->regbase; - unsigned mask = 1 << d->hwirq; - - if (pio) - writel_relaxed(mask, pio + PIO_IER); -} - -static int gpio_irq_type(struct irq_data *d, unsigned type) -{ - switch (type) { - case IRQ_TYPE_NONE: - case IRQ_TYPE_EDGE_BOTH: - return 0; - default: - return -EINVAL; - } -} - -/* Alternate irq type for PIO3 support */ -static int alt_gpio_irq_type(struct irq_data *d, unsigned type) -{ - struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); - void __iomem *pio = at91_gpio->regbase; - unsigned mask = 1 << d->hwirq; - - switch (type) { - case IRQ_TYPE_EDGE_RISING: - writel_relaxed(mask, pio + PIO_ESR); - writel_relaxed(mask, pio + PIO_REHLSR); - break; - case IRQ_TYPE_EDGE_FALLING: - writel_relaxed(mask, pio + PIO_ESR); - writel_relaxed(mask, pio + PIO_FELLSR); - break; - case IRQ_TYPE_LEVEL_LOW: - writel_relaxed(mask, pio + PIO_LSR); - writel_relaxed(mask, pio + PIO_FELLSR); - break; - case IRQ_TYPE_LEVEL_HIGH: - writel_relaxed(mask, pio + PIO_LSR); - writel_relaxed(mask, pio + PIO_REHLSR); - break; - case IRQ_TYPE_EDGE_BOTH: - /* - * disable additional interrupt modes: - * fall back to default behavior - */ - writel_relaxed(mask, pio + PIO_AIMDR); - return 0; - case IRQ_TYPE_NONE: - default: - pr_warn("AT91: No type for irq %d\n", gpio_to_irq(d->irq)); - return -EINVAL; - } - - /* enable additional interrupt modes */ - writel_relaxed(mask, pio + PIO_AIMER); - - return 0; -} - -#ifdef CONFIG_PM -static int gpio_irq_set_wake(struct irq_data *d, unsigned state) -{ - struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); - unsigned bank = at91_gpio->pioc_idx; - - if (unlikely(bank >= MAX_GPIO_BANKS)) - return -EINVAL; - - irq_set_irq_wake(at91_gpio->pioc_virq, state); - - return 0; -} -#else -#define gpio_irq_set_wake NULL -#endif - -static struct irq_chip gpio_irqchip = { - .name = "GPIO", - .irq_disable = gpio_irq_mask, - .irq_mask = gpio_irq_mask, - .irq_unmask = gpio_irq_unmask, - /* .irq_set_type is set dynamically */ - .irq_set_wake = gpio_irq_set_wake, -}; - -static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) -{ - struct irq_chip *chip = irq_desc_get_chip(desc); - struct irq_data *idata = irq_desc_get_irq_data(desc); - struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata); - void __iomem *pio = at91_gpio->regbase; - unsigned long isr; - int n; - - chained_irq_enter(chip, desc); - for (;;) { - /* Reading ISR acks pending (edge triggered) GPIO interrupts. - * When there none are pending, we're finished unless we need - * to process multiple banks (like ID_PIOCDE on sam9263). - */ - isr = readl_relaxed(pio + PIO_ISR) & readl_relaxed(pio + PIO_IMR); - if (!isr) { - if (!at91_gpio->next) - break; - at91_gpio = at91_gpio->next; - pio = at91_gpio->regbase; - continue; - } - - for_each_set_bit(n, &isr, BITS_PER_LONG) { - generic_handle_irq(irq_find_mapping(at91_gpio->domain, n)); - } - } - chained_irq_exit(chip, desc); - /* now it may re-trigger */ -} - -/* - * This lock class tells lockdep that GPIO irqs are in a different - * category than their parents, so it won't report false recursion. - */ -static struct lock_class_key gpio_lock_class; - -static int at91_gpio_irq_map(struct irq_domain *h, unsigned int virq, - irq_hw_number_t hw) -{ - struct at91_gpio_chip *at91_gpio = h->host_data; - - irq_set_lockdep_class(virq, &gpio_lock_class); - - /* - * Can use the "simple" and not "edge" handler since it's - * shorter, and the AIC handles interrupts sanely. - */ - irq_set_chip_and_handler(virq, &gpio_irqchip, - handle_simple_irq); - set_irq_flags(virq, IRQF_VALID); - irq_set_chip_data(virq, at91_gpio); - - return 0; -} - -static int at91_gpio_irq_domain_xlate(struct irq_domain *d, - struct device_node *ctrlr, - const u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, - unsigned int *out_type) -{ - struct at91_gpio_chip *at91_gpio = d->host_data; - int ret; - int pin = at91_gpio->chip.base + intspec[0]; - - if (WARN_ON(intsize < 2)) - return -EINVAL; - *out_hwirq = intspec[0]; - *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK; - - ret = gpio_request(pin, ctrlr->full_name); - if (ret) - return ret; - - ret = gpio_direction_input(pin); - if (ret) - return ret; - - return 0; -} - -static struct irq_domain_ops at91_gpio_ops = { - .map = at91_gpio_irq_map, - .xlate = at91_gpio_irq_domain_xlate, -}; - -static int at91_gpio_of_irq_setup(struct device_node *node, - struct at91_gpio_chip *at91_gpio) -{ - struct at91_gpio_chip *prev = NULL; - struct irq_data *d = irq_get_irq_data(at91_gpio->pioc_virq); - - at91_gpio->pioc_hwirq = irqd_to_hwirq(d); - - /* Setup proper .irq_set_type function */ - gpio_irqchip.irq_set_type = at91_gpio->ops->irq_type; - - /* Disable irqs of this PIO controller */ - writel_relaxed(~0, at91_gpio->regbase + PIO_IDR); - - /* Setup irq domain */ - at91_gpio->domain = irq_domain_add_linear(node, at91_gpio->chip.ngpio, - &at91_gpio_ops, at91_gpio); - if (!at91_gpio->domain) - panic("at91_gpio.%d: couldn't allocate irq domain (DT).\n", - at91_gpio->pioc_idx); - - /* Setup chained handler */ - if (at91_gpio->pioc_idx) - prev = gpio_chips[at91_gpio->pioc_idx - 1]; - - /* The toplevel handler handles one bank of GPIOs, except - * on some SoC it can handles up to three... - * We only set up the handler for the first of the list. - */ - if (prev && prev->next == at91_gpio) - return 0; - - irq_set_chip_data(at91_gpio->pioc_virq, at91_gpio); - irq_set_chained_handler(at91_gpio->pioc_virq, gpio_irq_handler); - - return 0; -} - -/* This structure is replicated for each GPIO block allocated at probe time */ -static struct gpio_chip at91_gpio_template = { - .request = at91_gpio_request, - .free = at91_gpio_free, - .direction_input = at91_gpio_direction_input, - .get = at91_gpio_get, - .direction_output = at91_gpio_direction_output, - .set = at91_gpio_set, - .to_irq = at91_gpio_to_irq, - .dbg_show = at91_gpio_dbg_show, - .can_sleep = 0, - .ngpio = MAX_NB_GPIO_PER_BANK, -}; - -static void __devinit at91_gpio_probe_fixup(void) -{ - unsigned i; - struct at91_gpio_chip *at91_gpio, *last = NULL; - - for (i = 0; i < gpio_banks; i++) { - at91_gpio = gpio_chips[i]; - - /* - * GPIO controller are grouped on some SoC: - * PIOC, PIOD and PIOE can share the same IRQ line - */ - if (last && last->pioc_virq == at91_gpio->pioc_virq) - last->next = at91_gpio; - last = at91_gpio; - } -} - -static struct of_device_id at91_gpio_of_match[] __devinitdata = { - { .compatible = "atmel,at91sam9x5-gpio", .data = &at91sam9x5_ops, }, - { .compatible = "atmel,at91rm9200-gpio", .data = &at91rm9200_ops }, - { /* sentinel */ } -}; - -static int __devinit at91_gpio_probe(struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node; - struct resource *res; - struct at91_gpio_chip *at91_chip = NULL; - struct gpio_chip *chip; - struct pinctrl_gpio_range *range; - int ret = 0; - int irq, i; - int alias_idx = of_alias_get_id(np, "gpio"); - uint32_t ngpio; - char **names; - - BUG_ON(alias_idx >= ARRAY_SIZE(gpio_chips)); - if (gpio_chips[alias_idx]) { - ret = -EBUSY; - goto err; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - ret = -ENOENT; - goto err; - } - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - ret = irq; - goto err; - } - - at91_chip = devm_kzalloc(&pdev->dev, sizeof(*at91_chip), GFP_KERNEL); - if (!at91_chip) { - ret = -ENOMEM; - goto err; - } - - at91_chip->regbase = devm_request_and_ioremap(&pdev->dev, res); - if (!at91_chip->regbase) { - dev_err(&pdev->dev, "failed to map registers, ignoring.\n"); - ret = -EBUSY; - goto err; - } - - at91_chip->ops = (struct at91_pinctrl_mux_ops*) - of_match_device(at91_gpio_of_match, &pdev->dev)->data; - at91_chip->pioc_virq = irq; - at91_chip->pioc_idx = alias_idx; - - at91_chip->clock = clk_get(&pdev->dev, NULL); - if (IS_ERR(at91_chip->clock)) { - dev_err(&pdev->dev, "failed to get clock, ignoring.\n"); - goto err; - } - - if (clk_prepare(at91_chip->clock)) - goto clk_prep_err; - - /* enable PIO controller's clock */ - if (clk_enable(at91_chip->clock)) { - dev_err(&pdev->dev, "failed to enable clock, ignoring.\n"); - goto clk_err; - } - - at91_chip->chip = at91_gpio_template; - - chip = &at91_chip->chip; - chip->of_node = np; - chip->label = dev_name(&pdev->dev); - chip->dev = &pdev->dev; - chip->owner = THIS_MODULE; - chip->base = alias_idx * MAX_NB_GPIO_PER_BANK; - - if (!of_property_read_u32(np, "#gpio-lines", &ngpio)) { - if (ngpio >= MAX_NB_GPIO_PER_BANK) - pr_err("at91_gpio.%d, gpio-nb >= %d failback to %d\n", - alias_idx, MAX_NB_GPIO_PER_BANK, MAX_NB_GPIO_PER_BANK); - else - chip->ngpio = ngpio; - } - - names = devm_kzalloc(&pdev->dev, sizeof(char*) * chip->ngpio, GFP_KERNEL); - - if (!names) { - ret = -ENOMEM; - goto clk_err; - } - - for (i = 0; i < chip->ngpio; i++) - names[i] = kasprintf(GFP_KERNEL, "pio%c%d", alias_idx + 'A', i); - - chip->names = (const char*const*)names; - - range = &at91_chip->range; - range->name = chip->label; - range->id = alias_idx; - range->pin_base = range->base = range->id * MAX_NB_GPIO_PER_BANK; - - range->npins = chip->ngpio; - range->gc = chip; - - ret = gpiochip_add(chip); - if (ret) - goto clk_err; - - gpio_chips[alias_idx] = at91_chip; - gpio_banks = max(gpio_banks, alias_idx + 1); - - at91_gpio_probe_fixup(); - - at91_gpio_of_irq_setup(np, at91_chip); - - dev_info(&pdev->dev, "at address %p\n", at91_chip->regbase); - - return 0; - -clk_err: - clk_unprepare(at91_chip->clock); -clk_prep_err: - clk_put(at91_chip->clock); -err: - dev_err(&pdev->dev, "Failure %i for GPIO %i\n", ret, alias_idx); - - return ret; -} - -static struct platform_driver at91_gpio_driver = { - .driver = { - .name = "gpio-at91", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(at91_gpio_of_match), - }, - .probe = at91_gpio_probe, -}; - -static struct platform_driver at91_pinctrl_driver = { - .driver = { - .name = "pinctrl-at91", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(at91_pinctrl_of_match), - }, - .probe = at91_pinctrl_probe, - .remove = __devexit_p(at91_pinctrl_remove), -}; - -static int __init at91_pinctrl_init(void) -{ - int ret; - - ret = platform_driver_register(&at91_gpio_driver); - if (ret) - return ret; - return platform_driver_register(&at91_pinctrl_driver); -} -arch_initcall(at91_pinctrl_init); - -static void __exit at91_pinctrl_exit(void) -{ - platform_driver_unregister(&at91_pinctrl_driver); -} - -module_exit(at91_pinctrl_exit); -MODULE_AUTHOR("Jean-Christophe PLAGNIOL-VILLARD "); -MODULE_DESCRIPTION("Atmel AT91 pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/pinctrl/pinctrl-bcm2835.c b/trunk/drivers/pinctrl/pinctrl-bcm2835.c index 9a963edd66d1..7e9be18ec2d2 100644 --- a/trunk/drivers/pinctrl/pinctrl-bcm2835.c +++ b/trunk/drivers/pinctrl/pinctrl-bcm2835.c @@ -916,7 +916,7 @@ static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev, return 0; } -static struct pinconf_ops bcm2835_pinconf_ops = { +struct pinconf_ops bcm2835_pinconf_ops = { .pin_config_get = bcm2835_pinconf_get, .pin_config_set = bcm2835_pinconf_set, }; diff --git a/trunk/drivers/pinctrl/pinctrl-coh901.c b/trunk/drivers/pinctrl/pinctrl-coh901.c index fbb37154471c..b446c9641212 100644 --- a/trunk/drivers/pinctrl/pinctrl-coh901.c +++ b/trunk/drivers/pinctrl/pinctrl-coh901.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -65,8 +64,10 @@ struct u300_gpio { struct gpio_chip chip; struct list_head port_list; struct clk *clk; + struct resource *memres; void __iomem *base; struct device *dev; + int irq_base; u32 stride; /* Register offsets */ u32 pcr; @@ -82,7 +83,6 @@ struct u300_gpio_port { struct list_head node; struct u300_gpio *gpio; char name[8]; - struct irq_domain *domain; int irq; int number; u8 toggle_edge_mode; @@ -314,30 +314,10 @@ static int u300_gpio_direction_output(struct gpio_chip *chip, unsigned offset, static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset) { struct u300_gpio *gpio = to_u300_gpio(chip); - int portno = offset >> 3; - struct u300_gpio_port *port = NULL; - struct list_head *p; - int retirq; + int retirq = gpio->irq_base + offset; - list_for_each(p, &gpio->port_list) { - port = list_entry(p, struct u300_gpio_port, node); - if (port->number == portno) - break; - } - if (port == NULL) { - dev_err(gpio->dev, "could not locate port for GPIO %d IRQ\n", - offset); - return -EINVAL; - } - - /* - * The local hwirqs on the port are the lower three bits, there - * are exactly 8 IRQs per port since they are 8-bit - */ - retirq = irq_find_mapping(port->domain, (offset & 0x7)); - - dev_dbg(gpio->dev, "request IRQ for GPIO %d, return %d from port %d\n", - offset, retirq, port->number); + dev_dbg(gpio->dev, "request IRQ for GPIO %d, return %d\n", offset, + retirq); return retirq; } @@ -487,7 +467,7 @@ static int u300_gpio_irq_type(struct irq_data *d, unsigned trigger) { struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); struct u300_gpio *gpio = port->gpio; - int offset = (port->number << 3) + d->hwirq; + int offset = d->irq - gpio->irq_base; u32 val; if ((trigger & IRQF_TRIGGER_RISING) && @@ -523,12 +503,10 @@ static void u300_gpio_irq_enable(struct irq_data *d) { struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); struct u300_gpio *gpio = port->gpio; - int offset = (port->number << 3) + d->hwirq; + int offset = d->irq - gpio->irq_base; u32 val; unsigned long flags; - dev_dbg(gpio->dev, "enable IRQ for hwirq %lu on port %s, offset %d\n", - d->hwirq, port->name, offset); local_irq_save(flags); val = readl(U300_PIN_REG(offset, ien)); writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, ien)); @@ -539,7 +517,7 @@ static void u300_gpio_irq_disable(struct irq_data *d) { struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); struct u300_gpio *gpio = port->gpio; - int offset = (port->number << 3) + d->hwirq; + int offset = d->irq - gpio->irq_base; u32 val; unsigned long flags; @@ -577,7 +555,8 @@ static void u300_gpio_irq_handler(unsigned irq, struct irq_desc *desc) int irqoffset; for_each_set_bit(irqoffset, &val, U300_GPIO_PINS_PER_PORT) { - int pin_irq = irq_find_mapping(port->domain, irqoffset); + int pin_irq = gpio->irq_base + (port->number << 3) + + irqoffset; int offset = pinoffset + irqoffset; dev_dbg(gpio->dev, "GPIO IRQ %d on pin %d\n", @@ -652,86 +631,64 @@ static inline void u300_gpio_free_ports(struct u300_gpio *gpio) list_for_each_safe(p, n, &gpio->port_list) { port = list_entry(p, struct u300_gpio_port, node); list_del(&port->node); - if (port->domain) - irq_domain_remove(port->domain); kfree(port); } } -/* - * Here we map a GPIO in the local gpio_chip pin space to a pin in - * the local pinctrl pin space. The pin controller used is - * pinctrl-u300. - */ -struct coh901_pinpair { - unsigned int offset; - unsigned int pin_base; -}; - -#define COH901_PINRANGE(a, b) { .offset = a, .pin_base = b } - -static struct coh901_pinpair coh901_pintable[] = { - COH901_PINRANGE(10, 426), - COH901_PINRANGE(11, 180), - COH901_PINRANGE(12, 165), /* MS/MMC card insertion */ - COH901_PINRANGE(13, 179), - COH901_PINRANGE(14, 178), - COH901_PINRANGE(16, 194), - COH901_PINRANGE(17, 193), - COH901_PINRANGE(18, 192), - COH901_PINRANGE(19, 191), - COH901_PINRANGE(20, 186), - COH901_PINRANGE(21, 185), - COH901_PINRANGE(22, 184), - COH901_PINRANGE(23, 183), - COH901_PINRANGE(24, 182), - COH901_PINRANGE(25, 181), -}; - static int __init u300_gpio_probe(struct platform_device *pdev) { struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev); struct u300_gpio *gpio; - struct resource *memres; int err = 0; int portno; u32 val; u32 ifr; int i; - gpio = devm_kzalloc(&pdev->dev, sizeof(struct u300_gpio), GFP_KERNEL); - if (gpio == NULL) + gpio = kzalloc(sizeof(struct u300_gpio), GFP_KERNEL); + if (gpio == NULL) { + dev_err(&pdev->dev, "failed to allocate memory\n"); return -ENOMEM; + } gpio->chip = u300_gpio_chip; gpio->chip.ngpio = plat->ports * U300_GPIO_PINS_PER_PORT; + gpio->irq_base = plat->gpio_irq_base; gpio->chip.dev = &pdev->dev; gpio->chip.base = plat->gpio_base; gpio->dev = &pdev->dev; - memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!memres) { - dev_err(gpio->dev, "could not get GPIO memory resource\n"); - return -ENODEV; - } - - gpio->base = devm_request_and_ioremap(&pdev->dev, memres); - if (!gpio->base) { - dev_err(gpio->dev, "could not get remap memory\n"); - return -ENOMEM; - } - - gpio->clk = devm_clk_get(gpio->dev, NULL); + /* Get GPIO clock */ + gpio->clk = clk_get(gpio->dev, NULL); if (IS_ERR(gpio->clk)) { err = PTR_ERR(gpio->clk); dev_err(gpio->dev, "could not get GPIO clock\n"); - return err; + goto err_no_clk; } - err = clk_prepare_enable(gpio->clk); if (err) { dev_err(gpio->dev, "could not enable GPIO clock\n"); - return err; + goto err_no_clk_enable; + } + + gpio->memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!gpio->memres) { + dev_err(gpio->dev, "could not get GPIO memory resource\n"); + err = -ENODEV; + goto err_no_resource; + } + + if (!request_mem_region(gpio->memres->start, + resource_size(gpio->memres), + "GPIO Controller")) { + err = -ENODEV; + goto err_no_ioregion; + } + + gpio->base = ioremap(gpio->memres->start, resource_size(gpio->memres)); + if (!gpio->base) { + err = -ENOMEM; + goto err_no_ioremap; } dev_info(gpio->dev, @@ -775,28 +732,18 @@ static int __init u300_gpio_probe(struct platform_device *pdev) port->irq = platform_get_irq_byname(pdev, port->name); - dev_dbg(gpio->dev, "register IRQ %d for port %s\n", port->irq, + dev_dbg(gpio->dev, "register IRQ %d for %s\n", port->irq, port->name); - port->domain = irq_domain_add_linear(pdev->dev.of_node, - U300_GPIO_PINS_PER_PORT, - &irq_domain_simple_ops, - port); - if (!port->domain) { - err = -ENOMEM; - goto err_no_domain; - } - irq_set_chained_handler(port->irq, u300_gpio_irq_handler); irq_set_handler_data(port->irq, port); /* For each GPIO pin set the unique IRQ handler */ for (i = 0; i < U300_GPIO_PINS_PER_PORT; i++) { - int irqno = irq_create_mapping(port->domain, i); + int irqno = gpio->irq_base + (portno << 3) + i; - dev_dbg(gpio->dev, "GPIO%d on port %s gets IRQ %d\n", - gpio->chip.base + (port->number << 3) + i, - port->name, irqno); + dev_dbg(gpio->dev, "handler for IRQ %d on %s\n", + irqno, port->name); irq_set_chip_and_handler(irqno, &u300_gpio_irqchip, handle_simple_irq); set_irq_flags(irqno, IRQF_VALID); @@ -816,31 +763,32 @@ static int __init u300_gpio_probe(struct platform_device *pdev) goto err_no_chip; } - /* - * Add pinctrl pin ranges, the pin controller must be registered - * at this point - */ - for (i = 0; i < ARRAY_SIZE(coh901_pintable); i++) { - struct coh901_pinpair *p = &coh901_pintable[i]; - - err = gpiochip_add_pin_range(&gpio->chip, "pinctrl-u300", - p->offset, p->pin_base, 1); - if (err) - goto err_no_range; - } + /* Spawn pin controller device as child of the GPIO, pass gpio chip */ + plat->pinctrl_device->dev.platform_data = &gpio->chip; + err = platform_device_register(plat->pinctrl_device); + if (err) + goto err_no_pinctrl; platform_set_drvdata(pdev, gpio); return 0; -err_no_range: +err_no_pinctrl: err = gpiochip_remove(&gpio->chip); err_no_chip: -err_no_domain: err_no_port: u300_gpio_free_ports(gpio); + iounmap(gpio->base); +err_no_ioremap: + release_mem_region(gpio->memres->start, resource_size(gpio->memres)); +err_no_ioregion: +err_no_resource: clk_disable_unprepare(gpio->clk); - dev_err(&pdev->dev, "module ERROR:%d\n", err); +err_no_clk_enable: + clk_put(gpio->clk); +err_no_clk: + kfree(gpio); + dev_info(&pdev->dev, "module ERROR:%d\n", err); return err; } @@ -858,8 +806,13 @@ static int __exit u300_gpio_remove(struct platform_device *pdev) return err; } u300_gpio_free_ports(gpio); + iounmap(gpio->base); + release_mem_region(gpio->memres->start, + resource_size(gpio->memres)); clk_disable_unprepare(gpio->clk); + clk_put(gpio->clk); platform_set_drvdata(pdev, NULL); + kfree(gpio); return 0; } diff --git a/trunk/drivers/pinctrl/mvebu/pinctrl-dove.c b/trunk/drivers/pinctrl/pinctrl-dove.c similarity index 100% rename from trunk/drivers/pinctrl/mvebu/pinctrl-dove.c rename to trunk/drivers/pinctrl/pinctrl-dove.c diff --git a/trunk/drivers/pinctrl/pinctrl-exynos.c b/trunk/drivers/pinctrl/pinctrl-exynos.c index 6ff665209a4c..21362f48d370 100644 --- a/trunk/drivers/pinctrl/pinctrl-exynos.c +++ b/trunk/drivers/pinctrl/pinctrl-exynos.c @@ -36,7 +36,6 @@ /* list of external wakeup controllers supported */ static const struct of_device_id exynos_wkup_irq_ids[] = { { .compatible = "samsung,exynos4210-wakeup-eint", }, - { } }; static void exynos_gpio_irq_unmask(struct irq_data *irqd) diff --git a/trunk/drivers/pinctrl/pinctrl-falcon.c b/trunk/drivers/pinctrl/pinctrl-falcon.c index 8ed20e84cb02..ee7305903470 100644 --- a/trunk/drivers/pinctrl/pinctrl-falcon.c +++ b/trunk/drivers/pinctrl/pinctrl-falcon.c @@ -322,7 +322,7 @@ static void falcon_pinconf_group_dbg_show(struct pinctrl_dev *pctrldev, { } -static struct pinconf_ops falcon_pinconf_ops = { +struct pinconf_ops falcon_pinconf_ops = { .pin_config_get = falcon_pinconf_get, .pin_config_set = falcon_pinconf_set, .pin_config_group_get = falcon_pinconf_group_get, diff --git a/trunk/drivers/pinctrl/pinctrl-imx.c b/trunk/drivers/pinctrl/pinctrl-imx.c index 525a2c8644f6..63866d95357d 100644 --- a/trunk/drivers/pinctrl/pinctrl-imx.c +++ b/trunk/drivers/pinctrl/pinctrl-imx.c @@ -71,7 +71,7 @@ static const struct imx_pin_reg *imx_find_pin_reg( break; } - if (i == info->npin_regs) { + if (!pin_reg) { dev_err(info->dev, "Pin(%s): unable to find pin reg map\n", info->pins[pin].name); return NULL; @@ -397,7 +397,7 @@ static void imx_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, } } -static struct pinconf_ops imx_pinconf_ops = { +struct pinconf_ops imx_pinconf_ops = { .pin_config_get = imx_pinconf_get, .pin_config_set = imx_pinconf_set, .pin_config_dbg_show = imx_pinconf_dbg_show, diff --git a/trunk/drivers/pinctrl/mvebu/pinctrl-kirkwood.c b/trunk/drivers/pinctrl/pinctrl-kirkwood.c similarity index 100% rename from trunk/drivers/pinctrl/mvebu/pinctrl-kirkwood.c rename to trunk/drivers/pinctrl/pinctrl-kirkwood.c diff --git a/trunk/drivers/pinctrl/pinctrl-lantiq.c b/trunk/drivers/pinctrl/pinctrl-lantiq.c index 15f501d89026..07ba7682cf22 100644 --- a/trunk/drivers/pinctrl/pinctrl-lantiq.c +++ b/trunk/drivers/pinctrl/pinctrl-lantiq.c @@ -46,8 +46,8 @@ static int ltq_get_group_pins(struct pinctrl_dev *pctrldev, return 0; } -static void ltq_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, - struct pinctrl_map *map, unsigned num_maps) +void ltq_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, + struct pinctrl_map *map, unsigned num_maps) { int i; @@ -128,10 +128,10 @@ static int ltq_pinctrl_dt_subnode_size(struct device_node *np) return ret; } -static int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np_config, - struct pinctrl_map **map, - unsigned *num_maps) +int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, + struct device_node *np_config, + struct pinctrl_map **map, + unsigned *num_maps) { struct pinctrl_map *tmp; struct device_node *np; @@ -275,6 +275,16 @@ static int ltq_pmx_enable(struct pinctrl_dev *pctrldev, return 0; } +static void ltq_pmx_disable(struct pinctrl_dev *pctrldev, + unsigned func, + unsigned group) +{ + /* + * Nothing to do here. However, pinconf_check_ops() requires this + * callback to be defined. + */ +} + static int ltq_pmx_gpio_request_enable(struct pinctrl_dev *pctrldev, struct pinctrl_gpio_range *range, unsigned pin) @@ -302,6 +312,7 @@ static struct pinmux_ops ltq_pmx_ops = { .get_function_name = ltq_pmx_func_name, .get_function_groups = ltq_pmx_get_groups, .enable = ltq_pmx_enable, + .disable = ltq_pmx_disable, .gpio_request_enable = ltq_pmx_gpio_request_enable, }; diff --git a/trunk/drivers/pinctrl/mvebu/pinctrl-mvebu.c b/trunk/drivers/pinctrl/pinctrl-mvebu.c similarity index 99% rename from trunk/drivers/pinctrl/mvebu/pinctrl-mvebu.c rename to trunk/drivers/pinctrl/pinctrl-mvebu.c index 6c44b7e8964c..8e6266c6249a 100644 --- a/trunk/drivers/pinctrl/mvebu/pinctrl-mvebu.c +++ b/trunk/drivers/pinctrl/pinctrl-mvebu.c @@ -24,6 +24,7 @@ #include #include +#include "core.h" #include "pinctrl-mvebu.h" #define MPPS_PER_REG 8 diff --git a/trunk/drivers/pinctrl/mvebu/pinctrl-mvebu.h b/trunk/drivers/pinctrl/pinctrl-mvebu.h similarity index 100% rename from trunk/drivers/pinctrl/mvebu/pinctrl-mvebu.h rename to trunk/drivers/pinctrl/pinctrl-mvebu.h diff --git a/trunk/drivers/pinctrl/pinctrl-mxs.c b/trunk/drivers/pinctrl/pinctrl-mxs.c index 3e7d4d63f8bf..4ba4636b6a4a 100644 --- a/trunk/drivers/pinctrl/pinctrl-mxs.c +++ b/trunk/drivers/pinctrl/pinctrl-mxs.c @@ -319,7 +319,7 @@ static void mxs_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, seq_printf(s, "0x%lx", config); } -static struct pinconf_ops mxs_pinconf_ops = { +struct pinconf_ops mxs_pinconf_ops = { .pin_config_get = mxs_pinconf_get, .pin_config_set = mxs_pinconf_set, .pin_config_group_get = mxs_pinconf_group_get, diff --git a/trunk/drivers/pinctrl/pinctrl-nomadik-db8500.c b/trunk/drivers/pinctrl/pinctrl-nomadik-db8500.c index 7d88ae352119..debaa75b0552 100644 --- a/trunk/drivers/pinctrl/pinctrl-nomadik-db8500.c +++ b/trunk/drivers/pinctrl/pinctrl-nomadik-db8500.c @@ -475,10 +475,8 @@ static const unsigned hsit_a_1_pins[] = { DB8500_PIN_AJ9, DB8500_PIN_AH9, DB8500_PIN_AG9, DB8500_PIN_AG8, DB8500_PIN_AF8 }; static const unsigned hsit_a_2_pins[] = { DB8500_PIN_AJ9, DB8500_PIN_AH9, DB8500_PIN_AG9, DB8500_PIN_AG8 }; -static const unsigned clkout1_a_1_pins[] = { DB8500_PIN_AH7 }; -static const unsigned clkout1_a_2_pins[] = { DB8500_PIN_AG7 }; -static const unsigned clkout2_a_1_pins[] = { DB8500_PIN_AJ6 }; -static const unsigned clkout2_a_2_pins[] = { DB8500_PIN_AF7 }; +static const unsigned clkout_a_1_pins[] = { DB8500_PIN_AH7, DB8500_PIN_AJ6 }; +static const unsigned clkout_a_2_pins[] = { DB8500_PIN_AG7, DB8500_PIN_AF7 }; static const unsigned usb_a_1_pins[] = { DB8500_PIN_AF28, DB8500_PIN_AE29, DB8500_PIN_AD29, DB8500_PIN_AC29, DB8500_PIN_AD28, DB8500_PIN_AD26, DB8500_PIN_AE26, DB8500_PIN_AG29, DB8500_PIN_AE27, DB8500_PIN_AD27, @@ -594,8 +592,7 @@ static const unsigned stmmod_c_1_pins[] = { DB8500_PIN_C20, DB8500_PIN_B21, DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24 }; static const unsigned usbsim_c_1_pins[] = { DB8500_PIN_D22 }; static const unsigned mc4rstn_c_1_pins[] = { DB8500_PIN_AF25 }; -static const unsigned clkout1_c_1_pins[] = { DB8500_PIN_AH13 }; -static const unsigned clkout2_c_1_pins[] = { DB8500_PIN_AH12 }; +static const unsigned clkout_c_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AH12 }; static const unsigned i2c3_c_1_pins[] = { DB8500_PIN_AG12, DB8500_PIN_AH11 }; static const unsigned spi0_c_1_pins[] = { DB8500_PIN_AH10, DB8500_PIN_AH9, DB8500_PIN_AG9, DB8500_PIN_AG8 }; @@ -603,66 +600,14 @@ static const unsigned usbsim_c_2_pins[] = { DB8500_PIN_AF8 }; static const unsigned i2c3_c_2_pins[] = { DB8500_PIN_AG7, DB8500_PIN_AF7 }; /* Other C1 column */ -static const unsigned u2rx_oc1_1_pins[] = { DB8500_PIN_AB2 }; -static const unsigned stmape_oc1_1_pins[] = { DB8500_PIN_AA4, DB8500_PIN_Y4, - DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 }; -static const unsigned remap0_oc1_1_pins[] = { DB8500_PIN_E1 }; -static const unsigned remap1_oc1_1_pins[] = { DB8500_PIN_E2 }; -static const unsigned ptma9_oc1_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4, - DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3, DB8500_PIN_H2, - DB8500_PIN_J2, DB8500_PIN_H1 }; static const unsigned kp_oc1_1_pins[] = { DB8500_PIN_C6, DB8500_PIN_B3, DB8500_PIN_C4, DB8500_PIN_E6, DB8500_PIN_A3, DB8500_PIN_B6, DB8500_PIN_D6, DB8500_PIN_B7 }; -static const unsigned rf_oc1_1_pins[] = { DB8500_PIN_D8, DB8500_PIN_D9 }; -static const unsigned hxclk_oc1_1_pins[] = { DB8500_PIN_D16 }; -static const unsigned uartmodrx_oc1_1_pins[] = { DB8500_PIN_B17 }; -static const unsigned uartmodtx_oc1_1_pins[] = { DB8500_PIN_C16 }; -static const unsigned stmmod_oc1_1_pins[] = { DB8500_PIN_C19, DB8500_PIN_C17, - DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19 }; -static const unsigned hxgpio_oc1_1_pins[] = { DB8500_PIN_D21, DB8500_PIN_D20, - DB8500_PIN_C20, DB8500_PIN_B21, DB8500_PIN_C21, DB8500_PIN_A22, - DB8500_PIN_B24, DB8500_PIN_C22 }; -static const unsigned rf_oc1_2_pins[] = { DB8500_PIN_C23, DB8500_PIN_D23 }; static const unsigned spi2_oc1_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AG12, DB8500_PIN_AH12, DB8500_PIN_AH11 }; static const unsigned spi2_oc1_2_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AH12, DB8500_PIN_AH11 }; -/* Other C2 column */ -static const unsigned sbag_oc2_1_pins[] = { DB8500_PIN_AA4, DB8500_PIN_AB2, - DB8500_PIN_Y4, DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 }; -static const unsigned etmr4_oc2_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4, - DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3, DB8500_PIN_H2, - DB8500_PIN_J2, DB8500_PIN_H1 }; -static const unsigned ptma9_oc2_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16, - DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17, - DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20, - DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21, - DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 }; - -/* Other C3 column */ -static const unsigned stmmod_oc3_1_pins[] = { DB8500_PIN_AB2, DB8500_PIN_W2, - DB8500_PIN_W3, DB8500_PIN_V3, DB8500_PIN_V2 }; -static const unsigned stmmod_oc3_2_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4, - DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3 }; -static const unsigned uartmodrx_oc3_1_pins[] = { DB8500_PIN_H2 }; -static const unsigned uartmodtx_oc3_1_pins[] = { DB8500_PIN_J2 }; -static const unsigned etmr4_oc3_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16, - DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17, - DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20, - DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21, - DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 }; - -/* Other C4 column */ -static const unsigned sbag_oc4_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4, - DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3, DB8500_PIN_H1 }; -static const unsigned hwobs_oc4_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16, - DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17, - DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20, - DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21, - DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 }; - #define DB8500_PIN_GROUP(a,b) { .name = #a, .pins = a##_pins, \ .npins = ARRAY_SIZE(a##_pins), .altsetting = b } @@ -694,7 +639,6 @@ static const struct nmk_pingroup nmk_db8500_groups[] = { DB8500_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A), DB8500_PIN_GROUP(ipgpio0_a_1, NMK_GPIO_ALT_A), DB8500_PIN_GROUP(ipgpio1_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(kp_a_2, NMK_GPIO_ALT_A), DB8500_PIN_GROUP(msp2sck_a_1, NMK_GPIO_ALT_A), DB8500_PIN_GROUP(msp2_a_1, NMK_GPIO_ALT_A), DB8500_PIN_GROUP(mc4_a_1, NMK_GPIO_ALT_A), @@ -703,10 +647,8 @@ static const struct nmk_pingroup nmk_db8500_groups[] = { DB8500_PIN_GROUP(hsir_a_1, NMK_GPIO_ALT_A), DB8500_PIN_GROUP(hsit_a_1, NMK_GPIO_ALT_A), DB8500_PIN_GROUP(hsit_a_2, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(clkout1_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(clkout1_a_2, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(clkout2_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(clkout2_a_2, NMK_GPIO_ALT_A), + DB8500_PIN_GROUP(clkout_a_1, NMK_GPIO_ALT_A), + DB8500_PIN_GROUP(clkout_a_2, NMK_GPIO_ALT_A), DB8500_PIN_GROUP(usb_a_1, NMK_GPIO_ALT_A), /* Altfunction B column */ DB8500_PIN_GROUP(trig_b_1, NMK_GPIO_ALT_B), @@ -778,41 +720,15 @@ static const struct nmk_pingroup nmk_db8500_groups[] = { DB8500_PIN_GROUP(stmmod_c_1, NMK_GPIO_ALT_C), DB8500_PIN_GROUP(usbsim_c_1, NMK_GPIO_ALT_C), DB8500_PIN_GROUP(mc4rstn_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(clkout1_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(clkout2_c_1, NMK_GPIO_ALT_C), + DB8500_PIN_GROUP(clkout_c_1, NMK_GPIO_ALT_C), DB8500_PIN_GROUP(i2c3_c_1, NMK_GPIO_ALT_C), DB8500_PIN_GROUP(spi0_c_1, NMK_GPIO_ALT_C), DB8500_PIN_GROUP(usbsim_c_2, NMK_GPIO_ALT_C), DB8500_PIN_GROUP(i2c3_c_2, NMK_GPIO_ALT_C), /* Other alt C1 column */ - DB8500_PIN_GROUP(u2rx_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(stmape_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(remap0_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(remap1_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(ptma9_oc1_1, NMK_GPIO_ALT_C1), DB8500_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(rf_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(hxclk_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(uartmodrx_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(uartmodtx_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(stmmod_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(hxgpio_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(rf_oc1_2, NMK_GPIO_ALT_C1), DB8500_PIN_GROUP(spi2_oc1_1, NMK_GPIO_ALT_C1), DB8500_PIN_GROUP(spi2_oc1_2, NMK_GPIO_ALT_C1), - /* Other alt C2 column */ - DB8500_PIN_GROUP(sbag_oc2_1, NMK_GPIO_ALT_C2), - DB8500_PIN_GROUP(etmr4_oc2_1, NMK_GPIO_ALT_C2), - DB8500_PIN_GROUP(ptma9_oc2_1, NMK_GPIO_ALT_C2), - /* Other alt C3 column */ - DB8500_PIN_GROUP(stmmod_oc3_1, NMK_GPIO_ALT_C3), - DB8500_PIN_GROUP(stmmod_oc3_2, NMK_GPIO_ALT_C3), - DB8500_PIN_GROUP(uartmodrx_oc3_1, NMK_GPIO_ALT_C3), - DB8500_PIN_GROUP(uartmodtx_oc3_1, NMK_GPIO_ALT_C3), - DB8500_PIN_GROUP(etmr4_oc3_1, NMK_GPIO_ALT_C3), - /* Other alt C4 column */ - DB8500_PIN_GROUP(sbag_oc4_1, NMK_GPIO_ALT_C4), - DB8500_PIN_GROUP(hwobs_oc4_1, NMK_GPIO_ALT_C4), }; /* We use this macro to define the groups applicable to a function */ @@ -826,7 +742,7 @@ DB8500_FUNC_GROUPS(u1, "u1rxtx_a_1", "u1ctsrts_a_1"); * only available on two pins in alternative function C */ DB8500_FUNC_GROUPS(u2, "u2rxtx_b_1", "u2rxtx_c_1", "u2ctsrts_c_1", - "u2rxtx_c_2", "u2rxtx_c_3", "u2rx_oc1_1"); + "u2rxtx_c_2", "u2rxtx_c_3"); DB8500_FUNC_GROUPS(ipi2c, "ipi2c_a_1", "ipi2c_a_2"); /* * MSP0 can only be on a certain set of pins, but the TX/RX pins can be @@ -841,7 +757,7 @@ DB8500_FUNC_GROUPS(msp1, "msp1txrx_a_1", "msp1_a_1", "msp1txrx_b_1"); DB8500_FUNC_GROUPS(lcdb, "lcdb_a_1"); DB8500_FUNC_GROUPS(lcd, "lcdvsi0_a_1", "lcdvsi1_a_1", "lcd_d0_d7_a_1", "lcd_d8_d11_a_1", "lcd_d12_d23_a_1", "lcd_b_1"); -DB8500_FUNC_GROUPS(kp, "kp_a_1", "kp_a_2", "kp_b_1", "kp_b_2", "kp_c_1", "kp_oc1_1"); +DB8500_FUNC_GROUPS(kp, "kp_a_1", "kp_b_1", "kp_b_2", "kp_c_1", "kp_oc1_1"); DB8500_FUNC_GROUPS(mc2, "mc2_a_1", "mc2rstn_c_1"); DB8500_FUNC_GROUPS(ssp1, "ssp1_a_1"); DB8500_FUNC_GROUPS(ssp0, "ssp0_a_1"); @@ -857,8 +773,7 @@ DB8500_FUNC_GROUPS(msp2, "msp2sck_a_1", "msp2_a_1"); DB8500_FUNC_GROUPS(mc4, "mc4_a_1", "mc4rstn_c_1"); DB8500_FUNC_GROUPS(mc1, "mc1_a_1", "mc1_a_2", "mc1dir_a_1"); DB8500_FUNC_GROUPS(hsi, "hsir_a_1", "hsit_a_1", "hsit_a_2"); -DB8500_FUNC_GROUPS(clkout, "clkout1_a_1", "clkout1_a_2", "clkout1_c_1", - "clkout2_a_1", "clkout2_a_2", "clkout2_c_1"); +DB8500_FUNC_GROUPS(clkout, "clkout_a_1", "clkout_a_2", "clkout_c_1"); DB8500_FUNC_GROUPS(usb, "usb_a_1"); DB8500_FUNC_GROUPS(trig, "trig_b_1"); DB8500_FUNC_GROUPS(i2c4, "i2c4_b_1"); @@ -869,10 +784,8 @@ DB8500_FUNC_GROUPS(i2c2, "i2c2_b_1", "i2c2_b_2"); * so select one of each. */ DB8500_FUNC_GROUPS(uartmod, "uartmodtx_b_1", "uartmodrx_b_1", "uartmodrx_b_2", - "uartmodrx_c_1", "uartmod_tx_c_1", "uartmodrx_oc1_1", - "uartmodtx_oc1_1", "uartmodrx_oc3_1", "uartmodtx_oc3_1"); -DB8500_FUNC_GROUPS(stmmod, "stmmod_b_1", "stmmod_c_1", "stmmod_oc1_1", - "stmmod_oc3_1", "stmmod_oc3_2"); + "uartmodrx_c_1", "uartmod_tx_c_1"); +DB8500_FUNC_GROUPS(stmmod, "stmmod_b_1", "stmmod_c_1"); DB8500_FUNC_GROUPS(spi3, "spi3_b_1"); /* Select between CS0 on alt B or PS1 on alt C */ DB8500_FUNC_GROUPS(sm, "sm_b_1", "smcs0_b_1", "smcs1_b_1", "smcleale_c_1", @@ -886,19 +799,13 @@ DB8500_FUNC_GROUPS(ipjtag, "ipjtag_c_1"); DB8500_FUNC_GROUPS(slim0, "slim0_c_1"); DB8500_FUNC_GROUPS(ms, "ms_c_1"); DB8500_FUNC_GROUPS(iptrigout, "iptrigout_c_1"); -DB8500_FUNC_GROUPS(stmape, "stmape_c_1", "stmape_c_2", "stmape_oc1_1"); +DB8500_FUNC_GROUPS(stmape, "stmape_c_1", "stmape_c_2"); DB8500_FUNC_GROUPS(mc5, "mc5_c_1"); DB8500_FUNC_GROUPS(usbsim, "usbsim_c_1", "usbsim_c_2"); DB8500_FUNC_GROUPS(i2c3, "i2c3_c_1", "i2c3_c_2"); DB8500_FUNC_GROUPS(spi0, "spi0_c_1"); DB8500_FUNC_GROUPS(spi2, "spi2_oc1_1", "spi2_oc1_2"); -DB8500_FUNC_GROUPS(remap, "remap0_oc1_1", "remap1_oc1_1"); -DB8500_FUNC_GROUPS(sbag, "sbag_oc2_1", "sbag_oc4_1"); -DB8500_FUNC_GROUPS(ptm, "ptma9_oc1_1", "ptma9_oc2_1"); -DB8500_FUNC_GROUPS(rf, "rf_oc1_1", "rf_oc1_2"); -DB8500_FUNC_GROUPS(hx, "hxclk_oc1_1", "hxgpio_oc1_1"); -DB8500_FUNC_GROUPS(etm, "etmr4_oc2_1", "etmr4_oc3_1"); -DB8500_FUNC_GROUPS(hwobs, "hwobs_oc4_1"); + #define FUNCTION(fname) \ { \ .name = #fname, \ @@ -951,12 +858,6 @@ static const struct nmk_function nmk_db8500_functions[] = { FUNCTION(i2c3), FUNCTION(spi0), FUNCTION(spi2), - FUNCTION(remap), - FUNCTION(ptm), - FUNCTION(rf), - FUNCTION(hx), - FUNCTION(etm), - FUNCTION(hwobs), }; static const struct prcm_gpiocr_altcx_pin_desc db8500_altcx_pins[] = { diff --git a/trunk/drivers/pinctrl/pinctrl-nomadik-db8540.c b/trunk/drivers/pinctrl/pinctrl-nomadik-db8540.c index bb6a4016322a..52fc30181f7e 100644 --- a/trunk/drivers/pinctrl/pinctrl-nomadik-db8540.c +++ b/trunk/drivers/pinctrl/pinctrl-nomadik-db8540.c @@ -460,10 +460,8 @@ static const unsigned hsit_a_1_pins[] = { DB8540_PIN_B11, DB8540_PIN_B10, DB8540_PIN_E10, DB8540_PIN_B12, DB8540_PIN_D10 }; static const unsigned hsit_a_2_pins[] = { DB8540_PIN_B11, DB8540_PIN_B10, DB8540_PIN_E10, DB8540_PIN_B12 }; -static const unsigned clkout1_a_1_pins[] = { DB8540_PIN_D11 }; -static const unsigned clkout1_a_2_pins[] = { DB8540_PIN_B13 }; -static const unsigned clkout2_a_1_pins[] = { DB8540_PIN_AJ6 }; -static const unsigned clkout2_a_2_pins[] = { DB8540_PIN_C12 }; +static const unsigned clkout_a_1_pins[] = { DB8540_PIN_D11, DB8540_PIN_AJ6 }; +static const unsigned clkout_a_2_pins[] = { DB8540_PIN_B13, DB8540_PIN_C12 }; static const unsigned msp4_a_1_pins[] = { DB8540_PIN_B14, DB8540_PIN_E11 }; static const unsigned usb_a_1_pins[] = { DB8540_PIN_D12, DB8540_PIN_D15, DB8540_PIN_C13, DB8540_PIN_C14, DB8540_PIN_C18, DB8540_PIN_C16, @@ -700,10 +698,8 @@ static const struct nmk_pingroup nmk_db8540_groups[] = { DB8540_PIN_GROUP(hsir_a_1, NMK_GPIO_ALT_A), DB8540_PIN_GROUP(hsit_a_1, NMK_GPIO_ALT_A), DB8540_PIN_GROUP(hsit_a_2, NMK_GPIO_ALT_A), - DB8540_PIN_GROUP(clkout1_a_1, NMK_GPIO_ALT_A), - DB8540_PIN_GROUP(clkout1_a_2, NMK_GPIO_ALT_A), - DB8540_PIN_GROUP(clkout2_a_1, NMK_GPIO_ALT_A), - DB8540_PIN_GROUP(clkout2_a_2, NMK_GPIO_ALT_A), + DB8540_PIN_GROUP(clkout_a_1, NMK_GPIO_ALT_A), + DB8540_PIN_GROUP(clkout_a_2, NMK_GPIO_ALT_A), DB8540_PIN_GROUP(msp4_a_1, NMK_GPIO_ALT_A), DB8540_PIN_GROUP(usb_a_1, NMK_GPIO_ALT_A), /* Altfunction B column */ @@ -826,7 +822,6 @@ static const struct nmk_pingroup nmk_db8540_groups[] = { DB8540_PIN_GROUP(modaccuarttxrx_oc4_1, NMK_GPIO_ALT_C4), DB8540_PIN_GROUP(modaccuartrtscts_oc4_1, NMK_GPIO_ALT_C4), DB8540_PIN_GROUP(stmmod_oc4_1, NMK_GPIO_ALT_C4), - DB8540_PIN_GROUP(moduartstmmux_oc4_1, NMK_GPIO_ALT_C4), }; @@ -835,8 +830,7 @@ static const struct nmk_pingroup nmk_db8540_groups[] = { static const char * const a##_groups[] = { b }; DB8540_FUNC_GROUPS(apetrig, "apetrig_b_1"); -DB8540_FUNC_GROUPS(clkout, "clkoutreq_a_1", "clkout1_a_1", "clkout1_a_2", - "clkout2_a_1", "clkout2_a_2"); +DB8540_FUNC_GROUPS(clkout, "clkoutreq_a_1", "clkout_a_1", "clkout_a_2"); DB8540_FUNC_GROUPS(ddrtrig, "ddrtrig_b_1"); DB8540_FUNC_GROUPS(hsi, "hsir_a_1", "hsit_a_1", "hsit_a_2"); DB8540_FUNC_GROUPS(hwobs, "hwobs_oc4_1"); diff --git a/trunk/drivers/pinctrl/pinctrl-nomadik.c b/trunk/drivers/pinctrl/pinctrl-nomadik.c index 8ef3e85cb011..01aea1c3b5fa 100644 --- a/trunk/drivers/pinctrl/pinctrl-nomadik.c +++ b/trunk/drivers/pinctrl/pinctrl-nomadik.c @@ -30,10 +30,26 @@ #include /* Since we request GPIOs from ourself */ #include -#include +/* + * For the U8500 archs, use the PRCMU register interface, for the older + * Nomadik, provide some stubs. The functions using these will only be + * called on the U8500 series. + */ +#ifdef CONFIG_ARCH_U8500 +#include +#else +static inline u32 prcmu_read(unsigned int reg) { + return 0; +} +static inline void prcmu_write(unsigned int reg, u32 value) {} +static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value) {} +#endif #include +#include +#include + #include "pinctrl-nomadik.h" /* @@ -44,6 +60,8 @@ * Symbols in this file are called "nmk_gpio" for "nomadik gpio" */ +#define NMK_GPIO_PER_CHIP 32 + struct nmk_gpio_chip { struct gpio_chip chip; struct irq_domain *domain; @@ -68,18 +86,10 @@ struct nmk_gpio_chip { u32 lowemi; }; -/** - * struct nmk_pinctrl - state container for the Nomadik pin controller - * @dev: containing device pointer - * @pctl: corresponding pin controller device - * @soc: SoC data for this specific chip - * @prcm_base: PRCM register range virtual base - */ struct nmk_pinctrl { struct device *dev; struct pinctrl_dev *pctl; const struct nmk_pinctrl_soc_data *soc; - void __iomem *prcm_base; }; static struct nmk_gpio_chip * @@ -241,15 +251,6 @@ nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset) dev_dbg(nmk_chip->chip.dev, "%d: clearing interrupt mask\n", gpio); } -static void nmk_write_masked(void __iomem *reg, u32 mask, u32 value) -{ - u32 val; - - val = readl(reg); - val = ((val & ~mask) | (value & mask)); - writel(val, reg); -} - static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, unsigned offset, unsigned alt_num) { @@ -288,8 +289,8 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, if (pin_desc->altcx[i].used == true) { reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; bit = pin_desc->altcx[i].control_bit; - if (readl(npct->prcm_base + reg) & BIT(bit)) { - nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0); + if (prcmu_read(reg) & BIT(bit)) { + prcmu_write_masked(reg, BIT(bit), 0); dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n", offset, i+1); @@ -317,8 +318,8 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, if (pin_desc->altcx[i].used == true) { reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; bit = pin_desc->altcx[i].control_bit; - if (readl(npct->prcm_base + reg) & BIT(bit)) { - nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0); + if (prcmu_read(reg) & BIT(bit)) { + prcmu_write_masked(reg, BIT(bit), 0); dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n", offset, i+1); @@ -330,7 +331,7 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, bit = pin_desc->altcx[alt_index].control_bit; dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been selected\n", offset, alt_index+1); - nmk_write_masked(npct->prcm_base + reg, BIT(bit), BIT(bit)); + prcmu_write_masked(reg, BIT(bit), BIT(bit)); } static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, @@ -535,7 +536,7 @@ static int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep) * and its sleep mode based on the specified configuration. The @cfg is * usually one of the SoC specific macros defined in mach/-pins.h. These * are constructed using, and can be further enhanced with, the macros in - * + * plat/pincfg.h. * * If a pin's mode is set to GPIO, it is configured as an input to avoid * side-effects. The gpio can be manipulated later using standard GPIO API @@ -674,35 +675,6 @@ int nmk_gpio_set_mode(int gpio, int gpio_mode) } EXPORT_SYMBOL(nmk_gpio_set_mode); -static int nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio) -{ - int i; - u16 reg; - u8 bit; - struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); - const struct prcm_gpiocr_altcx_pin_desc *pin_desc; - const u16 *gpiocr_regs; - - for (i = 0; i < npct->soc->npins_altcx; i++) { - if (npct->soc->altcx_pins[i].pin == gpio) - break; - } - if (i == npct->soc->npins_altcx) - return NMK_GPIO_ALT_C; - - pin_desc = npct->soc->altcx_pins + i; - gpiocr_regs = npct->soc->prcm_gpiocr_registers; - for (i = 0; i < PRCM_IDX_GPIOCR_ALTC_MAX; i++) { - if (pin_desc->altcx[i].used == true) { - reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; - bit = pin_desc->altcx[i].control_bit; - if (readl(npct->prcm_base + reg) & BIT(bit)) - return NMK_GPIO_ALT_C+i+1; - } - } - return NMK_GPIO_ALT_C; -} - int nmk_gpio_get_mode(int gpio) { struct nmk_gpio_chip *nmk_chip; @@ -1084,16 +1056,15 @@ static int nmk_gpio_to_irq(struct gpio_chip *chip, unsigned offset) struct nmk_gpio_chip *nmk_chip = container_of(chip, struct nmk_gpio_chip, chip); - return irq_create_mapping(nmk_chip->domain, offset); + return irq_find_mapping(nmk_chip->domain, offset); } #ifdef CONFIG_DEBUG_FS #include -static void nmk_gpio_dbg_show_one(struct seq_file *s, - struct pinctrl_dev *pctldev, struct gpio_chip *chip, - unsigned offset, unsigned gpio) +static void nmk_gpio_dbg_show_one(struct seq_file *s, struct gpio_chip *chip, + unsigned offset, unsigned gpio) { const char *label = gpiochip_is_requested(chip, offset); struct nmk_gpio_chip *nmk_chip = @@ -1107,18 +1078,12 @@ static void nmk_gpio_dbg_show_one(struct seq_file *s, [NMK_GPIO_ALT_A] = "altA", [NMK_GPIO_ALT_B] = "altB", [NMK_GPIO_ALT_C] = "altC", - [NMK_GPIO_ALT_C+1] = "altC1", - [NMK_GPIO_ALT_C+2] = "altC2", - [NMK_GPIO_ALT_C+3] = "altC3", - [NMK_GPIO_ALT_C+4] = "altC4", }; clk_enable(nmk_chip->clk); is_out = !!(readl(nmk_chip->addr + NMK_GPIO_DIR) & bit); pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & bit); mode = nmk_gpio_get_mode(gpio); - if ((mode == NMK_GPIO_ALT_C) && pctldev) - mode = nmk_prcm_gpiocr_get_mode(pctldev, gpio); seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s %s", gpio, label ?: "(none)", @@ -1162,14 +1127,13 @@ static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) unsigned gpio = chip->base; for (i = 0; i < chip->ngpio; i++, gpio++) { - nmk_gpio_dbg_show_one(s, NULL, chip, i, gpio); + nmk_gpio_dbg_show_one(s, chip, i, gpio); seq_printf(s, "\n"); } } #else static inline void nmk_gpio_dbg_show_one(struct seq_file *s, - struct pinctrl_dev *pctldev, struct gpio_chip *chip, unsigned offset, unsigned gpio) { @@ -1286,8 +1250,8 @@ void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up) } } -static int nmk_gpio_irq_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hwirq) +int nmk_gpio_irq_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hwirq) { struct nmk_gpio_chip *nmk_chip = d->host_data; @@ -1317,7 +1281,7 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) struct clk *clk; int secondary_irq; void __iomem *base; - int irq_start = 0; + int irq_start = -1; int irq; int ret; @@ -1423,7 +1387,7 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) if (!np) irq_start = NOMADIK_GPIO_TO_IRQ(pdata->first_gpio); - nmk_chip->domain = irq_domain_add_simple(np, + nmk_chip->domain = irq_domain_add_simple(NULL, NMK_GPIO_PER_CHIP, irq_start, &nmk_gpio_irq_simple_ops, nmk_chip); if (!nmk_chip->domain) { @@ -1500,7 +1464,7 @@ static void nmk_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, return; } chip = range->gc; - nmk_gpio_dbg_show_one(s, pctldev, chip, offset - chip->base, offset); + nmk_gpio_dbg_show_one(s, chip, offset - chip->base, offset); } static struct pinctrl_ops nmk_pinctrl_ops = { @@ -1671,9 +1635,9 @@ static void nmk_pmx_disable(struct pinctrl_dev *pctldev, dev_dbg(npct->dev, "disable group %s, %u pins\n", g->name, g->npins); } -static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, - unsigned offset) +int nmk_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) { struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); struct nmk_gpio_chip *nmk_chip; @@ -1702,9 +1666,9 @@ static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev, return 0; } -static void nmk_gpio_disable_free(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, - unsigned offset) +void nmk_gpio_disable_free(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) { struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); @@ -1722,15 +1686,17 @@ static struct pinmux_ops nmk_pinmux_ops = { .gpio_disable_free = nmk_gpio_disable_free, }; -static int nmk_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, - unsigned long *config) +int nmk_pin_config_get(struct pinctrl_dev *pctldev, + unsigned pin, + unsigned long *config) { /* Not implemented */ return -EINVAL; } -static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, - unsigned long config) +int nmk_pin_config_set(struct pinctrl_dev *pctldev, + unsigned pin, + unsigned long config) { static const char *pullnames[] = { [NMK_GPIO_PULL_NONE] = "none", @@ -1852,7 +1818,6 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev) const struct platform_device_id *platid = platform_get_device_id(pdev); struct device_node *np = pdev->dev.of_node; struct nmk_pinctrl *npct; - struct resource *res; unsigned int version = 0; int i; @@ -1862,14 +1827,9 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev) if (platid) version = platid->driver_data; - else if (np) { - const struct of_device_id *match; - - match = of_match_device(nmk_pinctrl_match, &pdev->dev); - if (!match) - return -ENODEV; - version = (unsigned int) match->data; - } + else if (np) + version = (unsigned int) + of_match_device(nmk_pinctrl_match, &pdev->dev)->data; /* Poke in other ASIC variants here */ if (version == PINCTRL_NMK_STN8815) @@ -1879,37 +1839,22 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev) if (version == PINCTRL_NMK_DB8540) nmk_pinctrl_db8540_init(&npct->soc); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res) { - npct->prcm_base = devm_ioremap(&pdev->dev, res->start, - resource_size(res)); - if (!npct->prcm_base) { - dev_err(&pdev->dev, - "failed to ioremap PRCM registers\n"); - return -ENOMEM; - } - } else { - dev_info(&pdev->dev, - "No PRCM base, assume no ALT-Cx control is available\n"); - } - /* * We need all the GPIO drivers to probe FIRST, or we will not be able * to obtain references to the struct gpio_chip * for them, and we * need this to proceed. */ for (i = 0; i < npct->soc->gpio_num_ranges; i++) { - if (!nmk_gpio_chips[npct->soc->gpio_ranges[i].id]) { + if (!nmk_gpio_chips[i]) { dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i); return -EPROBE_DEFER; } - npct->soc->gpio_ranges[i].gc = &nmk_gpio_chips[npct->soc->gpio_ranges[i].id]->chip; + npct->soc->gpio_ranges[i].gc = &nmk_gpio_chips[i]->chip; } nmk_pinctrl_desc.pins = npct->soc->pins; nmk_pinctrl_desc.npins = npct->soc->npins; npct->dev = &pdev->dev; - npct->pctl = pinctrl_register(&nmk_pinctrl_desc, &pdev->dev, npct); if (!npct->pctl) { dev_err(&pdev->dev, "could not register Nomadik pinctrl driver\n"); @@ -1944,7 +1889,6 @@ static const struct platform_device_id nmk_pinctrl_id[] = { { "pinctrl-stn8815", PINCTRL_NMK_STN8815 }, { "pinctrl-db8500", PINCTRL_NMK_DB8500 }, { "pinctrl-db8540", PINCTRL_NMK_DB8540 }, - { } }; static struct platform_driver nmk_pinctrl_driver = { diff --git a/trunk/drivers/pinctrl/pinctrl-nomadik.h b/trunk/drivers/pinctrl/pinctrl-nomadik.h index bcd4191e10ea..eef316e979a0 100644 --- a/trunk/drivers/pinctrl/pinctrl-nomadik.h +++ b/trunk/drivers/pinctrl/pinctrl-nomadik.h @@ -1,7 +1,7 @@ #ifndef PINCTRL_PINCTRL_NOMADIK_H #define PINCTRL_PINCTRL_NOMADIK_H -#include +#include /* Package definitions */ #define PINCTRL_NMK_STN8815 0 diff --git a/trunk/drivers/pinctrl/pinctrl-pxa3xx.c b/trunk/drivers/pinctrl/pinctrl-pxa3xx.c index 51f8a388b917..f14cd6ba4c0b 100644 --- a/trunk/drivers/pinctrl/pinctrl-pxa3xx.c +++ b/trunk/drivers/pinctrl/pinctrl-pxa3xx.c @@ -173,6 +173,7 @@ int pxa3xx_pinctrl_register(struct platform_device *pdev, { struct pinctrl_desc *desc; struct resource *res; + int ret = 0; if (!info || !info->cputype) return -EINVAL; @@ -187,17 +188,23 @@ int pxa3xx_pinctrl_register(struct platform_device *pdev, res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENOENT; - info->virt_base = devm_request_and_ioremap(&pdev->dev, res); + info->phy_base = res->start; + info->phy_size = resource_size(res); + info->virt_base = ioremap(info->phy_base, info->phy_size); if (!info->virt_base) return -ENOMEM; info->pctrl = pinctrl_register(desc, &pdev->dev, info); if (!info->pctrl) { dev_err(&pdev->dev, "failed to register PXA pinmux driver\n"); - return -EINVAL; + ret = -EINVAL; + goto err; } pinctrl_add_gpio_range(info->pctrl, &pxa3xx_pinctrl_gpio_range); platform_set_drvdata(pdev, info); return 0; +err: + iounmap(info->virt_base); + return ret; } int pxa3xx_pinctrl_unregister(struct platform_device *pdev) @@ -205,6 +212,7 @@ int pxa3xx_pinctrl_unregister(struct platform_device *pdev) struct pxa3xx_pinmux_info *info = platform_get_drvdata(pdev); pinctrl_unregister(info->pctrl); + iounmap(info->virt_base); platform_set_drvdata(pdev, NULL); return 0; } diff --git a/trunk/drivers/pinctrl/pinctrl-pxa3xx.h b/trunk/drivers/pinctrl/pinctrl-pxa3xx.h index 92fad0880834..8135744d6599 100644 --- a/trunk/drivers/pinctrl/pinctrl-pxa3xx.h +++ b/trunk/drivers/pinctrl/pinctrl-pxa3xx.h @@ -60,6 +60,8 @@ struct pxa3xx_pinmux_info { struct device *dev; struct pinctrl_dev *pctrl; enum pxa_cpu_type cputype; + unsigned int phy_base; + unsigned int phy_size; void __iomem *virt_base; struct pxa3xx_mfp_pin *mfp; diff --git a/trunk/drivers/pinctrl/pinctrl-single.c b/trunk/drivers/pinctrl/pinctrl-single.c index 554946356fba..726a729a2ec9 100644 --- a/trunk/drivers/pinctrl/pinctrl-single.c +++ b/trunk/drivers/pinctrl/pinctrl-single.c @@ -30,7 +30,6 @@ #define PCS_MUX_BITS_NAME "pinctrl-single,bits" #define PCS_REG_NAME_LEN ((sizeof(unsigned long) * 2) + 1) #define PCS_OFF_DISABLED ~0U -#define PCS_MAX_GPIO_VALUES 2 /** * struct pcs_pingroup - pingroups for a function @@ -77,16 +76,6 @@ struct pcs_function { struct list_head node; }; -/** - * struct pcs_gpio_range - pinctrl gpio range - * @range: subrange of the GPIO number space - * @gpio_func: gpio function value in the pinmux register - */ -struct pcs_gpio_range { - struct pinctrl_gpio_range range; - int gpio_func; -}; - /** * struct pcs_data - wrapper for data needed by pinctrl framework * @pa: pindesc array @@ -255,15 +244,15 @@ static int pcs_get_group_pins(struct pinctrl_dev *pctldev, static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, - unsigned pin) + unsigned offset) { struct pcs_device *pcs; - unsigned val, mux_bytes; + unsigned val; pcs = pinctrl_dev_get_drvdata(pctldev); - mux_bytes = pcs->width / BITS_PER_BYTE; - val = pcs->read(pcs->base + pin * mux_bytes); + val = pcs->read(pcs->base + offset); + val &= pcs->fmask; seq_printf(s, "%08x %s " , val, DRIVER_NAME); } @@ -414,26 +403,9 @@ static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector, } static int pcs_request_gpio(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, unsigned pin) + struct pinctrl_gpio_range *range, unsigned offset) { - struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); - struct pcs_gpio_range *gpio = NULL; - int end, mux_bytes; - unsigned data; - - gpio = container_of(range, struct pcs_gpio_range, range); - end = range->pin_base + range->npins - 1; - if (pin < range->pin_base || pin > end) { - dev_err(pctldev->dev, - "pin %d isn't in the range of %d to %d\n", - pin, range->pin_base, end); - return -EINVAL; - } - mux_bytes = pcs->width / BITS_PER_BYTE; - data = pcs->read(pcs->base + pin * mux_bytes) & ~pcs->fmask; - data |= gpio->gpio_func; - pcs->write(data, pcs->base + pin * mux_bytes); - return 0; + return -ENOTSUPP; } static struct pinmux_ops pcs_pinmux_ops = { @@ -800,7 +772,7 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev, pcs = pinctrl_dev_get_drvdata(pctldev); *map = devm_kzalloc(pcs->dev, sizeof(**map), GFP_KERNEL); - if (!*map) + if (!map) return -ENOMEM; *num_maps = 0; @@ -907,50 +879,6 @@ static void pcs_free_resources(struct pcs_device *pcs) static struct of_device_id pcs_of_match[]; -static int __devinit pcs_add_gpio_range(struct device_node *node, - struct pcs_device *pcs) -{ - struct pcs_gpio_range *gpio; - struct device_node *child; - struct resource r; - const char name[] = "pinctrl-single"; - u32 gpiores[PCS_MAX_GPIO_VALUES]; - int ret, i = 0, mux_bytes = 0; - - for_each_child_of_node(node, child) { - ret = of_address_to_resource(child, 0, &r); - if (ret < 0) - continue; - memset(gpiores, 0, sizeof(u32) * PCS_MAX_GPIO_VALUES); - ret = of_property_read_u32_array(child, "pinctrl-single,gpio", - gpiores, PCS_MAX_GPIO_VALUES); - if (ret < 0) - continue; - gpio = devm_kzalloc(pcs->dev, sizeof(*gpio), GFP_KERNEL); - if (!gpio) { - dev_err(pcs->dev, "failed to allocate pcs gpio\n"); - return -ENOMEM; - } - gpio->range.name = devm_kzalloc(pcs->dev, sizeof(name), - GFP_KERNEL); - if (!gpio->range.name) { - dev_err(pcs->dev, "failed to allocate range name\n"); - return -ENOMEM; - } - memcpy((char *)gpio->range.name, name, sizeof(name)); - - gpio->range.id = i++; - gpio->range.base = gpiores[0]; - gpio->gpio_func = gpiores[1]; - mux_bytes = pcs->width / BITS_PER_BYTE; - gpio->range.pin_base = (r.start - pcs->res->start) / mux_bytes; - gpio->range.npins = (r.end - r.start) / mux_bytes + 1; - - pinctrl_add_gpio_range(pcs->pctl, &gpio->range); - } - return 0; -} - static int __devinit pcs_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -1047,10 +975,6 @@ static int __devinit pcs_probe(struct platform_device *pdev) goto free; } - ret = pcs_add_gpio_range(np, pcs); - if (ret < 0) - goto free; - dev_info(pcs->dev, "%i pins at pa %p size %u\n", pcs->desc.npins, pcs->base, pcs->size); diff --git a/trunk/drivers/pinctrl/pinctrl-sirf.c b/trunk/drivers/pinctrl/pinctrl-sirf.c index a3905e58d1b3..9ecacf3d0a75 100644 --- a/trunk/drivers/pinctrl/pinctrl-sirf.c +++ b/trunk/drivers/pinctrl/pinctrl-sirf.c @@ -32,10 +32,10 @@ #define SIRFSOC_NUM_PADS 622 #define SIRFSOC_RSC_PIN_MUX 0x4 -#define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84) -#define SIRFSOC_GPIO_PAD_EN_CLR(g) ((g)*0x100 + 0x90) +#define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84) #define SIRFSOC_GPIO_CTRL(g, i) ((g)*0x100 + (i)*4) #define SIRFSOC_GPIO_DSP_EN0 (0x80) +#define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84) #define SIRFSOC_GPIO_INT_STATUS(g) ((g)*0x100 + 0x8C) #define SIRFSOC_GPIO_CTL_INTR_LOW_MASK 0x1 @@ -60,7 +60,6 @@ struct sirfsoc_gpio_bank { int id; int parent_irq; spinlock_t lock; - bool is_marco; /* for marco, some registers are different with prima2 */ }; static struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS]; @@ -192,7 +191,6 @@ struct sirfsoc_pmx { struct pinctrl_dev *pmx; void __iomem *gpio_virtbase; void __iomem *rsc_virtbase; - bool is_marco; }; /* SIRFSOC_GPIO_PAD_EN set */ @@ -1090,21 +1088,12 @@ static void sirfsoc_pinmux_endisable(struct sirfsoc_pmx *spmx, unsigned selector for (i = 0; i < mux->muxmask_counts; i++) { u32 muxval; - if (!spmx->is_marco) { - muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); - if (enable) - muxval = muxval & ~mask[i].mask; - else - muxval = muxval | mask[i].mask; - writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); - } else { - if (enable) - writel(mask[i].mask, spmx->gpio_virtbase + - SIRFSOC_GPIO_PAD_EN_CLR(mask[i].group)); - else - writel(mask[i].mask, spmx->gpio_virtbase + - SIRFSOC_GPIO_PAD_EN(mask[i].group)); - } + muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); + if (enable) + muxval = muxval & ~mask[i].mask; + else + muxval = muxval | mask[i].mask; + writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); } if (mux->funcmask && enable) { @@ -1169,14 +1158,9 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev, spmx = pinctrl_dev_get_drvdata(pmxdev); - if (!spmx->is_marco) { - muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); - muxval = muxval | (1 << (offset - range->pin_base)); - writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); - } else { - writel(1 << (offset - range->pin_base), spmx->gpio_virtbase + - SIRFSOC_GPIO_PAD_EN(group)); - } + muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); + muxval = muxval | (1 << (offset - range->pin_base)); + writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); return 0; } @@ -1234,7 +1218,6 @@ static void __iomem *sirfsoc_rsc_of_iomap(void) { const struct of_device_id rsc_ids[] = { { .compatible = "sirf,prima2-rsc" }, - { .compatible = "sirf,marco-rsc" }, {} }; struct device_node *np; @@ -1276,9 +1259,6 @@ static int __devinit sirfsoc_pinmux_probe(struct platform_device *pdev) goto out_no_rsc_remap; } - if (of_device_is_compatible(np, "sirf,marco-pinctrl")) - spmx->is_marco = 1; - /* Now register the pin controller and all pins it handles */ spmx->pmx = pinctrl_register(&sirfsoc_pinmux_desc, &pdev->dev, spmx); if (!spmx->pmx) { @@ -1307,7 +1287,6 @@ static int __devinit sirfsoc_pinmux_probe(struct platform_device *pdev) static const struct of_device_id pinmux_ids[] __devinitconst = { { .compatible = "sirf,prima2-pinctrl" }, - { .compatible = "sirf,marco-pinctrl" }, {} }; @@ -1642,8 +1621,8 @@ static void sirfsoc_gpio_set_value(struct gpio_chip *chip, unsigned offset, spin_unlock_irqrestore(&bank->lock, flags); } -static int sirfsoc_gpio_irq_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hwirq) +int sirfsoc_gpio_irq_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hwirq) { struct sirfsoc_gpio_bank *bank = d->host_data; @@ -1669,7 +1648,6 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np) struct sirfsoc_gpio_bank *bank; void *regs; struct platform_device *pdev; - bool is_marco = false; pdev = of_find_device_by_node(np); if (!pdev) @@ -1679,9 +1657,6 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np) if (!regs) return -ENOMEM; - if (of_device_is_compatible(np, "sirf,marco-pinctrl")) - is_marco = 1; - for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { bank = &sgpio_bank[i]; spin_lock_init(&bank->lock); @@ -1698,7 +1673,6 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np) bank->chip.gc.of_node = np; bank->chip.regs = regs; bank->id = i; - bank->is_marco = is_marco; bank->parent_irq = platform_get_irq(pdev, i); if (bank->parent_irq < 0) { err = bank->parent_irq; diff --git a/trunk/drivers/pinctrl/pinctrl-tegra.c b/trunk/drivers/pinctrl/pinctrl-tegra.c index e9f80a54b3d0..729b686c3ad2 100644 --- a/trunk/drivers/pinctrl/pinctrl-tegra.c +++ b/trunk/drivers/pinctrl/pinctrl-tegra.c @@ -178,9 +178,8 @@ static int add_config(struct device *dev, unsigned long **configs, return 0; } -static void tegra_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, - struct pinctrl_map *map, - unsigned num_maps) +void tegra_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, + struct pinctrl_map *map, unsigned num_maps) { int i; @@ -210,11 +209,11 @@ static const struct cfg_param { {"nvidia,slew-rate-rising", TEGRA_PINCONF_PARAM_SLEW_RATE_RISING}, }; -static int tegra_pinctrl_dt_subnode_to_map(struct device *dev, - struct device_node *np, - struct pinctrl_map **map, - unsigned *reserved_maps, - unsigned *num_maps) +int tegra_pinctrl_dt_subnode_to_map(struct device *dev, + struct device_node *np, + struct pinctrl_map **map, + unsigned *reserved_maps, + unsigned *num_maps) { int ret, i; const char *function; @@ -289,10 +288,9 @@ static int tegra_pinctrl_dt_subnode_to_map(struct device *dev, return ret; } -static int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np_config, - struct pinctrl_map **map, - unsigned *num_maps) +int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, + struct device_node *np_config, + struct pinctrl_map **map, unsigned *num_maps) { unsigned reserved_maps; struct device_node *np; @@ -466,7 +464,7 @@ static int tegra_pinconf_reg(struct tegra_pmx *pmx, *bank = g->drv_bank; *reg = g->drv_reg; *bit = g->lpmd_bit; - *width = 2; + *width = 1; break; case TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH: *bank = g->drv_bank; @@ -662,7 +660,7 @@ static void tegra_pinconf_config_dbg_show(struct pinctrl_dev *pctldev, } #endif -static struct pinconf_ops tegra_pinconf_ops = { +struct pinconf_ops tegra_pinconf_ops = { .pin_config_get = tegra_pinconf_get, .pin_config_set = tegra_pinconf_set, .pin_config_group_get = tegra_pinconf_group_get, diff --git a/trunk/drivers/pinctrl/pinctrl-tegra30.c b/trunk/drivers/pinctrl/pinctrl-tegra30.c index 7894f14c7059..0386fdf0da16 100644 --- a/trunk/drivers/pinctrl/pinctrl-tegra30.c +++ b/trunk/drivers/pinctrl/pinctrl-tegra30.c @@ -3345,10 +3345,10 @@ static const struct tegra_function tegra30_functions[] = { FUNCTION(vi_alt3), }; -#define DRV_PINGROUP_REG_A 0x868 /* bank 0 */ -#define PINGROUP_REG_A 0x3000 /* bank 1 */ +#define MUXCTL_REG_A 0x3000 +#define PINGROUP_REG_A 0x868 -#define PINGROUP_REG_Y(r) ((r) - PINGROUP_REG_A) +#define PINGROUP_REG_Y(r) ((r) - MUXCTL_REG_A) #define PINGROUP_REG_N(r) -1 #define PINGROUP(pg_name, f0, f1, f2, f3, f_safe, r, od, ior) \ @@ -3364,25 +3364,25 @@ static const struct tegra_function tegra30_functions[] = { }, \ .func_safe = TEGRA_MUX_ ## f_safe, \ .mux_reg = PINGROUP_REG_Y(r), \ - .mux_bank = 1, \ + .mux_bank = 0, \ .mux_bit = 0, \ .pupd_reg = PINGROUP_REG_Y(r), \ - .pupd_bank = 1, \ + .pupd_bank = 0, \ .pupd_bit = 2, \ .tri_reg = PINGROUP_REG_Y(r), \ - .tri_bank = 1, \ + .tri_bank = 0, \ .tri_bit = 4, \ .einput_reg = PINGROUP_REG_Y(r), \ - .einput_bank = 1, \ + .einput_bank = 0, \ .einput_bit = 5, \ .odrain_reg = PINGROUP_REG_##od(r), \ - .odrain_bank = 1, \ + .odrain_bank = 0, \ .odrain_bit = 6, \ .lock_reg = PINGROUP_REG_Y(r), \ - .lock_bank = 1, \ + .lock_bank = 0, \ .lock_bit = 7, \ .ioreset_reg = PINGROUP_REG_##ior(r), \ - .ioreset_bank = 1, \ + .ioreset_bank = 0, \ .ioreset_bit = 8, \ .drv_reg = -1, \ } @@ -3401,8 +3401,8 @@ static const struct tegra_function tegra30_functions[] = { .odrain_reg = -1, \ .lock_reg = -1, \ .ioreset_reg = -1, \ - .drv_reg = ((r) - DRV_PINGROUP_REG_A), \ - .drv_bank = 0, \ + .drv_reg = ((r) - PINGROUP_REG_A), \ + .drv_bank = 1, \ .hsm_bit = hsm_b, \ .schmitt_bit = schmitt_b, \ .lpmd_bit = lpmd_b, \ diff --git a/trunk/drivers/pinctrl/pinctrl-u300.c b/trunk/drivers/pinctrl/pinctrl-u300.c index b84de03ed54d..309f5b9a70ec 100644 --- a/trunk/drivers/pinctrl/pinctrl-u300.c +++ b/trunk/drivers/pinctrl/pinctrl-u300.c @@ -663,6 +663,8 @@ static const struct pinctrl_pin_desc u300_pads[] = { struct u300_pmx { struct device *dev; struct pinctrl_dev *pctl; + u32 phybase; + u32 physize; void __iomem *virtbase; }; @@ -1011,11 +1013,52 @@ static struct pinmux_ops u300_pmx_ops = { .disable = u300_pmx_disable, }; -static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, - unsigned long *config) +/* + * GPIO ranges handled by the application-side COH901XXX GPIO controller + * Very many pins can be converted into GPIO pins, but we only list those + * that are useful in practice to cut down on tables. + */ +#define U300_GPIO_RANGE(a, b, c) { .name = "COH901XXX", .id = a, .base= a, \ + .pin_base = b, .npins = c } + +static struct pinctrl_gpio_range u300_gpio_ranges[] = { + U300_GPIO_RANGE(10, 426, 1), + U300_GPIO_RANGE(11, 180, 1), + U300_GPIO_RANGE(12, 165, 1), /* MS/MMC card insertion */ + U300_GPIO_RANGE(13, 179, 1), + U300_GPIO_RANGE(14, 178, 1), + U300_GPIO_RANGE(16, 194, 1), + U300_GPIO_RANGE(17, 193, 1), + U300_GPIO_RANGE(18, 192, 1), + U300_GPIO_RANGE(19, 191, 1), + U300_GPIO_RANGE(20, 186, 1), + U300_GPIO_RANGE(21, 185, 1), + U300_GPIO_RANGE(22, 184, 1), + U300_GPIO_RANGE(23, 183, 1), + U300_GPIO_RANGE(24, 182, 1), + U300_GPIO_RANGE(25, 181, 1), +}; + +static struct pinctrl_gpio_range *u300_match_gpio_range(unsigned pin) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) { + struct pinctrl_gpio_range *range; + + range = &u300_gpio_ranges[i]; + if (pin >= range->pin_base && + pin <= (range->pin_base + range->npins - 1)) + return range; + } + return NULL; +} + +int u300_pin_config_get(struct pinctrl_dev *pctldev, + unsigned pin, + unsigned long *config) { - struct pinctrl_gpio_range *range = - pinctrl_find_gpio_range_from_pin(pctldev, pin); + struct pinctrl_gpio_range *range = u300_match_gpio_range(pin); /* We get config for those pins we CAN get it for and that's it */ if (!range) @@ -1026,11 +1069,11 @@ static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, config); } -static int u300_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, - unsigned long config) +int u300_pin_config_set(struct pinctrl_dev *pctldev, + unsigned pin, + unsigned long config) { - struct pinctrl_gpio_range *range = - pinctrl_find_gpio_range_from_pin(pctldev, pin); + struct pinctrl_gpio_range *range = u300_match_gpio_range(pin); int ret; if (!range) @@ -1066,6 +1109,9 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev) { struct u300_pmx *upmx; struct resource *res; + struct gpio_chip *gpio_chip = dev_get_platdata(&pdev->dev); + int ret; + int i; /* Create state holders etc for this driver */ upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL); @@ -1077,15 +1123,32 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENOENT; + upmx->phybase = res->start; + upmx->physize = resource_size(res); - upmx->virtbase = devm_request_and_ioremap(&pdev->dev, res); - if (!upmx->virtbase) - return -ENOMEM; + if (request_mem_region(upmx->phybase, upmx->physize, + DRIVER_NAME) == NULL) { + ret = -ENOMEM; + goto out_no_memregion; + } + + upmx->virtbase = ioremap(upmx->phybase, upmx->physize); + if (!upmx->virtbase) { + ret = -ENOMEM; + goto out_no_remap; + } upmx->pctl = pinctrl_register(&u300_pmx_desc, &pdev->dev, upmx); if (!upmx->pctl) { dev_err(&pdev->dev, "could not register U300 pinmux driver\n"); - return -EINVAL; + ret = -EINVAL; + goto out_no_pmx; + } + + /* We will handle a range of GPIO pins */ + for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) { + u300_gpio_ranges[i].gc = gpio_chip; + pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_ranges[i]); } platform_set_drvdata(pdev, upmx); @@ -1093,6 +1156,14 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev) dev_info(&pdev->dev, "initialized U300 pin control driver\n"); return 0; + +out_no_pmx: + iounmap(upmx->virtbase); +out_no_remap: + platform_set_drvdata(pdev, NULL); +out_no_memregion: + release_mem_region(upmx->phybase, upmx->physize); + return ret; } static int __devexit u300_pmx_remove(struct platform_device *pdev) @@ -1100,6 +1171,8 @@ static int __devexit u300_pmx_remove(struct platform_device *pdev) struct u300_pmx *upmx = platform_get_drvdata(pdev); pinctrl_unregister(upmx->pctl); + iounmap(upmx->virtbase); + release_mem_region(upmx->phybase, upmx->physize); platform_set_drvdata(pdev, NULL); return 0; diff --git a/trunk/drivers/pinctrl/pinctrl-xway.c b/trunk/drivers/pinctrl/pinctrl-xway.c index ad90984ec500..b9bcaec66223 100644 --- a/trunk/drivers/pinctrl/pinctrl-xway.c +++ b/trunk/drivers/pinctrl/pinctrl-xway.c @@ -522,7 +522,7 @@ static int xway_pinconf_set(struct pinctrl_dev *pctldev, return 0; } -static struct pinconf_ops xway_pinconf_ops = { +struct pinconf_ops xway_pinconf_ops = { .pin_config_get = xway_pinconf_get, .pin_config_set = xway_pinconf_set, }; diff --git a/trunk/drivers/pinctrl/pinmux.c b/trunk/drivers/pinctrl/pinmux.c index 1a00658b3ea0..9301a7a95eff 100644 --- a/trunk/drivers/pinctrl/pinmux.c +++ b/trunk/drivers/pinctrl/pinmux.c @@ -314,11 +314,14 @@ int pinmux_map_to_setting(struct pinctrl_map const *map, { struct pinctrl_dev *pctldev = setting->pctldev; const struct pinmux_ops *pmxops = pctldev->desc->pmxops; + const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; char const * const *groups; unsigned num_groups; int ret; const char *group; int i; + const unsigned *pins; + unsigned num_pins; if (!pmxops) { dev_err(pctldev->dev, "does not support mux function\n"); @@ -373,12 +376,53 @@ int pinmux_map_to_setting(struct pinctrl_map const *map, } setting->data.mux.group = ret; + ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, &pins, + &num_pins); + if (ret) { + dev_err(pctldev->dev, + "could not get pins for device %s group selector %d\n", + pinctrl_dev_get_name(pctldev), setting->data.mux.group); + return -ENODEV; + } + + /* Try to allocate all pins in this group, one by one */ + for (i = 0; i < num_pins; i++) { + ret = pin_request(pctldev, pins[i], map->dev_name, NULL); + if (ret) { + dev_err(pctldev->dev, + "could not request pin %d on device %s\n", + pins[i], pinctrl_dev_get_name(pctldev)); + /* On error release all taken pins */ + i--; /* this pin just failed */ + for (; i >= 0; i--) + pin_free(pctldev, pins[i], NULL); + return -ENODEV; + } + } + return 0; } void pinmux_free_setting(struct pinctrl_setting const *setting) { - /* This function is currently unused */ + struct pinctrl_dev *pctldev = setting->pctldev; + const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; + const unsigned *pins; + unsigned num_pins; + int ret; + int i; + + ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, + &pins, &num_pins); + if (ret) { + dev_err(pctldev->dev, + "could not get pins for device %s group selector %d\n", + pinctrl_dev_get_name(pctldev), setting->data.mux.group); + return; + } + + for (i = 0; i < num_pins; i++) + pin_free(pctldev, pins[i], NULL); } int pinmux_enable_setting(struct pinctrl_setting const *setting) @@ -402,18 +446,6 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting) num_pins = 0; } - /* Try to allocate all pins in this group, one by one */ - for (i = 0; i < num_pins; i++) { - ret = pin_request(pctldev, pins[i], setting->dev_name, NULL); - if (ret) { - dev_err(pctldev->dev, - "could not request pin %d on device %s\n", - pins[i], pinctrl_dev_get_name(pctldev)); - goto err_pin_request; - } - } - - /* Now that we have acquired the pins, encode the mux setting */ for (i = 0; i < num_pins; i++) { desc = pin_desc_get(pctldev, pins[i]); if (desc == NULL) { @@ -425,26 +457,8 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting) desc->mux_setting = &(setting->data.mux); } - ret = ops->enable(pctldev, setting->data.mux.func, - setting->data.mux.group); - - if (ret) - goto err_enable; - - return 0; - -err_enable: - for (i = 0; i < num_pins; i++) { - desc = pin_desc_get(pctldev, pins[i]); - if (desc) - desc->mux_setting = NULL; - } -err_pin_request: - /* On error release all taken pins */ - while (--i >= 0) - pin_free(pctldev, pins[i], NULL); - - return ret; + return ops->enable(pctldev, setting->data.mux.func, + setting->data.mux.group); } void pinmux_disable_setting(struct pinctrl_setting const *setting) @@ -468,7 +482,6 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting) num_pins = 0; } - /* Flag the descs that no setting is active */ for (i = 0; i < num_pins; i++) { desc = pin_desc_get(pctldev, pins[i]); if (desc == NULL) { @@ -480,10 +493,6 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting) desc->mux_setting = NULL; } - /* And release the pins */ - for (i = 0; i < num_pins; i++) - pin_free(pctldev, pins[i], NULL); - if (ops->disable) ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group); } diff --git a/trunk/drivers/pinctrl/spear/Kconfig b/trunk/drivers/pinctrl/spear/Kconfig index 04d93e602674..91558791e766 100644 --- a/trunk/drivers/pinctrl/spear/Kconfig +++ b/trunk/drivers/pinctrl/spear/Kconfig @@ -25,31 +25,20 @@ config PINCTRL_SPEAR310 bool "ST Microelectronics SPEAr310 SoC pin controller driver" depends on MACH_SPEAR310 select PINCTRL_SPEAR3XX - select PINCTRL_SPEAR_PLGPIO config PINCTRL_SPEAR320 bool "ST Microelectronics SPEAr320 SoC pin controller driver" depends on MACH_SPEAR320 select PINCTRL_SPEAR3XX - select PINCTRL_SPEAR_PLGPIO config PINCTRL_SPEAR1310 bool "ST Microelectronics SPEAr1310 SoC pin controller driver" depends on MACH_SPEAR1310 select PINCTRL_SPEAR - select PINCTRL_SPEAR_PLGPIO config PINCTRL_SPEAR1340 bool "ST Microelectronics SPEAr1340 SoC pin controller driver" depends on MACH_SPEAR1340 select PINCTRL_SPEAR - select PINCTRL_SPEAR_PLGPIO - -config PINCTRL_SPEAR_PLGPIO - bool "SPEAr SoC PLGPIO Controller" - depends on GPIOLIB && PINCTRL_SPEAR - help - Say yes here to support PLGPIO controller on ST Microelectronics SPEAr - SoCs. endif diff --git a/trunk/drivers/pinctrl/spear/Makefile b/trunk/drivers/pinctrl/spear/Makefile index 0e400ebeb8ff..b28a7ba22443 100644 --- a/trunk/drivers/pinctrl/spear/Makefile +++ b/trunk/drivers/pinctrl/spear/Makefile @@ -1,6 +1,5 @@ # SPEAr pinmux support -obj-$(CONFIG_PINCTRL_SPEAR_PLGPIO) += pinctrl-plgpio.o obj-$(CONFIG_PINCTRL_SPEAR) += pinctrl-spear.o obj-$(CONFIG_PINCTRL_SPEAR3XX) += pinctrl-spear3xx.o obj-$(CONFIG_PINCTRL_SPEAR300) += pinctrl-spear300.o diff --git a/trunk/drivers/pinctrl/spear/pinctrl-plgpio.c b/trunk/drivers/pinctrl/spear/pinctrl-plgpio.c deleted file mode 100644 index 4c045053bbdd..000000000000 --- a/trunk/drivers/pinctrl/spear/pinctrl-plgpio.c +++ /dev/null @@ -1,758 +0,0 @@ -/* - * SPEAr platform PLGPIO driver - * - * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_GPIO_PER_REG 32 -#define PIN_OFFSET(pin) (pin % MAX_GPIO_PER_REG) -#define REG_OFFSET(base, reg, pin) (base + reg + (pin / MAX_GPIO_PER_REG) \ - * sizeof(int *)) - -/* - * plgpio pins in all machines are not one to one mapped, bitwise with registers - * bits. These set of macros define register masks for which below functions - * (pin_to_offset and offset_to_pin) are required to be called. - */ -#define PTO_ENB_REG 0x001 -#define PTO_WDATA_REG 0x002 -#define PTO_DIR_REG 0x004 -#define PTO_IE_REG 0x008 -#define PTO_RDATA_REG 0x010 -#define PTO_MIS_REG 0x020 - -struct plgpio_regs { - u32 enb; /* enable register */ - u32 wdata; /* write data register */ - u32 dir; /* direction set register */ - u32 rdata; /* read data register */ - u32 ie; /* interrupt enable register */ - u32 mis; /* mask interrupt status register */ - u32 eit; /* edge interrupt type */ -}; - -/* - * struct plgpio: plgpio driver specific structure - * - * lock: lock for guarding gpio registers - * base: base address of plgpio block - * irq_base: irq number of plgpio0 - * chip: gpio framework specific chip information structure - * p2o: function ptr for pin to offset conversion. This is required only for - * machines where mapping b/w pin and offset is not 1-to-1. - * o2p: function ptr for offset to pin conversion. This is required only for - * machines where mapping b/w pin and offset is not 1-to-1. - * p2o_regs: mask of registers for which p2o and o2p are applicable - * regs: register offsets - * csave_regs: context save registers for standby/sleep/hibernate cases - */ -struct plgpio { - spinlock_t lock; - void __iomem *base; - struct clk *clk; - unsigned irq_base; - struct irq_domain *irq_domain; - struct gpio_chip chip; - int (*p2o)(int pin); /* pin_to_offset */ - int (*o2p)(int offset); /* offset_to_pin */ - u32 p2o_regs; - struct plgpio_regs regs; -#ifdef CONFIG_PM - struct plgpio_regs *csave_regs; -#endif -}; - -/* register manipulation inline functions */ -static inline u32 is_plgpio_set(void __iomem *base, u32 pin, u32 reg) -{ - u32 offset = PIN_OFFSET(pin); - void __iomem *reg_off = REG_OFFSET(base, reg, pin); - u32 val = readl_relaxed(reg_off); - - return !!(val & (1 << offset)); -} - -static inline void plgpio_reg_set(void __iomem *base, u32 pin, u32 reg) -{ - u32 offset = PIN_OFFSET(pin); - void __iomem *reg_off = REG_OFFSET(base, reg, pin); - u32 val = readl_relaxed(reg_off); - - writel_relaxed(val | (1 << offset), reg_off); -} - -static inline void plgpio_reg_reset(void __iomem *base, u32 pin, u32 reg) -{ - u32 offset = PIN_OFFSET(pin); - void __iomem *reg_off = REG_OFFSET(base, reg, pin); - u32 val = readl_relaxed(reg_off); - - writel_relaxed(val & ~(1 << offset), reg_off); -} - -/* gpio framework specific routines */ -static int plgpio_direction_input(struct gpio_chip *chip, unsigned offset) -{ - struct plgpio *plgpio = container_of(chip, struct plgpio, chip); - unsigned long flags; - - /* get correct offset for "offset" pin */ - if (plgpio->p2o && (plgpio->p2o_regs & PTO_DIR_REG)) { - offset = plgpio->p2o(offset); - if (offset == -1) - return -EINVAL; - } - - spin_lock_irqsave(&plgpio->lock, flags); - plgpio_reg_set(plgpio->base, offset, plgpio->regs.dir); - spin_unlock_irqrestore(&plgpio->lock, flags); - - return 0; -} - -static int plgpio_direction_output(struct gpio_chip *chip, unsigned offset, - int value) -{ - struct plgpio *plgpio = container_of(chip, struct plgpio, chip); - unsigned long flags; - unsigned dir_offset = offset, wdata_offset = offset, tmp; - - /* get correct offset for "offset" pin */ - if (plgpio->p2o && (plgpio->p2o_regs & (PTO_DIR_REG | PTO_WDATA_REG))) { - tmp = plgpio->p2o(offset); - if (tmp == -1) - return -EINVAL; - - if (plgpio->p2o_regs & PTO_DIR_REG) - dir_offset = tmp; - if (plgpio->p2o_regs & PTO_WDATA_REG) - wdata_offset = tmp; - } - - spin_lock_irqsave(&plgpio->lock, flags); - if (value) - plgpio_reg_set(plgpio->base, wdata_offset, - plgpio->regs.wdata); - else - plgpio_reg_reset(plgpio->base, wdata_offset, - plgpio->regs.wdata); - - plgpio_reg_reset(plgpio->base, dir_offset, plgpio->regs.dir); - spin_unlock_irqrestore(&plgpio->lock, flags); - - return 0; -} - -static int plgpio_get_value(struct gpio_chip *chip, unsigned offset) -{ - struct plgpio *plgpio = container_of(chip, struct plgpio, chip); - - if (offset >= chip->ngpio) - return -EINVAL; - - /* get correct offset for "offset" pin */ - if (plgpio->p2o && (plgpio->p2o_regs & PTO_RDATA_REG)) { - offset = plgpio->p2o(offset); - if (offset == -1) - return -EINVAL; - } - - return is_plgpio_set(plgpio->base, offset, plgpio->regs.rdata); -} - -static void plgpio_set_value(struct gpio_chip *chip, unsigned offset, int value) -{ - struct plgpio *plgpio = container_of(chip, struct plgpio, chip); - - if (offset >= chip->ngpio) - return; - - /* get correct offset for "offset" pin */ - if (plgpio->p2o && (plgpio->p2o_regs & PTO_WDATA_REG)) { - offset = plgpio->p2o(offset); - if (offset == -1) - return; - } - - if (value) - plgpio_reg_set(plgpio->base, offset, plgpio->regs.wdata); - else - plgpio_reg_reset(plgpio->base, offset, plgpio->regs.wdata); -} - -static int plgpio_request(struct gpio_chip *chip, unsigned offset) -{ - struct plgpio *plgpio = container_of(chip, struct plgpio, chip); - int gpio = chip->base + offset; - unsigned long flags; - int ret = 0; - - if (offset >= chip->ngpio) - return -EINVAL; - - ret = pinctrl_request_gpio(gpio); - if (ret) - return ret; - - if (!IS_ERR(plgpio->clk)) { - ret = clk_enable(plgpio->clk); - if (ret) - goto err0; - } - - if (plgpio->regs.enb == -1) - return 0; - - /* - * put gpio in IN mode before enabling it. This make enabling gpio safe - */ - ret = plgpio_direction_input(chip, offset); - if (ret) - goto err1; - - /* get correct offset for "offset" pin */ - if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) { - offset = plgpio->p2o(offset); - if (offset == -1) { - ret = -EINVAL; - goto err1; - } - } - - spin_lock_irqsave(&plgpio->lock, flags); - plgpio_reg_set(plgpio->base, offset, plgpio->regs.enb); - spin_unlock_irqrestore(&plgpio->lock, flags); - return 0; - -err1: - if (!IS_ERR(plgpio->clk)) - clk_disable(plgpio->clk); -err0: - pinctrl_free_gpio(gpio); - return ret; -} - -static void plgpio_free(struct gpio_chip *chip, unsigned offset) -{ - struct plgpio *plgpio = container_of(chip, struct plgpio, chip); - int gpio = chip->base + offset; - unsigned long flags; - - if (offset >= chip->ngpio) - return; - - if (plgpio->regs.enb == -1) - goto disable_clk; - - /* get correct offset for "offset" pin */ - if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) { - offset = plgpio->p2o(offset); - if (offset == -1) - return; - } - - spin_lock_irqsave(&plgpio->lock, flags); - plgpio_reg_reset(plgpio->base, offset, plgpio->regs.enb); - spin_unlock_irqrestore(&plgpio->lock, flags); - -disable_clk: - if (!IS_ERR(plgpio->clk)) - clk_disable(plgpio->clk); - - pinctrl_free_gpio(gpio); -} - -static int plgpio_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct plgpio *plgpio = container_of(chip, struct plgpio, chip); - - if (IS_ERR_VALUE(plgpio->irq_base)) - return -EINVAL; - - return irq_find_mapping(plgpio->irq_domain, offset); -} - -/* PLGPIO IRQ */ -static void plgpio_irq_disable(struct irq_data *d) -{ - struct plgpio *plgpio = irq_data_get_irq_chip_data(d); - int offset = d->irq - plgpio->irq_base; - unsigned long flags; - - /* get correct offset for "offset" pin */ - if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) { - offset = plgpio->p2o(offset); - if (offset == -1) - return; - } - - spin_lock_irqsave(&plgpio->lock, flags); - plgpio_reg_set(plgpio->base, offset, plgpio->regs.ie); - spin_unlock_irqrestore(&plgpio->lock, flags); -} - -static void plgpio_irq_enable(struct irq_data *d) -{ - struct plgpio *plgpio = irq_data_get_irq_chip_data(d); - int offset = d->irq - plgpio->irq_base; - unsigned long flags; - - /* get correct offset for "offset" pin */ - if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) { - offset = plgpio->p2o(offset); - if (offset == -1) - return; - } - - spin_lock_irqsave(&plgpio->lock, flags); - plgpio_reg_reset(plgpio->base, offset, plgpio->regs.ie); - spin_unlock_irqrestore(&plgpio->lock, flags); -} - -static int plgpio_irq_set_type(struct irq_data *d, unsigned trigger) -{ - struct plgpio *plgpio = irq_data_get_irq_chip_data(d); - int offset = d->irq - plgpio->irq_base; - void __iomem *reg_off; - unsigned int supported_type = 0, val; - - if (offset >= plgpio->chip.ngpio) - return -EINVAL; - - if (plgpio->regs.eit == -1) - supported_type = IRQ_TYPE_LEVEL_HIGH; - else - supported_type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; - - if (!(trigger & supported_type)) - return -EINVAL; - - if (plgpio->regs.eit == -1) - return 0; - - reg_off = REG_OFFSET(plgpio->base, plgpio->regs.eit, offset); - val = readl_relaxed(reg_off); - - offset = PIN_OFFSET(offset); - if (trigger & IRQ_TYPE_EDGE_RISING) - writel_relaxed(val | (1 << offset), reg_off); - else - writel_relaxed(val & ~(1 << offset), reg_off); - - return 0; -} - -static struct irq_chip plgpio_irqchip = { - .name = "PLGPIO", - .irq_enable = plgpio_irq_enable, - .irq_disable = plgpio_irq_disable, - .irq_set_type = plgpio_irq_set_type, -}; - -static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc) -{ - struct plgpio *plgpio = irq_get_handler_data(irq); - struct irq_chip *irqchip = irq_desc_get_chip(desc); - int regs_count, count, pin, offset, i = 0; - unsigned long pending; - - count = plgpio->chip.ngpio; - regs_count = DIV_ROUND_UP(count, MAX_GPIO_PER_REG); - - chained_irq_enter(irqchip, desc); - /* check all plgpio MIS registers for a possible interrupt */ - for (; i < regs_count; i++) { - pending = readl_relaxed(plgpio->base + plgpio->regs.mis + - i * sizeof(int *)); - if (!pending) - continue; - - /* clear interrupts */ - writel_relaxed(~pending, plgpio->base + plgpio->regs.mis + - i * sizeof(int *)); - /* - * clear extra bits in last register having gpios < MAX/REG - * ex: Suppose there are max 102 plgpios. then last register - * must have only (102 - MAX_GPIO_PER_REG * 3) = 6 relevant bits - * so, we must not take other 28 bits into consideration for - * checking interrupt. so clear those bits. - */ - count = count - i * MAX_GPIO_PER_REG; - if (count < MAX_GPIO_PER_REG) - pending &= (1 << count) - 1; - - for_each_set_bit(offset, &pending, MAX_GPIO_PER_REG) { - /* get correct pin for "offset" */ - if (plgpio->o2p && (plgpio->p2o_regs & PTO_MIS_REG)) { - pin = plgpio->o2p(offset); - if (pin == -1) - continue; - } else - pin = offset; - - /* get correct irq line number */ - pin = i * MAX_GPIO_PER_REG + pin; - generic_handle_irq(plgpio_to_irq(&plgpio->chip, pin)); - } - } - chained_irq_exit(irqchip, desc); -} - -/* - * pin to offset and offset to pin converter functions - * - * In spear310 there is inconsistency among bit positions in plgpio regiseters, - * for different plgpio pins. For example: for pin 27, bit offset is 23, pin - * 28-33 are not supported, pin 95 has offset bit 95, bit 100 has offset bit 1 - */ -static int spear310_p2o(int pin) -{ - int offset = pin; - - if (pin <= 27) - offset += 4; - else if (pin <= 33) - offset = -1; - else if (pin <= 97) - offset -= 2; - else if (pin <= 101) - offset = 101 - pin; - else - offset = -1; - - return offset; -} - -int spear310_o2p(int offset) -{ - if (offset <= 3) - return 101 - offset; - else if (offset <= 31) - return offset - 4; - else - return offset + 2; -} - -static int __devinit plgpio_probe_dt(struct platform_device *pdev, - struct plgpio *plgpio) -{ - struct device_node *np = pdev->dev.of_node; - int ret = -EINVAL; - u32 val; - - if (of_machine_is_compatible("st,spear310")) { - plgpio->p2o = spear310_p2o; - plgpio->o2p = spear310_o2p; - plgpio->p2o_regs = PTO_WDATA_REG | PTO_DIR_REG | PTO_IE_REG | - PTO_RDATA_REG | PTO_MIS_REG; - } - - if (!of_property_read_u32(np, "st-plgpio,ngpio", &val)) { - plgpio->chip.ngpio = val; - } else { - dev_err(&pdev->dev, "DT: Invalid ngpio field\n"); - goto end; - } - - if (!of_property_read_u32(np, "st-plgpio,enb-reg", &val)) - plgpio->regs.enb = val; - else - plgpio->regs.enb = -1; - - if (!of_property_read_u32(np, "st-plgpio,wdata-reg", &val)) { - plgpio->regs.wdata = val; - } else { - dev_err(&pdev->dev, "DT: Invalid wdata reg\n"); - goto end; - } - - if (!of_property_read_u32(np, "st-plgpio,dir-reg", &val)) { - plgpio->regs.dir = val; - } else { - dev_err(&pdev->dev, "DT: Invalid dir reg\n"); - goto end; - } - - if (!of_property_read_u32(np, "st-plgpio,ie-reg", &val)) { - plgpio->regs.ie = val; - } else { - dev_err(&pdev->dev, "DT: Invalid ie reg\n"); - goto end; - } - - if (!of_property_read_u32(np, "st-plgpio,rdata-reg", &val)) { - plgpio->regs.rdata = val; - } else { - dev_err(&pdev->dev, "DT: Invalid rdata reg\n"); - goto end; - } - - if (!of_property_read_u32(np, "st-plgpio,mis-reg", &val)) { - plgpio->regs.mis = val; - } else { - dev_err(&pdev->dev, "DT: Invalid mis reg\n"); - goto end; - } - - if (!of_property_read_u32(np, "st-plgpio,eit-reg", &val)) - plgpio->regs.eit = val; - else - plgpio->regs.eit = -1; - - return 0; - -end: - return ret; -} -static int __devinit plgpio_probe(struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node; - struct plgpio *plgpio; - struct resource *res; - int ret, irq, i; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "invalid IORESOURCE_MEM\n"); - return -EBUSY; - } - - plgpio = devm_kzalloc(&pdev->dev, sizeof(*plgpio), GFP_KERNEL); - if (!plgpio) { - dev_err(&pdev->dev, "memory allocation fail\n"); - return -ENOMEM; - } - - plgpio->base = devm_request_and_ioremap(&pdev->dev, res); - if (!plgpio->base) { - dev_err(&pdev->dev, "request and ioremap fail\n"); - return -ENOMEM; - } - - ret = plgpio_probe_dt(pdev, plgpio); - if (ret) { - dev_err(&pdev->dev, "DT probe failed\n"); - return ret; - } - - plgpio->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(plgpio->clk)) - dev_warn(&pdev->dev, "clk_get() failed, work without it\n"); - -#ifdef CONFIG_PM - plgpio->csave_regs = devm_kzalloc(&pdev->dev, - sizeof(*plgpio->csave_regs) * - DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG), - GFP_KERNEL); - if (!plgpio->csave_regs) { - dev_err(&pdev->dev, "csave registers memory allocation fail\n"); - return -ENOMEM; - } -#endif - - platform_set_drvdata(pdev, plgpio); - spin_lock_init(&plgpio->lock); - - plgpio->irq_base = -1; - plgpio->chip.base = -1; - plgpio->chip.request = plgpio_request; - plgpio->chip.free = plgpio_free; - plgpio->chip.direction_input = plgpio_direction_input; - plgpio->chip.direction_output = plgpio_direction_output; - plgpio->chip.get = plgpio_get_value; - plgpio->chip.set = plgpio_set_value; - plgpio->chip.to_irq = plgpio_to_irq; - plgpio->chip.label = dev_name(&pdev->dev); - plgpio->chip.dev = &pdev->dev; - plgpio->chip.owner = THIS_MODULE; - - if (!IS_ERR(plgpio->clk)) { - ret = clk_prepare(plgpio->clk); - if (ret) { - dev_err(&pdev->dev, "clk prepare failed\n"); - return ret; - } - } - - ret = gpiochip_add(&plgpio->chip); - if (ret) { - dev_err(&pdev->dev, "unable to add gpio chip\n"); - goto unprepare_clk; - } - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_info(&pdev->dev, "irqs not supported\n"); - return 0; - } - - plgpio->irq_base = irq_alloc_descs(-1, 0, plgpio->chip.ngpio, 0); - if (IS_ERR_VALUE(plgpio->irq_base)) { - /* we would not support irq for gpio */ - dev_warn(&pdev->dev, "couldn't allocate irq base\n"); - return 0; - } - - plgpio->irq_domain = irq_domain_add_legacy(np, plgpio->chip.ngpio, - plgpio->irq_base, 0, &irq_domain_simple_ops, NULL); - if (WARN_ON(!plgpio->irq_domain)) { - dev_err(&pdev->dev, "irq domain init failed\n"); - irq_free_descs(plgpio->irq_base, plgpio->chip.ngpio); - ret = -ENXIO; - goto remove_gpiochip; - } - - irq_set_chained_handler(irq, plgpio_irq_handler); - for (i = 0; i < plgpio->chip.ngpio; i++) { - irq_set_chip_and_handler(i + plgpio->irq_base, &plgpio_irqchip, - handle_simple_irq); - set_irq_flags(i + plgpio->irq_base, IRQF_VALID); - irq_set_chip_data(i + plgpio->irq_base, plgpio); - } - - irq_set_handler_data(irq, plgpio); - dev_info(&pdev->dev, "PLGPIO registered with IRQs\n"); - - return 0; - -remove_gpiochip: - dev_info(&pdev->dev, "Remove gpiochip\n"); - if (gpiochip_remove(&plgpio->chip)) - dev_err(&pdev->dev, "unable to remove gpiochip\n"); -unprepare_clk: - if (!IS_ERR(plgpio->clk)) - clk_unprepare(plgpio->clk); - - return ret; -} - -#ifdef CONFIG_PM -static int plgpio_suspend(struct device *dev) -{ - struct plgpio *plgpio = dev_get_drvdata(dev); - int i, reg_count = DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG); - void __iomem *off; - - for (i = 0; i < reg_count; i++) { - off = plgpio->base + i * sizeof(int *); - - if (plgpio->regs.enb != -1) - plgpio->csave_regs[i].enb = - readl_relaxed(plgpio->regs.enb + off); - if (plgpio->regs.eit != -1) - plgpio->csave_regs[i].eit = - readl_relaxed(plgpio->regs.eit + off); - plgpio->csave_regs[i].wdata = readl_relaxed(plgpio->regs.wdata + - off); - plgpio->csave_regs[i].dir = readl_relaxed(plgpio->regs.dir + - off); - plgpio->csave_regs[i].ie = readl_relaxed(plgpio->regs.ie + off); - } - - return 0; -} - -/* - * This is used to correct the values in end registers. End registers contain - * extra bits that might be used for other purpose in platform. So, we shouldn't - * overwrite these bits. This macro, reads given register again, preserves other - * bit values (non-plgpio bits), and retain captured value (plgpio bits). - */ -#define plgpio_prepare_reg(__reg, _off, _mask, _tmp) \ -{ \ - _tmp = readl_relaxed(plgpio->regs.__reg + _off); \ - _tmp &= ~_mask; \ - plgpio->csave_regs[i].__reg = \ - _tmp | (plgpio->csave_regs[i].__reg & _mask); \ -} - -static int plgpio_resume(struct device *dev) -{ - struct plgpio *plgpio = dev_get_drvdata(dev); - int i, reg_count = DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG); - void __iomem *off; - u32 mask, tmp; - - for (i = 0; i < reg_count; i++) { - off = plgpio->base + i * sizeof(int *); - - if (i == reg_count - 1) { - mask = (1 << (plgpio->chip.ngpio - i * - MAX_GPIO_PER_REG)) - 1; - - if (plgpio->regs.enb != -1) - plgpio_prepare_reg(enb, off, mask, tmp); - - if (plgpio->regs.eit != -1) - plgpio_prepare_reg(eit, off, mask, tmp); - - plgpio_prepare_reg(wdata, off, mask, tmp); - plgpio_prepare_reg(dir, off, mask, tmp); - plgpio_prepare_reg(ie, off, mask, tmp); - } - - writel_relaxed(plgpio->csave_regs[i].wdata, plgpio->regs.wdata + - off); - writel_relaxed(plgpio->csave_regs[i].dir, plgpio->regs.dir + - off); - - if (plgpio->regs.eit != -1) - writel_relaxed(plgpio->csave_regs[i].eit, - plgpio->regs.eit + off); - - writel_relaxed(plgpio->csave_regs[i].ie, plgpio->regs.ie + off); - - if (plgpio->regs.enb != -1) - writel_relaxed(plgpio->csave_regs[i].enb, - plgpio->regs.enb + off); - } - - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(plgpio_dev_pm_ops, plgpio_suspend, plgpio_resume); - -static const struct of_device_id plgpio_of_match[] = { - { .compatible = "st,spear-plgpio" }, - {} -}; -MODULE_DEVICE_TABLE(of, plgpio_of_match); - -static struct platform_driver plgpio_driver = { - .probe = plgpio_probe, - .driver = { - .owner = THIS_MODULE, - .name = "spear-plgpio", - .pm = &plgpio_dev_pm_ops, - .of_match_table = of_match_ptr(plgpio_of_match), - }, -}; - -static int __init plgpio_init(void) -{ - return platform_driver_register(&plgpio_driver); -} -subsys_initcall(plgpio_init); - -MODULE_AUTHOR("Viresh Kumar "); -MODULE_DESCRIPTION("ST Microlectronics SPEAr PLGPIO driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear.c b/trunk/drivers/pinctrl/spear/pinctrl-spear.c index bf78eb7f85c4..5d4f44f462f0 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear.c @@ -14,10 +14,10 @@ */ #include +#include #include #include #include -#include #include #include #include @@ -28,26 +28,14 @@ #define DRIVER_NAME "spear-pinmux" -static void muxregs_endisable(struct spear_pmx *pmx, - struct spear_muxreg *muxregs, u8 count, bool enable) +static inline u32 pmx_readl(struct spear_pmx *pmx, u32 reg) { - struct spear_muxreg *muxreg; - u32 val, temp, j; - - for (j = 0; j < count; j++) { - muxreg = &muxregs[j]; - - val = pmx_readl(pmx, muxreg->reg); - val &= ~muxreg->mask; - - if (enable) - temp = muxreg->val; - else - temp = ~muxreg->val; + return readl_relaxed(pmx->vbase + reg); +} - val |= muxreg->mask & temp; - pmx_writel(pmx, val, muxreg->reg); - } +static inline void pmx_writel(struct spear_pmx *pmx, u32 val, u32 reg) +{ + writel_relaxed(val, pmx->vbase + reg); } static int set_mode(struct spear_pmx *pmx, int mode) @@ -82,17 +70,6 @@ static int set_mode(struct spear_pmx *pmx, int mode) return 0; } -void __devinit -pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup, - unsigned count, u16 reg) -{ - int i, j; - - for (i = 0; i < count; i++) - for (j = 0; j < gpio_pingroup[i].nmuxregs; j++) - gpio_pingroup[i].muxregs[j].reg = reg; -} - void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg) { struct spear_pingroup *pgroup; @@ -144,10 +121,9 @@ static void spear_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev, seq_printf(s, " " DRIVER_NAME); } -static int spear_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np_config, - struct pinctrl_map **map, - unsigned *num_maps) +int spear_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, + struct device_node *np_config, + struct pinctrl_map **map, unsigned *num_maps) { struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); struct device_node *np; @@ -192,9 +168,8 @@ static int spear_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, return 0; } -static void spear_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, - struct pinctrl_map *map, - unsigned num_maps) +void spear_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, + struct pinctrl_map *map, unsigned num_maps) { kfree(map); } @@ -241,7 +216,9 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev, struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); const struct spear_pingroup *pgroup; const struct spear_modemux *modemux; - int i; + struct spear_muxreg *muxreg; + u32 val, temp; + int i, j; bool found = false; pgroup = pmx->machdata->groups[group]; @@ -256,8 +233,20 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev, } found = true; - muxregs_endisable(pmx, modemux->muxregs, modemux->nmuxregs, - enable); + for (j = 0; j < modemux->nmuxregs; j++) { + muxreg = &modemux->muxregs[j]; + + val = pmx_readl(pmx, muxreg->reg); + val &= ~muxreg->mask; + + if (enable) + temp = muxreg->val; + else + temp = ~muxreg->val; + + val |= temp; + pmx_writel(pmx, val, muxreg->reg); + } } if (!found) { @@ -281,74 +270,12 @@ static void spear_pinctrl_disable(struct pinctrl_dev *pctldev, spear_pinctrl_endisable(pctldev, function, group, false); } -/* gpio with pinmux */ -static struct spear_gpio_pingroup *get_gpio_pingroup(struct spear_pmx *pmx, - unsigned pin) -{ - struct spear_gpio_pingroup *gpio_pingroup; - int i, j; - - if (!pmx->machdata->gpio_pingroups) - return NULL; - - for (i = 0; i < pmx->machdata->ngpio_pingroups; i++) { - gpio_pingroup = &pmx->machdata->gpio_pingroups[i]; - - for (j = 0; j < gpio_pingroup->npins; j++) { - if (gpio_pingroup->pins[j] == pin) - return gpio_pingroup; - } - } - - return NULL; -} - -static int gpio_request_endisable(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, unsigned offset, bool enable) -{ - struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - struct spear_pinctrl_machdata *machdata = pmx->machdata; - struct spear_gpio_pingroup *gpio_pingroup; - - /* - * Some SoC have configuration options applicable to group of pins, - * rather than a single pin. - */ - gpio_pingroup = get_gpio_pingroup(pmx, offset); - if (gpio_pingroup) - muxregs_endisable(pmx, gpio_pingroup->muxregs, - gpio_pingroup->nmuxregs, enable); - - /* - * SoC may need some extra configurations, or configurations for single - * pin - */ - if (machdata->gpio_request_endisable) - machdata->gpio_request_endisable(pmx, offset, enable); - - return 0; -} - -static int gpio_request_enable(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, unsigned offset) -{ - return gpio_request_endisable(pctldev, range, offset, true); -} - -static void gpio_disable_free(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, unsigned offset) -{ - gpio_request_endisable(pctldev, range, offset, false); -} - static struct pinmux_ops spear_pinmux_ops = { .get_functions_count = spear_pinctrl_get_funcs_count, .get_function_name = spear_pinctrl_get_func_name, .get_function_groups = spear_pinctrl_get_func_groups, .enable = spear_pinctrl_enable, .disable = spear_pinctrl_disable, - .gpio_request_enable = gpio_request_enable, - .gpio_disable_free = gpio_disable_free, }; static struct pinctrl_desc spear_pinctrl_desc = { diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear.h b/trunk/drivers/pinctrl/spear/pinctrl-spear.h index b06332719b2c..d950eb78d939 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear.h +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear.h @@ -12,14 +12,11 @@ #ifndef __PINMUX_SPEAR_H__ #define __PINMUX_SPEAR_H__ -#include -#include #include #include struct platform_device; struct device; -struct spear_pmx; /** * struct spear_pmx_mode - SPEAr pmx mode @@ -49,44 +46,6 @@ struct spear_muxreg { u32 val; }; -struct spear_gpio_pingroup { - const unsigned *pins; - unsigned npins; - struct spear_muxreg *muxregs; - u8 nmuxregs; -}; - -/* ste: set to enable */ -#define DEFINE_MUXREG(__pins, __muxreg, __mask, __ste) \ -static struct spear_muxreg __pins##_muxregs[] = { \ - { \ - .reg = __muxreg, \ - .mask = __mask, \ - .val = __ste ? __mask : 0, \ - }, \ -} - -#define DEFINE_2_MUXREG(__pins, __muxreg1, __muxreg2, __mask, __ste1, __ste2) \ -static struct spear_muxreg __pins##_muxregs[] = { \ - { \ - .reg = __muxreg1, \ - .mask = __mask, \ - .val = __ste1 ? __mask : 0, \ - }, { \ - .reg = __muxreg2, \ - .mask = __mask, \ - .val = __ste2 ? __mask : 0, \ - }, \ -} - -#define GPIO_PINGROUP(__pins) \ - { \ - .pins = __pins, \ - .npins = ARRAY_SIZE(__pins), \ - .muxregs = __pins##_muxregs, \ - .nmuxregs = ARRAY_SIZE(__pins##_muxregs), \ - } - /** * struct spear_modemux - SPEAr mode mux configuration * @modes: mode ids supported by this group of muxregs @@ -141,8 +100,6 @@ struct spear_function { * @nfunctions: The numbmer of entries in @functions. * @groups: An array describing all pin groups the pin SoC supports. * @ngroups: The numbmer of entries in @groups. - * @gpio_pingroups: gpio pingroups - * @ngpio_pingroups: gpio pingroups count * * @modes_supported: Does SoC support modes * @mode: mode configured from probe @@ -156,10 +113,6 @@ struct spear_pinctrl_machdata { unsigned nfunctions; struct spear_pingroup **groups; unsigned ngroups; - struct spear_gpio_pingroup *gpio_pingroups; - void (*gpio_request_endisable)(struct spear_pmx *pmx, int offset, - bool enable); - unsigned ngpio_pingroups; bool modes_supported; u16 mode; @@ -182,20 +135,7 @@ struct spear_pmx { }; /* exported routines */ -static inline u32 pmx_readl(struct spear_pmx *pmx, u32 reg) -{ - return readl_relaxed(pmx->vbase + reg); -} - -static inline void pmx_writel(struct spear_pmx *pmx, u32 val, u32 reg) -{ - writel_relaxed(val, pmx->vbase + reg); -} - void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg); -void __devinit -pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup, - unsigned count, u16 reg); int __devinit spear_pinctrl_probe(struct platform_device *pdev, struct spear_pinctrl_machdata *machdata); int __devexit spear_pinctrl_remove(struct platform_device *pdev); diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear1310.c b/trunk/drivers/pinctrl/spear/pinctrl-spear1310.c index 30134f727455..d6cca8c81b92 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear1310.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear1310.c @@ -25,8 +25,8 @@ static const struct pinctrl_pin_desc spear1310_pins[] = { }; /* registers */ -#define PERIP_CFG 0x3B0 - #define MCIF_SEL_SHIFT 5 +#define PERIP_CFG 0x32C + #define MCIF_SEL_SHIFT 3 #define MCIF_SEL_SD (0x1 << MCIF_SEL_SHIFT) #define MCIF_SEL_CF (0x2 << MCIF_SEL_SHIFT) #define MCIF_SEL_XD (0x3 << MCIF_SEL_SHIFT) @@ -164,10 +164,6 @@ static const struct pinctrl_pin_desc spear1310_pins[] = { #define PMX_SSP0_CS0_MASK (1 << 29) #define PMX_SSP0_CS1_2_MASK (1 << 30) -#define PAD_DIRECTION_SEL_0 0x65C -#define PAD_DIRECTION_SEL_1 0x660 -#define PAD_DIRECTION_SEL_2 0x664 - /* combined macros */ #define PMX_GMII_MASK (PMX_GMIICLK_MASK | \ PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK | \ @@ -241,10 +237,6 @@ static struct spear_muxreg i2c0_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_I2C0_MASK, .val = PMX_I2C0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_I2C0_MASK, - .val = PMX_I2C0_MASK, }, }; @@ -277,10 +269,6 @@ static struct spear_muxreg ssp0_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_SSP0_MASK, .val = PMX_SSP0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_SSP0_MASK, - .val = PMX_SSP0_MASK, }, }; @@ -306,10 +294,6 @@ static struct spear_muxreg ssp0_cs0_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_SSP0_CS0_MASK, .val = PMX_SSP0_CS0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_SSP0_CS0_MASK, - .val = PMX_SSP0_CS0_MASK, }, }; @@ -335,10 +319,6 @@ static struct spear_muxreg ssp0_cs1_2_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_SSP0_CS1_2_MASK, .val = PMX_SSP0_CS1_2_MASK, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_SSP0_CS1_2_MASK, - .val = PMX_SSP0_CS1_2_MASK, }, }; @@ -372,10 +352,6 @@ static struct spear_muxreg i2s0_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_I2S0_MASK, .val = PMX_I2S0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_I2S0_MASK, - .val = PMX_I2S0_MASK, }, }; @@ -408,10 +384,6 @@ static struct spear_muxreg i2s1_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_I2S1_MASK, .val = PMX_I2S1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_I2S1_MASK, - .val = PMX_I2S1_MASK, }, }; @@ -446,10 +418,6 @@ static struct spear_muxreg clcd_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_CLCD1_MASK, .val = PMX_CLCD1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_CLCD1_MASK, - .val = PMX_CLCD1_MASK, }, }; @@ -475,10 +443,6 @@ static struct spear_muxreg clcd_high_res_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_CLCD2_MASK, .val = PMX_CLCD2_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_CLCD2_MASK, - .val = PMX_CLCD2_MASK, }, }; @@ -497,7 +461,7 @@ static struct spear_pingroup clcd_high_res_pingroup = { .nmodemuxs = ARRAY_SIZE(clcd_high_res_modemux), }; -static const char *const clcd_grps[] = { "clcd_grp", "clcd_high_res_grp" }; +static const char *const clcd_grps[] = { "clcd_grp", "clcd_high_res" }; static struct spear_function clcd_function = { .name = "clcd", .groups = clcd_grps, @@ -515,14 +479,6 @@ static struct spear_muxreg arm_gpio_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_EGPIO_1_GRP_MASK, .val = PMX_EGPIO_1_GRP_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_EGPIO_0_GRP_MASK, - .val = PMX_EGPIO_0_GRP_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_EGPIO_1_GRP_MASK, - .val = PMX_EGPIO_1_GRP_MASK, }, }; @@ -555,10 +511,6 @@ static struct spear_muxreg smi_2_chips_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_SMI_MASK, .val = PMX_SMI_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_SMI_MASK, - .val = PMX_SMI_MASK, }, }; @@ -587,14 +539,6 @@ static struct spear_muxreg smi_4_chips_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, .val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_SMI_MASK, - .val = PMX_SMI_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, - .val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, }, }; @@ -629,10 +573,6 @@ static struct spear_muxreg gmii_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_GMII_MASK, .val = PMX_GMII_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_GMII_MASK, - .val = PMX_GMII_MASK, }, }; @@ -675,18 +615,6 @@ static struct spear_muxreg rgmii_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_RGMII_REG2_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_RGMII_REG0_MASK, - .val = PMX_RGMII_REG0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_RGMII_REG1_MASK, - .val = PMX_RGMII_REG1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_RGMII_REG2_MASK, - .val = PMX_RGMII_REG2_MASK, }, }; @@ -721,10 +649,6 @@ static struct spear_muxreg smii_0_1_2_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_SMII_0_1_2_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_SMII_0_1_2_MASK, - .val = PMX_SMII_0_1_2_MASK, }, }; @@ -757,10 +681,6 @@ static struct spear_muxreg ras_mii_txclk_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_NFCE2_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_NFCE2_MASK, - .val = PMX_NFCE2_MASK, }, }; @@ -801,14 +721,6 @@ static struct spear_muxreg nand_8bit_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_NAND8BIT_1_MASK, .val = PMX_NAND8BIT_1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_NAND8BIT_0_MASK, - .val = PMX_NAND8BIT_0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_NAND8BIT_1_MASK, - .val = PMX_NAND8BIT_1_MASK, }, }; @@ -835,10 +747,6 @@ static struct spear_muxreg nand_16bit_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_NAND16BIT_1_MASK, .val = PMX_NAND16BIT_1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_NAND16BIT_1_MASK, - .val = PMX_NAND16BIT_1_MASK, }, }; @@ -864,10 +772,6 @@ static struct spear_muxreg nand_4_chips_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_NAND_4CHIPS_MASK, .val = PMX_NAND_4CHIPS_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_NAND_4CHIPS_MASK, - .val = PMX_NAND_4CHIPS_MASK, }, }; @@ -929,10 +833,6 @@ static struct spear_muxreg keyboard_rowcol6_8_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_KBD_ROWCOL68_MASK, .val = PMX_KBD_ROWCOL68_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_KBD_ROWCOL68_MASK, - .val = PMX_KBD_ROWCOL68_MASK, }, }; @@ -966,10 +866,6 @@ static struct spear_muxreg uart0_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_UART0_MASK, .val = PMX_UART0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_UART0_MASK, - .val = PMX_UART0_MASK, }, }; @@ -995,10 +891,6 @@ static struct spear_muxreg uart0_modem_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_UART0_MODEM_MASK, .val = PMX_UART0_MODEM_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_UART0_MODEM_MASK, - .val = PMX_UART0_MODEM_MASK, }, }; @@ -1031,10 +923,6 @@ static struct spear_muxreg gpt0_tmr0_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_GPT0_TMR0_MASK, .val = PMX_GPT0_TMR0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_GPT0_TMR0_MASK, - .val = PMX_GPT0_TMR0_MASK, }, }; @@ -1060,10 +948,6 @@ static struct spear_muxreg gpt0_tmr1_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_GPT0_TMR1_MASK, .val = PMX_GPT0_TMR1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_GPT0_TMR1_MASK, - .val = PMX_GPT0_TMR1_MASK, }, }; @@ -1096,10 +980,6 @@ static struct spear_muxreg gpt1_tmr0_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_GPT1_TMR0_MASK, .val = PMX_GPT1_TMR0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_GPT1_TMR0_MASK, - .val = PMX_GPT1_TMR0_MASK, }, }; @@ -1125,10 +1005,6 @@ static struct spear_muxreg gpt1_tmr1_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_GPT1_TMR1_MASK, .val = PMX_GPT1_TMR1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_GPT1_TMR1_MASK, - .val = PMX_GPT1_TMR1_MASK, }, }; @@ -1173,20 +1049,6 @@ static const unsigned mcif_pins[] = { 86, 87, 88, 89, 90, 91, 92, 93, 213, 214, .reg = PAD_FUNCTION_EN_2, \ .mask = PMX_MCIFALL_2_MASK, \ .val = PMX_MCIFALL_2_MASK, \ - }, { \ - .reg = PAD_DIRECTION_SEL_0, \ - .mask = PMX_MCI_DATA8_15_MASK, \ - .val = PMX_MCI_DATA8_15_MASK, \ - }, { \ - .reg = PAD_DIRECTION_SEL_1, \ - .mask = PMX_MCIFALL_1_MASK | PMX_NFWPRT1_MASK | \ - PMX_NFWPRT2_MASK, \ - .val = PMX_MCIFALL_1_MASK | PMX_NFWPRT1_MASK | \ - PMX_NFWPRT2_MASK, \ - }, { \ - .reg = PAD_DIRECTION_SEL_2, \ - .mask = PMX_MCIFALL_2_MASK, \ - .val = PMX_MCIFALL_2_MASK, \ } /* sdhci device */ @@ -1292,10 +1154,6 @@ static struct spear_muxreg touch_xy_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_TOUCH_XY_MASK, .val = PMX_TOUCH_XY_MASK, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_TOUCH_XY_MASK, - .val = PMX_TOUCH_XY_MASK, }, }; @@ -1329,10 +1187,6 @@ static struct spear_muxreg uart1_dis_i2c_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_I2C0_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_I2C0_MASK, - .val = PMX_I2C0_MASK, }, }; @@ -1359,12 +1213,6 @@ static struct spear_muxreg uart1_dis_sd_muxreg[] = { .mask = PMX_MCIDATA1_MASK | PMX_MCIDATA2_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_MCIDATA1_MASK | - PMX_MCIDATA2_MASK, - .val = PMX_MCIDATA1_MASK | - PMX_MCIDATA2_MASK, }, }; @@ -1398,10 +1246,6 @@ static struct spear_muxreg uart2_3_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_I2S0_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_I2S0_MASK, - .val = PMX_I2S0_MASK, }, }; @@ -1434,10 +1278,6 @@ static struct spear_muxreg uart4_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_I2S0_MASK | PMX_CLCD1_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_I2S0_MASK | PMX_CLCD1_MASK, - .val = PMX_I2S0_MASK | PMX_CLCD1_MASK, }, }; @@ -1470,10 +1310,6 @@ static struct spear_muxreg uart5_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_CLCD1_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_CLCD1_MASK, - .val = PMX_CLCD1_MASK, }, }; @@ -1508,10 +1344,6 @@ static struct spear_muxreg rs485_0_1_tdm_0_1_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_CLCD1_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_CLCD1_MASK, - .val = PMX_CLCD1_MASK, }, }; @@ -1544,10 +1376,6 @@ static struct spear_muxreg i2c_1_2_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_CLCD1_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_CLCD1_MASK, - .val = PMX_CLCD1_MASK, }, }; @@ -1581,10 +1409,6 @@ static struct spear_muxreg i2c3_dis_smi_clcd_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_CLCD1_MASK | PMX_SMI_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_CLCD1_MASK | PMX_SMI_MASK, - .val = PMX_CLCD1_MASK | PMX_SMI_MASK, }, }; @@ -1611,10 +1435,6 @@ static struct spear_muxreg i2c3_dis_sd_i2s0_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, - .val = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, }, }; @@ -1649,10 +1469,6 @@ static struct spear_muxreg i2c_4_5_dis_smi_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_SMI_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_SMI_MASK, - .val = PMX_SMI_MASK, }, }; @@ -1683,14 +1499,6 @@ static struct spear_muxreg i2c4_dis_sd_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_MCIDATA5_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_MCIDATA4_MASK, - .val = PMX_MCIDATA4_MASK, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCIDATA5_MASK, - .val = PMX_MCIDATA5_MASK, }, }; @@ -1718,12 +1526,6 @@ static struct spear_muxreg i2c5_dis_sd_muxreg[] = { .mask = PMX_MCIDATA6_MASK | PMX_MCIDATA7_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCIDATA6_MASK | - PMX_MCIDATA7_MASK, - .val = PMX_MCIDATA6_MASK | - PMX_MCIDATA7_MASK, }, }; @@ -1758,10 +1560,6 @@ static struct spear_muxreg i2c_6_7_dis_kbd_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_KBD_ROWCOL25_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_KBD_ROWCOL25_MASK, - .val = PMX_KBD_ROWCOL25_MASK, }, }; @@ -1789,12 +1587,6 @@ static struct spear_muxreg i2c6_dis_sd_muxreg[] = { .mask = PMX_MCIIORDRE_MASK | PMX_MCIIOWRWE_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCIIORDRE_MASK | - PMX_MCIIOWRWE_MASK, - .val = PMX_MCIIORDRE_MASK | - PMX_MCIIOWRWE_MASK, }, }; @@ -1821,12 +1613,6 @@ static struct spear_muxreg i2c7_dis_sd_muxreg[] = { .mask = PMX_MCIRESETCF_MASK | PMX_MCICS0CE_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCIRESETCF_MASK | - PMX_MCICS0CE_MASK, - .val = PMX_MCIRESETCF_MASK | - PMX_MCICS0CE_MASK, }, }; @@ -1865,14 +1651,6 @@ static struct spear_muxreg can0_dis_nor_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_NFRSTPWDWN3_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_NFRSTPWDWN2_MASK, - .val = PMX_NFRSTPWDWN2_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_NFRSTPWDWN3_MASK, - .val = PMX_NFRSTPWDWN3_MASK, }, }; @@ -1899,10 +1677,6 @@ static struct spear_muxreg can0_dis_sd_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, - .val = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, }, }; @@ -1937,10 +1711,6 @@ static struct spear_muxreg can1_dis_sd_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, - .val = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, }, }; @@ -1967,10 +1737,6 @@ static struct spear_muxreg can1_dis_kbd_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_KBD_ROWCOL25_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_KBD_ROWCOL25_MASK, - .val = PMX_KBD_ROWCOL25_MASK, }, }; @@ -1997,64 +1763,29 @@ static struct spear_function can1_function = { .ngroups = ARRAY_SIZE(can1_grps), }; -/* Pad multiplexing for (ras-ip) pci device */ -static const unsigned pci_pins[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18, +/* Pad multiplexing for pci device */ +static const unsigned pci_sata_pins[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 }; +#define PCI_SATA_MUXREG \ + { \ + .reg = PAD_FUNCTION_EN_0, \ + .mask = PMX_MCI_DATA8_15_MASK, \ + .val = 0, \ + }, { \ + .reg = PAD_FUNCTION_EN_1, \ + .mask = PMX_PCI_REG1_MASK, \ + .val = 0, \ + }, { \ + .reg = PAD_FUNCTION_EN_2, \ + .mask = PMX_PCI_REG2_MASK, \ + .val = 0, \ + } -static struct spear_muxreg pci_muxreg[] = { - { - .reg = PAD_FUNCTION_EN_0, - .mask = PMX_MCI_DATA8_15_MASK, - .val = 0, - }, { - .reg = PAD_FUNCTION_EN_1, - .mask = PMX_PCI_REG1_MASK, - .val = 0, - }, { - .reg = PAD_FUNCTION_EN_2, - .mask = PMX_PCI_REG2_MASK, - .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_MCI_DATA8_15_MASK, - .val = PMX_MCI_DATA8_15_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_PCI_REG1_MASK, - .val = PMX_PCI_REG1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_PCI_REG2_MASK, - .val = PMX_PCI_REG2_MASK, - }, -}; - -static struct spear_modemux pci_modemux[] = { - { - .muxregs = pci_muxreg, - .nmuxregs = ARRAY_SIZE(pci_muxreg), - }, -}; - -static struct spear_pingroup pci_pingroup = { - .name = "pci_grp", - .pins = pci_pins, - .npins = ARRAY_SIZE(pci_pins), - .modemuxs = pci_modemux, - .nmodemuxs = ARRAY_SIZE(pci_modemux), -}; - -static const char *const pci_grps[] = { "pci_grp" }; -static struct spear_function pci_function = { - .name = "pci", - .groups = pci_grps, - .ngroups = ARRAY_SIZE(pci_grps), -}; - -/* pad multiplexing for (fix-part) pcie0 device */ +/* pad multiplexing for pcie0 device */ static struct spear_muxreg pcie0_muxreg[] = { + PCI_SATA_MUXREG, { .reg = PCIE_SATA_CFG, .mask = PCIE_CFG_VAL(0), @@ -2071,12 +1802,15 @@ static struct spear_modemux pcie0_modemux[] = { static struct spear_pingroup pcie0_pingroup = { .name = "pcie0_grp", + .pins = pci_sata_pins, + .npins = ARRAY_SIZE(pci_sata_pins), .modemuxs = pcie0_modemux, .nmodemuxs = ARRAY_SIZE(pcie0_modemux), }; -/* pad multiplexing for (fix-part) pcie1 device */ +/* pad multiplexing for pcie1 device */ static struct spear_muxreg pcie1_muxreg[] = { + PCI_SATA_MUXREG, { .reg = PCIE_SATA_CFG, .mask = PCIE_CFG_VAL(1), @@ -2093,12 +1827,15 @@ static struct spear_modemux pcie1_modemux[] = { static struct spear_pingroup pcie1_pingroup = { .name = "pcie1_grp", + .pins = pci_sata_pins, + .npins = ARRAY_SIZE(pci_sata_pins), .modemuxs = pcie1_modemux, .nmodemuxs = ARRAY_SIZE(pcie1_modemux), }; -/* pad multiplexing for (fix-part) pcie2 device */ +/* pad multiplexing for pcie2 device */ static struct spear_muxreg pcie2_muxreg[] = { + PCI_SATA_MUXREG, { .reg = PCIE_SATA_CFG, .mask = PCIE_CFG_VAL(2), @@ -2115,20 +1852,22 @@ static struct spear_modemux pcie2_modemux[] = { static struct spear_pingroup pcie2_pingroup = { .name = "pcie2_grp", + .pins = pci_sata_pins, + .npins = ARRAY_SIZE(pci_sata_pins), .modemuxs = pcie2_modemux, .nmodemuxs = ARRAY_SIZE(pcie2_modemux), }; -static const char *const pcie_grps[] = { "pcie0_grp", "pcie1_grp", "pcie2_grp" -}; -static struct spear_function pcie_function = { - .name = "pci_express", - .groups = pcie_grps, - .ngroups = ARRAY_SIZE(pcie_grps), +static const char *const pci_grps[] = { "pcie0_grp", "pcie1_grp", "pcie2_grp" }; +static struct spear_function pci_function = { + .name = "pci", + .groups = pci_grps, + .ngroups = ARRAY_SIZE(pci_grps), }; /* pad multiplexing for sata0 device */ static struct spear_muxreg sata0_muxreg[] = { + PCI_SATA_MUXREG, { .reg = PCIE_SATA_CFG, .mask = SATA_CFG_VAL(0), @@ -2145,12 +1884,15 @@ static struct spear_modemux sata0_modemux[] = { static struct spear_pingroup sata0_pingroup = { .name = "sata0_grp", + .pins = pci_sata_pins, + .npins = ARRAY_SIZE(pci_sata_pins), .modemuxs = sata0_modemux, .nmodemuxs = ARRAY_SIZE(sata0_modemux), }; /* pad multiplexing for sata1 device */ static struct spear_muxreg sata1_muxreg[] = { + PCI_SATA_MUXREG, { .reg = PCIE_SATA_CFG, .mask = SATA_CFG_VAL(1), @@ -2167,12 +1909,15 @@ static struct spear_modemux sata1_modemux[] = { static struct spear_pingroup sata1_pingroup = { .name = "sata1_grp", + .pins = pci_sata_pins, + .npins = ARRAY_SIZE(pci_sata_pins), .modemuxs = sata1_modemux, .nmodemuxs = ARRAY_SIZE(sata1_modemux), }; /* pad multiplexing for sata2 device */ static struct spear_muxreg sata2_muxreg[] = { + PCI_SATA_MUXREG, { .reg = PCIE_SATA_CFG, .mask = SATA_CFG_VAL(2), @@ -2189,6 +1934,8 @@ static struct spear_modemux sata2_modemux[] = { static struct spear_pingroup sata2_pingroup = { .name = "sata2_grp", + .pins = pci_sata_pins, + .npins = ARRAY_SIZE(pci_sata_pins), .modemuxs = sata2_modemux, .nmodemuxs = ARRAY_SIZE(sata2_modemux), }; @@ -2210,14 +1957,6 @@ static struct spear_muxreg ssp1_dis_kbd_muxreg[] = { PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | PMX_NFCE2_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL1_MASK | - PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | - PMX_NFCE2_MASK, - .val = PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL1_MASK | - PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | - PMX_NFCE2_MASK, }, }; @@ -2244,12 +1983,6 @@ static struct spear_muxreg ssp1_dis_sd_muxreg[] = { .mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | PMX_MCICECF_MASK | PMX_MCICEXD_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | - PMX_MCICECF_MASK | PMX_MCICEXD_MASK, - .val = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | - PMX_MCICECF_MASK | PMX_MCICEXD_MASK, }, }; @@ -2284,12 +2017,6 @@ static struct spear_muxreg gpt64_muxreg[] = { .mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK | PMX_MCILEDS_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK - | PMX_MCILEDS_MASK, - .val = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK - | PMX_MCILEDS_MASK, }, }; @@ -2366,7 +2093,6 @@ static struct spear_pingroup *spear1310_pingroups[] = { &can0_dis_sd_pingroup, &can1_dis_sd_pingroup, &can1_dis_kbd_pingroup, - &pci_pingroup, &pcie0_pingroup, &pcie1_pingroup, &pcie2_pingroup, @@ -2412,274 +2138,11 @@ static struct spear_function *spear1310_functions[] = { &can0_function, &can1_function, &pci_function, - &pcie_function, &sata_function, &ssp1_function, &gpt64_function, }; -static const unsigned pin18[] = { 18, }; -static const unsigned pin19[] = { 19, }; -static const unsigned pin20[] = { 20, }; -static const unsigned pin21[] = { 21, }; -static const unsigned pin22[] = { 22, }; -static const unsigned pin23[] = { 23, }; -static const unsigned pin54[] = { 54, }; -static const unsigned pin55[] = { 55, }; -static const unsigned pin56[] = { 56, }; -static const unsigned pin57[] = { 57, }; -static const unsigned pin58[] = { 58, }; -static const unsigned pin59[] = { 59, }; -static const unsigned pin60[] = { 60, }; -static const unsigned pin61[] = { 61, }; -static const unsigned pin62[] = { 62, }; -static const unsigned pin63[] = { 63, }; -static const unsigned pin143[] = { 143, }; -static const unsigned pin144[] = { 144, }; -static const unsigned pin145[] = { 145, }; -static const unsigned pin146[] = { 146, }; -static const unsigned pin147[] = { 147, }; -static const unsigned pin148[] = { 148, }; -static const unsigned pin149[] = { 149, }; -static const unsigned pin150[] = { 150, }; -static const unsigned pin151[] = { 151, }; -static const unsigned pin152[] = { 152, }; -static const unsigned pin205[] = { 205, }; -static const unsigned pin206[] = { 206, }; -static const unsigned pin211[] = { 211, }; -static const unsigned pin212[] = { 212, }; -static const unsigned pin213[] = { 213, }; -static const unsigned pin214[] = { 214, }; -static const unsigned pin215[] = { 215, }; -static const unsigned pin216[] = { 216, }; -static const unsigned pin217[] = { 217, }; -static const unsigned pin218[] = { 218, }; -static const unsigned pin219[] = { 219, }; -static const unsigned pin220[] = { 220, }; -static const unsigned pin221[] = { 221, }; -static const unsigned pin222[] = { 222, }; -static const unsigned pin223[] = { 223, }; -static const unsigned pin224[] = { 224, }; -static const unsigned pin225[] = { 225, }; -static const unsigned pin226[] = { 226, }; -static const unsigned pin227[] = { 227, }; -static const unsigned pin228[] = { 228, }; -static const unsigned pin229[] = { 229, }; -static const unsigned pin230[] = { 230, }; -static const unsigned pin231[] = { 231, }; -static const unsigned pin232[] = { 232, }; -static const unsigned pin233[] = { 233, }; -static const unsigned pin234[] = { 234, }; -static const unsigned pin235[] = { 235, }; -static const unsigned pin236[] = { 236, }; -static const unsigned pin237[] = { 237, }; -static const unsigned pin238[] = { 238, }; -static const unsigned pin239[] = { 239, }; -static const unsigned pin240[] = { 240, }; -static const unsigned pin241[] = { 241, }; -static const unsigned pin242[] = { 242, }; -static const unsigned pin243[] = { 243, }; -static const unsigned pin244[] = { 244, }; -static const unsigned pin245[] = { 245, }; - -static const unsigned pin_grp0[] = { 173, 174, }; -static const unsigned pin_grp1[] = { 175, 185, 188, 197, 198, }; -static const unsigned pin_grp2[] = { 176, 177, 178, 179, 184, 186, 187, 189, - 190, 191, 192, }; -static const unsigned pin_grp3[] = { 180, 181, 182, 183, 193, 194, 195, 196, }; -static const unsigned pin_grp4[] = { 199, 200, }; -static const unsigned pin_grp5[] = { 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, }; -static const unsigned pin_grp6[] = { 86, 87, 88, 89, 90, 91, 92, 93, }; -static const unsigned pin_grp7[] = { 98, 99, }; -static const unsigned pin_grp8[] = { 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, }; - -/* Define muxreg arrays */ -DEFINE_2_MUXREG(i2c0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_I2C0_MASK, 0, 1); -DEFINE_2_MUXREG(ssp0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_SSP0_MASK, 0, 1); -DEFINE_2_MUXREG(ssp0_cs0_pins, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_SSP0_CS0_MASK, 0, 1); -DEFINE_2_MUXREG(ssp0_cs1_2_pins, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_SSP0_CS1_2_MASK, 0, 1); -DEFINE_2_MUXREG(i2s0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_I2S0_MASK, 0, 1); -DEFINE_2_MUXREG(i2s1_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_I2S1_MASK, 0, 1); -DEFINE_2_MUXREG(clcd_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_CLCD1_MASK, 0, 1); -DEFINE_2_MUXREG(clcd_high_res_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_CLCD2_MASK, 0, 1); -DEFINE_2_MUXREG(pin18, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO15_MASK, 0, 1); -DEFINE_2_MUXREG(pin19, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO14_MASK, 0, 1); -DEFINE_2_MUXREG(pin20, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO13_MASK, 0, 1); -DEFINE_2_MUXREG(pin21, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO12_MASK, 0, 1); -DEFINE_2_MUXREG(pin22, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO11_MASK, 0, 1); -DEFINE_2_MUXREG(pin23, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO10_MASK, 0, 1); -DEFINE_2_MUXREG(pin143, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO00_MASK, 0, 1); -DEFINE_2_MUXREG(pin144, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO01_MASK, 0, 1); -DEFINE_2_MUXREG(pin145, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO02_MASK, 0, 1); -DEFINE_2_MUXREG(pin146, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO03_MASK, 0, 1); -DEFINE_2_MUXREG(pin147, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO04_MASK, 0, 1); -DEFINE_2_MUXREG(pin148, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO05_MASK, 0, 1); -DEFINE_2_MUXREG(pin149, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO06_MASK, 0, 1); -DEFINE_2_MUXREG(pin150, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO07_MASK, 0, 1); -DEFINE_2_MUXREG(pin151, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO08_MASK, 0, 1); -DEFINE_2_MUXREG(pin152, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO09_MASK, 0, 1); -DEFINE_2_MUXREG(smi_2_chips_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_SMI_MASK, 0, 1); -DEFINE_2_MUXREG(pin54, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_SMINCS3_MASK, 0, 1); -DEFINE_2_MUXREG(pin55, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_SMINCS2_MASK, 0, 1); -DEFINE_2_MUXREG(pin56, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NFRSTPWDWN3_MASK, 0, 1); -DEFINE_2_MUXREG(pin57, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFRSTPWDWN2_MASK, 0, 1); -DEFINE_2_MUXREG(pin58, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFRSTPWDWN1_MASK, 0, 1); -DEFINE_2_MUXREG(pin59, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFRSTPWDWN0_MASK, 0, 1); -DEFINE_2_MUXREG(pin60, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFWPRT3_MASK, 0, 1); -DEFINE_2_MUXREG(pin61, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFCE3_MASK, 0, 1); -DEFINE_2_MUXREG(pin62, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFAD25_MASK, 0, 1); -DEFINE_2_MUXREG(pin63, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFAD24_MASK, 0, 1); -DEFINE_2_MUXREG(pin_grp0, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_GMIICLK_MASK, 0, 1); -DEFINE_2_MUXREG(pin_grp1, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK, 0, 1); -DEFINE_2_MUXREG(pin_grp2, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_RXCLK_RDV_TXEN_D03_MASK, 0, 1); -DEFINE_2_MUXREG(pin_grp3, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_GMIID47_MASK, 0, 1); -DEFINE_2_MUXREG(pin_grp4, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_MDC_MDIO_MASK, 0, 1); -DEFINE_2_MUXREG(pin_grp5, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFAD23_MASK, 0, 1); -DEFINE_2_MUXREG(pin_grp6, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_MCI_DATA8_15_MASK, 0, 1); -DEFINE_2_MUXREG(pin_grp7, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NFCE2_MASK, 0, 1); -DEFINE_2_MUXREG(pin_grp8, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NAND8_MASK, 0, 1); -DEFINE_2_MUXREG(nand_16bit_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NAND16BIT_1_MASK, 0, 1); -DEFINE_2_MUXREG(pin205, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_COL1_MASK | PMX_NFCE1_MASK, 0, 1); -DEFINE_2_MUXREG(pin206, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_COL0_MASK | PMX_NFCE2_MASK, 0, 1); -DEFINE_2_MUXREG(pin211, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_ROW1_MASK | PMX_NFWPRT1_MASK, 0, 1); -DEFINE_2_MUXREG(pin212, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_ROW0_MASK | PMX_NFWPRT2_MASK, 0, 1); -DEFINE_2_MUXREG(pin213, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA0_MASK, 0, 1); -DEFINE_2_MUXREG(pin214, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA1_MASK, 0, 1); -DEFINE_2_MUXREG(pin215, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA2_MASK, 0, 1); -DEFINE_2_MUXREG(pin216, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA3_MASK, 0, 1); -DEFINE_2_MUXREG(pin217, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA4_MASK, 0, 1); -DEFINE_2_MUXREG(pin218, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA5_MASK, 0, 1); -DEFINE_2_MUXREG(pin219, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA6_MASK, 0, 1); -DEFINE_2_MUXREG(pin220, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA7_MASK, 0, 1); -DEFINE_2_MUXREG(pin221, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA1SD_MASK, 0, 1); -DEFINE_2_MUXREG(pin222, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA2SD_MASK, 0, 1); -DEFINE_2_MUXREG(pin223, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA3SD_MASK, 0, 1); -DEFINE_2_MUXREG(pin224, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIADDR0ALE_MASK, 0, 1); -DEFINE_2_MUXREG(pin225, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIADDR1CLECLK_MASK, 0, 1); -DEFINE_2_MUXREG(pin226, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIADDR2_MASK, 0, 1); -DEFINE_2_MUXREG(pin227, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICECF_MASK, 0, 1); -DEFINE_2_MUXREG(pin228, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICEXD_MASK, 0, 1); -DEFINE_2_MUXREG(pin229, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICESDMMC_MASK, 0, 1); -DEFINE_2_MUXREG(pin230, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDCF1_MASK, 0, 1); -DEFINE_2_MUXREG(pin231, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDCF2_MASK, 0, 1); -DEFINE_2_MUXREG(pin232, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDXD_MASK, 0, 1); -DEFINE_2_MUXREG(pin233, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDSDMMC_MASK, 0, 1); -DEFINE_2_MUXREG(pin234, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATADIR_MASK, 0, 1); -DEFINE_2_MUXREG(pin235, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDMARQWP_MASK, 0, 1); -DEFINE_2_MUXREG(pin236, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIIORDRE_MASK, 0, 1); -DEFINE_2_MUXREG(pin237, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIIOWRWE_MASK, 0, 1); -DEFINE_2_MUXREG(pin238, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIRESETCF_MASK, 0, 1); -DEFINE_2_MUXREG(pin239, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICS0CE_MASK, 0, 1); -DEFINE_2_MUXREG(pin240, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICFINTR_MASK, 0, 1); -DEFINE_2_MUXREG(pin241, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIIORDY_MASK, 0, 1); -DEFINE_2_MUXREG(pin242, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICS1_MASK, 0, 1); -DEFINE_2_MUXREG(pin243, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDMAACK_MASK, 0, 1); -DEFINE_2_MUXREG(pin244, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCISDCMD_MASK, 0, 1); -DEFINE_2_MUXREG(pin245, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCILEDS_MASK, 0, 1); -DEFINE_2_MUXREG(keyboard_rowcol6_8_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_ROWCOL68_MASK, 0, 1); -DEFINE_2_MUXREG(uart0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_UART0_MASK, 0, 1); -DEFINE_2_MUXREG(uart0_modem_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_UART0_MODEM_MASK, 0, 1); -DEFINE_2_MUXREG(gpt0_tmr0_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT0_TMR0_MASK, 0, 1); -DEFINE_2_MUXREG(gpt0_tmr1_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT0_TMR1_MASK, 0, 1); -DEFINE_2_MUXREG(gpt1_tmr0_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT1_TMR0_MASK, 0, 1); -DEFINE_2_MUXREG(gpt1_tmr1_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT1_TMR1_MASK, 0, 1); -DEFINE_2_MUXREG(touch_xy_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_TOUCH_XY_MASK, 0, 1); - -static struct spear_gpio_pingroup spear1310_gpio_pingroup[] = { - GPIO_PINGROUP(i2c0_pins), - GPIO_PINGROUP(ssp0_pins), - GPIO_PINGROUP(ssp0_cs0_pins), - GPIO_PINGROUP(ssp0_cs1_2_pins), - GPIO_PINGROUP(i2s0_pins), - GPIO_PINGROUP(i2s1_pins), - GPIO_PINGROUP(clcd_pins), - GPIO_PINGROUP(clcd_high_res_pins), - GPIO_PINGROUP(pin18), - GPIO_PINGROUP(pin19), - GPIO_PINGROUP(pin20), - GPIO_PINGROUP(pin21), - GPIO_PINGROUP(pin22), - GPIO_PINGROUP(pin23), - GPIO_PINGROUP(pin143), - GPIO_PINGROUP(pin144), - GPIO_PINGROUP(pin145), - GPIO_PINGROUP(pin146), - GPIO_PINGROUP(pin147), - GPIO_PINGROUP(pin148), - GPIO_PINGROUP(pin149), - GPIO_PINGROUP(pin150), - GPIO_PINGROUP(pin151), - GPIO_PINGROUP(pin152), - GPIO_PINGROUP(smi_2_chips_pins), - GPIO_PINGROUP(pin54), - GPIO_PINGROUP(pin55), - GPIO_PINGROUP(pin56), - GPIO_PINGROUP(pin57), - GPIO_PINGROUP(pin58), - GPIO_PINGROUP(pin59), - GPIO_PINGROUP(pin60), - GPIO_PINGROUP(pin61), - GPIO_PINGROUP(pin62), - GPIO_PINGROUP(pin63), - GPIO_PINGROUP(pin_grp0), - GPIO_PINGROUP(pin_grp1), - GPIO_PINGROUP(pin_grp2), - GPIO_PINGROUP(pin_grp3), - GPIO_PINGROUP(pin_grp4), - GPIO_PINGROUP(pin_grp5), - GPIO_PINGROUP(pin_grp6), - GPIO_PINGROUP(pin_grp7), - GPIO_PINGROUP(pin_grp8), - GPIO_PINGROUP(nand_16bit_pins), - GPIO_PINGROUP(pin205), - GPIO_PINGROUP(pin206), - GPIO_PINGROUP(pin211), - GPIO_PINGROUP(pin212), - GPIO_PINGROUP(pin213), - GPIO_PINGROUP(pin214), - GPIO_PINGROUP(pin215), - GPIO_PINGROUP(pin216), - GPIO_PINGROUP(pin217), - GPIO_PINGROUP(pin218), - GPIO_PINGROUP(pin219), - GPIO_PINGROUP(pin220), - GPIO_PINGROUP(pin221), - GPIO_PINGROUP(pin222), - GPIO_PINGROUP(pin223), - GPIO_PINGROUP(pin224), - GPIO_PINGROUP(pin225), - GPIO_PINGROUP(pin226), - GPIO_PINGROUP(pin227), - GPIO_PINGROUP(pin228), - GPIO_PINGROUP(pin229), - GPIO_PINGROUP(pin230), - GPIO_PINGROUP(pin231), - GPIO_PINGROUP(pin232), - GPIO_PINGROUP(pin233), - GPIO_PINGROUP(pin234), - GPIO_PINGROUP(pin235), - GPIO_PINGROUP(pin236), - GPIO_PINGROUP(pin237), - GPIO_PINGROUP(pin238), - GPIO_PINGROUP(pin239), - GPIO_PINGROUP(pin240), - GPIO_PINGROUP(pin241), - GPIO_PINGROUP(pin242), - GPIO_PINGROUP(pin243), - GPIO_PINGROUP(pin244), - GPIO_PINGROUP(pin245), - GPIO_PINGROUP(keyboard_rowcol6_8_pins), - GPIO_PINGROUP(uart0_pins), - GPIO_PINGROUP(uart0_modem_pins), - GPIO_PINGROUP(gpt0_tmr0_pins), - GPIO_PINGROUP(gpt0_tmr1_pins), - GPIO_PINGROUP(gpt1_tmr0_pins), - GPIO_PINGROUP(gpt1_tmr1_pins), - GPIO_PINGROUP(touch_xy_pins), -}; - static struct spear_pinctrl_machdata spear1310_machdata = { .pins = spear1310_pins, .npins = ARRAY_SIZE(spear1310_pins), @@ -2687,8 +2150,6 @@ static struct spear_pinctrl_machdata spear1310_machdata = { .ngroups = ARRAY_SIZE(spear1310_pingroups), .functions = spear1310_functions, .nfunctions = ARRAY_SIZE(spear1310_functions), - .gpio_pingroups = spear1310_gpio_pingroup, - .ngpio_pingroups = ARRAY_SIZE(spear1310_gpio_pingroup), .modes_supported = false, }; diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear1340.c b/trunk/drivers/pinctrl/spear/pinctrl-spear1340.c index 0b4af0e5cdc1..a0eb057e55bd 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear1340.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear1340.c @@ -213,7 +213,7 @@ static const struct pinctrl_pin_desc spear1340_pins[] = { * Pad multiplexing for making all pads as gpio's. This is done to override the * values passed from bootloader and start from scratch. */ -static const unsigned pads_as_gpio_pins[] = { 12, 88, 89, 251 }; +static const unsigned pads_as_gpio_pins[] = { 251 }; static struct spear_muxreg pads_as_gpio_muxreg[] = { { .reg = PAD_FUNCTION_EN_1, @@ -1692,43 +1692,7 @@ static struct spear_pingroup clcd_pingroup = { .nmodemuxs = ARRAY_SIZE(clcd_modemux), }; -/* Disable cld runtime to save panel damage */ -static struct spear_muxreg clcd_sleep_muxreg[] = { - { - .reg = PAD_SHARED_IP_EN_1, - .mask = ARM_TRACE_MASK | MIPHY_DBG_MASK, - .val = 0, - }, { - .reg = PAD_FUNCTION_EN_5, - .mask = CLCD_REG4_MASK | CLCD_AND_ARM_TRACE_REG4_MASK, - .val = 0x0, - }, { - .reg = PAD_FUNCTION_EN_6, - .mask = CLCD_AND_ARM_TRACE_REG5_MASK, - .val = 0x0, - }, { - .reg = PAD_FUNCTION_EN_7, - .mask = CLCD_AND_ARM_TRACE_REG6_MASK, - .val = 0x0, - }, -}; - -static struct spear_modemux clcd_sleep_modemux[] = { - { - .muxregs = clcd_sleep_muxreg, - .nmuxregs = ARRAY_SIZE(clcd_sleep_muxreg), - }, -}; - -static struct spear_pingroup clcd_sleep_pingroup = { - .name = "clcd_sleep_grp", - .pins = clcd_pins, - .npins = ARRAY_SIZE(clcd_pins), - .modemuxs = clcd_sleep_modemux, - .nmodemuxs = ARRAY_SIZE(clcd_sleep_modemux), -}; - -static const char *const clcd_grps[] = { "clcd_grp", "clcd_sleep_grp" }; +static const char *const clcd_grps[] = { "clcd_grp" }; static struct spear_function clcd_function = { .name = "clcd", .groups = clcd_grps, @@ -1929,7 +1893,6 @@ static struct spear_pingroup *spear1340_pingroups[] = { &sdhci_pingroup, &cf_pingroup, &xd_pingroup, - &clcd_sleep_pingroup, &clcd_pingroup, &arm_trace_pingroup, &miphy_dbg_pingroup, @@ -1971,32 +1934,6 @@ static struct spear_function *spear1340_functions[] = { &sata_function, }; -static void gpio_request_endisable(struct spear_pmx *pmx, int pin, - bool enable) -{ - unsigned int regoffset, regindex, bitoffset; - unsigned int val; - - /* pin++ as gpio configuration starts from 2nd bit of base register */ - pin++; - - regindex = pin / 32; - bitoffset = pin % 32; - - if (regindex <= 3) - regoffset = PAD_FUNCTION_EN_1 + regindex * sizeof(int *); - else - regoffset = PAD_FUNCTION_EN_5 + (regindex - 4) * sizeof(int *); - - val = pmx_readl(pmx, regoffset); - if (enable) - val &= ~(0x1 << bitoffset); - else - val |= 0x1 << bitoffset; - - pmx_writel(pmx, val, regoffset); -} - static struct spear_pinctrl_machdata spear1340_machdata = { .pins = spear1340_pins, .npins = ARRAY_SIZE(spear1340_pins), @@ -2004,7 +1941,6 @@ static struct spear_pinctrl_machdata spear1340_machdata = { .ngroups = ARRAY_SIZE(spear1340_pingroups), .functions = spear1340_functions, .nfunctions = ARRAY_SIZE(spear1340_functions), - .gpio_request_endisable = gpio_request_endisable, .modes_supported = false, }; diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear300.c b/trunk/drivers/pinctrl/spear/pinctrl-spear300.c index 9a491007f42d..4dfc2849b172 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear300.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear300.c @@ -661,8 +661,6 @@ static int __devinit spear300_pinctrl_probe(struct platform_device *pdev) spear3xx_machdata.ngroups = ARRAY_SIZE(spear300_pingroups); spear3xx_machdata.functions = spear300_functions; spear3xx_machdata.nfunctions = ARRAY_SIZE(spear300_functions); - spear3xx_machdata.gpio_pingroups = NULL; - spear3xx_machdata.ngpio_pingroups = 0; spear3xx_machdata.modes_supported = true; spear3xx_machdata.pmx_modes = spear300_pmx_modes; diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear310.c b/trunk/drivers/pinctrl/spear/pinctrl-spear310.c index 4d5dfe9c760a..96883693fb7e 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear310.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear310.c @@ -388,8 +388,6 @@ static int __devinit spear310_pinctrl_probe(struct platform_device *pdev) spear3xx_machdata.nfunctions = ARRAY_SIZE(spear310_functions); pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG); - pmx_init_gpio_pingroup_addr(spear3xx_machdata.gpio_pingroups, - spear3xx_machdata.ngpio_pingroups, PMX_CONFIG_REG); spear3xx_machdata.modes_supported = false; diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear320.c b/trunk/drivers/pinctrl/spear/pinctrl-spear320.c index c996e26e3b6c..020b1e0bdb3e 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear320.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear320.c @@ -2239,10 +2239,6 @@ static struct spear_muxreg pwm2_pin_34_muxreg[] = { .reg = PMX_CONFIG_REG, .mask = PMX_SSP_CS_MASK, .val = 0, - }, { - .reg = MODE_CONFIG_REG, - .mask = PMX_PWM_MASK, - .val = PMX_PWM_MASK, }, { .reg = IP_SEL_PAD_30_39_REG, .mask = PMX_PL_34_MASK, @@ -2960,9 +2956,9 @@ static struct spear_function mii2_function = { }; /* Pad multiplexing for cadence mii 1_2 as smii or rmii device */ -static const unsigned rmii0_1_pins[] = { 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, +static const unsigned smii0_1_pins[] = { 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 }; -static const unsigned smii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 }; +static const unsigned rmii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 }; static struct spear_muxreg mii0_1_muxreg[] = { { .reg = PMX_CONFIG_REG, @@ -3431,8 +3427,6 @@ static int __devinit spear320_pinctrl_probe(struct platform_device *pdev) spear3xx_machdata.npmx_modes = ARRAY_SIZE(spear320_pmx_modes); pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG); - pmx_init_gpio_pingroup_addr(spear3xx_machdata.gpio_pingroups, - spear3xx_machdata.ngpio_pingroups, PMX_CONFIG_REG); ret = spear_pinctrl_probe(pdev, &spear3xx_machdata); if (ret) diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.c b/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.c index 12ee21af766b..0242378f7cb8 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.c @@ -481,44 +481,7 @@ struct spear_function spear3xx_timer_2_3_function = { .ngroups = ARRAY_SIZE(timer_2_3_grps), }; -/* Define muxreg arrays */ -DEFINE_MUXREG(firda_pins, 0, PMX_FIRDA_MASK, 0); -DEFINE_MUXREG(i2c_pins, 0, PMX_I2C_MASK, 0); -DEFINE_MUXREG(ssp_cs_pins, 0, PMX_SSP_CS_MASK, 0); -DEFINE_MUXREG(ssp_pins, 0, PMX_SSP_MASK, 0); -DEFINE_MUXREG(mii_pins, 0, PMX_MII_MASK, 0); -DEFINE_MUXREG(gpio0_pin0_pins, 0, PMX_GPIO_PIN0_MASK, 0); -DEFINE_MUXREG(gpio0_pin1_pins, 0, PMX_GPIO_PIN1_MASK, 0); -DEFINE_MUXREG(gpio0_pin2_pins, 0, PMX_GPIO_PIN2_MASK, 0); -DEFINE_MUXREG(gpio0_pin3_pins, 0, PMX_GPIO_PIN3_MASK, 0); -DEFINE_MUXREG(gpio0_pin4_pins, 0, PMX_GPIO_PIN4_MASK, 0); -DEFINE_MUXREG(gpio0_pin5_pins, 0, PMX_GPIO_PIN5_MASK, 0); -DEFINE_MUXREG(uart0_ext_pins, 0, PMX_UART0_MODEM_MASK, 0); -DEFINE_MUXREG(uart0_pins, 0, PMX_UART0_MASK, 0); -DEFINE_MUXREG(timer_0_1_pins, 0, PMX_TIMER_0_1_MASK, 0); -DEFINE_MUXREG(timer_2_3_pins, 0, PMX_TIMER_2_3_MASK, 0); - -static struct spear_gpio_pingroup spear3xx_gpio_pingroup[] = { - GPIO_PINGROUP(firda_pins), - GPIO_PINGROUP(i2c_pins), - GPIO_PINGROUP(ssp_cs_pins), - GPIO_PINGROUP(ssp_pins), - GPIO_PINGROUP(mii_pins), - GPIO_PINGROUP(gpio0_pin0_pins), - GPIO_PINGROUP(gpio0_pin1_pins), - GPIO_PINGROUP(gpio0_pin2_pins), - GPIO_PINGROUP(gpio0_pin3_pins), - GPIO_PINGROUP(gpio0_pin4_pins), - GPIO_PINGROUP(gpio0_pin5_pins), - GPIO_PINGROUP(uart0_ext_pins), - GPIO_PINGROUP(uart0_pins), - GPIO_PINGROUP(timer_0_1_pins), - GPIO_PINGROUP(timer_2_3_pins), -}; - struct spear_pinctrl_machdata spear3xx_machdata = { .pins = spear3xx_pins, .npins = ARRAY_SIZE(spear3xx_pins), - .gpio_pingroups = spear3xx_gpio_pingroup, - .ngpio_pingroups = ARRAY_SIZE(spear3xx_gpio_pingroup), }; diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.h b/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.h index 7860b36053c4..31f44347f17c 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.h +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.h @@ -15,7 +15,6 @@ #include "pinctrl-spear.h" /* pad mux declarations */ -#define PMX_PWM_MASK (1 << 16) #define PMX_FIRDA_MASK (1 << 14) #define PMX_I2C_MASK (1 << 13) #define PMX_SSP_CS_MASK (1 << 12) diff --git a/trunk/drivers/rapidio/rio.c b/trunk/drivers/rapidio/rio.c index 0c6fcb461faf..c17ae22567e0 100644 --- a/trunk/drivers/rapidio/rio.c +++ b/trunk/drivers/rapidio/rio.c @@ -401,7 +401,7 @@ EXPORT_SYMBOL_GPL(rio_release_inb_pwrite); /** * rio_map_inb_region -- Map inbound memory region. * @mport: Master port. - * @local: physical address of memory region to be mapped + * @lstart: physical address of memory region to be mapped * @rbase: RIO base address assigned to this window * @size: Size of the memory region * @rflags: Flags for mapping. diff --git a/trunk/drivers/regulator/core.c b/trunk/drivers/regulator/core.c index e872c8be080e..5c4829cba6a6 100644 --- a/trunk/drivers/regulator/core.c +++ b/trunk/drivers/regulator/core.c @@ -1381,14 +1381,22 @@ struct regulator *regulator_get_exclusive(struct device *dev, const char *id) } EXPORT_SYMBOL_GPL(regulator_get_exclusive); -/* Locks held by regulator_put() */ -static void _regulator_put(struct regulator *regulator) +/** + * regulator_put - "free" the regulator source + * @regulator: regulator source + * + * Note: drivers must ensure that all regulator_enable calls made on this + * regulator source are balanced by regulator_disable calls prior to calling + * this function. + */ +void regulator_put(struct regulator *regulator) { struct regulator_dev *rdev; if (regulator == NULL || IS_ERR(regulator)) return; + mutex_lock(®ulator_list_mutex); rdev = regulator->rdev; debugfs_remove_recursive(regulator->debugfs); @@ -1404,20 +1412,6 @@ static void _regulator_put(struct regulator *regulator) rdev->exclusive = 0; module_put(rdev->owner); -} - -/** - * regulator_put - "free" the regulator source - * @regulator: regulator source - * - * Note: drivers must ensure that all regulator_enable calls made on this - * regulator source are balanced by regulator_disable calls prior to calling - * this function. - */ -void regulator_put(struct regulator *regulator) -{ - mutex_lock(®ulator_list_mutex); - _regulator_put(regulator); mutex_unlock(®ulator_list_mutex); } EXPORT_SYMBOL_GPL(regulator_put); @@ -1980,7 +1974,7 @@ int regulator_is_supported_voltage(struct regulator *regulator, if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { ret = regulator_get_voltage(regulator); if (ret >= 0) - return (min_uV <= ret && ret <= max_uV); + return (min_uV >= ret && ret <= max_uV); else return ret; } @@ -3371,7 +3365,7 @@ regulator_register(const struct regulator_desc *regulator_desc, if (ret != 0) { rdev_err(rdev, "Failed to request enable GPIO%d: %d\n", config->ena_gpio, ret); - goto wash; + goto clean; } rdev->ena_gpio = config->ena_gpio; @@ -3451,11 +3445,10 @@ regulator_register(const struct regulator_desc *regulator_desc, scrub: if (rdev->supply) - _regulator_put(rdev->supply); + regulator_put(rdev->supply); if (rdev->ena_gpio) gpio_free(rdev->ena_gpio); kfree(rdev->constraints); -wash: device_unregister(&rdev->dev); /* device core frees rdev */ rdev = ERR_PTR(ret); diff --git a/trunk/drivers/remoteproc/remoteproc_virtio.c b/trunk/drivers/remoteproc/remoteproc_virtio.c index 9e198e590675..e7a4780e93db 100644 --- a/trunk/drivers/remoteproc/remoteproc_virtio.c +++ b/trunk/drivers/remoteproc/remoteproc_virtio.c @@ -120,11 +120,15 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev, return vq; } -static void __rproc_virtio_del_vqs(struct virtio_device *vdev) +static void rproc_virtio_del_vqs(struct virtio_device *vdev) { struct virtqueue *vq, *n; + struct rproc *rproc = vdev_to_rproc(vdev); struct rproc_vring *rvring; + /* power down the remote processor before deleting vqs */ + rproc_shutdown(rproc); + list_for_each_entry_safe(vq, n, &vdev->vqs, list) { rvring = vq->priv; rvring->vq = NULL; @@ -133,16 +137,6 @@ static void __rproc_virtio_del_vqs(struct virtio_device *vdev) } } -static void rproc_virtio_del_vqs(struct virtio_device *vdev) -{ - struct rproc *rproc = vdev_to_rproc(vdev); - - /* power down the remote processor before deleting vqs */ - rproc_shutdown(rproc); - - __rproc_virtio_del_vqs(vdev); -} - static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs, struct virtqueue *vqs[], vq_callback_t *callbacks[], @@ -169,7 +163,7 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs, return 0; error: - __rproc_virtio_del_vqs(vdev); + rproc_virtio_del_vqs(vdev); return ret; } diff --git a/trunk/drivers/rtc/rtc-imxdi.c b/trunk/drivers/rtc/rtc-imxdi.c index 4eed51044c5d..891cd6c61d0a 100644 --- a/trunk/drivers/rtc/rtc-imxdi.c +++ b/trunk/drivers/rtc/rtc-imxdi.c @@ -392,8 +392,6 @@ static int dryice_rtc_probe(struct platform_device *pdev) if (imxdi->ioaddr == NULL) return -ENOMEM; - spin_lock_init(&imxdi->irq_lock); - imxdi->irq = platform_get_irq(pdev, 0); if (imxdi->irq < 0) return imxdi->irq; diff --git a/trunk/drivers/rtc/rtc-tps65910.c b/trunk/drivers/rtc/rtc-tps65910.c index 073108dcf9e7..7a82337e4dee 100644 --- a/trunk/drivers/rtc/rtc-tps65910.c +++ b/trunk/drivers/rtc/rtc-tps65910.c @@ -288,11 +288,11 @@ static int __devinit tps65910_rtc_probe(struct platform_device *pdev) static int __devexit tps65910_rtc_remove(struct platform_device *pdev) { /* leave rtc running, but disable irqs */ - struct tps65910_rtc *tps_rtc = platform_get_drvdata(pdev); + struct rtc_device *rtc = platform_get_drvdata(pdev); - tps65910_rtc_alarm_irq_enable(&pdev->dev, 0); + tps65910_rtc_alarm_irq_enable(&rtc->dev, 0); - rtc_device_unregister(tps_rtc->rtc); + rtc_device_unregister(rtc); return 0; } diff --git a/trunk/drivers/s390/char/con3215.c b/trunk/drivers/s390/char/con3215.c index 4ed343e4eb41..9ffb6d5f17aa 100644 --- a/trunk/drivers/s390/char/con3215.c +++ b/trunk/drivers/s390/char/con3215.c @@ -44,6 +44,7 @@ #define RAW3215_NR_CCWS 3 #define RAW3215_TIMEOUT HZ/10 /* time for delayed output */ +#define RAW3215_FIXED 1 /* 3215 console device is not be freed */ #define RAW3215_WORKING 4 /* set if a request is being worked on */ #define RAW3215_THROTTLED 8 /* set if reading is disabled */ #define RAW3215_STOPPED 16 /* set if writing is disabled */ @@ -338,10 +339,8 @@ static void raw3215_wakeup(unsigned long data) struct tty_struct *tty; tty = tty_port_tty_get(&raw->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } + tty_wakeup(tty); + tty_kref_put(tty); } /* @@ -630,7 +629,8 @@ static void raw3215_shutdown(struct raw3215_info *raw) DECLARE_WAITQUEUE(wait, current); unsigned long flags; - if (!(raw->port.flags & ASYNC_INITIALIZED)) + if (!(raw->port.flags & ASYNC_INITIALIZED) || + (raw->flags & RAW3215_FIXED)) return; /* Wait for outstanding requests, then free irq */ spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); @@ -926,6 +926,8 @@ static int __init con3215_init(void) dev_set_drvdata(&cdev->dev, raw); cdev->handler = raw3215_irq; + raw->flags |= RAW3215_FIXED; + /* Request the console irq */ if (raw3215_startup(raw) != 0) { raw3215_free_info(raw); diff --git a/trunk/drivers/s390/cio/css.c b/trunk/drivers/s390/cio/css.c index fd00afd8b850..b4d572f65f07 100644 --- a/trunk/drivers/s390/cio/css.c +++ b/trunk/drivers/s390/cio/css.c @@ -377,11 +377,7 @@ static int css_evaluate_new_subchannel(struct subchannel_id schid, int slow) /* Will be done on the slow path. */ return -EAGAIN; } - if (stsch_err(schid, &schib)) { - /* Subchannel is not provided. */ - return -ENXIO; - } - if (!css_sch_is_valid(&schib)) { + if (stsch_err(schid, &schib) || !css_sch_is_valid(&schib)) { /* Unusable - ignore. */ return 0; } @@ -540,7 +536,6 @@ static int slow_eval_unknown_fn(struct subchannel_id schid, void *data) case -ENOMEM: case -EIO: /* These should abort looping */ - idset_sch_del_subseq(slow_subchannel_set, schid); break; default: rc = 0; diff --git a/trunk/drivers/s390/cio/css.h b/trunk/drivers/s390/cio/css.h index 4af3dfe70ef5..33bb4d891e16 100644 --- a/trunk/drivers/s390/cio/css.h +++ b/trunk/drivers/s390/cio/css.h @@ -112,6 +112,9 @@ extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *); extern void css_reiterate_subchannels(void); void css_update_ssd_info(struct subchannel *sch); +#define __MAX_SUBCHANNEL 65535 +#define __MAX_SSID 3 + struct channel_subsystem { u8 cssid; int valid; diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index fd3143c291c6..fc916f5d7314 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -1424,7 +1424,7 @@ static enum io_sch_action sch_get_action(struct subchannel *sch) } if (device_is_disconnected(cdev)) return IO_SCH_REPROBE; - if (cdev->online && !cdev->private->flags.resuming) + if (cdev->online) return IO_SCH_VERIFY; if (cdev->private->state == DEV_STATE_NOT_OPER) return IO_SCH_UNREG_ATTACH; @@ -1469,6 +1469,12 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process) rc = 0; goto out_unlock; case IO_SCH_VERIFY: + if (cdev->private->flags.resuming == 1) { + if (cio_enable_subchannel(sch, (u32)(addr_t)sch)) { + ccw_device_set_notoper(cdev); + break; + } + } /* Trigger path verification. */ io_subchannel_verify(sch); rc = 0; diff --git a/trunk/drivers/s390/cio/idset.c b/trunk/drivers/s390/cio/idset.c index 65d13e38803f..e6d5f8c49524 100644 --- a/trunk/drivers/s390/cio/idset.c +++ b/trunk/drivers/s390/cio/idset.c @@ -1,10 +1,9 @@ /* - * Copyright IBM Corp. 2007, 2012 + * Copyright IBM Corp. 2007 * Author(s): Peter Oberparleiter */ #include -#include #include #include "idset.h" #include "css.h" @@ -90,14 +89,6 @@ void idset_sch_del(struct idset *set, struct subchannel_id schid) idset_del(set, schid.ssid, schid.sch_no); } -/* Clear ids starting from @schid up to end of subchannel set. */ -void idset_sch_del_subseq(struct idset *set, struct subchannel_id schid) -{ - int pos = schid.ssid * set->num_id + schid.sch_no; - - bitmap_clear(set->bitmap, pos, set->num_id - schid.sch_no); -} - int idset_sch_contains(struct idset *set, struct subchannel_id schid) { return idset_contains(set, schid.ssid, schid.sch_no); @@ -120,12 +111,20 @@ int idset_sch_get_first(struct idset *set, struct subchannel_id *schid) int idset_is_empty(struct idset *set) { - return bitmap_empty(set->bitmap, set->num_ssid * set->num_id); + int bitnum; + + bitnum = find_first_bit(set->bitmap, set->num_ssid * set->num_id); + if (bitnum >= set->num_ssid * set->num_id) + return 1; + return 0; } void idset_add_set(struct idset *to, struct idset *from) { - int len = min(to->num_ssid * to->num_id, from->num_ssid * from->num_id); + unsigned long i, len; - bitmap_or(to->bitmap, to->bitmap, from->bitmap, len); + len = min(__BITOPS_WORDS(to->num_ssid * to->num_id), + __BITOPS_WORDS(from->num_ssid * from->num_id)); + for (i = 0; i < len ; i++) + to->bitmap[i] |= from->bitmap[i]; } diff --git a/trunk/drivers/s390/cio/idset.h b/trunk/drivers/s390/cio/idset.h index 06d3bc01bb09..3d943f03591e 100644 --- a/trunk/drivers/s390/cio/idset.h +++ b/trunk/drivers/s390/cio/idset.h @@ -1,5 +1,5 @@ /* - * Copyright IBM Corp. 2007, 2012 + * Copyright IBM Corp. 2007 * Author(s): Peter Oberparleiter */ @@ -17,7 +17,6 @@ void idset_fill(struct idset *set); struct idset *idset_sch_new(void); void idset_sch_add(struct idset *set, struct subchannel_id id); void idset_sch_del(struct idset *set, struct subchannel_id id); -void idset_sch_del_subseq(struct idset *set, struct subchannel_id schid); int idset_sch_contains(struct idset *set, struct subchannel_id id); int idset_sch_get_first(struct idset *set, struct subchannel_id *id); int idset_is_empty(struct idset *set); diff --git a/trunk/drivers/s390/net/qeth_core_main.c b/trunk/drivers/s390/net/qeth_core_main.c index 4d6ba00d0047..3e25d3150456 100644 --- a/trunk/drivers/s390/net/qeth_core_main.c +++ b/trunk/drivers/s390/net/qeth_core_main.c @@ -2942,33 +2942,13 @@ static int qeth_query_ipassists_cb(struct qeth_card *card, QETH_DBF_TEXT(SETUP, 2, "qipasscb"); cmd = (struct qeth_ipa_cmd *) data; - - switch (cmd->hdr.return_code) { - case IPA_RC_NOTSUPP: - case IPA_RC_L2_UNSUPPORTED_CMD: - QETH_DBF_TEXT(SETUP, 2, "ipaunsup"); - card->options.ipa4.supported_funcs |= IPA_SETADAPTERPARMS; - card->options.ipa6.supported_funcs |= IPA_SETADAPTERPARMS; - return -0; - default: - if (cmd->hdr.return_code) { - QETH_DBF_MESSAGE(1, "%s IPA_CMD_QIPASSIST: Unhandled " - "rc=%d\n", - dev_name(&card->gdev->dev), - cmd->hdr.return_code); - return 0; - } - } - if (cmd->hdr.prot_version == QETH_PROT_IPV4) { card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported; card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled; - } else if (cmd->hdr.prot_version == QETH_PROT_IPV6) { + } else { card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported; card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled; - } else - QETH_DBF_MESSAGE(1, "%s IPA_CMD_QIPASSIST: Flawed LIC detected" - "\n", dev_name(&card->gdev->dev)); + } QETH_DBF_TEXT(SETUP, 2, "suppenbl"); QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_supported); QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_enabled); diff --git a/trunk/drivers/s390/net/qeth_l2_main.c b/trunk/drivers/s390/net/qeth_l2_main.c index fddb62654b6a..e67e0258aec5 100644 --- a/trunk/drivers/s390/net/qeth_l2_main.c +++ b/trunk/drivers/s390/net/qeth_l2_main.c @@ -626,13 +626,10 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card) QETH_DBF_TEXT(SETUP, 2, "doL2init"); QETH_DBF_TEXT_(SETUP, 2, "doL2%s", CARD_BUS_ID(card)); - if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) { - rc = qeth_query_setadapterparms(card); - if (rc) { - QETH_DBF_MESSAGE(2, "could not query adapter " - "parameters on device %s: x%x\n", - CARD_BUS_ID(card), rc); - } + rc = qeth_query_setadapterparms(card); + if (rc) { + QETH_DBF_MESSAGE(2, "could not query adapter parameters on " + "device %s: x%x\n", CARD_BUS_ID(card), rc); } if (card->info.type == QETH_CARD_TYPE_IQD || @@ -679,7 +676,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) return -ERESTARTSYS; } rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]); - if (!rc || (rc == IPA_RC_L2_MAC_NOT_FOUND)) + if (!rc) rc = qeth_l2_send_setmac(card, addr->sa_data); return rc ? -EINVAL : 0; } diff --git a/trunk/drivers/scsi/isci/request.c b/trunk/drivers/scsi/isci/request.c index 9594ab62702b..c1bafc3f3fb1 100644 --- a/trunk/drivers/scsi/isci/request.c +++ b/trunk/drivers/scsi/isci/request.c @@ -1972,7 +1972,7 @@ sci_io_request_frame_handler(struct isci_request *ireq, frame_index, (void **)&frame_buffer); - sci_controller_copy_sata_response(&ireq->stp.rsp, + sci_controller_copy_sata_response(&ireq->stp.req, frame_header, frame_buffer); diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas.h b/trunk/drivers/scsi/megaraid/megaraid_sas.h index 3b2365c8eab2..16b7a72a70c4 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas.h +++ b/trunk/drivers/scsi/megaraid/megaraid_sas.h @@ -1276,7 +1276,7 @@ struct megasas_evt_detail { } __attribute__ ((packed)); struct megasas_aen_event { - struct delayed_work hotplug_work; + struct work_struct hotplug_work; struct megasas_instance *instance; }; diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas_base.c b/trunk/drivers/scsi/megaraid/megaraid_sas_base.c index e4f2baacf1e1..d2c5366aff7f 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/trunk/drivers/scsi/megaraid/megaraid_sas_base.c @@ -2060,9 +2060,9 @@ megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd) } else { ev->instance = instance; instance->ev = ev; - INIT_DELAYED_WORK(&ev->hotplug_work, - megasas_aen_polling); - schedule_delayed_work(&ev->hotplug_work, 0); + INIT_WORK(&ev->hotplug_work, megasas_aen_polling); + schedule_delayed_work( + (struct delayed_work *)&ev->hotplug_work, 0); } } } @@ -4352,7 +4352,8 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state) /* cancel the delayed work if this work still in queue */ if (instance->ev != NULL) { struct megasas_aen_event *ev = instance->ev; - cancel_delayed_work_sync(&ev->hotplug_work); + cancel_delayed_work_sync( + (struct delayed_work *)&ev->hotplug_work); instance->ev = NULL; } @@ -4544,7 +4545,8 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev) /* cancel the delayed work if this work still in queue*/ if (instance->ev != NULL) { struct megasas_aen_event *ev = instance->ev; - cancel_delayed_work_sync(&ev->hotplug_work); + cancel_delayed_work_sync( + (struct delayed_work *)&ev->hotplug_work); instance->ev = NULL; } @@ -5188,7 +5190,7 @@ static void megasas_aen_polling(struct work_struct *work) { struct megasas_aen_event *ev = - container_of(work, struct megasas_aen_event, hotplug_work.work); + container_of(work, struct megasas_aen_event, hotplug_work); struct megasas_instance *instance = ev->instance; union megasas_evt_class_locale class_locale; struct Scsi_Host *host; diff --git a/trunk/drivers/scsi/qla2xxx/qla_mid.c b/trunk/drivers/scsi/qla2xxx/qla_mid.c index 20fd974f903a..bd4708a422cd 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mid.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mid.c @@ -149,7 +149,6 @@ qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha) int qla24xx_disable_vp(scsi_qla_host_t *vha) { - unsigned long flags; int ret; ret = qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL); @@ -157,9 +156,7 @@ qla24xx_disable_vp(scsi_qla_host_t *vha) atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); /* Remove port id from vp target map */ - spin_lock_irqsave(&vha->hw->vport_slock, flags); qlt_update_vp_map(vha, RESET_AL_PA); - spin_unlock_irqrestore(&vha->hw->vport_slock, flags); qla2x00_mark_vp_devices_dead(vha); atomic_set(&vha->vp_state, VP_FAILED); diff --git a/trunk/drivers/scsi/qla2xxx/qla_target.c b/trunk/drivers/scsi/qla2xxx/qla_target.c index 62aa5584f644..0e09d8f433d1 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_target.c +++ b/trunk/drivers/scsi/qla2xxx/qla_target.c @@ -557,7 +557,6 @@ static bool qlt_check_fcport_exist(struct scsi_qla_host *vha, int pmap_len; fc_port_t *fcport; int global_resets; - unsigned long flags; retry: global_resets = atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count); @@ -626,10 +625,10 @@ static bool qlt_check_fcport_exist(struct scsi_qla_host *vha, sess->s_id.b.area, sess->loop_id, fcport->d_id.b.domain, fcport->d_id.b.al_pa, fcport->d_id.b.area, fcport->loop_id); - spin_lock_irqsave(&ha->hardware_lock, flags); - ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, - (fcport->flags & FCF_CONF_COMP_SUPPORTED)); - spin_unlock_irqrestore(&ha->hardware_lock, flags); + sess->s_id = fcport->d_id; + sess->loop_id = fcport->loop_id; + sess->conf_compl_supported = !!(fcport->flags & + FCF_CONF_COMP_SUPPORTED); res = true; @@ -741,9 +740,10 @@ static struct qla_tgt_sess *qlt_create_sess( qlt_undelete_sess(sess); kref_get(&sess->se_sess->sess_kref); - ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, - (fcport->flags & FCF_CONF_COMP_SUPPORTED)); - + sess->s_id = fcport->d_id; + sess->loop_id = fcport->loop_id; + sess->conf_compl_supported = !!(fcport->flags & + FCF_CONF_COMP_SUPPORTED); if (sess->local && !local) sess->local = 0; spin_unlock_irqrestore(&ha->hardware_lock, flags); @@ -796,7 +796,8 @@ static struct qla_tgt_sess *qlt_create_sess( */ kref_get(&sess->se_sess->sess_kref); - sess->conf_compl_supported = (fcport->flags & FCF_CONF_COMP_SUPPORTED); + sess->conf_compl_supported = !!(fcport->flags & + FCF_CONF_COMP_SUPPORTED); BUILD_BUG_ON(sizeof(sess->port_name) != sizeof(fcport->port_name)); memcpy(sess->port_name, fcport->port_name, sizeof(sess->port_name)); @@ -868,8 +869,10 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport) ql_dbg(ql_dbg_tgt_mgt, vha, 0xf007, "Reappeared sess %p\n", sess); } - ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, - (fcport->flags & FCF_CONF_COMP_SUPPORTED)); + sess->s_id = fcport->d_id; + sess->loop_id = fcport->loop_id; + sess->conf_compl_supported = !!(fcport->flags & + FCF_CONF_COMP_SUPPORTED); } if (sess && sess->local) { diff --git a/trunk/drivers/scsi/qla2xxx/qla_target.h b/trunk/drivers/scsi/qla2xxx/qla_target.h index bad749561ec2..170af1571214 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_target.h +++ b/trunk/drivers/scsi/qla2xxx/qla_target.h @@ -648,7 +648,6 @@ struct qla_tgt_func_tmpl { int (*check_initiator_node_acl)(struct scsi_qla_host *, unsigned char *, void *, uint8_t *, uint16_t); - void (*update_sess)(struct qla_tgt_sess *, port_id_t, uint16_t, bool); struct qla_tgt_sess *(*find_sess_by_loop_id)(struct scsi_qla_host *, const uint16_t); struct qla_tgt_sess *(*find_sess_by_s_id)(struct scsi_qla_host *, diff --git a/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 3d74f2f39ae1..2358c16c4c8e 100644 --- a/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -237,7 +237,7 @@ static char *tcm_qla2xxx_get_fabric_wwn(struct se_portal_group *se_tpg) struct tcm_qla2xxx_tpg, se_tpg); struct tcm_qla2xxx_lport *lport = tpg->lport; - return lport->lport_naa_name; + return &lport->lport_name[0]; } static char *tcm_qla2xxx_npiv_get_fabric_wwn(struct se_portal_group *se_tpg) @@ -1457,78 +1457,6 @@ static int tcm_qla2xxx_check_initiator_node_acl( return 0; } -static void tcm_qla2xxx_update_sess(struct qla_tgt_sess *sess, port_id_t s_id, - uint16_t loop_id, bool conf_compl_supported) -{ - struct qla_tgt *tgt = sess->tgt; - struct qla_hw_data *ha = tgt->ha; - struct tcm_qla2xxx_lport *lport = ha->tgt.target_lport_ptr; - struct se_node_acl *se_nacl = sess->se_sess->se_node_acl; - struct tcm_qla2xxx_nacl *nacl = container_of(se_nacl, - struct tcm_qla2xxx_nacl, se_node_acl); - u32 key; - - - if (sess->loop_id != loop_id || sess->s_id.b24 != s_id.b24) - pr_info("Updating session %p from port %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x loop_id %d -> %d s_id %x:%x:%x -> %x:%x:%x\n", - sess, - sess->port_name[0], sess->port_name[1], - sess->port_name[2], sess->port_name[3], - sess->port_name[4], sess->port_name[5], - sess->port_name[6], sess->port_name[7], - sess->loop_id, loop_id, - sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa, - s_id.b.domain, s_id.b.area, s_id.b.al_pa); - - if (sess->loop_id != loop_id) { - /* - * Because we can shuffle loop IDs around and we - * update different sessions non-atomically, we might - * have overwritten this session's old loop ID - * already, and we might end up overwriting some other - * session that will be updated later. So we have to - * be extra careful and we can't warn about those things... - */ - if (lport->lport_loopid_map[sess->loop_id].se_nacl == se_nacl) - lport->lport_loopid_map[sess->loop_id].se_nacl = NULL; - - lport->lport_loopid_map[loop_id].se_nacl = se_nacl; - - sess->loop_id = loop_id; - } - - if (sess->s_id.b24 != s_id.b24) { - key = (((u32) sess->s_id.b.domain << 16) | - ((u32) sess->s_id.b.area << 8) | - ((u32) sess->s_id.b.al_pa)); - - if (btree_lookup32(&lport->lport_fcport_map, key)) - WARN(btree_remove32(&lport->lport_fcport_map, key) != se_nacl, - "Found wrong se_nacl when updating s_id %x:%x:%x\n", - sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa); - else - WARN(1, "No lport_fcport_map entry for s_id %x:%x:%x\n", - sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa); - - key = (((u32) s_id.b.domain << 16) | - ((u32) s_id.b.area << 8) | - ((u32) s_id.b.al_pa)); - - if (btree_lookup32(&lport->lport_fcport_map, key)) { - WARN(1, "Already have lport_fcport_map entry for s_id %x:%x:%x\n", - s_id.b.domain, s_id.b.area, s_id.b.al_pa); - btree_update32(&lport->lport_fcport_map, key, se_nacl); - } else { - btree_insert32(&lport->lport_fcport_map, key, se_nacl, GFP_ATOMIC); - } - - sess->s_id = s_id; - nacl->nport_id = key; - } - - sess->conf_compl_supported = conf_compl_supported; -} - /* * Calls into tcm_qla2xxx used by qla2xxx LLD I/O path. */ @@ -1539,7 +1467,6 @@ static struct qla_tgt_func_tmpl tcm_qla2xxx_template = { .free_cmd = tcm_qla2xxx_free_cmd, .free_mcmd = tcm_qla2xxx_free_mcmd, .free_session = tcm_qla2xxx_free_session, - .update_sess = tcm_qla2xxx_update_sess, .check_initiator_node_acl = tcm_qla2xxx_check_initiator_node_acl, .find_sess_by_s_id = tcm_qla2xxx_find_sess_by_s_id, .find_sess_by_loop_id = tcm_qla2xxx_find_sess_by_loop_id, @@ -1607,7 +1534,6 @@ static struct se_wwn *tcm_qla2xxx_make_lport( lport->lport_wwpn = wwpn; tcm_qla2xxx_format_wwn(&lport->lport_name[0], TCM_QLA2XXX_NAMELEN, wwpn); - sprintf(lport->lport_naa_name, "naa.%016llx", (unsigned long long) wwpn); ret = tcm_qla2xxx_init_lport(lport); if (ret != 0) @@ -1675,7 +1601,6 @@ static struct se_wwn *tcm_qla2xxx_npiv_make_lport( lport->lport_npiv_wwnn = npiv_wwnn; tcm_qla2xxx_npiv_format_wwn(&lport->lport_npiv_name[0], TCM_QLA2XXX_NAMELEN, npiv_wwpn, npiv_wwnn); - sprintf(lport->lport_naa_name, "naa.%016llx", (unsigned long long) npiv_wwpn); /* FIXME: tcm_qla2xxx_npiv_make_lport */ ret = -ENOSYS; diff --git a/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.h b/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.h index 9ba075fe9781..825498103352 100644 --- a/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.h +++ b/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.h @@ -61,8 +61,6 @@ struct tcm_qla2xxx_lport { u64 lport_npiv_wwnn; /* ASCII formatted WWPN for FC Target Lport */ char lport_name[TCM_QLA2XXX_NAMELEN]; - /* ASCII formatted naa WWPN for VPD page 83 etc */ - char lport_naa_name[TCM_QLA2XXX_NAMELEN]; /* ASCII formatted WWPN+WWNN for NPIV FC Target Lport */ char lport_npiv_name[TCM_QLA2XXX_NPIV_NAMELEN]; /* map for fc_port pointers in 24-bit FC Port ID space */ diff --git a/trunk/drivers/scsi/qlogicpti.c b/trunk/drivers/scsi/qlogicpti.c index 71fddbc60f18..b191dd549207 100644 --- a/trunk/drivers/scsi/qlogicpti.c +++ b/trunk/drivers/scsi/qlogicpti.c @@ -1294,19 +1294,26 @@ static struct scsi_host_template qpti_template = { static const struct of_device_id qpti_match[]; static int __devinit qpti_sbus_probe(struct platform_device *op) { + const struct of_device_id *match; + struct scsi_host_template *tpnt; struct device_node *dp = op->dev.of_node; struct Scsi_Host *host; struct qlogicpti *qpti; static int nqptis; const char *fcode; + match = of_match_device(qpti_match, &op->dev); + if (!match) + return -EINVAL; + tpnt = match->data; + /* Sometimes Antares cards come up not completely * setup, and we get a report of a zero IRQ. */ if (op->archdata.irqs[0] == 0) return -ENODEV; - host = scsi_host_alloc(&qpti_template, sizeof(struct qlogicpti)); + host = scsi_host_alloc(tpnt, sizeof(struct qlogicpti)); if (!host) return -ENOMEM; @@ -1438,15 +1445,19 @@ static int __devexit qpti_sbus_remove(struct platform_device *op) static const struct of_device_id qpti_match[] = { { .name = "ptisp", + .data = &qpti_template, }, { .name = "PTI,ptisp", + .data = &qpti_template, }, { .name = "QLGC,isp", + .data = &qpti_template, }, { .name = "SUNW,isp", + .data = &qpti_template, }, {}, }; diff --git a/trunk/drivers/scsi/scsi.c b/trunk/drivers/scsi/scsi.c index 2c0d0ec8150b..2936b447cae9 100644 --- a/trunk/drivers/scsi/scsi.c +++ b/trunk/drivers/scsi/scsi.c @@ -55,7 +55,6 @@ #include #include #include -#include #include #include @@ -1062,50 +1061,6 @@ int scsi_get_vpd_page(struct scsi_device *sdev, u8 page, unsigned char *buf, } EXPORT_SYMBOL_GPL(scsi_get_vpd_page); -/** - * scsi_report_opcode - Find out if a given command opcode is supported - * @sdev: scsi device to query - * @buffer: scratch buffer (must be at least 20 bytes long) - * @len: length of buffer - * @opcode: opcode for command to look up - * - * Uses the REPORT SUPPORTED OPERATION CODES to look up the given - * opcode. Returns 0 if RSOC fails or if the command opcode is - * unsupported. Returns 1 if the device claims to support the command. - */ -int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, - unsigned int len, unsigned char opcode) -{ - unsigned char cmd[16]; - struct scsi_sense_hdr sshdr; - int result; - - if (sdev->no_report_opcodes || sdev->scsi_level < SCSI_SPC_3) - return 0; - - memset(cmd, 0, 16); - cmd[0] = MAINTENANCE_IN; - cmd[1] = MI_REPORT_SUPPORTED_OPERATION_CODES; - cmd[2] = 1; /* One command format */ - cmd[3] = opcode; - put_unaligned_be32(len, &cmd[6]); - memset(buffer, 0, len); - - result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len, - &sshdr, 30 * HZ, 3, NULL); - - if (result && scsi_sense_valid(&sshdr) && - sshdr.sense_key == ILLEGAL_REQUEST && - (sshdr.asc == 0x20 || sshdr.asc == 0x24) && sshdr.ascq == 0x00) - return 0; - - if ((buffer[1] & 3) == 3) /* Command supported */ - return 1; - - return 0; -} -EXPORT_SYMBOL(scsi_report_opcode); - /** * scsi_device_get - get an additional reference to a scsi_device * @sdev: device to get a reference to diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index 9032e910bca3..da36a3a81a9e 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -900,23 +900,11 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) action = ACTION_FAIL; error = -EILSEQ; /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ - } else if (sshdr.asc == 0x20 || sshdr.asc == 0x24) { - switch (cmd->cmnd[0]) { - case UNMAP: - description = "Discard failure"; - break; - case WRITE_SAME: - case WRITE_SAME_16: - if (cmd->cmnd[1] & 0x8) - description = "Discard failure"; - else - description = - "Write same failure"; - break; - default: - description = "Invalid command failure"; - break; - } + } else if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) && + (cmd->cmnd[0] == UNMAP || + cmd->cmnd[0] == WRITE_SAME_16 || + cmd->cmnd[0] == WRITE_SAME)) { + description = "Discard failure"; action = ACTION_FAIL; error = -EREMOTEIO; } else diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c index 352bc77b7c88..12f6fdfc1147 100644 --- a/trunk/drivers/scsi/sd.c +++ b/trunk/drivers/scsi/sd.c @@ -99,7 +99,6 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); #endif static void sd_config_discard(struct scsi_disk *, unsigned int); -static void sd_config_write_same(struct scsi_disk *); static int sd_revalidate_disk(struct gendisk *); static void sd_unlock_native_capacity(struct gendisk *disk); static int sd_probe(struct device *); @@ -396,45 +395,6 @@ sd_store_max_medium_access_timeouts(struct device *dev, return err ? err : count; } -static ssize_t -sd_show_write_same_blocks(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct scsi_disk *sdkp = to_scsi_disk(dev); - - return snprintf(buf, 20, "%u\n", sdkp->max_ws_blocks); -} - -static ssize_t -sd_store_write_same_blocks(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct scsi_disk *sdkp = to_scsi_disk(dev); - struct scsi_device *sdp = sdkp->device; - unsigned long max; - int err; - - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - - if (sdp->type != TYPE_DISK) - return -EINVAL; - - err = kstrtoul(buf, 10, &max); - - if (err) - return err; - - if (max == 0) - sdp->no_write_same = 1; - else if (max <= SD_MAX_WS16_BLOCKS) - sdkp->max_ws_blocks = max; - - sd_config_write_same(sdkp); - - return count; -} - static struct device_attribute sd_disk_attrs[] = { __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, sd_store_cache_type), @@ -450,8 +410,6 @@ static struct device_attribute sd_disk_attrs[] = { __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL), __ATTR(provisioning_mode, S_IRUGO|S_IWUSR, sd_show_provisioning_mode, sd_store_provisioning_mode), - __ATTR(max_write_same_blocks, S_IRUGO|S_IWUSR, - sd_show_write_same_blocks, sd_store_write_same_blocks), __ATTR(max_medium_access_timeouts, S_IRUGO|S_IWUSR, sd_show_max_medium_access_timeouts, sd_store_max_medium_access_timeouts), @@ -603,23 +561,19 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) return; case SD_LBP_UNMAP: - max_blocks = min_not_zero(sdkp->max_unmap_blocks, - (u32)SD_MAX_WS16_BLOCKS); + max_blocks = min_not_zero(sdkp->max_unmap_blocks, 0xffffffff); break; case SD_LBP_WS16: - max_blocks = min_not_zero(sdkp->max_ws_blocks, - (u32)SD_MAX_WS16_BLOCKS); + max_blocks = min_not_zero(sdkp->max_ws_blocks, 0xffffffff); break; case SD_LBP_WS10: - max_blocks = min_not_zero(sdkp->max_ws_blocks, - (u32)SD_MAX_WS10_BLOCKS); + max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff); break; case SD_LBP_ZERO: - max_blocks = min_not_zero(sdkp->max_ws_blocks, - (u32)SD_MAX_WS10_BLOCKS); + max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff); q->limits.discard_zeroes_data = 1; break; } @@ -629,26 +583,29 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) } /** - * sd_setup_discard_cmnd - unmap blocks on thinly provisioned device + * scsi_setup_discard_cmnd - unmap blocks on thinly provisioned device * @sdp: scsi device to operate one * @rq: Request to prepare * * Will issue either UNMAP or WRITE SAME(16) depending on preference * indicated by target device. **/ -static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) +static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) { struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); - sector_t sector = blk_rq_pos(rq); - unsigned int nr_sectors = blk_rq_sectors(rq); - unsigned int nr_bytes = blk_rq_bytes(rq); + struct bio *bio = rq->bio; + sector_t sector = bio->bi_sector; + unsigned int nr_sectors = bio_sectors(bio); unsigned int len; int ret; char *buf; struct page *page; - sector >>= ilog2(sdp->sector_size) - 9; - nr_sectors >>= ilog2(sdp->sector_size) - 9; + if (sdkp->device->sector_size == 4096) { + sector >>= 3; + nr_sectors >>= 3; + } + rq->timeout = SD_TIMEOUT; memset(rq->cmd, 0, rq->cmd_len); @@ -703,7 +660,6 @@ static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) blk_add_request_payload(rq, page, len); ret = scsi_setup_blk_pc_cmnd(sdp, rq); rq->buffer = page_address(page); - rq->__data_len = nr_bytes; out: if (ret != BLKPREP_OK) { @@ -713,83 +669,6 @@ static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) return ret; } -static void sd_config_write_same(struct scsi_disk *sdkp) -{ - struct request_queue *q = sdkp->disk->queue; - unsigned int logical_block_size = sdkp->device->sector_size; - unsigned int blocks = 0; - - if (sdkp->device->no_write_same) { - sdkp->max_ws_blocks = 0; - goto out; - } - - /* Some devices can not handle block counts above 0xffff despite - * supporting WRITE SAME(16). Consequently we default to 64k - * blocks per I/O unless the device explicitly advertises a - * bigger limit. - */ - if (sdkp->max_ws_blocks == 0) - sdkp->max_ws_blocks = SD_MAX_WS10_BLOCKS; - - if (sdkp->ws16 || sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS) - blocks = min_not_zero(sdkp->max_ws_blocks, - (u32)SD_MAX_WS16_BLOCKS); - else - blocks = min_not_zero(sdkp->max_ws_blocks, - (u32)SD_MAX_WS10_BLOCKS); - -out: - blk_queue_max_write_same_sectors(q, blocks * (logical_block_size >> 9)); -} - -/** - * sd_setup_write_same_cmnd - write the same data to multiple blocks - * @sdp: scsi device to operate one - * @rq: Request to prepare - * - * Will issue either WRITE SAME(10) or WRITE SAME(16) depending on - * preference indicated by target device. - **/ -static int sd_setup_write_same_cmnd(struct scsi_device *sdp, struct request *rq) -{ - struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); - struct bio *bio = rq->bio; - sector_t sector = blk_rq_pos(rq); - unsigned int nr_sectors = blk_rq_sectors(rq); - unsigned int nr_bytes = blk_rq_bytes(rq); - int ret; - - if (sdkp->device->no_write_same) - return BLKPREP_KILL; - - BUG_ON(bio_offset(bio) || bio_iovec(bio)->bv_len != sdp->sector_size); - - sector >>= ilog2(sdp->sector_size) - 9; - nr_sectors >>= ilog2(sdp->sector_size) - 9; - - rq->__data_len = sdp->sector_size; - rq->timeout = SD_WRITE_SAME_TIMEOUT; - memset(rq->cmd, 0, rq->cmd_len); - - if (sdkp->ws16 || sector > 0xffffffff || nr_sectors > 0xffff) { - rq->cmd_len = 16; - rq->cmd[0] = WRITE_SAME_16; - put_unaligned_be64(sector, &rq->cmd[2]); - put_unaligned_be32(nr_sectors, &rq->cmd[10]); - } else { - rq->cmd_len = 10; - rq->cmd[0] = WRITE_SAME; - put_unaligned_be32(sector, &rq->cmd[2]); - put_unaligned_be16(nr_sectors, &rq->cmd[7]); - } - - ret = scsi_setup_blk_pc_cmnd(sdp, rq); - rq->__data_len = nr_bytes; - - return ret; -} - static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq) { rq->timeout = SD_FLUSH_TIMEOUT; @@ -833,10 +712,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) * block PC requests to make life easier. */ if (rq->cmd_flags & REQ_DISCARD) { - ret = sd_setup_discard_cmnd(sdp, rq); - goto out; - } else if (rq->cmd_flags & REQ_WRITE_SAME) { - ret = sd_setup_write_same_cmnd(sdp, rq); + ret = scsi_setup_discard_cmnd(sdp, rq); goto out; } else if (rq->cmd_flags & REQ_FLUSH) { ret = scsi_setup_flush_cmnd(sdp, rq); @@ -1606,21 +1482,12 @@ static int sd_done(struct scsi_cmnd *SCpnt) unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt); struct scsi_sense_hdr sshdr; struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk); - struct request *req = SCpnt->request; int sense_valid = 0; int sense_deferred = 0; unsigned char op = SCpnt->cmnd[0]; - unsigned char unmap = SCpnt->cmnd[1] & 8; - if (req->cmd_flags & REQ_DISCARD || req->cmd_flags & REQ_WRITE_SAME) { - if (!result) { - good_bytes = blk_rq_bytes(req); - scsi_set_resid(SCpnt, 0); - } else { - good_bytes = 0; - scsi_set_resid(SCpnt, blk_rq_bytes(req)); - } - } + if ((SCpnt->request->cmd_flags & REQ_DISCARD) && !result) + scsi_set_resid(SCpnt, 0); if (result) { sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr); @@ -1669,25 +1536,9 @@ static int sd_done(struct scsi_cmnd *SCpnt) if (sshdr.asc == 0x10) /* DIX: Host detected corruption */ good_bytes = sd_completed_bytes(SCpnt); /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ - if (sshdr.asc == 0x20 || sshdr.asc == 0x24) { - switch (op) { - case UNMAP: - sd_config_discard(sdkp, SD_LBP_DISABLE); - break; - case WRITE_SAME_16: - case WRITE_SAME: - if (unmap) - sd_config_discard(sdkp, SD_LBP_DISABLE); - else { - sdkp->device->no_write_same = 1; - sd_config_write_same(sdkp); - - good_bytes = 0; - req->__data_len = blk_rq_bytes(req); - req->cmd_flags |= REQ_QUIET; - } - } - } + if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) && + (op == UNMAP || op == WRITE_SAME_16 || op == WRITE_SAME)) + sd_config_discard(sdkp, SD_LBP_DISABLE); break; default: break; @@ -2523,7 +2374,9 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) if (buffer[3] == 0x3c) { unsigned int lba_count, desc_count; - sdkp->max_ws_blocks = (u32)get_unaligned_be64(&buffer[36]); + sdkp->max_ws_blocks = + (u32) min_not_zero(get_unaligned_be64(&buffer[36]), + (u64)0xffffffff); if (!sdkp->lbpme) goto out; @@ -2616,13 +2469,6 @@ static void sd_read_block_provisioning(struct scsi_disk *sdkp) kfree(buffer); } -static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer) -{ - if (scsi_report_opcode(sdkp->device, buffer, SD_BUF_SIZE, - WRITE_SAME_16)) - sdkp->ws16 = 1; -} - static int sd_try_extended_inquiry(struct scsi_device *sdp) { /* @@ -2682,7 +2528,6 @@ static int sd_revalidate_disk(struct gendisk *disk) sd_read_write_protect_flag(sdkp, buffer); sd_read_cache_type(sdkp, buffer); sd_read_app_tag_own(sdkp, buffer); - sd_read_write_same(sdkp, buffer); } sdkp->first_scan = 0; @@ -2700,7 +2545,6 @@ static int sd_revalidate_disk(struct gendisk *disk) blk_queue_flush(sdkp->disk->queue, flush); set_capacity(disk, sdkp->capacity); - sd_config_write_same(sdkp); kfree(buffer); out: diff --git a/trunk/drivers/scsi/sd.h b/trunk/drivers/scsi/sd.h index 74a1e4ca5401..47c52a6d733c 100644 --- a/trunk/drivers/scsi/sd.h +++ b/trunk/drivers/scsi/sd.h @@ -14,7 +14,6 @@ #define SD_TIMEOUT (30 * HZ) #define SD_MOD_TIMEOUT (75 * HZ) #define SD_FLUSH_TIMEOUT (60 * HZ) -#define SD_WRITE_SAME_TIMEOUT (120 * HZ) /* * Number of allowed retries @@ -39,11 +38,6 @@ enum { SD_MEMPOOL_SIZE = 2, /* CDB pool size */ }; -enum { - SD_MAX_WS10_BLOCKS = 0xffff, - SD_MAX_WS16_BLOCKS = 0x7fffff, -}; - enum { SD_LBP_FULL = 0, /* Full logical block provisioning */ SD_LBP_UNMAP, /* Use UNMAP command */ @@ -83,7 +77,6 @@ struct scsi_disk { unsigned lbpws : 1; unsigned lbpws10 : 1; unsigned lbpvpd : 1; - unsigned ws16 : 1; }; #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev) diff --git a/trunk/drivers/spi/spi-mxs.c b/trunk/drivers/spi/spi-mxs.c index 86dd04d6bc87..edf1360ab09e 100644 --- a/trunk/drivers/spi/spi-mxs.c +++ b/trunk/drivers/spi/spi-mxs.c @@ -323,7 +323,6 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs, if (!ret) { dev_err(ssp->dev, "DMA transfer timeout\n"); ret = -ETIMEDOUT; - dmaengine_terminate_all(ssp->dmach); goto err_vmalloc; } @@ -481,7 +480,7 @@ static int mxs_spi_transfer_one(struct spi_master *master, first = last = 0; } - m->status = status; + m->status = 0; spi_finalize_current_message(master); return status; diff --git a/trunk/drivers/spi/spi-pl022.c b/trunk/drivers/spi/spi-pl022.c index a1db91a99b89..919464102d33 100644 --- a/trunk/drivers/spi/spi-pl022.c +++ b/trunk/drivers/spi/spi-pl022.c @@ -2186,6 +2186,8 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", adev->res.start, pl022->virtbase); + pm_runtime_resume(dev); + pl022->clk = devm_clk_get(&adev->dev, NULL); if (IS_ERR(pl022->clk)) { status = PTR_ERR(pl022->clk); @@ -2290,6 +2292,7 @@ pl022_remove(struct amba_device *adev) clk_disable(pl022->clk); clk_unprepare(pl022->clk); + pm_runtime_disable(&adev->dev); amba_release_regions(adev); tasklet_disable(&pl022->pump_transfers); spi_unregister_master(pl022->master); diff --git a/trunk/drivers/spi/spi-rspi.c b/trunk/drivers/spi/spi-rspi.c index 30faf6d4ab91..4894bde4bbff 100644 --- a/trunk/drivers/spi/spi-rspi.c +++ b/trunk/drivers/spi/spi-rspi.c @@ -147,6 +147,8 @@ struct rspi_data { unsigned char spsr; /* for dmaengine */ + struct sh_dmae_slave dma_tx; + struct sh_dmae_slave dma_rx; struct dma_chan *chan_tx; struct dma_chan *chan_rx; int irq; @@ -661,16 +663,20 @@ static irqreturn_t rspi_irq(int irq, void *_sr) return ret; } -static int __devinit rspi_request_dma(struct rspi_data *rspi, - struct platform_device *pdev) +static bool rspi_filter(struct dma_chan *chan, void *filter_param) +{ + chan->private = filter_param; + return true; +} + +static void __devinit rspi_request_dma(struct rspi_data *rspi, + struct platform_device *pdev) { struct rspi_plat_data *rspi_pd = pdev->dev.platform_data; dma_cap_mask_t mask; - struct dma_slave_config cfg; - int ret; if (!rspi_pd) - return 0; /* The driver assumes no error. */ + return; rspi->dma_width_16bit = rspi_pd->dma_width_16bit; @@ -678,35 +684,21 @@ static int __devinit rspi_request_dma(struct rspi_data *rspi, if (rspi_pd->dma_rx_id && rspi_pd->dma_tx_id) { dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); - rspi->chan_rx = dma_request_channel(mask, shdma_chan_filter, - (void *)rspi_pd->dma_rx_id); - if (rspi->chan_rx) { - cfg.slave_id = rspi_pd->dma_rx_id; - cfg.direction = DMA_DEV_TO_MEM; - ret = dmaengine_slave_config(rspi->chan_rx, &cfg); - if (!ret) - dev_info(&pdev->dev, "Use DMA when rx.\n"); - else - return ret; - } + rspi->dma_rx.slave_id = rspi_pd->dma_rx_id; + rspi->chan_rx = dma_request_channel(mask, rspi_filter, + &rspi->dma_rx); + if (rspi->chan_rx) + dev_info(&pdev->dev, "Use DMA when rx.\n"); } if (rspi_pd->dma_tx_id) { dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); - rspi->chan_tx = dma_request_channel(mask, shdma_chan_filter, - (void *)rspi_pd->dma_tx_id); - if (rspi->chan_tx) { - cfg.slave_id = rspi_pd->dma_tx_id; - cfg.direction = DMA_MEM_TO_DEV; - ret = dmaengine_slave_config(rspi->chan_tx, &cfg); - if (!ret) - dev_info(&pdev->dev, "Use DMA when tx\n"); - else - return ret; - } + rspi->dma_tx.slave_id = rspi_pd->dma_tx_id; + rspi->chan_tx = dma_request_channel(mask, rspi_filter, + &rspi->dma_tx); + if (rspi->chan_tx) + dev_info(&pdev->dev, "Use DMA when tx\n"); } - - return 0; } static void __devexit rspi_release_dma(struct rspi_data *rspi) @@ -796,11 +788,7 @@ static int __devinit rspi_probe(struct platform_device *pdev) } rspi->irq = irq; - ret = rspi_request_dma(rspi, pdev); - if (ret < 0) { - dev_err(&pdev->dev, "rspi_request_dma failed.\n"); - goto error4; - } + rspi_request_dma(rspi, pdev); ret = spi_register_master(master); if (ret < 0) { diff --git a/trunk/drivers/staging/android/android_alarm.h b/trunk/drivers/staging/android/android_alarm.h index d0cafd637199..f2ffd963f1c3 100644 --- a/trunk/drivers/staging/android/android_alarm.h +++ b/trunk/drivers/staging/android/android_alarm.h @@ -51,10 +51,12 @@ enum android_alarm_return_flags { #define ANDROID_ALARM_WAIT _IO('a', 1) #define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size) +#define ALARM_IOR(c, type, size) _IOR('a', (c) | ((type) << 4), size) + /* Set alarm */ #define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec) #define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec) -#define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec) +#define ANDROID_ALARM_GET_TIME(type) ALARM_IOR(4, type, struct timespec) #define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec) #define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0))) #define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4) diff --git a/trunk/drivers/staging/android/binder.c b/trunk/drivers/staging/android/binder.c index 5d4610babd8a..7b0ba92e7e46 100644 --- a/trunk/drivers/staging/android/binder.c +++ b/trunk/drivers/staging/android/binder.c @@ -567,7 +567,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE]; BUG_ON(*page); - *page = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO); + *page = alloc_page(GFP_KERNEL | __GFP_ZERO); if (*page == NULL) { pr_err("binder: %d: binder_alloc_buf failed " "for page at %p\n", proc->pid, page_addr); @@ -2419,38 +2419,14 @@ static void binder_release_work(struct list_head *list) struct binder_transaction *t; t = container_of(w, struct binder_transaction, work); - if (t->buffer->target_node && - !(t->flags & TF_ONE_WAY)) { + if (t->buffer->target_node && !(t->flags & TF_ONE_WAY)) binder_send_failed_reply(t, BR_DEAD_REPLY); - } else { - binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, - "binder: undelivered transaction %d\n", - t->debug_id); - t->buffer->transaction = NULL; - kfree(t); - binder_stats_deleted(BINDER_STAT_TRANSACTION); - } } break; case BINDER_WORK_TRANSACTION_COMPLETE: { - binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, - "binder: undelivered TRANSACTION_COMPLETE\n"); kfree(w); binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); } break; - case BINDER_WORK_DEAD_BINDER_AND_CLEAR: - case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: { - struct binder_ref_death *death; - - death = container_of(w, struct binder_ref_death, work); - binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, - "binder: undelivered death notification, %p\n", - death->cookie); - kfree(death); - binder_stats_deleted(BINDER_STAT_DEATH); - } break; default: - pr_err("binder: unexpected work type, %d, not freed\n", - w->type); break; } } @@ -2923,7 +2899,6 @@ static void binder_deferred_release(struct binder_proc *proc) nodes++; rb_erase(&node->rb_node, &proc->nodes); list_del_init(&node->work.entry); - binder_release_work(&node->async_todo); if (hlist_empty(&node->refs)) { kfree(node); binder_stats_deleted(BINDER_STAT_NODE); @@ -2962,7 +2937,6 @@ static void binder_deferred_release(struct binder_proc *proc) binder_delete_ref(ref); } binder_release_work(&proc->todo); - binder_release_work(&proc->delivered_death); buffers = 0; while ((n = rb_first(&proc->allocated_buffers))) { diff --git a/trunk/drivers/staging/comedi/drivers/8255_pci.c b/trunk/drivers/staging/comedi/drivers/8255_pci.c index d00aff6671df..7dff3c01dc29 100644 --- a/trunk/drivers/staging/comedi/drivers/8255_pci.c +++ b/trunk/drivers/staging/comedi/drivers/8255_pci.c @@ -289,8 +289,6 @@ static void pci_8255_detach(struct comedi_device *dev) struct comedi_subdevice *s; int i; - if (!board || !devpriv) - return; if (dev->subdevices) { for (i = 0; i < board->n_8255; i++) { s = &dev->subdevices[i]; diff --git a/trunk/drivers/staging/comedi/drivers/amplc_dio200.c b/trunk/drivers/staging/comedi/drivers/amplc_dio200.c index 29eb52d11d2f..08f305210a69 100644 --- a/trunk/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/trunk/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1410,8 +1410,6 @@ static void dio200_detach(struct comedi_device *dev) const struct dio200_layout_struct *layout; unsigned n; - if (!thisboard) - return; if (dev->irq) free_irq(dev->irq, dev); if (dev->subdevices) { diff --git a/trunk/drivers/staging/comedi/drivers/amplc_pc236.c b/trunk/drivers/staging/comedi/drivers/amplc_pc236.c index 4e4f3c15df87..eacb5e4735d7 100644 --- a/trunk/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/trunk/drivers/staging/comedi/drivers/amplc_pc236.c @@ -573,10 +573,9 @@ static int __devinit pc236_attach_pci(struct comedi_device *dev, static void pc236_detach(struct comedi_device *dev) { const struct pc236_board *thisboard = comedi_board(dev); + struct pc236_private *devpriv = dev->private; - if (!thisboard) - return; - if (dev->iobase) + if (devpriv) pc236_intr_disable(dev); if (dev->irq) free_irq(dev->irq, dev); diff --git a/trunk/drivers/staging/comedi/drivers/amplc_pc263.c b/trunk/drivers/staging/comedi/drivers/amplc_pc263.c index d0a4c441228b..60830ccfb903 100644 --- a/trunk/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/trunk/drivers/staging/comedi/drivers/amplc_pc263.c @@ -323,8 +323,6 @@ static void pc263_detach(struct comedi_device *dev) { const struct pc263_board *thisboard = comedi_board(dev); - if (!thisboard) - return; if (is_isa_board(thisboard)) { if (dev->iobase) release_region(dev->iobase, PC263_IO_SIZE); diff --git a/trunk/drivers/staging/comedi/drivers/das08.c b/trunk/drivers/staging/comedi/drivers/das08.c index c304528cfb13..5fd21fa6c1c7 100644 --- a/trunk/drivers/staging/comedi/drivers/das08.c +++ b/trunk/drivers/staging/comedi/drivers/das08.c @@ -846,8 +846,6 @@ static void __maybe_unused das08_detach(struct comedi_device *dev) { const struct das08_board_struct *thisboard = comedi_board(dev); - if (!thisboard) - return; das08_common_detach(dev); if (is_isa_board(thisboard)) { if (dev->iobase) diff --git a/trunk/drivers/staging/comedi/drivers/ni_daq_700.c b/trunk/drivers/staging/comedi/drivers/ni_daq_700.c index 68d7c6a5db7d..2ba0ade45c64 100644 --- a/trunk/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/trunk/drivers/staging/comedi/drivers/ni_daq_700.c @@ -95,7 +95,7 @@ static int daq700_dio_insn_bits(struct comedi_device *dev, } data[1] = s->state & 0xff; - data[1] |= inb(dev->iobase + DIO_R) << 8; + data[1] |= inb(dev->iobase + DIO_R); return insn->n; } diff --git a/trunk/drivers/staging/comedi/drivers/ni_labpc.c b/trunk/drivers/staging/comedi/drivers/ni_labpc.c index b5a19a0863fb..28b91a6c3789 100644 --- a/trunk/drivers/staging/comedi/drivers/ni_labpc.c +++ b/trunk/drivers/staging/comedi/drivers/ni_labpc.c @@ -772,8 +772,6 @@ void labpc_common_detach(struct comedi_device *dev) { struct comedi_subdevice *s; - if (!thisboard) - return; if (dev->subdevices) { s = &dev->subdevices[2]; subdev_8255_cleanup(dev, s); diff --git a/trunk/drivers/staging/iio/accel/adis16201_core.c b/trunk/drivers/staging/iio/accel/adis16201_core.c index b12ca68cd9e4..8e37d6e04277 100644 --- a/trunk/drivers/staging/iio/accel/adis16201_core.c +++ b/trunk/drivers/staging/iio/accel/adis16201_core.c @@ -310,32 +310,30 @@ static int adis16201_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_VOLTAGE: - if (chan->channel == 0) { - *val = 1; - *val2 = 220000; /* 1.22 mV */ - } else { - *val = 0; - *val2 = 610000; /* 0.610 mV */ - } + *val = 0; + if (chan->channel == 0) + *val2 = 1220; + else + *val2 = 610; return IIO_VAL_INT_PLUS_MICRO; case IIO_TEMP: - *val = -470; /* 0.47 C */ - *val2 = 0; + *val = 0; + *val2 = -470000; return IIO_VAL_INT_PLUS_MICRO; case IIO_ACCEL: *val = 0; - *val2 = IIO_G_TO_M_S_2(462400); /* 0.4624 mg */ - return IIO_VAL_INT_PLUS_NANO; + *val2 = 462500; + return IIO_VAL_INT_PLUS_MICRO; case IIO_INCLI: *val = 0; - *val2 = 100000; /* 0.1 degree */ + *val2 = 100000; return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; } break; case IIO_CHAN_INFO_OFFSET: - *val = 25000 / -470 - 1278; /* 25 C = 1278 */ + *val = 25; return IIO_VAL_INT; case IIO_CHAN_INFO_CALIBBIAS: switch (chan->type) { diff --git a/trunk/drivers/staging/iio/accel/adis16203_core.c b/trunk/drivers/staging/iio/accel/adis16203_core.c index e7b3441115ae..002fa9dfc375 100644 --- a/trunk/drivers/staging/iio/accel/adis16203_core.c +++ b/trunk/drivers/staging/iio/accel/adis16203_core.c @@ -316,27 +316,25 @@ static int adis16203_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_VOLTAGE: - if (chan->channel == 0) { - *val = 1; - *val2 = 220000; /* 1.22 mV */ - } else { - *val = 0; - *val2 = 610000; /* 0.61 mV */ - } + *val = 0; + if (chan->channel == 0) + *val2 = 1220; + else + *val2 = 610; return IIO_VAL_INT_PLUS_MICRO; case IIO_TEMP: - *val = -470; /* -0.47 C */ - *val2 = 0; + *val = 0; + *val2 = -470000; return IIO_VAL_INT_PLUS_MICRO; case IIO_INCLI: *val = 0; - *val2 = 25000; /* 0.025 degree */ + *val2 = 25000; return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; } case IIO_CHAN_INFO_OFFSET: - *val = 25000 / -470 - 1278; /* 25 C = 1278 */ + *val = 25; return IIO_VAL_INT; case IIO_CHAN_INFO_CALIBBIAS: bits = 14; diff --git a/trunk/drivers/staging/iio/accel/adis16204_core.c b/trunk/drivers/staging/iio/accel/adis16204_core.c index c6234c2f46aa..05bdb7c2c8e3 100644 --- a/trunk/drivers/staging/iio/accel/adis16204_core.c +++ b/trunk/drivers/staging/iio/accel/adis16204_core.c @@ -317,28 +317,26 @@ static int adis16204_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_VOLTAGE: - if (chan->channel == 0) { - *val = 1; - *val2 = 220000; /* 1.22 mV */ - } else { - *val = 0; - *val2 = 610000; /* 0.61 mV */ - } + *val = 0; + if (chan->channel == 0) + *val2 = 1220; + else + *val2 = 610; return IIO_VAL_INT_PLUS_MICRO; case IIO_TEMP: - *val = -470; /* 0.47 C */ - *val2 = 0; + *val = 0; + *val2 = -470000; return IIO_VAL_INT_PLUS_MICRO; case IIO_ACCEL: *val = 0; switch (chan->channel2) { case IIO_MOD_X: case IIO_MOD_ROOT_SUM_SQUARED_X_Y: - *val2 = IIO_G_TO_M_S_2(17125); /* 17.125 mg */ + *val2 = 17125; break; case IIO_MOD_Y: case IIO_MOD_Z: - *val2 = IIO_G_TO_M_S_2(8407); /* 8.407 mg */ + *val2 = 8407; break; } return IIO_VAL_INT_PLUS_MICRO; @@ -347,7 +345,7 @@ static int adis16204_read_raw(struct iio_dev *indio_dev, } break; case IIO_CHAN_INFO_OFFSET: - *val = 25000 / -470 - 1278; /* 25 C = 1278 */ + *val = 25; return IIO_VAL_INT; case IIO_CHAN_INFO_CALIBBIAS: case IIO_CHAN_INFO_PEAK: diff --git a/trunk/drivers/staging/iio/accel/adis16209_core.c b/trunk/drivers/staging/iio/accel/adis16209_core.c index 7ee974b45d7d..b7333bfe0b2f 100644 --- a/trunk/drivers/staging/iio/accel/adis16209_core.c +++ b/trunk/drivers/staging/iio/accel/adis16209_core.c @@ -343,29 +343,28 @@ static int adis16209_read_raw(struct iio_dev *indio_dev, case IIO_VOLTAGE: *val = 0; if (chan->channel == 0) - *val2 = 305180; /* 0.30518 mV */ + *val2 = 305180; else - *val2 = 610500; /* 0.6105 mV */ + *val2 = 610500; return IIO_VAL_INT_PLUS_MICRO; case IIO_TEMP: - *val = -470; /* -0.47 C */ - *val2 = 0; + *val = 0; + *val2 = -470000; return IIO_VAL_INT_PLUS_MICRO; case IIO_ACCEL: *val = 0; - *val2 = IIO_G_TO_M_S_2(244140); /* 0.244140 mg */ - return IIO_VAL_INT_PLUS_NANO; + *val2 = 2394; + return IIO_VAL_INT_PLUS_MICRO; case IIO_INCLI: - case IIO_ROT: *val = 0; - *val2 = 25000; /* 0.025 degree */ + *val2 = 436; return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; } break; case IIO_CHAN_INFO_OFFSET: - *val = 25000 / -470 - 0x4FE; /* 25 C = 0x4FE */ + *val = 25; return IIO_VAL_INT; case IIO_CHAN_INFO_CALIBBIAS: switch (chan->type) { @@ -492,7 +491,6 @@ static const struct iio_chan_spec adis16209_channels[] = { .modified = 1, .channel2 = IIO_MOD_X, .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, - IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = rot, .scan_index = ADIS16209_SCAN_ROT, .scan_type = { diff --git a/trunk/drivers/staging/iio/accel/adis16220_core.c b/trunk/drivers/staging/iio/accel/adis16220_core.c index eaadd9df3f78..c755089c7117 100644 --- a/trunk/drivers/staging/iio/accel/adis16220_core.c +++ b/trunk/drivers/staging/iio/accel/adis16220_core.c @@ -486,7 +486,7 @@ static int adis16220_read_raw(struct iio_dev *indio_dev, break; case IIO_CHAN_INFO_OFFSET: if (chan->type == IIO_TEMP) { - *val = 25000 / -470 - 1278; /* 25 C = 1278 */ + *val = 25; return IIO_VAL_INT; } addrind = 1; @@ -495,22 +495,19 @@ static int adis16220_read_raw(struct iio_dev *indio_dev, addrind = 2; break; case IIO_CHAN_INFO_SCALE: + *val = 0; switch (chan->type) { case IIO_TEMP: - *val = -470; /* -0.47 C */ - *val2 = 0; + *val2 = -470000; return IIO_VAL_INT_PLUS_MICRO; case IIO_ACCEL: - *val2 = IIO_G_TO_M_S_2(19073); /* 19.073 g */ + *val2 = 1887042; return IIO_VAL_INT_PLUS_MICRO; case IIO_VOLTAGE: - if (chan->channel == 0) { - *val = 1; - *val2 = 220700; /* 1.2207 mV */ - } else { - /* Should really be dependent on VDD */ - *val2 = 305180; /* 305.18 uV */ - } + if (chan->channel == 0) + *val2 = 0012221; + else /* Should really be dependent on VDD */ + *val2 = 305; return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; diff --git a/trunk/drivers/staging/iio/accel/adis16240_core.c b/trunk/drivers/staging/iio/accel/adis16240_core.c index 35e093973d5c..0fc26a49d681 100644 --- a/trunk/drivers/staging/iio/accel/adis16240_core.c +++ b/trunk/drivers/staging/iio/accel/adis16240_core.c @@ -373,31 +373,30 @@ static int adis16240_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_VOLTAGE: - if (chan->channel == 0) { - *val = 4; - *val2 = 880000; /* 4.88 mV */ - return IIO_VAL_INT_PLUS_MICRO; - } else { + *val = 0; + if (chan->channel == 0) + *val2 = 4880; + else return -EINVAL; - } + return IIO_VAL_INT_PLUS_MICRO; case IIO_TEMP: - *val = 244; /* 0.244 C */ - *val2 = 0; + *val = 0; + *val2 = 244000; return IIO_VAL_INT_PLUS_MICRO; case IIO_ACCEL: *val = 0; - *val2 = IIO_G_TO_M_S_2(51400); /* 51.4 mg */ + *val2 = 504062; return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; } break; case IIO_CHAN_INFO_PEAK_SCALE: - *val = 0; - *val2 = IIO_G_TO_M_S_2(51400); /* 51.4 mg */ + *val = 6; + *val2 = 629295; return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_OFFSET: - *val = 25000 / 244 - 0x133; /* 25 C = 0x133 */ + *val = 25; return IIO_VAL_INT; case IIO_CHAN_INFO_CALIBBIAS: bits = 10; diff --git a/trunk/drivers/staging/iio/gyro/adis16260_core.c b/trunk/drivers/staging/iio/gyro/adis16260_core.c index aa964a2d8290..9571c03aa4cc 100644 --- a/trunk/drivers/staging/iio/gyro/adis16260_core.c +++ b/trunk/drivers/staging/iio/gyro/adis16260_core.c @@ -498,33 +498,28 @@ static int adis16260_read_raw(struct iio_dev *indio_dev, switch (chan->type) { case IIO_ANGL_VEL: *val = 0; - if (spi_get_device_id(st->us)->driver_data) { - /* 0.01832 degree / sec */ - *val2 = IIO_DEGREE_TO_RAD(18320); - } else { - /* 0.07326 degree / sec */ - *val2 = IIO_DEGREE_TO_RAD(73260); - } + if (spi_get_device_id(st->us)->driver_data) + *val2 = 320; + else + *val2 = 1278; return IIO_VAL_INT_PLUS_MICRO; case IIO_VOLTAGE: - if (chan->channel == 0) { - *val = 1; - *val2 = 831500; /* 1.8315 mV */ - } else { - *val = 0; - *val2 = 610500; /* 610.5 uV */ - } + *val = 0; + if (chan->channel == 0) + *val2 = 18315; + else + *val2 = 610500; return IIO_VAL_INT_PLUS_MICRO; case IIO_TEMP: - *val = 145; - *val2 = 300000; /* 0.1453 C */ + *val = 0; + *val2 = 145300; return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; } break; case IIO_CHAN_INFO_OFFSET: - *val = 250000 / 1453; /* 25 C = 0x00 */ + *val = 25; return IIO_VAL_INT; case IIO_CHAN_INFO_CALIBBIAS: switch (chan->type) { diff --git a/trunk/drivers/staging/iio/imu/adis16400.h b/trunk/drivers/staging/iio/imu/adis16400.h index 77c601da1846..d59d7ac856a9 100644 --- a/trunk/drivers/staging/iio/imu/adis16400.h +++ b/trunk/drivers/staging/iio/imu/adis16400.h @@ -139,8 +139,6 @@ struct adis16400_chip_info { const long flags; unsigned int gyro_scale_micro; unsigned int accel_scale_micro; - int temp_scale_nano; - int temp_offset; unsigned long default_scan_mask; }; diff --git a/trunk/drivers/staging/iio/imu/adis16400_core.c b/trunk/drivers/staging/iio/imu/adis16400_core.c index 3144a7b1e1c4..b302c9ba2712 100644 --- a/trunk/drivers/staging/iio/imu/adis16400_core.c +++ b/trunk/drivers/staging/iio/imu/adis16400_core.c @@ -553,13 +553,10 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT_PLUS_MICRO; case IIO_VOLTAGE: *val = 0; - if (chan->channel == 0) { - *val = 2; - *val2 = 418000; /* 2.418 mV */ - } else { - *val = 0; - *val2 = 805800; /* 805.8 uV */ - } + if (chan->channel == 0) + *val2 = 2418; + else + *val2 = 806; return IIO_VAL_INT_PLUS_MICRO; case IIO_ACCEL: *val = 0; @@ -567,11 +564,11 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT_PLUS_MICRO; case IIO_MAGN: *val = 0; - *val2 = 500; /* 0.5 mgauss */ + *val2 = 500; return IIO_VAL_INT_PLUS_MICRO; case IIO_TEMP: - *val = st->variant->temp_scale_nano / 1000000; - *val2 = (st->variant->temp_scale_nano % 1000000); + *val = 0; + *val2 = 140000; return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; @@ -589,8 +586,9 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT; case IIO_CHAN_INFO_OFFSET: /* currently only temperature */ - *val = st->variant->temp_offset; - return IIO_VAL_INT; + *val = 198; + *val2 = 160000; + return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: mutex_lock(&indio_dev->mlock); /* Need both the number of taps and the sampling frequency */ @@ -1037,7 +1035,7 @@ static const struct iio_chan_spec adis16334_channels[] = { .indexed = 1, .channel = 0, .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = temp0, .scan_index = ADIS16400_SCAN_TEMP, @@ -1060,10 +1058,8 @@ static struct adis16400_chip_info adis16400_chips[] = { [ADIS16300] = { .channels = adis16300_channels, .num_channels = ARRAY_SIZE(adis16300_channels), - .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ + .gyro_scale_micro = 873, .accel_scale_micro = 5884, - .temp_scale_nano = 140000000, /* 0.14 C */ - .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */ .default_scan_mask = (1 << ADIS16400_SCAN_SUPPLY) | (1 << ADIS16400_SCAN_GYRO_X) | (1 << ADIS16400_SCAN_ACC_X) | (1 << ADIS16400_SCAN_ACC_Y) | (1 << ADIS16400_SCAN_ACC_Z) | @@ -1074,10 +1070,8 @@ static struct adis16400_chip_info adis16400_chips[] = { [ADIS16334] = { .channels = adis16334_channels, .num_channels = ARRAY_SIZE(adis16334_channels), - .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ - .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */ - .temp_scale_nano = 67850000, /* 0.06785 C */ - .temp_offset = 25000000 / 67850, /* 25 C = 0x00 */ + .gyro_scale_micro = 873, + .accel_scale_micro = 981, .default_scan_mask = (1 << ADIS16400_SCAN_GYRO_X) | (1 << ADIS16400_SCAN_GYRO_Y) | (1 << ADIS16400_SCAN_GYRO_Z) | (1 << ADIS16400_SCAN_ACC_X) | (1 << ADIS16400_SCAN_ACC_Y) | @@ -1086,10 +1080,8 @@ static struct adis16400_chip_info adis16400_chips[] = { [ADIS16350] = { .channels = adis16350_channels, .num_channels = ARRAY_SIZE(adis16350_channels), - .gyro_scale_micro = IIO_DEGREE_TO_RAD(73260), /* 0.07326 deg/s */ - .accel_scale_micro = IIO_G_TO_M_S_2(2522), /* 0.002522 g */ - .temp_scale_nano = 145300000, /* 0.1453 C */ - .temp_offset = 25000000 / 145300, /* 25 C = 0x00 */ + .gyro_scale_micro = 872664, + .accel_scale_micro = 24732, .default_scan_mask = 0x7FF, .flags = ADIS16400_NO_BURST, }, @@ -1098,10 +1090,8 @@ static struct adis16400_chip_info adis16400_chips[] = { .num_channels = ARRAY_SIZE(adis16350_channels), .flags = ADIS16400_HAS_PROD_ID, .product_id = 0x3FE8, - .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ - .accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */ - .temp_scale_nano = 136000000, /* 0.136 C */ - .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ + .gyro_scale_micro = 1279, + .accel_scale_micro = 24732, .default_scan_mask = 0x7FF, }, [ADIS16362] = { @@ -1109,10 +1099,8 @@ static struct adis16400_chip_info adis16400_chips[] = { .num_channels = ARRAY_SIZE(adis16350_channels), .flags = ADIS16400_HAS_PROD_ID, .product_id = 0x3FEA, - .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ - .accel_scale_micro = IIO_G_TO_M_S_2(333), /* 0.333 mg */ - .temp_scale_nano = 136000000, /* 0.136 C */ - .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ + .gyro_scale_micro = 1279, + .accel_scale_micro = 24732, .default_scan_mask = 0x7FF, }, [ADIS16364] = { @@ -1120,10 +1108,8 @@ static struct adis16400_chip_info adis16400_chips[] = { .num_channels = ARRAY_SIZE(adis16350_channels), .flags = ADIS16400_HAS_PROD_ID, .product_id = 0x3FEC, - .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ - .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */ - .temp_scale_nano = 136000000, /* 0.136 C */ - .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ + .gyro_scale_micro = 1279, + .accel_scale_micro = 24732, .default_scan_mask = 0x7FF, }, [ADIS16365] = { @@ -1131,10 +1117,8 @@ static struct adis16400_chip_info adis16400_chips[] = { .num_channels = ARRAY_SIZE(adis16350_channels), .flags = ADIS16400_HAS_PROD_ID, .product_id = 0x3FED, - .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ - .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */ - .temp_scale_nano = 136000000, /* 0.136 C */ - .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ + .gyro_scale_micro = 1279, + .accel_scale_micro = 24732, .default_scan_mask = 0x7FF, }, [ADIS16400] = { @@ -1142,11 +1126,9 @@ static struct adis16400_chip_info adis16400_chips[] = { .num_channels = ARRAY_SIZE(adis16400_channels), .flags = ADIS16400_HAS_PROD_ID, .product_id = 0x4015, - .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ - .accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */ + .gyro_scale_micro = 873, + .accel_scale_micro = 32656, .default_scan_mask = 0xFFF, - .temp_scale_nano = 140000000, /* 0.14 C */ - .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */ } }; diff --git a/trunk/drivers/staging/ipack/bridges/tpci200.c b/trunk/drivers/staging/ipack/bridges/tpci200.c index 46d6657280b8..bb8aa70281cd 100644 --- a/trunk/drivers/staging/ipack/bridges/tpci200.c +++ b/trunk/drivers/staging/ipack/bridges/tpci200.c @@ -12,7 +12,6 @@ */ #include -#include #include "tpci200.h" static u16 tpci200_status_timeout[] = { diff --git a/trunk/drivers/staging/omapdrm/omap_gem.c b/trunk/drivers/staging/omapdrm/omap_gem.c index 66e2c2f8a239..3434e6ec0142 100644 --- a/trunk/drivers/staging/omapdrm/omap_gem.c +++ b/trunk/drivers/staging/omapdrm/omap_gem.c @@ -246,7 +246,7 @@ static int omap_gem_attach_pages(struct drm_gem_object *obj) * DSS, GPU, etc. are not cache coherent: */ if (omap_obj->flags & (OMAP_BO_WC|OMAP_BO_UNCACHED)) { - addrs = kmalloc(npages * sizeof(*addrs), GFP_KERNEL); + addrs = kmalloc(npages * sizeof(addrs), GFP_KERNEL); if (!addrs) { ret = -ENOMEM; goto free_pages; @@ -257,7 +257,7 @@ static int omap_gem_attach_pages(struct drm_gem_object *obj) 0, PAGE_SIZE, DMA_BIDIRECTIONAL); } } else { - addrs = kzalloc(npages * sizeof(*addrs), GFP_KERNEL); + addrs = kzalloc(npages * sizeof(addrs), GFP_KERNEL); if (!addrs) { ret = -ENOMEM; goto free_pages; diff --git a/trunk/drivers/staging/ramster/Kconfig b/trunk/drivers/staging/ramster/Kconfig index 3abf6619dace..843c54101438 100644 --- a/trunk/drivers/staging/ramster/Kconfig +++ b/trunk/drivers/staging/ramster/Kconfig @@ -18,7 +18,6 @@ config ZCACHE2 config RAMSTER bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem" depends on CONFIGFS_FS=y && SYSFS=y && !HIGHMEM && ZCACHE2=y - depends on NET # must ensure struct page is 8-byte aligned select HAVE_ALIGNED_STRUCT_PAGE if !64_BIT default n diff --git a/trunk/drivers/staging/tidspbridge/core/tiomap3430.c b/trunk/drivers/staging/tidspbridge/core/tiomap3430.c index f619fb3c56d2..066a3ceec65e 100644 --- a/trunk/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/trunk/drivers/staging/tidspbridge/core/tiomap3430.c @@ -126,8 +126,7 @@ static int mem_map_vmalloc(struct bridge_dev_context *dev_context, u32 ul_num_bytes, struct hw_mmu_map_attrs_t *hw_attrs); -bool wait_for_start(struct bridge_dev_context *dev_context, - void __iomem *sync_addr); +bool wait_for_start(struct bridge_dev_context *dev_context, u32 dw_sync_addr); /* ----------------------------------- Globals */ @@ -364,11 +363,10 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, { int status = 0; struct bridge_dev_context *dev_context = dev_ctxt; - void __iomem *sync_addr; + u32 dw_sync_addr = 0; u32 ul_shm_base; /* Gpp Phys SM base addr(byte) */ u32 ul_shm_base_virt; /* Dsp Virt SM base addr */ u32 ul_tlb_base_virt; /* Base of MMU TLB entry */ - u32 shm_sync_pa; /* Offset of shm_base_virt from tlb_base_virt */ u32 ul_shm_offset_virt; s32 entry_ndx; @@ -399,22 +397,15 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, /* Kernel logical address */ ul_shm_base = dev_context->atlb_entry[0].gpp_va + ul_shm_offset_virt; - /* SHM physical sync address */ - shm_sync_pa = dev_context->atlb_entry[0].gpp_pa + ul_shm_offset_virt + - SHMSYNCOFFSET; - /* 2nd wd is used as sync field */ - sync_addr = ioremap(shm_sync_pa, SZ_32); - if (!sync_addr) - return -ENOMEM; - + dw_sync_addr = ul_shm_base + SHMSYNCOFFSET; /* Write a signature into the shm base + offset; this will * get cleared when the DSP program starts. */ if ((ul_shm_base_virt == 0) || (ul_shm_base == 0)) { pr_err("%s: Illegal SM base\n", __func__); status = -EPERM; } else - __raw_writel(0xffffffff, sync_addr); + __raw_writel(0xffffffff, dw_sync_addr); if (!status) { resources = dev_context->resources; @@ -428,10 +419,8 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, * function is made available. */ void __iomem *ctrl = ioremap(0x48002000, SZ_4K); - if (!ctrl) { - iounmap(sync_addr); + if (!ctrl) return -ENOMEM; - } (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, OMAP3430_RST1_IVA2_MASK, OMAP3430_IVA2_MOD, @@ -599,15 +588,15 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, 0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); - dev_dbg(bridge, "Waiting for Sync @ 0x%x\n", *(u32 *)sync_addr); + dev_dbg(bridge, "Waiting for Sync @ 0x%x\n", dw_sync_addr); dev_dbg(bridge, "DSP c_int00 Address = 0x%x\n", dsp_addr); if (dsp_debug) - while (__raw_readw(sync_addr)) + while (__raw_readw(dw_sync_addr)) ; /* Wait for DSP to clear word in shared memory */ /* Read the Location */ - if (!wait_for_start(dev_context, sync_addr)) + if (!wait_for_start(dev_context, dw_sync_addr)) status = -ETIMEDOUT; dev_get_symbol(dev_context->dev_obj, "_WDT_enable", &wdt_en); @@ -623,7 +612,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, /* Write the synchronization bit to indicate the * completion of OPP table update to DSP */ - __raw_writel(0XCAFECAFE, sync_addr); + __raw_writel(0XCAFECAFE, dw_sync_addr); /* update board state */ dev_context->brd_state = BRD_RUNNING; @@ -632,9 +621,6 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, dev_context->brd_state = BRD_UNKNOWN; } } - - iounmap(sync_addr); - return status; } @@ -1810,13 +1796,12 @@ static int mem_map_vmalloc(struct bridge_dev_context *dev_context, * ======== wait_for_start ======== * Wait for the singal from DSP that it has started, or time out. */ -bool wait_for_start(struct bridge_dev_context *dev_context, - void __iomem *sync_addr) +bool wait_for_start(struct bridge_dev_context *dev_context, u32 dw_sync_addr) { u16 timeout = TIHELEN_ACKTIMEOUT; /* Wait for response from board */ - while (__raw_readw(sync_addr) && --timeout) + while (__raw_readw(dw_sync_addr) && --timeout) udelay(10); /* If timed out: return false */ diff --git a/trunk/drivers/staging/tidspbridge/hw/hw_mmu.c b/trunk/drivers/staging/tidspbridge/hw/hw_mmu.c index 50244a474178..71cb82293649 100644 --- a/trunk/drivers/staging/tidspbridge/hw/hw_mmu.c +++ b/trunk/drivers/staging/tidspbridge/hw/hw_mmu.c @@ -47,13 +47,38 @@ enum hw_mmu_page_size_t { HW_MMU_SUPERSECTION }; +/* + * FUNCTION : mmu_flush_entry + * + * INPUTS: + * + * Identifier : base_address + * Type : const u32 + * Description : Base Address of instance of MMU module + * + * RETURNS: + * + * Type : hw_status + * Description : 0 -- No errors occurred + * RET_BAD_NULL_PARAM -- A Pointer + * Parameter was set to NULL + * + * PURPOSE: : Flush the TLB entry pointed by the + * lock counter register + * even if this entry is set protected + * + * METHOD: : Check the Input parameter and Flush a + * single entry in the TLB. + */ +static hw_status mmu_flush_entry(const void __iomem *base_address); + /* * FUNCTION : mmu_set_cam_entry * * INPUTS: * * Identifier : base_address - * Type : void __iomem * + * TypE : const u32 * Description : Base Address of instance of MMU module * * Identifier : page_sz @@ -87,7 +112,7 @@ enum hw_mmu_page_size_t { * * METHOD: : Check the Input parameters and set the CAM entry. */ -static hw_status mmu_set_cam_entry(void __iomem *base_address, +static hw_status mmu_set_cam_entry(const void __iomem *base_address, const u32 page_sz, const u32 preserved_bit, const u32 valid_bit, @@ -99,7 +124,7 @@ static hw_status mmu_set_cam_entry(void __iomem *base_address, * INPUTS: * * Identifier : base_address - * Type : void __iomem * + * Type : const u32 * Description : Base Address of instance of MMU module * * Identifier : physical_addr @@ -132,7 +157,7 @@ static hw_status mmu_set_cam_entry(void __iomem *base_address, * * METHOD: : Check the Input parameters and set the RAM entry. */ -static hw_status mmu_set_ram_entry(void __iomem *base_address, +static hw_status mmu_set_ram_entry(const void __iomem *base_address, const u32 physical_addr, enum hw_endianism_t endianism, enum hw_element_size_t element_size, @@ -140,7 +165,7 @@ static hw_status mmu_set_ram_entry(void __iomem *base_address, /* HW FUNCTIONS */ -hw_status hw_mmu_enable(void __iomem *base_address) +hw_status hw_mmu_enable(const void __iomem *base_address) { hw_status status = 0; @@ -149,7 +174,7 @@ hw_status hw_mmu_enable(void __iomem *base_address) return status; } -hw_status hw_mmu_disable(void __iomem *base_address) +hw_status hw_mmu_disable(const void __iomem *base_address) { hw_status status = 0; @@ -158,7 +183,7 @@ hw_status hw_mmu_disable(void __iomem *base_address) return status; } -hw_status hw_mmu_num_locked_set(void __iomem *base_address, +hw_status hw_mmu_num_locked_set(const void __iomem *base_address, u32 num_locked_entries) { hw_status status = 0; @@ -168,7 +193,7 @@ hw_status hw_mmu_num_locked_set(void __iomem *base_address, return status; } -hw_status hw_mmu_victim_num_set(void __iomem *base_address, +hw_status hw_mmu_victim_num_set(const void __iomem *base_address, u32 victim_entry_num) { hw_status status = 0; @@ -178,7 +203,7 @@ hw_status hw_mmu_victim_num_set(void __iomem *base_address, return status; } -hw_status hw_mmu_event_ack(void __iomem *base_address, u32 irq_mask) +hw_status hw_mmu_event_ack(const void __iomem *base_address, u32 irq_mask) { hw_status status = 0; @@ -187,7 +212,7 @@ hw_status hw_mmu_event_ack(void __iomem *base_address, u32 irq_mask) return status; } -hw_status hw_mmu_event_disable(void __iomem *base_address, u32 irq_mask) +hw_status hw_mmu_event_disable(const void __iomem *base_address, u32 irq_mask) { hw_status status = 0; u32 irq_reg; @@ -199,7 +224,7 @@ hw_status hw_mmu_event_disable(void __iomem *base_address, u32 irq_mask) return status; } -hw_status hw_mmu_event_enable(void __iomem *base_address, u32 irq_mask) +hw_status hw_mmu_event_enable(const void __iomem *base_address, u32 irq_mask) { hw_status status = 0; u32 irq_reg; @@ -211,7 +236,7 @@ hw_status hw_mmu_event_enable(void __iomem *base_address, u32 irq_mask) return status; } -hw_status hw_mmu_event_status(void __iomem *base_address, u32 *irq_mask) +hw_status hw_mmu_event_status(const void __iomem *base_address, u32 *irq_mask) { hw_status status = 0; @@ -220,7 +245,7 @@ hw_status hw_mmu_event_status(void __iomem *base_address, u32 *irq_mask) return status; } -hw_status hw_mmu_fault_addr_read(void __iomem *base_address, u32 *addr) +hw_status hw_mmu_fault_addr_read(const void __iomem *base_address, u32 *addr) { hw_status status = 0; @@ -230,7 +255,7 @@ hw_status hw_mmu_fault_addr_read(void __iomem *base_address, u32 *addr) return status; } -hw_status hw_mmu_ttb_set(void __iomem *base_address, u32 ttb_phys_addr) +hw_status hw_mmu_ttb_set(const void __iomem *base_address, u32 ttb_phys_addr) { hw_status status = 0; u32 load_ttb; @@ -242,7 +267,7 @@ hw_status hw_mmu_ttb_set(void __iomem *base_address, u32 ttb_phys_addr) return status; } -hw_status hw_mmu_twl_enable(void __iomem *base_address) +hw_status hw_mmu_twl_enable(const void __iomem *base_address) { hw_status status = 0; @@ -251,7 +276,7 @@ hw_status hw_mmu_twl_enable(void __iomem *base_address) return status; } -hw_status hw_mmu_twl_disable(void __iomem *base_address) +hw_status hw_mmu_twl_disable(const void __iomem *base_address) { hw_status status = 0; @@ -260,7 +285,45 @@ hw_status hw_mmu_twl_disable(void __iomem *base_address) return status; } -hw_status hw_mmu_tlb_add(void __iomem *base_address, +hw_status hw_mmu_tlb_flush(const void __iomem *base_address, u32 virtual_addr, + u32 page_sz) +{ + hw_status status = 0; + u32 virtual_addr_tag; + enum hw_mmu_page_size_t pg_size_bits; + + switch (page_sz) { + case HW_PAGE_SIZE4KB: + pg_size_bits = HW_MMU_SMALL_PAGE; + break; + + case HW_PAGE_SIZE64KB: + pg_size_bits = HW_MMU_LARGE_PAGE; + break; + + case HW_PAGE_SIZE1MB: + pg_size_bits = HW_MMU_SECTION; + break; + + case HW_PAGE_SIZE16MB: + pg_size_bits = HW_MMU_SUPERSECTION; + break; + + default: + return -EINVAL; + } + + /* Generate the 20-bit tag from virtual address */ + virtual_addr_tag = ((virtual_addr & MMU_ADDR_MASK) >> 12); + + mmu_set_cam_entry(base_address, pg_size_bits, 0, 0, virtual_addr_tag); + + mmu_flush_entry(base_address); + + return status; +} + +hw_status hw_mmu_tlb_add(const void __iomem *base_address, u32 physical_addr, u32 virtual_addr, u32 page_sz, @@ -440,8 +503,20 @@ hw_status hw_mmu_pte_clear(const u32 pg_tbl_va, u32 virtual_addr, u32 page_size) return status; } +/* mmu_flush_entry */ +static hw_status mmu_flush_entry(const void __iomem *base_address) +{ + hw_status status = 0; + u32 flush_entry_data = 0x1; + + /* write values to register */ + MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32(base_address, flush_entry_data); + + return status; +} + /* mmu_set_cam_entry */ -static hw_status mmu_set_cam_entry(void __iomem *base_address, +static hw_status mmu_set_cam_entry(const void __iomem *base_address, const u32 page_sz, const u32 preserved_bit, const u32 valid_bit, @@ -461,7 +536,7 @@ static hw_status mmu_set_cam_entry(void __iomem *base_address, } /* mmu_set_ram_entry */ -static hw_status mmu_set_ram_entry(void __iomem *base_address, +static hw_status mmu_set_ram_entry(const void __iomem *base_address, const u32 physical_addr, enum hw_endianism_t endianism, enum hw_element_size_t element_size, @@ -481,7 +556,7 @@ static hw_status mmu_set_ram_entry(void __iomem *base_address, } -void hw_mmu_tlb_flush_all(void __iomem *base) +void hw_mmu_tlb_flush_all(const void __iomem *base) { __raw_writel(1, base + MMU_GFLUSH); } diff --git a/trunk/drivers/staging/tidspbridge/hw/hw_mmu.h b/trunk/drivers/staging/tidspbridge/hw/hw_mmu.h index 1c50bb36edfe..1458a2c6027b 100644 --- a/trunk/drivers/staging/tidspbridge/hw/hw_mmu.h +++ b/trunk/drivers/staging/tidspbridge/hw/hw_mmu.h @@ -42,41 +42,44 @@ struct hw_mmu_map_attrs_t { bool donotlockmpupage; }; -extern hw_status hw_mmu_enable(void __iomem *base_address); +extern hw_status hw_mmu_enable(const void __iomem *base_address); -extern hw_status hw_mmu_disable(void __iomem *base_address); +extern hw_status hw_mmu_disable(const void __iomem *base_address); -extern hw_status hw_mmu_num_locked_set(void __iomem *base_address, +extern hw_status hw_mmu_num_locked_set(const void __iomem *base_address, u32 num_locked_entries); -extern hw_status hw_mmu_victim_num_set(void __iomem *base_address, +extern hw_status hw_mmu_victim_num_set(const void __iomem *base_address, u32 victim_entry_num); /* For MMU faults */ -extern hw_status hw_mmu_event_ack(void __iomem *base_address, +extern hw_status hw_mmu_event_ack(const void __iomem *base_address, u32 irq_mask); -extern hw_status hw_mmu_event_disable(void __iomem *base_address, +extern hw_status hw_mmu_event_disable(const void __iomem *base_address, u32 irq_mask); -extern hw_status hw_mmu_event_enable(void __iomem *base_address, +extern hw_status hw_mmu_event_enable(const void __iomem *base_address, u32 irq_mask); -extern hw_status hw_mmu_event_status(void __iomem *base_address, +extern hw_status hw_mmu_event_status(const void __iomem *base_address, u32 *irq_mask); -extern hw_status hw_mmu_fault_addr_read(void __iomem *base_address, +extern hw_status hw_mmu_fault_addr_read(const void __iomem *base_address, u32 *addr); /* Set the TT base address */ -extern hw_status hw_mmu_ttb_set(void __iomem *base_address, +extern hw_status hw_mmu_ttb_set(const void __iomem *base_address, u32 ttb_phys_addr); -extern hw_status hw_mmu_twl_enable(void __iomem *base_address); +extern hw_status hw_mmu_twl_enable(const void __iomem *base_address); -extern hw_status hw_mmu_twl_disable(void __iomem *base_address); +extern hw_status hw_mmu_twl_disable(const void __iomem *base_address); -extern hw_status hw_mmu_tlb_add(void __iomem *base_address, +extern hw_status hw_mmu_tlb_flush(const void __iomem *base_address, + u32 virtual_addr, u32 page_sz); + +extern hw_status hw_mmu_tlb_add(const void __iomem *base_address, u32 physical_addr, u32 virtual_addr, u32 page_sz, @@ -94,7 +97,7 @@ extern hw_status hw_mmu_pte_set(const u32 pg_tbl_va, extern hw_status hw_mmu_pte_clear(const u32 pg_tbl_va, u32 virtual_addr, u32 page_size); -void hw_mmu_tlb_flush_all(void __iomem *base); +void hw_mmu_tlb_flush_all(const void __iomem *base); static inline u32 hw_mmu_pte_addr_l1(u32 l1_base, u32 va) { diff --git a/trunk/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h b/trunk/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h index b32c75673ab4..60a278136bdf 100644 --- a/trunk/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h +++ b/trunk/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h @@ -53,8 +53,8 @@ struct cfg_hostres { u32 chnl_buf_size; u32 num_chnls; void __iomem *per_base; - void __iomem *per_pm_base; - void __iomem *core_pm_base; + u32 per_pm_base; + u32 core_pm_base; void __iomem *dmmu_base; }; diff --git a/trunk/drivers/staging/tidspbridge/include/dspbridge/host_os.h b/trunk/drivers/staging/tidspbridge/include/dspbridge/host_os.h index 5e2f4d82d925..ed00d3da3205 100644 --- a/trunk/drivers/staging/tidspbridge/include/dspbridge/host_os.h +++ b/trunk/drivers/staging/tidspbridge/include/dspbridge/host_os.h @@ -47,8 +47,8 @@ #include #include -/* TODO -- Remove, once omap-iommu is used */ -#define INT_DSP_MMU_IRQ (28 + NR_IRQS) +/* TODO -- Remove, once BP defines them */ +#define INT_DSP_MMU_IRQ 28 #define PRCM_VDD1 1 diff --git a/trunk/drivers/staging/tidspbridge/rmgr/drv.c b/trunk/drivers/staging/tidspbridge/rmgr/drv.c index db1da28cecba..6795205b0155 100644 --- a/trunk/drivers/staging/tidspbridge/rmgr/drv.c +++ b/trunk/drivers/staging/tidspbridge/rmgr/drv.c @@ -667,10 +667,10 @@ int drv_request_bridge_res_dsp(void **phost_resources) OMAP_DSP_MEM3_SIZE); host_res->per_base = ioremap(OMAP_PER_CM_BASE, OMAP_PER_CM_SIZE); - host_res->per_pm_base = ioremap(OMAP_PER_PRM_BASE, - OMAP_PER_PRM_SIZE); - host_res->core_pm_base = ioremap(OMAP_CORE_PRM_BASE, - OMAP_CORE_PRM_SIZE); + host_res->per_pm_base = (u32) ioremap(OMAP_PER_PRM_BASE, + OMAP_PER_PRM_SIZE); + host_res->core_pm_base = (u32) ioremap(OMAP_CORE_PRM_BASE, + OMAP_CORE_PRM_SIZE); host_res->dmmu_base = ioremap(OMAP_DMMU_BASE, OMAP_DMMU_SIZE); diff --git a/trunk/drivers/staging/tidspbridge/rmgr/node.c b/trunk/drivers/staging/tidspbridge/rmgr/node.c index 294e9b40f516..c2fc6137c770 100644 --- a/trunk/drivers/staging/tidspbridge/rmgr/node.c +++ b/trunk/drivers/staging/tidspbridge/rmgr/node.c @@ -304,7 +304,8 @@ int node_allocate(struct proc_object *hprocessor, u32 pul_value; u32 dynext_base; u32 off_set = 0; - u32 ul_stack_seg_val; + u32 ul_stack_seg_addr, ul_stack_seg_val; + u32 ul_gpp_mem_base; struct cfg_hostres *host_res; struct bridge_dev_context *pbridge_context; u32 mapped_addr = 0; @@ -580,9 +581,6 @@ int node_allocate(struct proc_object *hprocessor, if (strcmp((char *) pnode->dcd_props.obj_data.node_obj.ndb_props. stack_seg_name, STACKSEGLABEL) == 0) { - void __iomem *stack_seg; - u32 stack_seg_pa; - status = hnode_mgr->nldr_fxns. get_fxn_addr(pnode->nldr_node_obj, "DYNEXT_BEG", @@ -610,21 +608,14 @@ int node_allocate(struct proc_object *hprocessor, goto func_end; } + ul_gpp_mem_base = (u32) host_res->mem_base[1]; off_set = pul_value - dynext_base; - stack_seg_pa = host_res->mem_phys[1] + off_set; - stack_seg = ioremap(stack_seg_pa, SZ_32); - if (!stack_seg) { - status = -ENOMEM; - goto func_end; - } - - ul_stack_seg_val = readl(stack_seg); - - iounmap(stack_seg); + ul_stack_seg_addr = ul_gpp_mem_base + off_set; + ul_stack_seg_val = readl(ul_stack_seg_addr); dev_dbg(bridge, "%s: StackSegVal = 0x%x, StackSegAddr =" " 0x%x\n", __func__, ul_stack_seg_val, - host_res->mem_base[1] + off_set); + ul_stack_seg_addr); pnode->create_args.asa.task_arg_obj.stack_seg = ul_stack_seg_val; diff --git a/trunk/drivers/staging/zram/zram_drv.c b/trunk/drivers/staging/zram/zram_drv.c index 6edefde23722..653b074035f7 100644 --- a/trunk/drivers/staging/zram/zram_drv.c +++ b/trunk/drivers/staging/zram/zram_drv.c @@ -223,13 +223,8 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, cmem = zs_map_object(zram->mem_pool, zram->table[index].handle, ZS_MM_RO); - if (zram->table[index].size == PAGE_SIZE) { - memcpy(uncmem, cmem, PAGE_SIZE); - ret = LZO_E_OK; - } else { - ret = lzo1x_decompress_safe(cmem, zram->table[index].size, + ret = lzo1x_decompress_safe(cmem, zram->table[index].size, uncmem, &clen); - } if (is_partial_io(bvec)) { memcpy(user_mem + bvec->bv_offset, uncmem + offset, @@ -347,11 +342,8 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, goto out; } - if (unlikely(clen > max_zpage_size)) { + if (unlikely(clen > max_zpage_size)) zram_stat_inc(&zram->stats.bad_compress); - src = uncmem; - clen = PAGE_SIZE; - } handle = zs_malloc(zram->mem_pool, clen); if (!handle) { diff --git a/trunk/drivers/target/iscsi/iscsi_target.c b/trunk/drivers/target/iscsi/iscsi_target.c index 035c2c762537..d6ce2182e672 100644 --- a/trunk/drivers/target/iscsi/iscsi_target.c +++ b/trunk/drivers/target/iscsi/iscsi_target.c @@ -3719,9 +3719,7 @@ int iscsi_target_tx_thread(void *arg) */ iscsit_thread_check_cpumask(conn, current, 1); - wait_event_interruptible(conn->queues_wq, - !iscsit_conn_all_queues_empty(conn) || - ts->status == ISCSI_THREAD_SET_RESET); + schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT); if ((ts->status == ISCSI_THREAD_SET_RESET) || signal_pending(current)) diff --git a/trunk/drivers/target/iscsi/iscsi_target_core.h b/trunk/drivers/target/iscsi/iscsi_target_core.h index 21048dbf7d13..2ba9f9b9435c 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_core.h +++ b/trunk/drivers/target/iscsi/iscsi_target_core.h @@ -486,7 +486,6 @@ struct iscsi_tmr_req { }; struct iscsi_conn { - wait_queue_head_t queues_wq; /* Authentication Successful for this connection */ u8 auth_complete; /* State connection is currently in */ diff --git a/trunk/drivers/target/iscsi/iscsi_target_login.c b/trunk/drivers/target/iscsi/iscsi_target_login.c index f8dbec05d5e5..cdc8a10939c3 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_login.c +++ b/trunk/drivers/target/iscsi/iscsi_target_login.c @@ -41,7 +41,6 @@ static int iscsi_login_init_conn(struct iscsi_conn *conn) { - init_waitqueue_head(&conn->queues_wq); INIT_LIST_HEAD(&conn->conn_list); INIT_LIST_HEAD(&conn->conn_cmd_list); INIT_LIST_HEAD(&conn->immed_queue_list); diff --git a/trunk/drivers/target/iscsi/iscsi_target_util.c b/trunk/drivers/target/iscsi/iscsi_target_util.c index 1a91195ab619..afd98ccd40ae 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_util.c +++ b/trunk/drivers/target/iscsi/iscsi_target_util.c @@ -488,7 +488,7 @@ void iscsit_add_cmd_to_immediate_queue( atomic_set(&conn->check_immediate_queue, 1); spin_unlock_bh(&conn->immed_queue_lock); - wake_up(&conn->queues_wq); + wake_up_process(conn->thread_set->tx_thread); } struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *conn) @@ -562,7 +562,7 @@ void iscsit_add_cmd_to_response_queue( atomic_inc(&cmd->response_queue_count); spin_unlock_bh(&conn->response_queue_lock); - wake_up(&conn->queues_wq); + wake_up_process(conn->thread_set->tx_thread); } struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *conn) @@ -616,24 +616,6 @@ static void iscsit_remove_cmd_from_response_queue( } } -bool iscsit_conn_all_queues_empty(struct iscsi_conn *conn) -{ - bool empty; - - spin_lock_bh(&conn->immed_queue_lock); - empty = list_empty(&conn->immed_queue_list); - spin_unlock_bh(&conn->immed_queue_lock); - - if (!empty) - return empty; - - spin_lock_bh(&conn->response_queue_lock); - empty = list_empty(&conn->response_queue_list); - spin_unlock_bh(&conn->response_queue_lock); - - return empty; -} - void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn) { struct iscsi_queue_req *qr, *qr_tmp; diff --git a/trunk/drivers/target/iscsi/iscsi_target_util.h b/trunk/drivers/target/iscsi/iscsi_target_util.h index 894d0f837924..44054bd35437 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_util.h +++ b/trunk/drivers/target/iscsi/iscsi_target_util.h @@ -25,7 +25,6 @@ extern struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_ extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8); extern struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *); extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_conn *); -extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *); extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *); extern void iscsit_release_cmd(struct iscsi_cmd *); extern void iscsit_free_cmd(struct iscsi_cmd *); diff --git a/trunk/drivers/target/target_core_configfs.c b/trunk/drivers/target/target_core_configfs.c index c123327499a3..015f5be27bf6 100644 --- a/trunk/drivers/target/target_core_configfs.c +++ b/trunk/drivers/target/target_core_configfs.c @@ -3206,8 +3206,7 @@ static int __init target_core_init_configfs(void) if (ret < 0) goto out; - ret = core_dev_setup_virtual_lun0(); - if (ret < 0) + if (core_dev_setup_virtual_lun0() < 0) goto out; return 0; diff --git a/trunk/drivers/target/target_core_device.c b/trunk/drivers/target/target_core_device.c index 9abef9f8eb76..8d774da16320 100644 --- a/trunk/drivers/target/target_core_device.c +++ b/trunk/drivers/target/target_core_device.c @@ -850,20 +850,20 @@ int se_dev_check_shutdown(struct se_device *dev) static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) { - u32 aligned_max_sectors; - u32 alignment; + u32 tmp, aligned_max_sectors; /* * Limit max_sectors to a PAGE_SIZE aligned value for modern * transport_allocate_data_tasks() operation. */ - alignment = max(1ul, PAGE_SIZE / block_size); - aligned_max_sectors = rounddown(max_sectors, alignment); - - if (max_sectors != aligned_max_sectors) - pr_info("Rounding down aligned max_sectors from %u to %u\n", - max_sectors, aligned_max_sectors); + tmp = rounddown((max_sectors * block_size), PAGE_SIZE); + aligned_max_sectors = (tmp / block_size); + if (max_sectors != aligned_max_sectors) { + printk(KERN_INFO "Rounding down aligned max_sectors from %u" + " to %u\n", max_sectors, aligned_max_sectors); + return aligned_max_sectors; + } - return aligned_max_sectors; + return max_sectors; } void se_dev_set_default_attribs( diff --git a/trunk/drivers/target/target_core_sbc.c b/trunk/drivers/target/target_core_sbc.c index a6e27d967c7b..868f8aa04f13 100644 --- a/trunk/drivers/target/target_core_sbc.c +++ b/trunk/drivers/target/target_core_sbc.c @@ -135,12 +135,6 @@ static int sbc_emulate_verify(struct se_cmd *cmd) return 0; } -static int sbc_emulate_noop(struct se_cmd *cmd) -{ - target_complete_cmd(cmd, GOOD); - return 0; -} - static inline u32 sbc_get_size(struct se_cmd *cmd, u32 sectors) { return cmd->se_dev->se_sub_dev->se_dev_attrib.block_size * sectors; @@ -537,18 +531,6 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) size = 0; cmd->execute_cmd = sbc_emulate_verify; break; - case REZERO_UNIT: - case SEEK_6: - case SEEK_10: - /* - * There are still clients out there which use these old SCSI-2 - * commands. This mainly happens when running VMs with legacy - * guest systems, connected via SCSI command pass-through to - * iSCSI targets. Make them happy and return status GOOD. - */ - size = 0; - cmd->execute_cmd = sbc_emulate_noop; - break; default: ret = spc_parse_cdb(cmd, &size); if (ret) diff --git a/trunk/drivers/target/target_core_spc.c b/trunk/drivers/target/target_core_spc.c index 6fd434d3d7e4..9229bd9ad61b 100644 --- a/trunk/drivers/target/target_core_spc.c +++ b/trunk/drivers/target/target_core_spc.c @@ -605,8 +605,6 @@ static int spc_emulate_inquiry(struct se_cmd *cmd) unsigned char buf[SE_INQUIRY_BUF]; int p, ret; - memset(buf, 0, SE_INQUIRY_BUF); - if (dev == tpg->tpg_virt_lun0.lun_se_dev) buf[0] = 0x3f; /* Not connected */ else diff --git a/trunk/drivers/target/target_core_tmr.c b/trunk/drivers/target/target_core_tmr.c index be75c4331a92..1c59a3c23b2c 100644 --- a/trunk/drivers/target/target_core_tmr.c +++ b/trunk/drivers/target/target_core_tmr.c @@ -140,15 +140,15 @@ void core_tmr_abort_task( printk("ABORT_TASK: Found referenced %s task_tag: %u\n", se_cmd->se_tfo->get_fabric_name(), ref_tag); - spin_lock(&se_cmd->t_state_lock); + spin_lock_irq(&se_cmd->t_state_lock); if (se_cmd->transport_state & CMD_T_COMPLETE) { printk("ABORT_TASK: ref_tag: %u already complete, skipping\n", ref_tag); - spin_unlock(&se_cmd->t_state_lock); + spin_unlock_irq(&se_cmd->t_state_lock); spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); goto out; } se_cmd->transport_state |= CMD_T_ABORTED; - spin_unlock(&se_cmd->t_state_lock); + spin_unlock_irq(&se_cmd->t_state_lock); list_del_init(&se_cmd->se_cmd_list); kref_get(&se_cmd->cmd_kref); diff --git a/trunk/drivers/target/target_core_transport.c b/trunk/drivers/target/target_core_transport.c index dcecbfb17243..c33baff86aa6 100644 --- a/trunk/drivers/target/target_core_transport.c +++ b/trunk/drivers/target/target_core_transport.c @@ -1616,6 +1616,7 @@ static void target_complete_tmr_failure(struct work_struct *work) se_cmd->se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST; se_cmd->se_tfo->queue_tm_rsp(se_cmd); + transport_generic_free_cmd(se_cmd, 0); } /** @@ -1819,10 +1820,8 @@ void target_execute_cmd(struct se_cmd *cmd) /* * If the received CDB has aleady been aborted stop processing it here. */ - if (transport_check_aborted_status(cmd, 1)) { - complete(&cmd->t_transport_stop_comp); + if (transport_check_aborted_status(cmd, 1)) return; - } /* * Determine if IOCTL context caller in requesting the stopping of this @@ -3069,7 +3068,7 @@ void transport_send_task_abort(struct se_cmd *cmd) unsigned long flags; spin_lock_irqsave(&cmd->t_state_lock, flags); - if (cmd->se_cmd_flags & (SCF_SENT_CHECK_CONDITION | SCF_SENT_DELAYED_TAS)) { + if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) { spin_unlock_irqrestore(&cmd->t_state_lock, flags); return; } diff --git a/trunk/drivers/thermal/exynos_thermal.c b/trunk/drivers/thermal/exynos_thermal.c index 6dd29e4ce36b..fd03e8581afc 100644 --- a/trunk/drivers/thermal/exynos_thermal.c +++ b/trunk/drivers/thermal/exynos_thermal.c @@ -815,7 +815,7 @@ static struct platform_device_id exynos_tmu_driver_ids[] = { }, { }, }; -MODULE_DEVICE_TABLE(platform, exynos_tmu_driver_ids); +MODULE_DEVICE_TABLE(platform, exynos4_tmu_driver_ids); static inline struct exynos_tmu_platform_data *exynos_get_driver_data( struct platform_device *pdev) diff --git a/trunk/drivers/thermal/rcar_thermal.c b/trunk/drivers/thermal/rcar_thermal.c index f7a1b574a304..d4452716aaab 100644 --- a/trunk/drivers/thermal/rcar_thermal.c +++ b/trunk/drivers/thermal/rcar_thermal.c @@ -210,7 +210,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) goto error_free_priv; } - zone = thermal_zone_device_register("rcar_thermal", 0, 0, priv, + zone = thermal_zone_device_register("rcar_thermal", 0, priv, &rcar_thermal_zone_ops, 0, 0); if (IS_ERR(zone)) { dev_err(&pdev->dev, "thermal zone device is NULL\n"); diff --git a/trunk/drivers/tty/hvc/hvc_console.c b/trunk/drivers/tty/hvc/hvc_console.c index 13ee53bd0bf6..a5dec1ca1b82 100644 --- a/trunk/drivers/tty/hvc/hvc_console.c +++ b/trunk/drivers/tty/hvc/hvc_console.c @@ -424,6 +424,7 @@ static void hvc_hangup(struct tty_struct *tty) { struct hvc_struct *hp = tty->driver_data; unsigned long flags; + int temp_open_count; if (!hp) return; @@ -443,6 +444,7 @@ static void hvc_hangup(struct tty_struct *tty) return; } + temp_open_count = hp->port.count; hp->port.count = 0; spin_unlock_irqrestore(&hp->port.lock, flags); tty_port_tty_set(&hp->port, NULL); @@ -451,6 +453,11 @@ static void hvc_hangup(struct tty_struct *tty) if (hp->ops->notifier_hangup) hp->ops->notifier_hangup(hp, hp->data); + + while(temp_open_count) { + --temp_open_count; + tty_port_put(&hp->port); + } } /* diff --git a/trunk/drivers/tty/serial/atmel_serial.c b/trunk/drivers/tty/serial/atmel_serial.c index 65f891be12d1..3d7e1ee2fa57 100644 --- a/trunk/drivers/tty/serial/atmel_serial.c +++ b/trunk/drivers/tty/serial/atmel_serial.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include @@ -1774,7 +1773,6 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev) struct atmel_uart_data *pdata = pdev->dev.platform_data; void *data; int ret = -ENODEV; - struct pinctrl *pinctrl; BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1)); @@ -1807,12 +1805,6 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev) atmel_init_port(port, pdev); - pinctrl = devm_pinctrl_get_select_default(&pdev->dev); - if (IS_ERR(pinctrl)) { - ret = PTR_ERR(pinctrl); - goto err; - } - if (!atmel_use_dma_rx(&port->uart)) { ret = -ENOMEM; data = kmalloc(sizeof(struct atmel_uart_char) diff --git a/trunk/drivers/tty/serial/max310x.c b/trunk/drivers/tty/serial/max310x.c index 1ab1d2c66de4..2bc28a59d385 100644 --- a/trunk/drivers/tty/serial/max310x.c +++ b/trunk/drivers/tty/serial/max310x.c @@ -1239,7 +1239,6 @@ static int __devexit max310x_remove(struct spi_device *spi) static const struct spi_device_id max310x_id_table[] = { { "max3107", MAX310X_TYPE_MAX3107 }, { "max3108", MAX310X_TYPE_MAX3108 }, - { } }; MODULE_DEVICE_TABLE(spi, max310x_id_table); diff --git a/trunk/drivers/tty/serial/omap-serial.c b/trunk/drivers/tty/serial/omap-serial.c index 6d3d26a607b9..6ede6fd92b4c 100644 --- a/trunk/drivers/tty/serial/omap-serial.c +++ b/trunk/drivers/tty/serial/omap-serial.c @@ -671,19 +671,19 @@ serial_omap_configure_xonxoff /* * IXON Flag: - * Enable XON/XOFF flow control on output. - * Transmit XON1, XOFF1 + * Flow control for OMAP.TX + * OMAP.RX should listen for XON/XOFF */ if (termios->c_iflag & IXON) - up->efr |= OMAP_UART_SW_TX; + up->efr |= OMAP_UART_SW_RX; /* * IXOFF Flag: - * Enable XON/XOFF flow control on input. - * Receiver compares XON1, XOFF1. + * Flow control for OMAP.RX + * OMAP.TX should send XON/XOFF */ if (termios->c_iflag & IXOFF) - up->efr |= OMAP_UART_SW_RX; + up->efr |= OMAP_UART_SW_TX; serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); diff --git a/trunk/drivers/tty/vt/vt.c b/trunk/drivers/tty/vt/vt.c index 4e0d0c3734b3..f87d7e8964bf 100644 --- a/trunk/drivers/tty/vt/vt.c +++ b/trunk/drivers/tty/vt/vt.c @@ -539,25 +539,25 @@ static void insert_char(struct vc_data *vc, unsigned int nr) { unsigned short *p = (unsigned short *) vc->vc_pos; - scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x) * 2); + scr_memmovew(p + nr, p, vc->vc_cols - vc->vc_x); scr_memsetw(p, vc->vc_video_erase_char, nr * 2); vc->vc_need_wrap = 0; if (DO_UPDATE(vc)) do_update_region(vc, (unsigned long) p, - vc->vc_cols - vc->vc_x); + (vc->vc_cols - vc->vc_x) / 2 + 1); } static void delete_char(struct vc_data *vc, unsigned int nr) { unsigned short *p = (unsigned short *) vc->vc_pos; - scr_memcpyw(p, p + nr, (vc->vc_cols - vc->vc_x - nr) * 2); + scr_memcpyw(p, p + nr, vc->vc_cols - vc->vc_x - nr); scr_memsetw(p + vc->vc_cols - vc->vc_x - nr, vc->vc_video_erase_char, nr * 2); vc->vc_need_wrap = 0; if (DO_UPDATE(vc)) do_update_region(vc, (unsigned long) p, - vc->vc_cols - vc->vc_x); + (vc->vc_cols - vc->vc_x) / 2); } static int softcursor_original; diff --git a/trunk/drivers/usb/core/hcd.c b/trunk/drivers/usb/core/hcd.c index f034716190ff..1e741bca0265 100644 --- a/trunk/drivers/usb/core/hcd.c +++ b/trunk/drivers/usb/core/hcd.c @@ -2151,15 +2151,8 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum); irqreturn_t usb_hcd_irq (int irq, void *__hcd) { struct usb_hcd *hcd = __hcd; - unsigned long flags; irqreturn_t rc; - /* IRQF_DISABLED doesn't work correctly with shared IRQs - * when the first handler doesn't use it. So let's just - * assume it's never used. - */ - local_irq_save(flags); - if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd))) rc = IRQ_NONE; else if (hcd->driver->irq(hcd) == IRQ_NONE) @@ -2167,7 +2160,6 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd) else rc = IRQ_HANDLED; - local_irq_restore(flags); return rc; } EXPORT_SYMBOL_GPL(usb_hcd_irq); @@ -2355,14 +2347,6 @@ static int usb_hcd_request_irqs(struct usb_hcd *hcd, int retval; if (hcd->driver->irq) { - - /* IRQF_DISABLED doesn't work as advertised when used together - * with IRQF_SHARED. As usb_hcd_irq() will always disable - * interrupts we can remove it here. - */ - if (irqflags & IRQF_SHARED) - irqflags &= ~IRQF_DISABLED; - snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", hcd->driver->description, hcd->self.busnum); retval = request_irq(irqnum, &usb_hcd_irq, irqflags, diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index 1af04bdeaf0c..64854d76f529 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -739,16 +739,13 @@ static void hub_tt_work(struct work_struct *work) int limit = 100; spin_lock_irqsave (&hub->tt.lock, flags); - while (!list_empty(&hub->tt.clear_list)) { + while (--limit && !list_empty (&hub->tt.clear_list)) { struct list_head *next; struct usb_tt_clear *clear; struct usb_device *hdev = hub->hdev; const struct hc_driver *drv; int status; - if (!hub->quiescing && --limit < 0) - break; - next = hub->tt.clear_list.next; clear = list_entry (next, struct usb_tt_clear, clear_list); list_del (&clear->clear_list); @@ -1213,7 +1210,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) if (hub->has_indicators) cancel_delayed_work_sync(&hub->leds); if (hub->tt.hub) - flush_work(&hub->tt.clear_work); + cancel_work_sync(&hub->tt.clear_work); } /* caller has locked the hub device */ diff --git a/trunk/drivers/usb/early/ehci-dbgp.c b/trunk/drivers/usb/early/ehci-dbgp.c index 4bfa78af379c..e426ad626d74 100644 --- a/trunk/drivers/usb/early/ehci-dbgp.c +++ b/trunk/drivers/usb/early/ehci-dbgp.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -615,6 +614,12 @@ static int _dbgp_external_startup(void) return -ENODEV; } +int dbgp_external_startup(struct usb_hcd *hcd) +{ + return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup(); +} +EXPORT_SYMBOL_GPL(dbgp_external_startup); + static int ehci_reset_port(int port) { u32 portsc; @@ -974,7 +979,6 @@ struct console early_dbgp_console = { .index = -1, }; -#if IS_ENABLED(CONFIG_USB_EHCI_HCD) int dbgp_reset_prep(struct usb_hcd *hcd) { int ret = xen_dbgp_reset_prep(hcd); @@ -1003,13 +1007,6 @@ int dbgp_reset_prep(struct usb_hcd *hcd) } EXPORT_SYMBOL_GPL(dbgp_reset_prep); -int dbgp_external_startup(struct usb_hcd *hcd) -{ - return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup(); -} -EXPORT_SYMBOL_GPL(dbgp_external_startup); -#endif /* USB_EHCI_HCD */ - #ifdef CONFIG_KGDB static char kgdbdbgp_buf[DBGP_MAX_PACKET]; diff --git a/trunk/drivers/usb/gadget/net2272.c b/trunk/drivers/usb/gadget/net2272.c index c009263a47e3..43ac7482fa91 100644 --- a/trunk/drivers/usb/gadget/net2272.c +++ b/trunk/drivers/usb/gadget/net2272.c @@ -2069,10 +2069,8 @@ static irqreturn_t net2272_irq(int irq, void *_dev) #if defined(PLX_PCI_RDK2) /* see if PCI int for us by checking irqstat */ intcsr = readl(dev->rdk2.fpga_base_addr + RDK2_IRQSTAT); - if (!intcsr & (1 << NET2272_PCI_IRQ)) { - spin_unlock(&dev->lock); + if (!intcsr & (1 << NET2272_PCI_IRQ)) return IRQ_NONE; - } /* check dma interrupts */ #endif /* Platform/devcice interrupt handler */ diff --git a/trunk/drivers/usb/gadget/u_ether.c b/trunk/drivers/usb/gadget/u_ether.c index 4ec3c0d7a18b..6458764994ef 100644 --- a/trunk/drivers/usb/gadget/u_ether.c +++ b/trunk/drivers/usb/gadget/u_ether.c @@ -20,7 +20,6 @@ #include #include #include -#include #include "u_ether.h" @@ -296,7 +295,7 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) while (skb2) { if (status < 0 || ETH_HLEN > skb2->len - || skb2->len > VLAN_ETH_FRAME_LEN) { + || skb2->len > ETH_FRAME_LEN) { dev->net->stats.rx_errors++; dev->net->stats.rx_length_errors++; DBG(dev, "rx length %d\n", skb2->len); diff --git a/trunk/drivers/usb/host/ehci-ls1x.c b/trunk/drivers/usb/host/ehci-ls1x.c index aa0f328922df..ca759652626b 100644 --- a/trunk/drivers/usb/host/ehci-ls1x.c +++ b/trunk/drivers/usb/host/ehci-ls1x.c @@ -113,7 +113,7 @@ static int ehci_hcd_ls1x_probe(struct platform_device *pdev) goto err_put_hcd; } - ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); + ret = usb_add_hcd(hcd, irq, IRQF_SHARED); if (ret) goto err_put_hcd; diff --git a/trunk/drivers/usb/host/ohci-xls.c b/trunk/drivers/usb/host/ohci-xls.c index 41e378f17c66..84201cd1a472 100644 --- a/trunk/drivers/usb/host/ohci-xls.c +++ b/trunk/drivers/usb/host/ohci-xls.c @@ -56,7 +56,7 @@ static int ohci_xls_probe_internal(const struct hc_driver *driver, goto err3; } - retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); + retval = usb_add_hcd(hcd, irq, IRQF_SHARED); if (retval != 0) goto err4; return retval; diff --git a/trunk/drivers/usb/host/pci-quirks.c b/trunk/drivers/usb/host/pci-quirks.c index 39f9e4a9a2d3..966d1484ee79 100644 --- a/trunk/drivers/usb/host/pci-quirks.c +++ b/trunk/drivers/usb/host/pci-quirks.c @@ -545,14 +545,7 @@ static const struct dmi_system_id __devinitconst ehci_dmi_nohandoff_table[] = { /* Pegatron Lucid (Ordissimo AIRIS) */ .matches = { DMI_MATCH(DMI_BOARD_NAME, "M11JB"), - DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"), - }, - }, - { - /* Pegatron Lucid (Ordissimo) */ - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "Ordissimo"), - DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"), + DMI_MATCH(DMI_BIOS_VERSION, "Lucid-GE-133"), }, }, { } diff --git a/trunk/drivers/usb/host/xhci-dbg.c b/trunk/drivers/usb/host/xhci-dbg.c index 5f3a7c74aa8d..4b436f5a4171 100644 --- a/trunk/drivers/usb/host/xhci-dbg.c +++ b/trunk/drivers/usb/host/xhci-dbg.c @@ -544,6 +544,7 @@ void xhci_dbg_ctx(struct xhci_hcd *xhci, int i; /* Fields are 32 bits wide, DMA addresses are in bytes */ int field_size = 32 / 8; + struct xhci_slot_ctx *slot_ctx; dma_addr_t dma = ctx->dma; int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params); @@ -569,6 +570,7 @@ void xhci_dbg_ctx(struct xhci_hcd *xhci, dbg_rsvd64(xhci, (u64 *)ctrl_ctx, dma); } + slot_ctx = xhci_get_slot_ctx(xhci, ctx); xhci_dbg_slot_ctx(xhci, ctx); xhci_dbg_ep_ctx(xhci, ctx, last_ep); } diff --git a/trunk/drivers/usb/host/xhci-hub.c b/trunk/drivers/usb/host/xhci-hub.c index a686cf4905bb..aa90ad4d4fd5 100644 --- a/trunk/drivers/usb/host/xhci-hub.c +++ b/trunk/drivers/usb/host/xhci-hub.c @@ -151,8 +151,9 @@ static void xhci_usb3_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci, if (portsc & PORT_DEV_REMOVE) port_removable |= 1 << (i + 1); } - - desc->u.ss.DeviceRemovable = cpu_to_le16(port_removable); + memset(&desc->u.ss.DeviceRemovable, + (__force __u16) cpu_to_le16(port_removable), + sizeof(__u16)); } static void xhci_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci, @@ -808,13 +809,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, temp = xhci_readl(xhci, port_array[wIndex]); xhci_dbg(xhci, "set port power, actual port %d status = 0x%x\n", wIndex, temp); - spin_unlock_irqrestore(&xhci->lock, flags); temp = usb_acpi_power_manageable(hcd->self.root_hub, wIndex); if (temp) usb_acpi_set_power_state(hcd->self.root_hub, wIndex, true); - spin_lock_irqsave(&xhci->lock, flags); break; case USB_PORT_FEAT_RESET: temp = (temp | PORT_RESET); @@ -918,13 +917,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, xhci_writel(xhci, temp & ~PORT_POWER, port_array[wIndex]); - spin_unlock_irqrestore(&xhci->lock, flags); temp = usb_acpi_power_manageable(hcd->self.root_hub, wIndex); if (temp) usb_acpi_set_power_state(hcd->self.root_hub, wIndex, false); - spin_lock_irqsave(&xhci->lock, flags); break; default: goto error; diff --git a/trunk/drivers/usb/host/xhci-ring.c b/trunk/drivers/usb/host/xhci-ring.c index 4e1a8946b8d1..c6ebb176dc4f 100644 --- a/trunk/drivers/usb/host/xhci-ring.c +++ b/trunk/drivers/usb/host/xhci-ring.c @@ -1228,17 +1228,6 @@ static void xhci_cmd_to_noop(struct xhci_hcd *xhci, struct xhci_cd *cur_cd) cur_seg = find_trb_seg(xhci->cmd_ring->first_seg, xhci->cmd_ring->dequeue, &cycle_state); - if (!cur_seg) { - xhci_warn(xhci, "Command ring mismatch, dequeue = %p %llx (dma)\n", - xhci->cmd_ring->dequeue, - (unsigned long long) - xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, - xhci->cmd_ring->dequeue)); - xhci_debug_ring(xhci, xhci->cmd_ring); - xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); - return; - } - /* find the command trb matched by cd from command ring */ for (cmd_trb = xhci->cmd_ring->dequeue; cmd_trb != xhci->cmd_ring->enqueue; diff --git a/trunk/drivers/usb/host/xhci.c b/trunk/drivers/usb/host/xhci.c index c9e419f29b74..7d462bf20092 100644 --- a/trunk/drivers/usb/host/xhci.c +++ b/trunk/drivers/usb/host/xhci.c @@ -1627,6 +1627,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct xhci_hcd *xhci; struct xhci_container_ctx *in_ctx, *out_ctx; unsigned int ep_index; + struct xhci_ep_ctx *ep_ctx; struct xhci_slot_ctx *slot_ctx; struct xhci_input_control_ctx *ctrl_ctx; u32 added_ctxs; @@ -1662,6 +1663,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, out_ctx = virt_dev->out_ctx; ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); ep_index = xhci_get_endpoint_index(&ep->desc); + ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); /* If this endpoint is already in use, and the upper layers are trying * to add it again without dropping it, reject the addition. @@ -1815,8 +1817,6 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci, case COMP_EBADSLT: dev_warn(&udev->dev, "WARN: slot not enabled for" "evaluate context command.\n"); - ret = -EINVAL; - break; case COMP_CTX_STATE: dev_warn(&udev->dev, "WARN: invalid context state for " "evaluate context command.\n"); @@ -4021,7 +4021,7 @@ int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev) static unsigned long long xhci_service_interval_to_ns( struct usb_endpoint_descriptor *desc) { - return (1ULL << (desc->bInterval - 1)) * 125 * 1000; + return (1 << (desc->bInterval - 1)) * 125 * 1000; } static u16 xhci_get_timeout_no_hub_lpm(struct usb_device *udev, @@ -4142,7 +4142,7 @@ static u16 xhci_calculate_intel_u2_timeout(struct usb_device *udev, (xhci_service_interval_to_ns(desc) > timeout_ns)) timeout_ns = xhci_service_interval_to_ns(desc); - u2_del_ns = le16_to_cpu(udev->bos->ss_cap->bU2DevExitLat) * 1000ULL; + u2_del_ns = udev->bos->ss_cap->bU2DevExitLat * 1000; if (u2_del_ns > timeout_ns) timeout_ns = u2_del_ns; diff --git a/trunk/drivers/usb/misc/ezusb.c b/trunk/drivers/usb/misc/ezusb.c index 6589268a6515..4223d761223d 100644 --- a/trunk/drivers/usb/misc/ezusb.c +++ b/trunk/drivers/usb/misc/ezusb.c @@ -158,4 +158,3 @@ int ezusb_fx2_ihex_firmware_download(struct usb_device *dev, } EXPORT_SYMBOL_GPL(ezusb_fx2_ihex_firmware_download); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/usb/musb/musb_dsps.c b/trunk/drivers/usb/musb/musb_dsps.c index ff5f112053d2..444346e1e10d 100644 --- a/trunk/drivers/usb/musb/musb_dsps.c +++ b/trunk/drivers/usb/musb/musb_dsps.c @@ -458,11 +458,11 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id) struct platform_device *musb; struct resource *res; struct resource resources[2]; - char res_name[11]; + char res_name[10]; int ret, musbid; /* get memory resource */ - snprintf(res_name, sizeof(res_name), "musb%d", id); + sprintf(res_name, "musb%d", id); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name); if (!res) { dev_err(dev, "%s get mem resource failed\n", res_name); @@ -473,7 +473,7 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id) resources[0] = *res; /* get irq resource */ - snprintf(res_name, sizeof(res_name), "musb%d-irq", id); + sprintf(res_name, "musb%d-irq", id); res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name); if (!res) { dev_err(dev, "%s get irq resource failed\n", res_name); @@ -530,7 +530,7 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id) of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps); of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits); - snprintf(res_name, sizeof(res_name), "port%d-mode", id); + sprintf(res_name, "port%d-mode", id); of_property_read_u32(np, res_name, (u32 *)&pdata->mode); of_property_read_u32(np, "power", (u32 *)&pdata->power); config->multipoint = of_property_read_bool(np, "multipoint"); diff --git a/trunk/drivers/usb/musb/musb_gadget.c b/trunk/drivers/usb/musb/musb_gadget.c index b6b84dacc791..d0b87e7b4abf 100644 --- a/trunk/drivers/usb/musb/musb_gadget.c +++ b/trunk/drivers/usb/musb/musb_gadget.c @@ -707,12 +707,11 @@ static void rxstate(struct musb *musb, struct musb_request *req) fifo_count = musb_readw(epio, MUSB_RXCOUNT); /* - * Enable Mode 1 on RX transfers only when short_not_ok flag - * is set. Currently short_not_ok flag is set only from - * file_storage and f_mass_storage drivers + * use mode 1 only if we expect data of at least ep packet_sz + * and have not yet received a short packet */ - - if (request->short_not_ok && fifo_count == musb_ep->packet_sz) + if ((request->length - request->actual >= musb_ep->packet_sz) && + (fifo_count >= musb_ep->packet_sz)) use_mode_1 = 1; else use_mode_1 = 0; @@ -728,27 +727,6 @@ static void rxstate(struct musb *musb, struct musb_request *req) c = musb->dma_controller; channel = musb_ep->dma; - /* We use DMA Req mode 0 in rx_csr, and DMA controller operates in - * mode 0 only. So we do not get endpoint interrupts due to DMA - * completion. We only get interrupts from DMA controller. - * - * We could operate in DMA mode 1 if we knew the size of the tranfer - * in advance. For mass storage class, request->length = what the host - * sends, so that'd work. But for pretty much everything else, - * request->length is routinely more than what the host sends. For - * most these gadgets, end of is signified either by a short packet, - * or filling the last byte of the buffer. (Sending extra data in - * that last pckate should trigger an overflow fault.) But in mode 1, - * we don't get DMA completion interrupt for short packets. - * - * Theoretically, we could enable DMAReq irq (MUSB_RXCSR_DMAMODE = 1), - * to get endpoint interrupt on every DMA req, but that didn't seem - * to work reliably. - * - * REVISIT an updated g_file_storage can set req->short_not_ok, which - * then becomes usable as a runtime "use mode 1" hint... - */ - /* Experimental: Mode1 works with mass storage use cases */ if (use_mode_1) { csr |= MUSB_RXCSR_AUTOCLEAR; diff --git a/trunk/drivers/usb/musb/ux500.c b/trunk/drivers/usb/musb/ux500.c index 0e62f504410e..d62a91fedc22 100644 --- a/trunk/drivers/usb/musb/ux500.c +++ b/trunk/drivers/usb/musb/ux500.c @@ -65,7 +65,7 @@ static int __devinit ux500_probe(struct platform_device *pdev) struct platform_device *musb; struct ux500_glue *glue; struct clk *clk; - int musbid; + int ret = -ENOMEM; glue = kzalloc(sizeof(*glue), GFP_KERNEL); diff --git a/trunk/drivers/usb/otg/Kconfig b/trunk/drivers/usb/otg/Kconfig index 6223062d5d1b..d8c8a42bff3e 100644 --- a/trunk/drivers/usb/otg/Kconfig +++ b/trunk/drivers/usb/otg/Kconfig @@ -58,7 +58,7 @@ config USB_ULPI_VIEWPORT config TWL4030_USB tristate "TWL4030 USB Transceiver Driver" - depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS + depends on TWL4030_CORE && REGULATOR_TWL4030 select USB_OTG_UTILS help Enable this to support the USB OTG transceiver on TWL4030 @@ -68,7 +68,7 @@ config TWL4030_USB config TWL6030_USB tristate "TWL6030 USB Transceiver Driver" - depends on TWL4030_CORE && OMAP_USB2 && USB_MUSB_OMAP2PLUS + depends on TWL4030_CORE && OMAP_USB2 select USB_OTG_UTILS help Enable this to support the USB OTG transceiver on TWL6030 diff --git a/trunk/drivers/usb/renesas_usbhs/fifo.c b/trunk/drivers/usb/renesas_usbhs/fifo.c index c021b202c0f3..143c4e9e1be4 100644 --- a/trunk/drivers/usb/renesas_usbhs/fifo.c +++ b/trunk/drivers/usb/renesas_usbhs/fifo.c @@ -795,7 +795,6 @@ static void xfer_work(struct work_struct *work) dev_dbg(dev, " %s %d (%d/ %d)\n", fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); - usbhs_pipe_enable(pipe); usbhsf_dma_start(pipe, fifo); dma_async_issue_pending(chan); } diff --git a/trunk/drivers/usb/renesas_usbhs/mod_host.c b/trunk/drivers/usb/renesas_usbhs/mod_host.c index 069cd765400c..9b69a1323294 100644 --- a/trunk/drivers/usb/renesas_usbhs/mod_host.c +++ b/trunk/drivers/usb/renesas_usbhs/mod_host.c @@ -334,11 +334,6 @@ static void usbhsh_pipe_detach(struct usbhsh_hpriv *hpriv, struct device *dev = usbhs_priv_to_dev(priv); unsigned long flags; - if (unlikely(!uep)) { - dev_err(dev, "no uep\n"); - return; - } - /******************** spin lock ********************/ usbhs_lock(priv, flags); diff --git a/trunk/drivers/usb/serial/ch341.c b/trunk/drivers/usb/serial/ch341.c index d255f66e708e..e9c7046ae355 100644 --- a/trunk/drivers/usb/serial/ch341.c +++ b/trunk/drivers/usb/serial/ch341.c @@ -242,11 +242,13 @@ out: kfree(buffer); return r; } -static int ch341_port_probe(struct usb_serial_port *port) +/* allocate private data */ +static int ch341_attach(struct usb_serial *serial) { struct ch341_private *priv; int r; + /* private data */ priv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -256,27 +258,17 @@ static int ch341_port_probe(struct usb_serial_port *port) priv->baud_rate = DEFAULT_BAUD_RATE; priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR; - r = ch341_configure(port->serial->dev, priv); + r = ch341_configure(serial->dev, priv); if (r < 0) goto error; - usb_set_serial_port_data(port, priv); + usb_set_serial_port_data(serial->port[0], priv); return 0; error: kfree(priv); return r; } -static int ch341_port_remove(struct usb_serial_port *port) -{ - struct ch341_private *priv; - - priv = usb_get_serial_port_data(port); - kfree(priv); - - return 0; -} - static int ch341_carrier_raised(struct usb_serial_port *port) { struct ch341_private *priv = usb_get_serial_port_data(port); @@ -312,7 +304,7 @@ static void ch341_close(struct usb_serial_port *port) static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port) { struct usb_serial *serial = port->serial; - struct ch341_private *priv = usb_get_serial_port_data(port); + struct ch341_private *priv = usb_get_serial_port_data(serial->port[0]); int r; priv->baud_rate = DEFAULT_BAUD_RATE; @@ -616,8 +608,7 @@ static struct usb_serial_driver ch341_device = { .tiocmget = ch341_tiocmget, .tiocmset = ch341_tiocmset, .read_int_callback = ch341_read_int_callback, - .port_probe = ch341_port_probe, - .port_remove = ch341_port_remove, + .attach = ch341_attach, .reset_resume = ch341_reset_resume, }; diff --git a/trunk/drivers/usb/serial/digi_acceleport.c b/trunk/drivers/usb/serial/digi_acceleport.c index b50fa1c6d885..c86f68c6b078 100644 --- a/trunk/drivers/usb/serial/digi_acceleport.c +++ b/trunk/drivers/usb/serial/digi_acceleport.c @@ -244,8 +244,6 @@ static int digi_startup_device(struct usb_serial *serial); static int digi_startup(struct usb_serial *serial); static void digi_disconnect(struct usb_serial *serial); static void digi_release(struct usb_serial *serial); -static int digi_port_probe(struct usb_serial_port *port); -static int digi_port_remove(struct usb_serial_port *port); static void digi_read_bulk_callback(struct urb *urb); static int digi_read_inb_callback(struct urb *urb); static int digi_read_oob_callback(struct urb *urb); @@ -296,8 +294,6 @@ static struct usb_serial_driver digi_acceleport_2_device = { .attach = digi_startup, .disconnect = digi_disconnect, .release = digi_release, - .port_probe = digi_port_probe, - .port_remove = digi_port_remove, }; static struct usb_serial_driver digi_acceleport_4_device = { @@ -324,8 +320,6 @@ static struct usb_serial_driver digi_acceleport_4_device = { .attach = digi_startup, .disconnect = digi_disconnect, .release = digi_release, - .port_probe = digi_port_probe, - .port_remove = digi_port_remove, }; static struct usb_serial_driver * const serial_drivers[] = { @@ -1246,50 +1240,59 @@ static int digi_startup_device(struct usb_serial *serial) return ret; } -static int digi_port_init(struct usb_serial_port *port, unsigned port_num) -{ - struct digi_port *priv; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - spin_lock_init(&priv->dp_port_lock); - priv->dp_port_num = port_num; - init_waitqueue_head(&priv->dp_modem_change_wait); - init_waitqueue_head(&priv->dp_transmit_idle_wait); - init_waitqueue_head(&priv->dp_flush_wait); - init_waitqueue_head(&priv->dp_close_wait); - INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); - priv->dp_port = port; - - init_waitqueue_head(&port->write_wait); - - usb_set_serial_port_data(port, priv); - - return 0; -} static int digi_startup(struct usb_serial *serial) { + + int i; + struct digi_port *priv; struct digi_serial *serial_priv; - int ret; - serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL); - if (!serial_priv) - return -ENOMEM; + /* allocate the private data structures for all ports */ + /* number of regular ports + 1 for the out-of-band port */ + for (i = 0; i < serial->type->num_ports + 1; i++) { + /* allocate port private structure */ + priv = kmalloc(sizeof(struct digi_port), GFP_KERNEL); + if (priv == NULL) { + while (--i >= 0) + kfree(usb_get_serial_port_data(serial->port[i])); + return 1; /* error */ + } - spin_lock_init(&serial_priv->ds_serial_lock); - serial_priv->ds_oob_port_num = serial->type->num_ports; - serial_priv->ds_oob_port = serial->port[serial_priv->ds_oob_port_num]; + /* initialize port private structure */ + spin_lock_init(&priv->dp_port_lock); + priv->dp_port_num = i; + priv->dp_out_buf_len = 0; + priv->dp_write_urb_in_use = 0; + priv->dp_modem_signals = 0; + init_waitqueue_head(&priv->dp_modem_change_wait); + priv->dp_transmit_idle = 0; + init_waitqueue_head(&priv->dp_transmit_idle_wait); + priv->dp_throttled = 0; + priv->dp_throttle_restart = 0; + init_waitqueue_head(&priv->dp_flush_wait); + init_waitqueue_head(&priv->dp_close_wait); + INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); + priv->dp_port = serial->port[i]; + /* initialize write wait queue for this port */ + init_waitqueue_head(&serial->port[i]->write_wait); + + usb_set_serial_port_data(serial->port[i], priv); + } - ret = digi_port_init(serial_priv->ds_oob_port, - serial_priv->ds_oob_port_num); - if (ret) { - kfree(serial_priv); - return ret; + /* allocate serial private structure */ + serial_priv = kmalloc(sizeof(struct digi_serial), GFP_KERNEL); + if (serial_priv == NULL) { + for (i = 0; i < serial->type->num_ports + 1; i++) + kfree(usb_get_serial_port_data(serial->port[i])); + return 1; /* error */ } + /* initialize serial private structure */ + spin_lock_init(&serial_priv->ds_serial_lock); + serial_priv->ds_oob_port_num = serial->type->num_ports; + serial_priv->ds_oob_port = serial->port[serial_priv->ds_oob_port_num]; + serial_priv->ds_device_started = 0; usb_set_serial_data(serial, serial_priv); return 0; @@ -1310,35 +1313,15 @@ static void digi_disconnect(struct usb_serial *serial) static void digi_release(struct usb_serial *serial) { - struct digi_serial *serial_priv; - struct digi_port *priv; - - serial_priv = usb_get_serial_data(serial); - - priv = usb_get_serial_port_data(serial_priv->ds_oob_port); - kfree(priv); - - kfree(serial_priv); -} - -static int digi_port_probe(struct usb_serial_port *port) -{ - unsigned port_num; - - port_num = port->number - port->serial->minor; + int i; - return digi_port_init(port, port_num); + /* free the private data structures for all ports */ + /* number of regular ports + 1 for the out-of-band port */ + for (i = 0; i < serial->type->num_ports + 1; i++) + kfree(usb_get_serial_port_data(serial->port[i])); + kfree(usb_get_serial_data(serial)); } -static int digi_port_remove(struct usb_serial_port *port) -{ - struct digi_port *priv; - - priv = usb_get_serial_port_data(port); - kfree(priv); - - return 0; -} static void digi_read_bulk_callback(struct urb *urb) { diff --git a/trunk/drivers/usb/serial/ipw.c b/trunk/drivers/usb/serial/ipw.c index 4264821a3b34..20a132ec39e2 100644 --- a/trunk/drivers/usb/serial/ipw.c +++ b/trunk/drivers/usb/serial/ipw.c @@ -203,7 +203,8 @@ static int ipw_open(struct tty_struct *tty, struct usb_serial_port *port) return 0; } -static int ipw_attach(struct usb_serial *serial) +/* fake probe - only to allocate data structures */ +static int ipw_probe(struct usb_serial *serial, const struct usb_device_id *id) { struct usb_wwan_intf_private *data; @@ -302,9 +303,9 @@ static struct usb_serial_driver ipw_device = { .num_ports = 1, .open = ipw_open, .close = ipw_close, - .attach = ipw_attach, + .probe = ipw_probe, + .attach = usb_wwan_startup, .release = ipw_release, - .port_probe = usb_wwan_port_probe, .port_remove = usb_wwan_port_remove, .dtr_rts = ipw_dtr_rts, .write = usb_wwan_write, diff --git a/trunk/drivers/usb/serial/keyspan.c b/trunk/drivers/usb/serial/keyspan.c index cff8dd5b462d..29c943d737d0 100644 --- a/trunk/drivers/usb/serial/keyspan.c +++ b/trunk/drivers/usb/serial/keyspan.c @@ -1374,9 +1374,13 @@ static struct callbacks { data in device_details */ static void keyspan_setup_urbs(struct usb_serial *serial) { + int i, j; struct keyspan_serial_private *s_priv; const struct keyspan_device_details *d_details; + struct usb_serial_port *port; + struct keyspan_port_private *p_priv; struct callbacks *cback; + int endp; s_priv = usb_get_serial_data(serial); d_details = s_priv->device_details; @@ -1400,6 +1404,45 @@ static void keyspan_setup_urbs(struct usb_serial *serial) (serial, d_details->glocont_endpoint, USB_DIR_OUT, serial, s_priv->glocont_buf, GLOCONT_BUFLEN, cback->glocont_callback); + + /* Setup endpoints for each port specific thing */ + for (i = 0; i < d_details->num_ports; i++) { + port = serial->port[i]; + p_priv = usb_get_serial_port_data(port); + + /* Do indat endpoints first, once for each flip */ + endp = d_details->indat_endpoints[i]; + for (j = 0; j <= d_details->indat_endp_flip; ++j, ++endp) { + p_priv->in_urbs[j] = keyspan_setup_urb + (serial, endp, USB_DIR_IN, port, + p_priv->in_buffer[j], 64, + cback->indat_callback); + } + for (; j < 2; ++j) + p_priv->in_urbs[j] = NULL; + + /* outdat endpoints also have flip */ + endp = d_details->outdat_endpoints[i]; + for (j = 0; j <= d_details->outdat_endp_flip; ++j, ++endp) { + p_priv->out_urbs[j] = keyspan_setup_urb + (serial, endp, USB_DIR_OUT, port, + p_priv->out_buffer[j], 64, + cback->outdat_callback); + } + for (; j < 2; ++j) + p_priv->out_urbs[j] = NULL; + + /* inack endpoint */ + p_priv->inack_urb = keyspan_setup_urb + (serial, d_details->inack_endpoints[i], USB_DIR_IN, + port, p_priv->inack_buffer, 1, cback->inack_callback); + + /* outcont endpoint */ + p_priv->outcont_urb = keyspan_setup_urb + (serial, d_details->outcont_endpoints[i], USB_DIR_OUT, + port, p_priv->outcont_buffer, 64, + cback->outcont_callback); + } } /* usa19 function doesn't require prescaler */ @@ -2364,7 +2407,9 @@ static void keyspan_send_setup(struct usb_serial_port *port, int reset_port) static int keyspan_startup(struct usb_serial *serial) { int i, err; + struct usb_serial_port *port; struct keyspan_serial_private *s_priv; + struct keyspan_port_private *p_priv; const struct keyspan_device_details *d_details; for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i) @@ -2387,6 +2432,19 @@ static int keyspan_startup(struct usb_serial *serial) s_priv->device_details = d_details; usb_set_serial_data(serial, s_priv); + /* Now setup per port private data */ + for (i = 0; i < serial->num_ports; i++) { + port = serial->port[i]; + p_priv = kzalloc(sizeof(struct keyspan_port_private), + GFP_KERNEL); + if (!p_priv) { + dev_dbg(&port->dev, "%s - kmalloc for keyspan_port_private (%d) failed!.\n", __func__, i); + return 1; + } + p_priv->device_details = d_details; + usb_set_serial_port_data(port, p_priv); + } + keyspan_setup_urbs(serial); if (s_priv->instat_urb != NULL) { @@ -2405,111 +2463,59 @@ static int keyspan_startup(struct usb_serial *serial) static void keyspan_disconnect(struct usb_serial *serial) { - struct keyspan_serial_private *s_priv; + int i, j; + struct usb_serial_port *port; + struct keyspan_serial_private *s_priv; + struct keyspan_port_private *p_priv; s_priv = usb_get_serial_data(serial); + /* Stop reading/writing urbs */ stop_urb(s_priv->instat_urb); stop_urb(s_priv->glocont_urb); stop_urb(s_priv->indat_urb); -} - -static void keyspan_release(struct usb_serial *serial) -{ - struct keyspan_serial_private *s_priv; - - s_priv = usb_get_serial_data(serial); + for (i = 0; i < serial->num_ports; ++i) { + port = serial->port[i]; + p_priv = usb_get_serial_port_data(port); + stop_urb(p_priv->inack_urb); + stop_urb(p_priv->outcont_urb); + for (j = 0; j < 2; j++) { + stop_urb(p_priv->in_urbs[j]); + stop_urb(p_priv->out_urbs[j]); + } + } + /* Now free them */ usb_free_urb(s_priv->instat_urb); usb_free_urb(s_priv->indat_urb); usb_free_urb(s_priv->glocont_urb); - - kfree(s_priv); + for (i = 0; i < serial->num_ports; ++i) { + port = serial->port[i]; + p_priv = usb_get_serial_port_data(port); + usb_free_urb(p_priv->inack_urb); + usb_free_urb(p_priv->outcont_urb); + for (j = 0; j < 2; j++) { + usb_free_urb(p_priv->in_urbs[j]); + usb_free_urb(p_priv->out_urbs[j]); + } + } } -static int keyspan_port_probe(struct usb_serial_port *port) +static void keyspan_release(struct usb_serial *serial) { - struct usb_serial *serial = port->serial; - struct keyspan_serial_private *s_priv; - struct keyspan_port_private *p_priv; - const struct keyspan_device_details *d_details; - struct callbacks *cback; - int endp; - int port_num; - int i; + int i; + struct usb_serial_port *port; + struct keyspan_serial_private *s_priv; s_priv = usb_get_serial_data(serial); - d_details = s_priv->device_details; - - p_priv = kzalloc(sizeof(*p_priv), GFP_KERNEL); - if (!p_priv) - return -ENOMEM; - - p_priv->device_details = d_details; - - /* Setup values for the various callback routines */ - cback = &keyspan_callbacks[d_details->msg_format]; - - port_num = port->number - port->serial->minor; - - /* Do indat endpoints first, once for each flip */ - endp = d_details->indat_endpoints[port_num]; - for (i = 0; i <= d_details->indat_endp_flip; ++i, ++endp) { - p_priv->in_urbs[i] = keyspan_setup_urb(serial, endp, - USB_DIR_IN, port, - p_priv->in_buffer[i], 64, - cback->indat_callback); - } - /* outdat endpoints also have flip */ - endp = d_details->outdat_endpoints[port_num]; - for (i = 0; i <= d_details->outdat_endp_flip; ++i, ++endp) { - p_priv->out_urbs[i] = keyspan_setup_urb(serial, endp, - USB_DIR_OUT, port, - p_priv->out_buffer[i], 64, - cback->outdat_callback); - } - /* inack endpoint */ - p_priv->inack_urb = keyspan_setup_urb(serial, - d_details->inack_endpoints[port_num], - USB_DIR_IN, port, - p_priv->inack_buffer, 1, - cback->inack_callback); - /* outcont endpoint */ - p_priv->outcont_urb = keyspan_setup_urb(serial, - d_details->outcont_endpoints[port_num], - USB_DIR_OUT, port, - p_priv->outcont_buffer, 64, - cback->outcont_callback); - - usb_set_serial_port_data(port, p_priv); - return 0; -} - -static int keyspan_port_remove(struct usb_serial_port *port) -{ - struct keyspan_port_private *p_priv; - int i; - - p_priv = usb_get_serial_port_data(port); - - stop_urb(p_priv->inack_urb); - stop_urb(p_priv->outcont_urb); - for (i = 0; i < 2; i++) { - stop_urb(p_priv->in_urbs[i]); - stop_urb(p_priv->out_urbs[i]); - } + kfree(s_priv); - usb_free_urb(p_priv->inack_urb); - usb_free_urb(p_priv->outcont_urb); - for (i = 0; i < 2; i++) { - usb_free_urb(p_priv->in_urbs[i]); - usb_free_urb(p_priv->out_urbs[i]); + /* Now free per port private data */ + for (i = 0; i < serial->num_ports; i++) { + port = serial->port[i]; + kfree(usb_get_serial_port_data(port)); } - - kfree(p_priv); - - return 0; } MODULE_AUTHOR(DRIVER_AUTHOR); diff --git a/trunk/drivers/usb/serial/keyspan.h b/trunk/drivers/usb/serial/keyspan.h index 0273dda303a4..0a8a40b5711e 100644 --- a/trunk/drivers/usb/serial/keyspan.h +++ b/trunk/drivers/usb/serial/keyspan.h @@ -42,8 +42,6 @@ static void keyspan_dtr_rts (struct usb_serial_port *port, int on); static int keyspan_startup (struct usb_serial *serial); static void keyspan_disconnect (struct usb_serial *serial); static void keyspan_release (struct usb_serial *serial); -static int keyspan_port_probe(struct usb_serial_port *port); -static int keyspan_port_remove(struct usb_serial_port *port); static int keyspan_write_room (struct tty_struct *tty); static int keyspan_write (struct tty_struct *tty, @@ -569,8 +567,6 @@ static struct usb_serial_driver keyspan_1port_device = { .attach = keyspan_startup, .disconnect = keyspan_disconnect, .release = keyspan_release, - .port_probe = keyspan_port_probe, - .port_remove = keyspan_port_remove, }; static struct usb_serial_driver keyspan_2port_device = { @@ -593,8 +589,6 @@ static struct usb_serial_driver keyspan_2port_device = { .attach = keyspan_startup, .disconnect = keyspan_disconnect, .release = keyspan_release, - .port_probe = keyspan_port_probe, - .port_remove = keyspan_port_remove, }; static struct usb_serial_driver keyspan_4port_device = { @@ -617,8 +611,6 @@ static struct usb_serial_driver keyspan_4port_device = { .attach = keyspan_startup, .disconnect = keyspan_disconnect, .release = keyspan_release, - .port_probe = keyspan_port_probe, - .port_remove = keyspan_port_remove, }; static struct usb_serial_driver * const serial_drivers[] = { diff --git a/trunk/drivers/usb/serial/mct_u232.c b/trunk/drivers/usb/serial/mct_u232.c index 8a2081004107..f3947712e137 100644 --- a/trunk/drivers/usb/serial/mct_u232.c +++ b/trunk/drivers/usb/serial/mct_u232.c @@ -49,8 +49,7 @@ * Function prototypes */ static int mct_u232_startup(struct usb_serial *serial); -static int mct_u232_port_probe(struct usb_serial_port *port); -static int mct_u232_port_remove(struct usb_serial_port *remove); +static void mct_u232_release(struct usb_serial *serial); static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port); static void mct_u232_close(struct usb_serial_port *port); static void mct_u232_dtr_rts(struct usb_serial_port *port, int on); @@ -100,8 +99,7 @@ static struct usb_serial_driver mct_u232_device = { .tiocmget = mct_u232_tiocmget, .tiocmset = mct_u232_tiocmset, .attach = mct_u232_startup, - .port_probe = mct_u232_port_probe, - .port_remove = mct_u232_port_remove, + .release = mct_u232_release, .ioctl = mct_u232_ioctl, .get_icount = mct_u232_get_icount, }; @@ -390,8 +388,18 @@ static void mct_u232_msr_to_state(struct usb_serial_port *port, static int mct_u232_startup(struct usb_serial *serial) { + struct mct_u232_private *priv; struct usb_serial_port *port, *rport; + priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL); + if (!priv) + return -ENOMEM; + spin_lock_init(&priv->lock); + init_waitqueue_head(&priv->msr_wait); + usb_set_serial_port_data(serial->port[0], priv); + + init_waitqueue_head(&serial->port[0]->write_wait); + /* Puh, that's dirty */ port = serial->port[0]; rport = serial->port[1]; @@ -404,31 +412,18 @@ static int mct_u232_startup(struct usb_serial *serial) return 0; } /* mct_u232_startup */ -static int mct_u232_port_probe(struct usb_serial_port *port) -{ - struct mct_u232_private *priv; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - spin_lock_init(&priv->lock); - init_waitqueue_head(&priv->msr_wait); - - usb_set_serial_port_data(port, priv); - return 0; -} - -static int mct_u232_port_remove(struct usb_serial_port *port) +static void mct_u232_release(struct usb_serial *serial) { struct mct_u232_private *priv; + int i; - priv = usb_get_serial_port_data(port); - kfree(priv); - - return 0; -} + for (i = 0; i < serial->num_ports; ++i) { + /* My special items, the standard routines free my urbs */ + priv = usb_get_serial_port_data(serial->port[i]); + kfree(priv); + } +} /* mct_u232_release */ static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port) { @@ -520,14 +515,12 @@ static void mct_u232_dtr_rts(struct usb_serial_port *port, int on) static void mct_u232_close(struct usb_serial_port *port) { - /* - * Must kill the read urb as it is actually an interrupt urb, which - * generic close thus fails to kill. - */ - usb_kill_urb(port->read_urb); - usb_kill_urb(port->interrupt_in_urb); - - usb_serial_generic_close(port); + if (port->serial->dev) { + /* shutdown our urbs */ + usb_kill_urb(port->write_urb); + usb_kill_urb(port->read_urb); + usb_kill_urb(port->interrupt_in_urb); + } } /* mct_u232_close */ diff --git a/trunk/drivers/usb/serial/metro-usb.c b/trunk/drivers/usb/serial/metro-usb.c index 6f29c74eb769..0b257ddffbdb 100644 --- a/trunk/drivers/usb/serial/metro-usb.c +++ b/trunk/drivers/usb/serial/metro-usb.c @@ -179,13 +179,16 @@ static void metrousb_cleanup(struct usb_serial_port *port) { dev_dbg(&port->dev, "%s\n", __func__); - usb_unlink_urb(port->interrupt_in_urb); - usb_kill_urb(port->interrupt_in_urb); - - mutex_lock(&port->serial->disc_mutex); - if (!port->serial->disconnected) + if (port->serial->dev) { + /* Shutdown any interrupt in urbs. */ + if (port->interrupt_in_urb) { + usb_unlink_urb(port->interrupt_in_urb); + usb_kill_urb(port->interrupt_in_urb); + } + + /* Send deactivate cmd to device */ metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port); - mutex_unlock(&port->serial->disc_mutex); + } } static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port) @@ -268,27 +271,51 @@ static int metrousb_set_modem_ctrl(struct usb_serial *serial, unsigned int contr return retval; } -static int metrousb_port_probe(struct usb_serial_port *port) +static void metrousb_shutdown(struct usb_serial *serial) { - struct metrousb_private *metro_priv; + int i = 0; - metro_priv = kzalloc(sizeof(*metro_priv), GFP_KERNEL); - if (!metro_priv) - return -ENOMEM; + dev_dbg(&serial->dev->dev, "%s\n", __func__); - spin_lock_init(&metro_priv->lock); + /* Stop reading and writing on all ports. */ + for (i = 0; i < serial->num_ports; ++i) { + /* Close any open urbs. */ + metrousb_cleanup(serial->port[i]); - usb_set_serial_port_data(port, metro_priv); + /* Free memory. */ + kfree(usb_get_serial_port_data(serial->port[i])); + usb_set_serial_port_data(serial->port[i], NULL); - return 0; + dev_dbg(&serial->dev->dev, "%s - freed port number=%d\n", + __func__, serial->port[i]->number); + } } -static int metrousb_port_remove(struct usb_serial_port *port) +static int metrousb_startup(struct usb_serial *serial) { struct metrousb_private *metro_priv; + struct usb_serial_port *port; + int i = 0; - metro_priv = usb_get_serial_port_data(port); - kfree(metro_priv); + dev_dbg(&serial->dev->dev, "%s\n", __func__); + + /* Loop through the serial ports setting up the private structures. + * Currently we only use one port. */ + for (i = 0; i < serial->num_ports; ++i) { + port = serial->port[i]; + + /* Declare memory. */ + metro_priv = kzalloc(sizeof(struct metrousb_private), GFP_KERNEL); + if (!metro_priv) + return -ENOMEM; + + /* Initialize memory. */ + spin_lock_init(&metro_priv->lock); + usb_set_serial_port_data(port, metro_priv); + + dev_dbg(&serial->dev->dev, "%s - port number=%d\n ", + __func__, port->number); + } return 0; } @@ -387,8 +414,8 @@ static struct usb_serial_driver metrousb_device = { .close = metrousb_cleanup, .read_int_callback = metrousb_read_int_callback, .write_int_callback = metrousb_write_int_callback, - .port_probe = metrousb_port_probe, - .port_remove = metrousb_port_remove, + .attach = metrousb_startup, + .release = metrousb_shutdown, .throttle = metrousb_throttle, .unthrottle = metrousb_unthrottle, .tiocmget = metrousb_tiocmget, diff --git a/trunk/drivers/usb/serial/mos7720.c b/trunk/drivers/usb/serial/mos7720.c index 75267421aad8..1bf1ad066666 100644 --- a/trunk/drivers/usb/serial/mos7720.c +++ b/trunk/drivers/usb/serial/mos7720.c @@ -1966,7 +1966,9 @@ static int mos7720_ioctl(struct tty_struct *tty, static int mos7720_startup(struct usb_serial *serial) { + struct moschip_port *mos7720_port; struct usb_device *dev; + int i; char data; u16 product; int ret_val; @@ -1997,6 +1999,29 @@ static int mos7720_startup(struct usb_serial *serial) serial->port[1]->interrupt_in_buffer = NULL; } + + /* set up serial port private structures */ + for (i = 0; i < serial->num_ports; ++i) { + mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); + if (mos7720_port == NULL) { + dev_err(&dev->dev, "%s - Out of memory\n", __func__); + return -ENOMEM; + } + + /* Initialize all port interrupt end point to port 0 int + * endpoint. Our device has only one interrupt endpoint + * common to all ports */ + serial->port[i]->interrupt_in_endpointAddress = + serial->port[0]->interrupt_in_endpointAddress; + + mos7720_port->port = serial->port[i]; + usb_set_serial_port_data(serial->port[i], mos7720_port); + + dev_dbg(&dev->dev, "port number is %d\n", serial->port[i]->number); + dev_dbg(&dev->dev, "serial number is %d\n", serial->minor); + } + + /* setting configuration feature to one */ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ); @@ -2024,6 +2049,8 @@ static int mos7720_startup(struct usb_serial *serial) static void mos7720_release(struct usb_serial *serial) { + int i; + #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT /* close the parallel port */ @@ -2062,36 +2089,9 @@ static void mos7720_release(struct usb_serial *serial) kref_put(&mos_parport->ref_count, destroy_mos_parport); } #endif -} - -static int mos7720_port_probe(struct usb_serial_port *port) -{ - struct moschip_port *mos7720_port; - - mos7720_port = kzalloc(sizeof(*mos7720_port), GFP_KERNEL); - if (!mos7720_port) - return -ENOMEM; - - /* Initialize all port interrupt end point to port 0 int endpoint. - * Our device has only one interrupt endpoint common to all ports. - */ - port->interrupt_in_endpointAddress = - port->serial->port[0]->interrupt_in_endpointAddress; - mos7720_port->port = port; - - usb_set_serial_port_data(port, mos7720_port); - - return 0; -} - -static int mos7720_port_remove(struct usb_serial_port *port) -{ - struct moschip_port *mos7720_port; - - mos7720_port = usb_get_serial_port_data(port); - kfree(mos7720_port); - - return 0; + /* free private structure allocated for serial port */ + for (i = 0; i < serial->num_ports; ++i) + kfree(usb_get_serial_port_data(serial->port[i])); } static struct usb_serial_driver moschip7720_2port_driver = { @@ -2109,8 +2109,6 @@ static struct usb_serial_driver moschip7720_2port_driver = { .probe = mos77xx_probe, .attach = mos7720_startup, .release = mos7720_release, - .port_probe = mos7720_port_probe, - .port_remove = mos7720_port_remove, .ioctl = mos7720_ioctl, .tiocmget = mos7720_tiocmget, .tiocmset = mos7720_tiocmset, diff --git a/trunk/drivers/usb/serial/mos7840.c b/trunk/drivers/usb/serial/mos7840.c index 1cf3375ec1af..d6d4eeca8c68 100644 --- a/trunk/drivers/usb/serial/mos7840.c +++ b/trunk/drivers/usb/serial/mos7840.c @@ -218,10 +218,12 @@ struct moschip_port { int port_num; /*Actual port number in the device(1,2,etc) */ struct urb *write_urb; /* write URB for this port */ struct urb *read_urb; /* read URB for this port */ + struct urb *int_urb; __u8 shadowLCR; /* last LCR value received */ __u8 shadowMCR; /* last MCR value received */ char open; char open_ports; + char zombie; wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */ int delta_msr_cond; @@ -476,6 +478,7 @@ static void mos7840_control_callback(struct urb *urb) struct moschip_port *mos7840_port; struct device *dev = &urb->dev->dev; __u8 regval = 0x0; + int result = 0; int status = urb->status; mos7840_port = urb->context; @@ -492,7 +495,7 @@ static void mos7840_control_callback(struct urb *urb) return; default: dev_dbg(dev, "%s - nonzero urb status received: %d\n", __func__, status); - return; + goto exit; } dev_dbg(dev, "%s urb buffer size is %d\n", __func__, urb->actual_length); @@ -505,6 +508,16 @@ static void mos7840_control_callback(struct urb *urb) mos7840_handle_new_msr(mos7840_port, regval); else if (mos7840_port->MsrLsr == 1) mos7840_handle_new_lsr(mos7840_port, regval); + +exit: + spin_lock(&mos7840_port->pool_lock); + if (!mos7840_port->zombie) + result = usb_submit_urb(mos7840_port->int_urb, GFP_ATOMIC); + spin_unlock(&mos7840_port->pool_lock); + if (result) { + dev_err(dev, "%s - Error %d submitting interrupt urb\n", + __func__, result); + } } static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg, @@ -673,7 +686,14 @@ static void mos7840_interrupt_callback(struct urb *urb) wreg = MODEM_STATUS_REGISTER; break; } - rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data); + spin_lock(&mos7840_port->pool_lock); + if (!mos7840_port->zombie) { + rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data); + } else { + spin_unlock(&mos7840_port->pool_lock); + return; + } + spin_unlock(&mos7840_port->pool_lock); } } } @@ -2327,249 +2347,309 @@ static int mos7840_calc_num_ports(struct usb_serial *serial) return mos7840_num_ports; } -static int mos7840_port_probe(struct usb_serial_port *port) +/**************************************************************************** + * mos7840_startup + ****************************************************************************/ + +static int mos7840_startup(struct usb_serial *serial) { - struct usb_serial *serial = port->serial; struct moschip_port *mos7840_port; - int status; - int pnum; + struct usb_device *dev; + int i, status; __u16 Data; + dev = serial->dev; + /* we set up the pointers to the endpoints in the mos7840_open * * function, as the structures aren't created yet. */ - pnum = port->number - serial->minor; - - dev_dbg(&port->dev, "mos7840_startup: configuring port %d\n", pnum); - mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); - if (mos7840_port == NULL) { - dev_err(&port->dev, "%s - Out of memory\n", __func__); - return -ENOMEM; - } - - /* Initialize all port interrupt end point to port 0 int - * endpoint. Our device has only one interrupt end point - * common to all port */ - - mos7840_port->port = port; - mos7840_set_port_private(port, mos7840_port); - spin_lock_init(&mos7840_port->pool_lock); - - /* minor is not initialised until later by - * usb-serial.c:get_free_serial() and cannot therefore be used - * to index device instances */ - mos7840_port->port_num = pnum + 1; - dev_dbg(&port->dev, "port->number = %d\n", port->number); - dev_dbg(&port->dev, "port->serial->minor = %d\n", port->serial->minor); - dev_dbg(&port->dev, "mos7840_port->port_num = %d\n", mos7840_port->port_num); - dev_dbg(&port->dev, "serial->minor = %d\n", serial->minor); - - if (mos7840_port->port_num == 1) { - mos7840_port->SpRegOffset = 0x0; - mos7840_port->ControlRegOffset = 0x1; - mos7840_port->DcrRegOffset = 0x4; - } else if ((mos7840_port->port_num == 2) && (serial->num_ports == 4)) { - mos7840_port->SpRegOffset = 0x8; - mos7840_port->ControlRegOffset = 0x9; - mos7840_port->DcrRegOffset = 0x16; - } else if ((mos7840_port->port_num == 2) && (serial->num_ports == 2)) { - mos7840_port->SpRegOffset = 0xa; - mos7840_port->ControlRegOffset = 0xb; - mos7840_port->DcrRegOffset = 0x19; - } else if ((mos7840_port->port_num == 3) && (serial->num_ports == 4)) { - mos7840_port->SpRegOffset = 0xa; - mos7840_port->ControlRegOffset = 0xb; - mos7840_port->DcrRegOffset = 0x19; - } else if ((mos7840_port->port_num == 4) && (serial->num_ports == 4)) { - mos7840_port->SpRegOffset = 0xc; - mos7840_port->ControlRegOffset = 0xd; - mos7840_port->DcrRegOffset = 0x1c; - } - mos7840_dump_serial_port(port, mos7840_port); - mos7840_set_port_private(port, mos7840_port); - - /* enable rx_disable bit in control register */ - status = mos7840_get_reg_sync(port, - mos7840_port->ControlRegOffset, &Data); - if (status < 0) { - dev_dbg(&port->dev, "Reading ControlReg failed status-0x%x\n", status); - goto out; - } else - dev_dbg(&port->dev, "ControlReg Reading success val is %x, status%d\n", Data, status); - Data |= 0x08; /* setting driver done bit */ - Data |= 0x04; /* sp1_bit to have cts change reflect in - modem status reg */ + /* set up port private structures */ + for (i = 0; i < serial->num_ports; ++i) { + dev_dbg(&dev->dev, "mos7840_startup: configuring port %d............\n", i); + mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); + if (mos7840_port == NULL) { + dev_err(&dev->dev, "%s - Out of memory\n", __func__); + status = -ENOMEM; + i--; /* don't follow NULL pointer cleaning up */ + goto error; + } - /* Data |= 0x20; //rx_disable bit */ - status = mos7840_set_reg_sync(port, - mos7840_port->ControlRegOffset, Data); - if (status < 0) { - dev_dbg(&port->dev, "Writing ControlReg failed(rx_disable) status-0x%x\n", status); - goto out; - } else - dev_dbg(&port->dev, "ControlReg Writing success(rx_disable) status%d\n", status); + /* Initialize all port interrupt end point to port 0 int + * endpoint. Our device has only one interrupt end point + * common to all port */ + + mos7840_port->port = serial->port[i]; + mos7840_set_port_private(serial->port[i], mos7840_port); + spin_lock_init(&mos7840_port->pool_lock); + + /* minor is not initialised until later by + * usb-serial.c:get_free_serial() and cannot therefore be used + * to index device instances */ + mos7840_port->port_num = i + 1; + dev_dbg(&dev->dev, "serial->port[i]->number = %d\n", serial->port[i]->number); + dev_dbg(&dev->dev, "serial->port[i]->serial->minor = %d\n", serial->port[i]->serial->minor); + dev_dbg(&dev->dev, "mos7840_port->port_num = %d\n", mos7840_port->port_num); + dev_dbg(&dev->dev, "serial->minor = %d\n", serial->minor); + + if (mos7840_port->port_num == 1) { + mos7840_port->SpRegOffset = 0x0; + mos7840_port->ControlRegOffset = 0x1; + mos7840_port->DcrRegOffset = 0x4; + } else if ((mos7840_port->port_num == 2) + && (serial->num_ports == 4)) { + mos7840_port->SpRegOffset = 0x8; + mos7840_port->ControlRegOffset = 0x9; + mos7840_port->DcrRegOffset = 0x16; + } else if ((mos7840_port->port_num == 2) + && (serial->num_ports == 2)) { + mos7840_port->SpRegOffset = 0xa; + mos7840_port->ControlRegOffset = 0xb; + mos7840_port->DcrRegOffset = 0x19; + } else if ((mos7840_port->port_num == 3) + && (serial->num_ports == 4)) { + mos7840_port->SpRegOffset = 0xa; + mos7840_port->ControlRegOffset = 0xb; + mos7840_port->DcrRegOffset = 0x19; + } else if ((mos7840_port->port_num == 4) + && (serial->num_ports == 4)) { + mos7840_port->SpRegOffset = 0xc; + mos7840_port->ControlRegOffset = 0xd; + mos7840_port->DcrRegOffset = 0x1c; + } + mos7840_dump_serial_port(serial->port[i], mos7840_port); + mos7840_set_port_private(serial->port[i], mos7840_port); - /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2 - and 0x24 in DCR3 */ - Data = 0x01; - status = mos7840_set_reg_sync(port, - (__u16) (mos7840_port->DcrRegOffset + 0), Data); - if (status < 0) { - dev_dbg(&port->dev, "Writing DCR0 failed status-0x%x\n", status); - goto out; - } else - dev_dbg(&port->dev, "DCR0 Writing success status%d\n", status); + /* enable rx_disable bit in control register */ + status = mos7840_get_reg_sync(serial->port[i], + mos7840_port->ControlRegOffset, &Data); + if (status < 0) { + dev_dbg(&dev->dev, "Reading ControlReg failed status-0x%x\n", status); + break; + } else + dev_dbg(&dev->dev, "ControlReg Reading success val is %x, status%d\n", Data, status); + Data |= 0x08; /* setting driver done bit */ + Data |= 0x04; /* sp1_bit to have cts change reflect in + modem status reg */ + + /* Data |= 0x20; //rx_disable bit */ + status = mos7840_set_reg_sync(serial->port[i], + mos7840_port->ControlRegOffset, Data); + if (status < 0) { + dev_dbg(&dev->dev, "Writing ControlReg failed(rx_disable) status-0x%x\n", status); + break; + } else + dev_dbg(&dev->dev, "ControlReg Writing success(rx_disable) status%d\n", status); - Data = 0x05; - status = mos7840_set_reg_sync(port, - (__u16) (mos7840_port->DcrRegOffset + 1), Data); - if (status < 0) { - dev_dbg(&port->dev, "Writing DCR1 failed status-0x%x\n", status); - goto out; - } else - dev_dbg(&port->dev, "DCR1 Writing success status%d\n", status); + /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2 + and 0x24 in DCR3 */ + Data = 0x01; + status = mos7840_set_reg_sync(serial->port[i], + (__u16) (mos7840_port->DcrRegOffset + 0), Data); + if (status < 0) { + dev_dbg(&dev->dev, "Writing DCR0 failed status-0x%x\n", status); + break; + } else + dev_dbg(&dev->dev, "DCR0 Writing success status%d\n", status); - Data = 0x24; - status = mos7840_set_reg_sync(port, - (__u16) (mos7840_port->DcrRegOffset + 2), Data); - if (status < 0) { - dev_dbg(&port->dev, "Writing DCR2 failed status-0x%x\n", status); - goto out; - } else - dev_dbg(&port->dev, "DCR2 Writing success status%d\n", status); + Data = 0x05; + status = mos7840_set_reg_sync(serial->port[i], + (__u16) (mos7840_port->DcrRegOffset + 1), Data); + if (status < 0) { + dev_dbg(&dev->dev, "Writing DCR1 failed status-0x%x\n", status); + break; + } else + dev_dbg(&dev->dev, "DCR1 Writing success status%d\n", status); - /* write values in clkstart0x0 and clkmulti 0x20 */ - Data = 0x0; - status = mos7840_set_reg_sync(port, CLK_START_VALUE_REGISTER, Data); - if (status < 0) { - dev_dbg(&port->dev, "Writing CLK_START_VALUE_REGISTER failed status-0x%x\n", status); - goto out; - } else - dev_dbg(&port->dev, "CLK_START_VALUE_REGISTER Writing success status%d\n", status); + Data = 0x24; + status = mos7840_set_reg_sync(serial->port[i], + (__u16) (mos7840_port->DcrRegOffset + 2), Data); + if (status < 0) { + dev_dbg(&dev->dev, "Writing DCR2 failed status-0x%x\n", status); + break; + } else + dev_dbg(&dev->dev, "DCR2 Writing success status%d\n", status); - Data = 0x20; - status = mos7840_set_reg_sync(port, CLK_MULTI_REGISTER, Data); - if (status < 0) { - dev_dbg(&port->dev, "Writing CLK_MULTI_REGISTER failed status-0x%x\n", status); - goto error; - } else - dev_dbg(&port->dev, "CLK_MULTI_REGISTER Writing success status%d\n", status); + /* write values in clkstart0x0 and clkmulti 0x20 */ + Data = 0x0; + status = mos7840_set_reg_sync(serial->port[i], + CLK_START_VALUE_REGISTER, Data); + if (status < 0) { + dev_dbg(&dev->dev, "Writing CLK_START_VALUE_REGISTER failed status-0x%x\n", status); + break; + } else + dev_dbg(&dev->dev, "CLK_START_VALUE_REGISTER Writing success status%d\n", status); - /* write value 0x0 to scratchpad register */ - Data = 0x00; - status = mos7840_set_uart_reg(port, SCRATCH_PAD_REGISTER, Data); - if (status < 0) { - dev_dbg(&port->dev, "Writing SCRATCH_PAD_REGISTER failed status-0x%x\n", status); - goto out; - } else - dev_dbg(&port->dev, "SCRATCH_PAD_REGISTER Writing success status%d\n", status); - - /* Zero Length flag register */ - if ((mos7840_port->port_num != 1) && (serial->num_ports == 2)) { - Data = 0xff; - status = mos7840_set_reg_sync(port, - (__u16) (ZLP_REG1 + - ((__u16)mos7840_port->port_num)), Data); - dev_dbg(&port->dev, "ZLIP offset %x\n", - (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num))); + Data = 0x20; + status = mos7840_set_reg_sync(serial->port[i], + CLK_MULTI_REGISTER, Data); if (status < 0) { - dev_dbg(&port->dev, "Writing ZLP_REG%d failed status-0x%x\n", pnum + 2, status); - goto out; + dev_dbg(&dev->dev, "Writing CLK_MULTI_REGISTER failed status-0x%x\n", status); + goto error; } else - dev_dbg(&port->dev, "ZLP_REG%d Writing success status%d\n", pnum + 2, status); - } else { - Data = 0xff; - status = mos7840_set_reg_sync(port, - (__u16) (ZLP_REG1 + - ((__u16)mos7840_port->port_num) - 0x1), Data); - dev_dbg(&port->dev, "ZLIP offset %x\n", - (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num) - 0x1)); + dev_dbg(&dev->dev, "CLK_MULTI_REGISTER Writing success status%d\n", status); + + /* write value 0x0 to scratchpad register */ + Data = 0x00; + status = mos7840_set_uart_reg(serial->port[i], + SCRATCH_PAD_REGISTER, Data); if (status < 0) { - dev_dbg(&port->dev, "Writing ZLP_REG%d failed status-0x%x\n", pnum + 1, status); - goto out; + dev_dbg(&dev->dev, "Writing SCRATCH_PAD_REGISTER failed status-0x%x\n", status); + break; } else - dev_dbg(&port->dev, "ZLP_REG%d Writing success status%d\n", pnum + 1, status); + dev_dbg(&dev->dev, "SCRATCH_PAD_REGISTER Writing success status%d\n", status); - } - mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL); - mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL); - mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest), - GFP_KERNEL); - if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf || - !mos7840_port->dr) { - status = -ENOMEM; - goto error; - } + /* Zero Length flag register */ + if ((mos7840_port->port_num != 1) + && (serial->num_ports == 2)) { - mos7840_port->has_led = false; + Data = 0xff; + status = mos7840_set_reg_sync(serial->port[i], + (__u16) (ZLP_REG1 + + ((__u16)mos7840_port->port_num)), Data); + dev_dbg(&dev->dev, "ZLIP offset %x\n", + (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num))); + if (status < 0) { + dev_dbg(&dev->dev, "Writing ZLP_REG%d failed status-0x%x\n", i + 2, status); + break; + } else + dev_dbg(&dev->dev, "ZLP_REG%d Writing success status%d\n", i + 2, status); + } else { + Data = 0xff; + status = mos7840_set_reg_sync(serial->port[i], + (__u16) (ZLP_REG1 + + ((__u16)mos7840_port->port_num) - 0x1), Data); + dev_dbg(&dev->dev, "ZLIP offset %x\n", + (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num) - 0x1)); + if (status < 0) { + dev_dbg(&dev->dev, "Writing ZLP_REG%d failed status-0x%x\n", i + 1, status); + break; + } else + dev_dbg(&dev->dev, "ZLP_REG%d Writing success status%d\n", i + 1, status); + + } + mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL); + mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL); + mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest), + GFP_KERNEL); + if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf || + !mos7840_port->dr) { + status = -ENOMEM; + goto error; + } - /* Initialize LED timers */ - if (device_type == MOSCHIP_DEVICE_ID_7810) { - mos7840_port->has_led = true; + mos7840_port->has_led = false; - init_timer(&mos7840_port->led_timer1); - mos7840_port->led_timer1.function = mos7840_led_off; - mos7840_port->led_timer1.expires = - jiffies + msecs_to_jiffies(LED_ON_MS); - mos7840_port->led_timer1.data = (unsigned long)mos7840_port; + /* Initialize LED timers */ + if (device_type == MOSCHIP_DEVICE_ID_7810) { + mos7840_port->has_led = true; - init_timer(&mos7840_port->led_timer2); - mos7840_port->led_timer2.function = mos7840_led_flag_off; - mos7840_port->led_timer2.expires = - jiffies + msecs_to_jiffies(LED_OFF_MS); - mos7840_port->led_timer2.data = (unsigned long)mos7840_port; + init_timer(&mos7840_port->led_timer1); + mos7840_port->led_timer1.function = mos7840_led_off; + mos7840_port->led_timer1.expires = + jiffies + msecs_to_jiffies(LED_ON_MS); + mos7840_port->led_timer1.data = + (unsigned long)mos7840_port; - mos7840_port->led_flag = false; + init_timer(&mos7840_port->led_timer2); + mos7840_port->led_timer2.function = + mos7840_led_flag_off; + mos7840_port->led_timer2.expires = + jiffies + msecs_to_jiffies(LED_OFF_MS); + mos7840_port->led_timer2.data = + (unsigned long)mos7840_port; - /* Turn off LED */ - mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300); - } -out: - if (pnum == serial->num_ports - 1) { - /* Zero Length flag enable */ - Data = 0x0f; - status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data); - if (status < 0) { - dev_dbg(&port->dev, "Writing ZLP_REG5 failed status-0x%x\n", status); - goto error; - } else - dev_dbg(&port->dev, "ZLP_REG5 Writing success status%d\n", status); + mos7840_port->led_flag = false; - /* setting configuration feature to one */ - usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - 0x03, 0x00, 0x01, 0x00, NULL, 0x00, - MOS_WDR_TIMEOUT); + /* Turn off LED */ + mos7840_set_led_sync(serial->port[i], + MODEM_CONTROL_REGISTER, 0x0300); + } } + + /* Zero Length flag enable */ + Data = 0x0f; + status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data); + if (status < 0) { + dev_dbg(&dev->dev, "Writing ZLP_REG5 failed status-0x%x\n", status); + goto error; + } else + dev_dbg(&dev->dev, "ZLP_REG5 Writing success status%d\n", status); + + /* setting configuration feature to one */ + usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, MOS_WDR_TIMEOUT); return 0; error: - kfree(mos7840_port->dr); - kfree(mos7840_port->ctrl_buf); - usb_free_urb(mos7840_port->control_urb); - kfree(mos7840_port); + for (/* nothing */; i >= 0; i--) { + mos7840_port = mos7840_get_port_private(serial->port[i]); + kfree(mos7840_port->dr); + kfree(mos7840_port->ctrl_buf); + usb_free_urb(mos7840_port->control_urb); + kfree(mos7840_port); + serial->port[i] = NULL; + } return status; } -static int mos7840_port_remove(struct usb_serial_port *port) +/**************************************************************************** + * mos7840_disconnect + * This function is called whenever the device is removed from the usb bus. + ****************************************************************************/ + +static void mos7840_disconnect(struct usb_serial *serial) { + int i; + unsigned long flags; struct moschip_port *mos7840_port; - mos7840_port = mos7840_get_port_private(port); + /* check for the ports to be closed,close the ports and disconnect */ - if (mos7840_port->has_led) { - /* Turn off LED */ - mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300); + /* free private structure allocated for serial port * + * stop reads and writes on all ports */ - del_timer_sync(&mos7840_port->led_timer1); - del_timer_sync(&mos7840_port->led_timer2); + for (i = 0; i < serial->num_ports; ++i) { + mos7840_port = mos7840_get_port_private(serial->port[i]); + if (mos7840_port) { + spin_lock_irqsave(&mos7840_port->pool_lock, flags); + mos7840_port->zombie = 1; + spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); + usb_kill_urb(mos7840_port->control_urb); + } } - usb_kill_urb(mos7840_port->control_urb); - usb_free_urb(mos7840_port->control_urb); - kfree(mos7840_port->ctrl_buf); - kfree(mos7840_port->dr); - kfree(mos7840_port); +} - return 0; +/**************************************************************************** + * mos7840_release + * This function is called when the usb_serial structure is freed. + ****************************************************************************/ + +static void mos7840_release(struct usb_serial *serial) +{ + int i; + struct moschip_port *mos7840_port; + + /* check for the ports to be closed,close the ports and disconnect */ + + /* free private structure allocated for serial port * + * stop reads and writes on all ports */ + + for (i = 0; i < serial->num_ports; ++i) { + mos7840_port = mos7840_get_port_private(serial->port[i]); + if (mos7840_port) { + if (mos7840_port->has_led) { + /* Turn off LED */ + mos7840_set_led_sync(mos7840_port->port, + MODEM_CONTROL_REGISTER, 0x0300); + + del_timer_sync(&mos7840_port->led_timer1); + del_timer_sync(&mos7840_port->led_timer2); + } + kfree(mos7840_port->ctrl_buf); + kfree(mos7840_port->dr); + kfree(mos7840_port); + } + } } static struct usb_serial_driver moschip7840_4port_device = { @@ -2597,8 +2677,9 @@ static struct usb_serial_driver moschip7840_4port_device = { .tiocmget = mos7840_tiocmget, .tiocmset = mos7840_tiocmset, .get_icount = mos7840_get_icount, - .port_probe = mos7840_port_probe, - .port_remove = mos7840_port_remove, + .attach = mos7840_startup, + .disconnect = mos7840_disconnect, + .release = mos7840_release, .read_bulk_callback = mos7840_bulk_in_callback, .read_int_callback = mos7840_interrupt_callback, }; diff --git a/trunk/drivers/usb/serial/omninet.c b/trunk/drivers/usb/serial/omninet.c index 9ab73d295774..6def58b79382 100644 --- a/trunk/drivers/usb/serial/omninet.c +++ b/trunk/drivers/usb/serial/omninet.c @@ -44,8 +44,8 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count); static int omninet_write_room(struct tty_struct *tty); static void omninet_disconnect(struct usb_serial *serial); -static int omninet_port_probe(struct usb_serial_port *port); -static int omninet_port_remove(struct usb_serial_port *port); +static void omninet_release(struct usb_serial *serial); +static int omninet_attach(struct usb_serial *serial); static const struct usb_device_id id_table[] = { { USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) }, @@ -62,8 +62,7 @@ static struct usb_serial_driver zyxel_omninet_device = { .description = "ZyXEL - omni.net lcd plus usb", .id_table = id_table, .num_ports = 1, - .port_probe = omninet_port_probe, - .port_remove = omninet_port_remove, + .attach = omninet_attach, .open = omninet_open, .close = omninet_close, .write = omninet_write, @@ -71,6 +70,7 @@ static struct usb_serial_driver zyxel_omninet_device = { .read_bulk_callback = omninet_read_bulk_callback, .write_bulk_callback = omninet_write_bulk_callback, .disconnect = omninet_disconnect, + .release = omninet_release, }; static struct usb_serial_driver * const serial_drivers[] = { @@ -112,26 +112,18 @@ struct omninet_data { __u8 od_outseq; /* Sequence number for bulk_out URBs */ }; -static int omninet_port_probe(struct usb_serial_port *port) +static int omninet_attach(struct usb_serial *serial) { struct omninet_data *od; + struct usb_serial_port *port = serial->port[0]; od = kmalloc(sizeof(struct omninet_data), GFP_KERNEL); - if (!od) + if (!od) { + dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", + __func__, sizeof(struct omninet_data)); return -ENOMEM; - + } usb_set_serial_port_data(port, od); - - return 0; -} - -static int omninet_port_remove(struct usb_serial_port *port) -{ - struct omninet_data *od; - - od = usb_get_serial_port_data(port); - kfree(od); - return 0; } @@ -287,6 +279,14 @@ static void omninet_disconnect(struct usb_serial *serial) usb_kill_urb(wport->write_urb); } + +static void omninet_release(struct usb_serial *serial) +{ + struct usb_serial_port *port = serial->port[0]; + + kfree(usb_get_serial_port_data(port)); +} + module_usb_serial_driver(serial_drivers, id_table); MODULE_AUTHOR(DRIVER_AUTHOR); diff --git a/trunk/drivers/usb/serial/opticon.c b/trunk/drivers/usb/serial/opticon.c index 6aba731d4864..41b1647306eb 100644 --- a/trunk/drivers/usb/serial/opticon.c +++ b/trunk/drivers/usb/serial/opticon.c @@ -155,11 +155,7 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype, { struct usb_serial *serial = port->serial; int retval; - u8 *buffer; - - buffer = kzalloc(1, GFP_KERNEL); - if (!buffer) - return -ENOMEM; + u8 buffer[2]; buffer[0] = val; /* Send the message to the vendor control endpoint @@ -168,7 +164,6 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype, requesttype, USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, 0, 0, buffer, 1, 0); - kfree(buffer); return retval; } @@ -286,7 +281,7 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, if (!dr) { dev_err(&port->dev, "out of memory\n"); count = -ENOMEM; - goto error_no_dr; + goto error; } dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT; @@ -316,8 +311,6 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, return count; error: - kfree(dr); -error_no_dr: usb_free_urb(urb); error_no_urb: kfree(buffer); diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index edc64bb6f457..54d4148d01d1 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -47,7 +47,6 @@ /* Function prototypes */ static int option_probe(struct usb_serial *serial, const struct usb_device_id *id); -static int option_attach(struct usb_serial *serial); static void option_release(struct usb_serial *serial); static int option_send_setup(struct usb_serial_port *port); static void option_instat_callback(struct urb *urb); @@ -158,7 +157,6 @@ static void option_instat_callback(struct urb *urb); #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0x8001 #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000 #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001 -#define NOVATELWIRELESS_PRODUCT_E362 0x9010 #define NOVATELWIRELESS_PRODUCT_G1 0xA001 #define NOVATELWIRELESS_PRODUCT_G1_M 0xA002 #define NOVATELWIRELESS_PRODUCT_G2 0xA010 @@ -194,9 +192,6 @@ static void option_instat_callback(struct urb *urb); #define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181 #define DELL_PRODUCT_5730_MINICARD_VZW 0x8182 -#define DELL_PRODUCT_5800_MINICARD_VZW 0x8195 /* Novatel E362 */ -#define DELL_PRODUCT_5800_V2_MINICARD_VZW 0x8196 /* Novatel E362 */ - #define KYOCERA_VENDOR_ID 0x0c88 #define KYOCERA_PRODUCT_KPC650 0x17da #define KYOCERA_PRODUCT_KPC680 0x180a @@ -287,7 +282,6 @@ static void option_instat_callback(struct urb *urb); /* ALCATEL PRODUCTS */ #define ALCATEL_VENDOR_ID 0x1bbb #define ALCATEL_PRODUCT_X060S_X200 0x0000 -#define ALCATEL_PRODUCT_X220_X500D 0x0017 #define PIRELLI_VENDOR_ID 0x1266 #define PIRELLI_PRODUCT_C100_1 0x1002 @@ -711,7 +705,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) }, /* Novatel Ovation MC551 a.k.a. Verizon USB551L */ { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, @@ -734,8 +727,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ - { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_MINICARD_VZW, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_V2_MINICARD_VZW, 0xff, 0xff, 0xff) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, @@ -1165,7 +1156,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist }, - { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D) }, { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), @@ -1298,9 +1288,8 @@ static struct usb_serial_driver option_1port_device = { .tiocmget = usb_wwan_tiocmget, .tiocmset = usb_wwan_tiocmset, .ioctl = usb_wwan_ioctl, - .attach = option_attach, + .attach = usb_wwan_startup, .release = option_release, - .port_probe = usb_wwan_port_probe, .port_remove = usb_wwan_port_remove, .read_int_callback = option_instat_callback, #ifdef CONFIG_PM @@ -1346,6 +1335,8 @@ static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason, static int option_probe(struct usb_serial *serial, const struct usb_device_id *id) { + struct usb_wwan_intf_private *data; + struct option_private *priv; struct usb_interface_descriptor *iface_desc = &serial->interface->cur_altsetting->desc; struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; @@ -1383,19 +1374,6 @@ static int option_probe(struct usb_serial *serial, iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) return -ENODEV; - /* Store device id so we can use it during attach. */ - usb_set_serial_data(serial, (void *)id); - - return 0; -} - -static int option_attach(struct usb_serial *serial) -{ - struct usb_interface_descriptor *iface_desc; - const struct usb_device_id *id; - struct usb_wwan_intf_private *data; - struct option_private *priv; - data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); if (!data) return -ENOMEM; @@ -1406,10 +1384,6 @@ static int option_attach(struct usb_serial *serial) return -ENOMEM; } - /* Retrieve device id stored at probe. */ - id = usb_get_serial_data(serial); - iface_desc = &serial->interface->cur_altsetting->desc; - priv->bInterfaceNumber = iface_desc->bInterfaceNumber; data->private = priv; diff --git a/trunk/drivers/usb/serial/qcserial.c b/trunk/drivers/usb/serial/qcserial.c index aa148c21ea40..c3ddb65c05f2 100644 --- a/trunk/drivers/usb/serial/qcserial.c +++ b/trunk/drivers/usb/serial/qcserial.c @@ -138,6 +138,7 @@ MODULE_DEVICE_TABLE(usb, id_table); static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) { + struct usb_wwan_intf_private *data; struct usb_host_interface *intf = serial->interface->cur_altsetting; struct device *dev = &serial->dev->dev; int retval = -ENODEV; @@ -153,6 +154,13 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) ifnum = intf->desc.bInterfaceNumber; dev_dbg(dev, "This Interface = %d\n", ifnum); + data = kzalloc(sizeof(struct usb_wwan_intf_private), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + spin_lock_init(&data->susp_lock); + if (nintf == 1) { /* QDL mode */ /* Gobi 2000 has a single altsetting, older ones have two */ @@ -245,28 +253,20 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) } } - return retval; -} - -static int qc_attach(struct usb_serial *serial) -{ - struct usb_wwan_intf_private *data; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; + /* Set serial->private if not returning error */ + if (retval == 0) + usb_set_serial_data(serial, data); + else + kfree(data); - spin_lock_init(&data->susp_lock); - - usb_set_serial_data(serial, data); - - return 0; + return retval; } static void qc_release(struct usb_serial *serial) { struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); + /* Free the private data allocated in qcprobe */ usb_set_serial_data(serial, NULL); kfree(priv); } @@ -285,9 +285,8 @@ static struct usb_serial_driver qcdevice = { .write = usb_wwan_write, .write_room = usb_wwan_write_room, .chars_in_buffer = usb_wwan_chars_in_buffer, - .attach = qc_attach, + .attach = usb_wwan_startup, .release = qc_release, - .port_probe = usb_wwan_port_probe, .port_remove = usb_wwan_port_remove, #ifdef CONFIG_PM .suspend = usb_wwan_suspend, diff --git a/trunk/drivers/usb/serial/quatech2.c b/trunk/drivers/usb/serial/quatech2.c index ffcfc962ab10..2cdfdcc90b37 100644 --- a/trunk/drivers/usb/serial/quatech2.c +++ b/trunk/drivers/usb/serial/quatech2.c @@ -143,12 +143,12 @@ static void qt2_read_bulk_callback(struct urb *urb); static void qt2_release(struct usb_serial *serial) { - struct qt2_serial_private *serial_priv; + int i; - serial_priv = usb_get_serial_data(serial); + kfree(usb_get_serial_data(serial)); - usb_free_urb(serial_priv->read_urb); - kfree(serial_priv); + for (i = 0; i < serial->num_ports; i++) + kfree(usb_get_serial_port_data(serial->port[i])); } static inline int calc_baud_divisor(int baudrate) @@ -423,16 +423,11 @@ static void qt2_close(struct usb_serial_port *port) port_priv->is_open = false; spin_lock_irqsave(&port_priv->urb_lock, flags); - usb_kill_urb(port_priv->write_urb); + if (port_priv->write_urb->status == -EINPROGRESS) + usb_kill_urb(port_priv->write_urb); port_priv->urb_in_use = false; spin_unlock_irqrestore(&port_priv->urb_lock, flags); - mutex_lock(&port->serial->disc_mutex); - if (port->serial->disconnected) { - mutex_unlock(&port->serial->disc_mutex); - return; - } - /* flush the port transmit buffer */ i = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), @@ -464,14 +459,26 @@ static void qt2_close(struct usb_serial_port *port) dev_err(&port->dev, "%s - close port failed %i\n", __func__, i); - mutex_unlock(&port->serial->disc_mutex); } static void qt2_disconnect(struct usb_serial *serial) { struct qt2_serial_private *serial_priv = usb_get_serial_data(serial); + struct qt2_port_private *port_priv; + int i; + + if (serial_priv->read_urb->status == -EINPROGRESS) + usb_kill_urb(serial_priv->read_urb); + + usb_free_urb(serial_priv->read_urb); - usb_kill_urb(serial_priv->read_urb); + for (i = 0; i < serial->num_ports; i++) { + port_priv = usb_get_serial_port_data(serial->port[i]); + + if (port_priv->write_urb->status == -EINPROGRESS) + usb_kill_urb(port_priv->write_urb); + usb_free_urb(port_priv->write_urb); + } } static int get_serial_info(struct usb_serial_port *port, @@ -766,9 +773,11 @@ static void qt2_read_bulk_callback(struct urb *urb) static int qt2_setup_urbs(struct usb_serial *serial) { + struct usb_serial_port *port; struct usb_serial_port *port0; struct qt2_serial_private *serial_priv; - int status; + struct qt2_port_private *port_priv; + int pcount, status; port0 = serial->port[0]; @@ -786,21 +795,46 @@ static int qt2_setup_urbs(struct usb_serial *serial) sizeof(serial_priv->read_buffer), qt2_read_bulk_callback, serial); + /* setup write_urb for each port */ + for (pcount = 0; pcount < serial->num_ports; pcount++) { + + port = serial->port[pcount]; + port_priv = usb_get_serial_port_data(port); + + port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!port_priv->write_urb) { + dev_err(&serial->dev->dev, + "failed to alloc write_urb for port %i\n", + pcount); + return -ENOMEM; + } + + usb_fill_bulk_urb(port_priv->write_urb, + serial->dev, + usb_sndbulkpipe(serial->dev, + port0-> + bulk_out_endpointAddress), + port_priv->write_buffer, + sizeof(port_priv->write_buffer), + qt2_write_bulk_callback, port); + } + status = usb_submit_urb(serial_priv->read_urb, GFP_KERNEL); if (status != 0) { dev_err(&serial->dev->dev, "%s - submit read urb failed %i\n", __func__, status); - usb_free_urb(serial_priv->read_urb); return status; } return 0; + } static int qt2_attach(struct usb_serial *serial) { struct qt2_serial_private *serial_priv; - int status; + struct qt2_port_private *port_priv; + int status, pcount; /* power on unit */ status = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), @@ -820,6 +854,26 @@ static int qt2_attach(struct usb_serial *serial) usb_set_serial_data(serial, serial_priv); + for (pcount = 0; pcount < serial->num_ports; pcount++) { + port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); + if (!port_priv) { + dev_err(&serial->dev->dev, + "%s- kmalloc(%Zd) failed.\n", __func__, + sizeof(*port_priv)); + pcount--; + status = -ENOMEM; + goto attach_failed; + } + + spin_lock_init(&port_priv->lock); + spin_lock_init(&port_priv->urb_lock); + init_waitqueue_head(&port_priv->delta_msr_wait); + + port_priv->port = serial->port[pcount]; + + usb_set_serial_port_data(serial->port[pcount], port_priv); + } + status = qt2_setup_urbs(serial); if (status != 0) goto attach_failed; @@ -827,51 +881,12 @@ static int qt2_attach(struct usb_serial *serial) return 0; attach_failed: - kfree(serial_priv); - return status; -} - -static int qt2_port_probe(struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - struct qt2_port_private *port_priv; - u8 bEndpointAddress; - - port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); - if (!port_priv) - return -ENOMEM; - - spin_lock_init(&port_priv->lock); - spin_lock_init(&port_priv->urb_lock); - init_waitqueue_head(&port_priv->delta_msr_wait); - port_priv->port = port; - - port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!port_priv->write_urb) { + for (/* empty */; pcount >= 0; pcount--) { + port_priv = usb_get_serial_port_data(serial->port[pcount]); kfree(port_priv); - return -ENOMEM; } - bEndpointAddress = serial->port[0]->bulk_out_endpointAddress; - usb_fill_bulk_urb(port_priv->write_urb, serial->dev, - usb_sndbulkpipe(serial->dev, bEndpointAddress), - port_priv->write_buffer, - sizeof(port_priv->write_buffer), - qt2_write_bulk_callback, port); - - usb_set_serial_port_data(port, port_priv); - - return 0; -} - -static int qt2_port_remove(struct usb_serial_port *port) -{ - struct qt2_port_private *port_priv; - - port_priv = usb_get_serial_port_data(port); - usb_free_urb(port_priv->write_urb); - kfree(port_priv); - - return 0; + kfree(serial_priv); + return status; } static int qt2_tiocmget(struct tty_struct *tty) @@ -1112,8 +1127,6 @@ static struct usb_serial_driver qt2_device = { .attach = qt2_attach, .release = qt2_release, .disconnect = qt2_disconnect, - .port_probe = qt2_port_probe, - .port_remove = qt2_port_remove, .dtr_rts = qt2_dtr_rts, .break_ctl = qt2_break_ctl, .tiocmget = qt2_tiocmget, diff --git a/trunk/drivers/usb/serial/sierra.c b/trunk/drivers/usb/serial/sierra.c index 270860f6bb2a..01d882cf3775 100644 --- a/trunk/drivers/usb/serial/sierra.c +++ b/trunk/drivers/usb/serial/sierra.c @@ -161,6 +161,7 @@ static int sierra_probe(struct usb_serial *serial, { int result = 0; struct usb_device *udev; + struct sierra_intf_private *data; u8 ifnum; udev = serial->dev; @@ -187,6 +188,11 @@ static int sierra_probe(struct usb_serial *serial, return -ENODEV; } + data = serial->private = kzalloc(sizeof(struct sierra_intf_private), GFP_KERNEL); + if (!data) + return -ENOMEM; + spin_lock_init(&data->susp_lock); + return result; } @@ -878,15 +884,11 @@ static void sierra_dtr_rts(struct usb_serial_port *port, int on) static int sierra_startup(struct usb_serial *serial) { - struct sierra_intf_private *intfdata; - - intfdata = kzalloc(sizeof(*intfdata), GFP_KERNEL); - if (!intfdata) - return -ENOMEM; - - spin_lock_init(&intfdata->susp_lock); - - usb_set_serial_data(serial, intfdata); + struct usb_serial_port *port; + struct sierra_port_private *portdata; + struct sierra_iface_info *himemoryp = NULL; + int i; + u8 ifnum; /* Set Device mode to D0 */ sierra_set_power_state(serial->dev, 0x0000); @@ -895,71 +897,68 @@ static int sierra_startup(struct usb_serial *serial) if (nmea) sierra_vsc_set_nmea(serial->dev, 1); - return 0; -} - -static void sierra_release(struct usb_serial *serial) -{ - struct sierra_intf_private *intfdata; - - intfdata = usb_get_serial_data(serial); - kfree(intfdata); -} - -static int sierra_port_probe(struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - struct sierra_port_private *portdata; - const struct sierra_iface_info *himemoryp; - u8 ifnum; - - portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); - if (!portdata) - return -ENOMEM; - - spin_lock_init(&portdata->lock); - init_usb_anchor(&portdata->active); - init_usb_anchor(&portdata->delayed); - - /* Assume low memory requirements */ - portdata->num_out_urbs = N_OUT_URB; - portdata->num_in_urbs = N_IN_URB; - - /* Determine actual memory requirements */ - if (serial->num_ports == 1) { - /* Get interface number for composite device */ - ifnum = sierra_calc_interface(serial); - himemoryp = &typeB_interface_list; - } else { - /* This is really the usb-serial port number of the interface - * rather than the interface number. - */ - ifnum = port->number - serial->minor; - himemoryp = &typeA_interface_list; - } - - if (is_himemory(ifnum, himemoryp)) { - portdata->num_out_urbs = N_OUT_URB_HM; - portdata->num_in_urbs = N_IN_URB_HM; - } - - dev_dbg(&port->dev, + /* Now setup per port private data */ + for (i = 0; i < serial->num_ports; i++) { + port = serial->port[i]; + portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); + if (!portdata) { + dev_dbg(&port->dev, "%s: kmalloc for " + "sierra_port_private (%d) failed!\n", + __func__, i); + return -ENOMEM; + } + spin_lock_init(&portdata->lock); + init_usb_anchor(&portdata->active); + init_usb_anchor(&portdata->delayed); + ifnum = i; + /* Assume low memory requirements */ + portdata->num_out_urbs = N_OUT_URB; + portdata->num_in_urbs = N_IN_URB; + + /* Determine actual memory requirements */ + if (serial->num_ports == 1) { + /* Get interface number for composite device */ + ifnum = sierra_calc_interface(serial); + himemoryp = + (struct sierra_iface_info *)&typeB_interface_list; + if (is_himemory(ifnum, himemoryp)) { + portdata->num_out_urbs = N_OUT_URB_HM; + portdata->num_in_urbs = N_IN_URB_HM; + } + } + else { + himemoryp = + (struct sierra_iface_info *)&typeA_interface_list; + if (is_himemory(i, himemoryp)) { + portdata->num_out_urbs = N_OUT_URB_HM; + portdata->num_in_urbs = N_IN_URB_HM; + } + } + dev_dbg(&serial->dev->dev, "Memory usage (urbs) interface #%d, in=%d, out=%d\n", - ifnum, portdata->num_in_urbs, portdata->num_out_urbs); - - usb_set_serial_port_data(port, portdata); + ifnum,portdata->num_in_urbs, portdata->num_out_urbs ); + /* Set the port private data pointer */ + usb_set_serial_port_data(port, portdata); + } return 0; } -static int sierra_port_remove(struct usb_serial_port *port) +static void sierra_release(struct usb_serial *serial) { + int i; + struct usb_serial_port *port; struct sierra_port_private *portdata; - portdata = usb_get_serial_port_data(port); - kfree(portdata); - - return 0; + for (i = 0; i < serial->num_ports; ++i) { + port = serial->port[i]; + if (!port) + continue; + portdata = usb_get_serial_port_data(port); + if (!portdata) + continue; + kfree(portdata); + } } #ifdef CONFIG_PM @@ -1063,8 +1062,6 @@ static struct usb_serial_driver sierra_device = { .tiocmset = sierra_tiocmset, .attach = sierra_startup, .release = sierra_release, - .port_probe = sierra_port_probe, - .port_remove = sierra_port_remove, .suspend = sierra_suspend, .resume = sierra_resume, .read_int_callback = sierra_instat_callback, diff --git a/trunk/drivers/usb/serial/usb-wwan.h b/trunk/drivers/usb/serial/usb-wwan.h index 684739b8efd0..1f034d2397c6 100644 --- a/trunk/drivers/usb/serial/usb-wwan.h +++ b/trunk/drivers/usb/serial/usb-wwan.h @@ -8,7 +8,7 @@ extern void usb_wwan_dtr_rts(struct usb_serial_port *port, int on); extern int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port); extern void usb_wwan_close(struct usb_serial_port *port); -extern int usb_wwan_port_probe(struct usb_serial_port *port); +extern int usb_wwan_startup(struct usb_serial *serial); extern int usb_wwan_port_remove(struct usb_serial_port *port); extern int usb_wwan_write_room(struct tty_struct *tty); extern void usb_wwan_set_termios(struct tty_struct *tty, diff --git a/trunk/drivers/usb/serial/usb_wwan.c b/trunk/drivers/usb/serial/usb_wwan.c index a3e9c095f0d8..e42aa398ed37 100644 --- a/trunk/drivers/usb/serial/usb_wwan.c +++ b/trunk/drivers/usb/serial/usb_wwan.c @@ -447,14 +447,15 @@ void usb_wwan_close(struct usb_serial_port *port) EXPORT_SYMBOL(usb_wwan_close); /* Helper functions used by usb_wwan_setup_urbs */ -static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port, - int endpoint, +static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint, int dir, void *ctx, char *buf, int len, void (*callback) (struct urb *)) { - struct usb_serial *serial = port->serial; struct urb *urb; + if (endpoint == -1) + return NULL; /* endpoint not needed */ + urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ if (urb == NULL) { dev_dbg(&serial->interface->dev, @@ -471,78 +472,101 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port, return urb; } -int usb_wwan_port_probe(struct usb_serial_port *port) +/* Setup urbs */ +static void usb_wwan_setup_urbs(struct usb_serial *serial) { + int i, j; + struct usb_serial_port *port; struct usb_wwan_port_private *portdata; - struct urb *urb; - u8 *buffer; - int err; - int i; - - portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); - if (!portdata) - return -ENOMEM; - init_usb_anchor(&portdata->delayed); - - for (i = 0; i < N_IN_URB; i++) { - if (!port->bulk_in_size) - break; + for (i = 0; i < serial->num_ports; i++) { + port = serial->port[i]; + portdata = usb_get_serial_port_data(port); - buffer = (u8 *)__get_free_page(GFP_KERNEL); - if (!buffer) - goto bail_out_error; - portdata->in_buffer[i] = buffer; + /* Do indat endpoints first */ + for (j = 0; j < N_IN_URB; ++j) { + portdata->in_urbs[j] = usb_wwan_setup_urb(serial, + port-> + bulk_in_endpointAddress, + USB_DIR_IN, + port, + portdata-> + in_buffer[j], + IN_BUFLEN, + usb_wwan_indat_callback); + } - urb = usb_wwan_setup_urb(port, port->bulk_in_endpointAddress, - USB_DIR_IN, port, - buffer, IN_BUFLEN, - usb_wwan_indat_callback); - portdata->in_urbs[i] = urb; + /* outdat endpoints */ + for (j = 0; j < N_OUT_URB; ++j) { + portdata->out_urbs[j] = usb_wwan_setup_urb(serial, + port-> + bulk_out_endpointAddress, + USB_DIR_OUT, + port, + portdata-> + out_buffer + [j], + OUT_BUFLEN, + usb_wwan_outdat_callback); + } } +} - for (i = 0; i < N_OUT_URB; i++) { - if (!port->bulk_out_size) - break; +int usb_wwan_startup(struct usb_serial *serial) +{ + int i, j, err; + struct usb_serial_port *port; + struct usb_wwan_port_private *portdata; + u8 *buffer; - buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); - if (!buffer) - goto bail_out_error2; - portdata->out_buffer[i] = buffer; + /* Now setup per port private data */ + for (i = 0; i < serial->num_ports; i++) { + port = serial->port[i]; + portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); + if (!portdata) { + dev_dbg(&port->dev, "%s: kmalloc for usb_wwan_port_private (%d) failed!.\n", + __func__, i); + return 1; + } + init_usb_anchor(&portdata->delayed); - urb = usb_wwan_setup_urb(port, port->bulk_out_endpointAddress, - USB_DIR_OUT, port, - buffer, OUT_BUFLEN, - usb_wwan_outdat_callback); - portdata->out_urbs[i] = urb; - } + for (j = 0; j < N_IN_URB; j++) { + buffer = (u8 *) __get_free_page(GFP_KERNEL); + if (!buffer) + goto bail_out_error; + portdata->in_buffer[j] = buffer; + } - usb_set_serial_port_data(port, portdata); + for (j = 0; j < N_OUT_URB; j++) { + buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); + if (!buffer) + goto bail_out_error2; + portdata->out_buffer[j] = buffer; + } - if (port->interrupt_in_urb) { + usb_set_serial_port_data(port, portdata); + + if (!port->interrupt_in_urb) + continue; err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (err) dev_dbg(&port->dev, "%s: submit irq_in urb failed %d\n", __func__, err); } - + usb_wwan_setup_urbs(serial); return 0; bail_out_error2: - for (i = 0; i < N_OUT_URB; i++) { - usb_free_urb(portdata->out_urbs[i]); - kfree(portdata->out_buffer[i]); - } + for (j = 0; j < N_OUT_URB; j++) + kfree(portdata->out_buffer[j]); bail_out_error: - for (i = 0; i < N_IN_URB; i++) { - usb_free_urb(portdata->in_urbs[i]); - free_page((unsigned long)portdata->in_buffer[i]); - } + for (j = 0; j < N_IN_URB; j++) + if (portdata->in_buffer[j]) + free_page((unsigned long)portdata->in_buffer[j]); kfree(portdata); - - return -ENOMEM; + return 1; } -EXPORT_SYMBOL_GPL(usb_wwan_port_probe); +EXPORT_SYMBOL(usb_wwan_startup); int usb_wwan_port_remove(struct usb_serial_port *port) { diff --git a/trunk/drivers/usb/serial/whiteheat.c b/trunk/drivers/usb/serial/whiteheat.c index b9fca3586d74..346c7efc20b0 100644 --- a/trunk/drivers/usb/serial/whiteheat.c +++ b/trunk/drivers/usb/serial/whiteheat.c @@ -83,8 +83,6 @@ static int whiteheat_firmware_attach(struct usb_serial *serial); /* function prototypes for the Connect Tech WhiteHEAT serial converter */ static int whiteheat_attach(struct usb_serial *serial); static void whiteheat_release(struct usb_serial *serial); -static int whiteheat_port_probe(struct usb_serial_port *port); -static int whiteheat_port_remove(struct usb_serial_port *port); static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port); static void whiteheat_close(struct usb_serial_port *port); @@ -119,8 +117,6 @@ static struct usb_serial_driver whiteheat_device = { .num_ports = 4, .attach = whiteheat_attach, .release = whiteheat_release, - .port_probe = whiteheat_port_probe, - .port_remove = whiteheat_port_remove, .open = whiteheat_open, .close = whiteheat_close, .ioctl = whiteheat_ioctl, @@ -222,12 +218,15 @@ static int whiteheat_attach(struct usb_serial *serial) { struct usb_serial_port *command_port; struct whiteheat_command_private *command_info; + struct usb_serial_port *port; + struct whiteheat_private *info; struct whiteheat_hw_info *hw_info; int pipe; int ret; int alen; __u8 *command; __u8 *result; + int i; command_port = serial->port[COMMAND_PORT]; @@ -286,6 +285,22 @@ static int whiteheat_attach(struct usb_serial *serial) serial->type->description, hw_info->sw_major_rev, hw_info->sw_minor_rev); + for (i = 0; i < serial->num_ports; i++) { + port = serial->port[i]; + + info = kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL); + if (info == NULL) { + dev_err(&port->dev, + "%s: Out of memory for port structures\n", + serial->type->description); + goto no_private; + } + + info->mcr = 0; + + usb_set_serial_port_data(port, info); + } + command_info = kmalloc(sizeof(struct whiteheat_command_private), GFP_KERNEL); if (command_info == NULL) { @@ -318,10 +333,16 @@ static int whiteheat_attach(struct usb_serial *serial) "%s: please contact support@connecttech.com\n", serial->type->description); kfree(result); - kfree(command); return -ENODEV; no_command_private: + for (i = serial->num_ports - 1; i >= 0; i--) { + port = serial->port[i]; + info = usb_get_serial_port_data(port); + kfree(info); +no_private: + ; + } kfree(result); no_result_buffer: kfree(command); @@ -329,36 +350,21 @@ static int whiteheat_attach(struct usb_serial *serial) return -ENOMEM; } + static void whiteheat_release(struct usb_serial *serial) { struct usb_serial_port *command_port; + struct whiteheat_private *info; + int i; /* free up our private data for our command port */ command_port = serial->port[COMMAND_PORT]; kfree(usb_get_serial_port_data(command_port)); -} - -static int whiteheat_port_probe(struct usb_serial_port *port) -{ - struct whiteheat_private *info; - - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) - return -ENOMEM; - - usb_set_serial_port_data(port, info); - - return 0; -} -static int whiteheat_port_remove(struct usb_serial_port *port) -{ - struct whiteheat_private *info; - - info = usb_get_serial_port_data(port); - kfree(info); - - return 0; + for (i = 0; i < serial->num_ports; i++) { + info = usb_get_serial_port_data(serial->port[i]); + kfree(info); + } } static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port) diff --git a/trunk/drivers/usb/storage/scsiglue.c b/trunk/drivers/usb/storage/scsiglue.c index 92f35abee92d..a3d54366afcc 100644 --- a/trunk/drivers/usb/storage/scsiglue.c +++ b/trunk/drivers/usb/storage/scsiglue.c @@ -186,12 +186,6 @@ static int slave_configure(struct scsi_device *sdev) /* Some devices don't handle VPD pages correctly */ sdev->skip_vpd_pages = 1; - /* Do not attempt to use REPORT SUPPORTED OPERATION CODES */ - sdev->no_report_opcodes = 1; - - /* Do not attempt to use WRITE SAME */ - sdev->no_write_same = 1; - /* Some disks return the total number of blocks in response * to READ CAPACITY rather than the highest block number. * If this device makes that mistake, tell the sd driver. */ diff --git a/trunk/drivers/usb/storage/unusual_devs.h b/trunk/drivers/usb/storage/unusual_devs.h index d305a5aa3a5d..779cd954abcb 100644 --- a/trunk/drivers/usb/storage/unusual_devs.h +++ b/trunk/drivers/usb/storage/unusual_devs.h @@ -1004,12 +1004,6 @@ UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9999, USB_SC_8070, USB_PR_CB, NULL, US_FL_NEED_OVERRIDE | US_FL_FIX_INQUIRY ), -/* Submitted by Oleksandr Chumachenko */ -UNUSUAL_DEV( 0x07cf, 0x1167, 0x0100, 0x0100, - "Casio", - "EX-N1 DigitalCamera", - USB_SC_8070, USB_PR_DEVICE, NULL, 0), - /* Submitted by Hartmut Wahl */ UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001, "Samsung", diff --git a/trunk/drivers/vhost/net.c b/trunk/drivers/vhost/net.c index 7f93f34b7f91..072cbbadbc36 100644 --- a/trunk/drivers/vhost/net.c +++ b/trunk/drivers/vhost/net.c @@ -379,8 +379,7 @@ static void handle_rx(struct vhost_net *net) .hdr.gso_type = VIRTIO_NET_HDR_GSO_NONE }; size_t total_len = 0; - int err, mergeable; - s16 headcount; + int err, headcount, mergeable; size_t vhost_hlen, sock_hlen; size_t vhost_len, sock_len; /* TODO: check that we are running from vhost_worker? */ diff --git a/trunk/drivers/vhost/vhost.c b/trunk/drivers/vhost/vhost.c index dedaf81d8f36..99ac2cb08b43 100644 --- a/trunk/drivers/vhost/vhost.c +++ b/trunk/drivers/vhost/vhost.c @@ -1076,7 +1076,7 @@ static int translate_desc(struct vhost_dev *dev, u64 addr, u32 len, } _iov = iov + ret; size = reg->memory_size - addr + reg->guest_phys_addr; - _iov->iov_len = min((u64)len - s, size); + _iov->iov_len = min((u64)len, size); _iov->iov_base = (void __user *)(unsigned long) (reg->userspace_addr + addr - reg->guest_phys_addr); s += size; diff --git a/trunk/drivers/video/backlight/Kconfig b/trunk/drivers/video/backlight/Kconfig index 765a945f8ea1..c101697a4ba7 100644 --- a/trunk/drivers/video/backlight/Kconfig +++ b/trunk/drivers/video/backlight/Kconfig @@ -60,8 +60,7 @@ config LCD_LTV350QV The LTV350QV panel is present on all ATSTK1000 boards. config LCD_ILI9320 - tristate "ILI Technology ILI9320 controller support" - depends on SPI + tristate help If you have a panel based on the ILI9320 controller chip then say y to include a power driver for it. diff --git a/trunk/drivers/video/omap2/dss/dsi.c b/trunk/drivers/video/omap2/dss/dsi.c index bee92846cfab..d64ac3842884 100644 --- a/trunk/drivers/video/omap2/dss/dsi.c +++ b/trunk/drivers/video/omap2/dss/dsi.c @@ -365,20 +365,11 @@ struct platform_device *dsi_get_dsidev_from_id(int module) struct omap_dss_output *out; enum omap_dss_output_id id; - switch (module) { - case 0: - id = OMAP_DSS_OUTPUT_DSI1; - break; - case 1: - id = OMAP_DSS_OUTPUT_DSI2; - break; - default: - return NULL; - } + id = module == 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2; out = omap_dss_get_output(id); - return out ? out->pdev : NULL; + return out->pdev; } static inline void dsi_write_reg(struct platform_device *dsidev, diff --git a/trunk/drivers/video/omap2/dss/dss.c b/trunk/drivers/video/omap2/dss/dss.c index 5f6eea801b06..2ab1c3e96553 100644 --- a/trunk/drivers/video/omap2/dss/dss.c +++ b/trunk/drivers/video/omap2/dss/dss.c @@ -697,15 +697,11 @@ static int dss_get_clocks(void) dss.dss_clk = clk; - if (dss.feat->clk_name) { - clk = clk_get(NULL, dss.feat->clk_name); - if (IS_ERR(clk)) { - DSSERR("Failed to get %s\n", dss.feat->clk_name); - r = PTR_ERR(clk); - goto err; - } - } else { - clk = NULL; + clk = clk_get(NULL, dss.feat->clk_name); + if (IS_ERR(clk)) { + DSSERR("Failed to get %s\n", dss.feat->clk_name); + r = PTR_ERR(clk); + goto err; } dss.dpll4_m4_ck = clk; @@ -809,10 +805,10 @@ static int __init dss_init_features(struct device *dev) if (cpu_is_omap24xx()) src = &omap24xx_dss_feats; - else if (cpu_is_omap3630()) - src = &omap3630_dss_feats; else if (cpu_is_omap34xx()) src = &omap34xx_dss_feats; + else if (cpu_is_omap3630()) + src = &omap3630_dss_feats; else if (cpu_is_omap44xx()) src = &omap44xx_dss_feats; else if (soc_is_omap54xx()) diff --git a/trunk/drivers/video/omap2/dss/hdmi.c b/trunk/drivers/video/omap2/dss/hdmi.c index 8c9b8b3b7f77..a48a7dd75b33 100644 --- a/trunk/drivers/video/omap2/dss/hdmi.c +++ b/trunk/drivers/video/omap2/dss/hdmi.c @@ -644,10 +644,8 @@ static void hdmi_dump_regs(struct seq_file *s) { mutex_lock(&hdmi.lock); - if (hdmi_runtime_get()) { - mutex_unlock(&hdmi.lock); + if (hdmi_runtime_get()) return; - } hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s); hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s); diff --git a/trunk/drivers/video/omap2/omapfb/omapfb-ioctl.c b/trunk/drivers/video/omap2/omapfb/omapfb-ioctl.c index d630b26a005c..606b89f12351 100644 --- a/trunk/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/trunk/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -787,7 +787,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) case OMAPFB_WAITFORVSYNC: DBG("ioctl WAITFORVSYNC\n"); - if (!display || !display->output || !display->output->manager) { + if (!display && !display->output && !display->output->manager) { r = -EINVAL; break; } diff --git a/trunk/drivers/video/xen-fbfront.c b/trunk/drivers/video/xen-fbfront.c index 917bb5681684..b7f5173ff9e9 100644 --- a/trunk/drivers/video/xen-fbfront.c +++ b/trunk/drivers/video/xen-fbfront.c @@ -641,6 +641,7 @@ static void xenfb_backend_changed(struct xenbus_device *dev, case XenbusStateReconfiguring: case XenbusStateReconfigured: case XenbusStateUnknown: + case XenbusStateClosed: break; case XenbusStateInitWait: @@ -669,10 +670,6 @@ static void xenfb_backend_changed(struct xenbus_device *dev, info->feature_resize = val; break; - case XenbusStateClosed: - if (dev->state == XenbusStateClosed) - break; - /* Missed the backend's CLOSING state -- fallthrough */ case XenbusStateClosing: xenbus_frontend_closed(dev); break; diff --git a/trunk/drivers/virtio/virtio.c b/trunk/drivers/virtio/virtio.c index 809b0de59c09..1e8659ca27ef 100644 --- a/trunk/drivers/virtio/virtio.c +++ b/trunk/drivers/virtio/virtio.c @@ -225,10 +225,8 @@ EXPORT_SYMBOL_GPL(register_virtio_device); void unregister_virtio_device(struct virtio_device *dev) { - int index = dev->index; /* save for after device release */ - device_unregister(&dev->dev); - ida_simple_remove(&virtio_index_ida, index); + ida_simple_remove(&virtio_index_ida, dev->index); } EXPORT_SYMBOL_GPL(unregister_virtio_device); diff --git a/trunk/drivers/xen/Kconfig b/trunk/drivers/xen/Kconfig index 126d8ce591ce..d4dffcd52873 100644 --- a/trunk/drivers/xen/Kconfig +++ b/trunk/drivers/xen/Kconfig @@ -3,7 +3,6 @@ menu "Xen driver support" config XEN_BALLOON bool "Xen memory balloon driver" - depends on !ARM default y help The balloon driver allows the Xen domain to request more memory from @@ -146,7 +145,6 @@ config SWIOTLB_XEN config XEN_TMEM bool - depends on !ARM default y if (CLEANCACHE || FRONTSWAP) help Shim to interface in-kernel Transcendent Memory hooks diff --git a/trunk/drivers/xen/Makefile b/trunk/drivers/xen/Makefile index 74354708c6c4..0e8637035457 100644 --- a/trunk/drivers/xen/Makefile +++ b/trunk/drivers/xen/Makefile @@ -2,7 +2,6 @@ ifneq ($(CONFIG_ARM),y) obj-y += manage.o balloon.o obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o endif -obj-$(CONFIG_X86) += fallback.o obj-y += grant-table.o features.o events.o obj-y += xenbus/ diff --git a/trunk/drivers/xen/balloon.c b/trunk/drivers/xen/balloon.c index d6886d90ccfd..31ab82fda38a 100644 --- a/trunk/drivers/xen/balloon.c +++ b/trunk/drivers/xen/balloon.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -87,7 +88,7 @@ struct balloon_stats balloon_stats; EXPORT_SYMBOL_GPL(balloon_stats); /* We increase/decrease in batches which fit in a page */ -static xen_pfn_t frame_list[PAGE_SIZE / sizeof(unsigned long)]; +static unsigned long frame_list[PAGE_SIZE / sizeof(unsigned long)]; #ifdef CONFIG_HIGHMEM #define inc_totalhigh_pages() (totalhigh_pages++) diff --git a/trunk/drivers/xen/dbgp.c b/trunk/drivers/xen/dbgp.c index f3ccc80a455f..42569c77ccc8 100644 --- a/trunk/drivers/xen/dbgp.c +++ b/trunk/drivers/xen/dbgp.c @@ -8,9 +8,7 @@ static int xen_dbgp_op(struct usb_hcd *hcd, int op) { -#ifdef CONFIG_PCI const struct device *ctrlr = hcd_to_bus(hcd)->controller; -#endif struct physdev_dbgp_op dbgp; if (!xen_initial_domain()) diff --git a/trunk/drivers/xen/events.c b/trunk/drivers/xen/events.c index 0be4df39e953..59e10a1286d5 100644 --- a/trunk/drivers/xen/events.c +++ b/trunk/drivers/xen/events.c @@ -115,9 +115,7 @@ struct irq_info { #define PIRQ_SHAREABLE (1 << 1) static int *evtchn_to_irq; -#ifdef CONFIG_X86 static unsigned long *pirq_eoi_map; -#endif static bool (*pirq_needs_eoi)(unsigned irq); static DEFINE_PER_CPU(unsigned long [NR_EVENT_CHANNELS/BITS_PER_LONG], @@ -279,12 +277,10 @@ static unsigned int cpu_from_evtchn(unsigned int evtchn) return ret; } -#ifdef CONFIG_X86 static bool pirq_check_eoi_map(unsigned irq) { return test_bit(pirq_from_irq(irq), pirq_eoi_map); } -#endif static bool pirq_needs_eoi_flag(unsigned irq) { @@ -1395,10 +1391,10 @@ void xen_evtchn_do_upcall(struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); - irq_enter(); #ifdef CONFIG_X86 exit_idle(); #endif + irq_enter(); __xen_evtchn_do_upcall(); diff --git a/trunk/drivers/xen/fallback.c b/trunk/drivers/xen/fallback.c deleted file mode 100644 index 0ef7c4d40f86..000000000000 --- a/trunk/drivers/xen/fallback.c +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include -#include -#include -#include -#include - -int xen_event_channel_op_compat(int cmd, void *arg) -{ - struct evtchn_op op; - int rc; - - op.cmd = cmd; - memcpy(&op.u, arg, sizeof(op.u)); - rc = _hypercall1(int, event_channel_op_compat, &op); - - switch (cmd) { - case EVTCHNOP_close: - case EVTCHNOP_send: - case EVTCHNOP_bind_vcpu: - case EVTCHNOP_unmask: - /* no output */ - break; - -#define COPY_BACK(eop) \ - case EVTCHNOP_##eop: \ - memcpy(arg, &op.u.eop, sizeof(op.u.eop)); \ - break - - COPY_BACK(bind_interdomain); - COPY_BACK(bind_virq); - COPY_BACK(bind_pirq); - COPY_BACK(status); - COPY_BACK(alloc_unbound); - COPY_BACK(bind_ipi); -#undef COPY_BACK - - default: - WARN_ON(rc != -ENOSYS); - break; - } - - return rc; -} -EXPORT_SYMBOL_GPL(xen_event_channel_op_compat); - -int HYPERVISOR_physdev_op_compat(int cmd, void *arg) -{ - struct physdev_op op; - int rc; - - op.cmd = cmd; - memcpy(&op.u, arg, sizeof(op.u)); - rc = _hypercall1(int, physdev_op_compat, &op); - - switch (cmd) { - case PHYSDEVOP_IRQ_UNMASK_NOTIFY: - case PHYSDEVOP_set_iopl: - case PHYSDEVOP_set_iobitmap: - case PHYSDEVOP_apic_write: - /* no output */ - break; - -#define COPY_BACK(pop, fld) \ - case PHYSDEVOP_##pop: \ - memcpy(arg, &op.u.fld, sizeof(op.u.fld)); \ - break - - COPY_BACK(irq_status_query, irq_status_query); - COPY_BACK(apic_read, apic_op); - COPY_BACK(ASSIGN_VECTOR, irq_op); -#undef COPY_BACK - - default: - WARN_ON(rc != -ENOSYS); - break; - } - - return rc; -} diff --git a/trunk/drivers/xen/gntdev.c b/trunk/drivers/xen/gntdev.c index 2e22df2f7a3f..610bfc6be177 100644 --- a/trunk/drivers/xen/gntdev.c +++ b/trunk/drivers/xen/gntdev.c @@ -105,21 +105,6 @@ static void gntdev_print_maps(struct gntdev_priv *priv, #endif } -static void gntdev_free_map(struct grant_map *map) -{ - if (map == NULL) - return; - - if (map->pages) - free_xenballooned_pages(map->count, map->pages); - kfree(map->pages); - kfree(map->grants); - kfree(map->map_ops); - kfree(map->unmap_ops); - kfree(map->kmap_ops); - kfree(map); -} - static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) { struct grant_map *add; @@ -157,7 +142,12 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) return add; err: - gntdev_free_map(add); + kfree(add->pages); + kfree(add->grants); + kfree(add->map_ops); + kfree(add->unmap_ops); + kfree(add->kmap_ops); + kfree(add); return NULL; } @@ -208,9 +198,17 @@ static void gntdev_put_map(struct grant_map *map) evtchn_put(map->notify.event); } - if (map->pages && !use_ptemod) - unmap_grant_pages(map, 0, map->count); - gntdev_free_map(map); + if (map->pages) { + if (!use_ptemod) + unmap_grant_pages(map, 0, map->count); + + free_xenballooned_pages(map->count, map->pages); + } + kfree(map->pages); + kfree(map->grants); + kfree(map->map_ops); + kfree(map->unmap_ops); + kfree(map); } /* ------------------------------------------------------------------ */ diff --git a/trunk/drivers/xen/grant-table.c b/trunk/drivers/xen/grant-table.c index b91f14e83164..b2b0a375b348 100644 --- a/trunk/drivers/xen/grant-table.c +++ b/trunk/drivers/xen/grant-table.c @@ -84,7 +84,7 @@ struct gnttab_ops { * nr_gframes is the number of frames to map grant table. Returning * GNTST_okay means success and negative value means failure. */ - int (*map_frames)(xen_pfn_t *frames, unsigned int nr_gframes); + int (*map_frames)(unsigned long *frames, unsigned int nr_gframes); /* * Release a list of frames which are mapped in map_frames for grant * entry status. @@ -960,7 +960,7 @@ static unsigned nr_status_frames(unsigned nr_grant_frames) return (nr_grant_frames * GREFS_PER_GRANT_FRAME + SPP - 1) / SPP; } -static int gnttab_map_frames_v1(xen_pfn_t *frames, unsigned int nr_gframes) +static int gnttab_map_frames_v1(unsigned long *frames, unsigned int nr_gframes) { int rc; @@ -977,7 +977,7 @@ static void gnttab_unmap_frames_v1(void) arch_gnttab_unmap(gnttab_shared.addr, nr_grant_frames); } -static int gnttab_map_frames_v2(xen_pfn_t *frames, unsigned int nr_gframes) +static int gnttab_map_frames_v2(unsigned long *frames, unsigned int nr_gframes) { uint64_t *sframes; unsigned int nr_sframes; @@ -1029,7 +1029,7 @@ static void gnttab_unmap_frames_v2(void) static int gnttab_map(unsigned int start_idx, unsigned int end_idx) { struct gnttab_setup_table setup; - xen_pfn_t *frames; + unsigned long *frames; unsigned int nr_gframes = end_idx + 1; int rc; diff --git a/trunk/drivers/xen/privcmd.c b/trunk/drivers/xen/privcmd.c index 71f5c459b088..8adb9cc267f9 100644 --- a/trunk/drivers/xen/privcmd.c +++ b/trunk/drivers/xen/privcmd.c @@ -361,13 +361,13 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version) down_write(&mm->mmap_sem); vma = find_vma(mm, m.addr); + ret = -EINVAL; if (!vma || vma->vm_ops != &privcmd_vm_ops || (m.addr != vma->vm_start) || ((m.addr + (nr_pages << PAGE_SHIFT)) != vma->vm_end) || !privcmd_enforce_singleshot_mapping(vma)) { up_write(&mm->mmap_sem); - ret = -EINVAL; goto out; } @@ -383,16 +383,12 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version) up_write(&mm->mmap_sem); - if (version == 1) { - if (state.global_error) { - /* Write back errors in second pass. */ - state.user_mfn = (xen_pfn_t *)m.arr; - state.err = err_array; - ret = traverse_pages(m.num, sizeof(xen_pfn_t), - &pagelist, mmap_return_errors_v1, &state); - } else - ret = 0; - + if (state.global_error && (version == 1)) { + /* Write back errors in second pass. */ + state.user_mfn = (xen_pfn_t *)m.arr; + state.err = err_array; + ret = traverse_pages(m.num, sizeof(xen_pfn_t), + &pagelist, mmap_return_errors_v1, &state); } else if (version == 2) { ret = __copy_to_user(m.err, err_array, m.num * sizeof(int)); if (ret) diff --git a/trunk/drivers/xen/sys-hypervisor.c b/trunk/drivers/xen/sys-hypervisor.c index 96453f8a85c5..5e5ad7e28858 100644 --- a/trunk/drivers/xen/sys-hypervisor.c +++ b/trunk/drivers/xen/sys-hypervisor.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -285,8 +284,7 @@ static ssize_t virtual_start_show(struct hyp_sysfs_attr *attr, char *buffer) ret = HYPERVISOR_xen_version(XENVER_platform_parameters, parms); if (!ret) - ret = sprintf(buffer, "%"PRI_xen_ulong"\n", - parms->virt_start); + ret = sprintf(buffer, "%lx\n", parms->virt_start); kfree(parms); } diff --git a/trunk/drivers/xen/xen-pciback/vpci.c b/trunk/drivers/xen/xen-pciback/vpci.c index 0f478ac483cd..46d140baebd8 100644 --- a/trunk/drivers/xen/xen-pciback/vpci.c +++ b/trunk/drivers/xen/xen-pciback/vpci.c @@ -89,15 +89,9 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, mutex_lock(&vpci_dev->lock); - /* - * Keep multi-function devices together on the virtual PCI bus, except - * virtual functions. - */ - if (!dev->is_virtfn) { - for (slot = 0; slot < PCI_SLOT_MAX; slot++) { - if (list_empty(&vpci_dev->dev_list[slot])) - continue; - + /* Keep multi-function devices together on the virtual PCI bus */ + for (slot = 0; slot < PCI_SLOT_MAX; slot++) { + if (!list_empty(&vpci_dev->dev_list[slot])) { t = list_entry(list_first(&vpci_dev->dev_list[slot]), struct pci_dev_entry, list); @@ -122,7 +116,7 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, pci_name(dev), slot); list_add_tail(&dev_entry->list, &vpci_dev->dev_list[slot]); - func = dev->is_virtfn ? 0 : PCI_FUNC(dev->devfn); + func = PCI_FUNC(dev->devfn); goto unlock; } } diff --git a/trunk/drivers/xen/xenbus/xenbus_dev_frontend.c b/trunk/drivers/xen/xenbus/xenbus_dev_frontend.c index ac727028e658..89f76252a16f 100644 --- a/trunk/drivers/xen/xenbus/xenbus_dev_frontend.c +++ b/trunk/drivers/xen/xenbus/xenbus_dev_frontend.c @@ -458,7 +458,7 @@ static ssize_t xenbus_file_write(struct file *filp, goto out; /* Can't write a xenbus message larger we can buffer */ - if (len > sizeof(u->u.buffer) - u->len) { + if ((len + u->len) > sizeof(u->u.buffer)) { /* On error, dump existing buffer */ u->len = 0; rc = -EINVAL; diff --git a/trunk/drivers/xen/xenbus/xenbus_xs.c b/trunk/drivers/xen/xenbus/xenbus_xs.c index acedeabe589c..f5dda83ad7a5 100644 --- a/trunk/drivers/xen/xenbus/xenbus_xs.c +++ b/trunk/drivers/xen/xenbus/xenbus_xs.c @@ -627,7 +627,6 @@ static struct xenbus_watch *find_watch(const char *token) */ static bool xen_strict_xenbus_quirk(void) { -#ifdef CONFIG_X86 uint32_t eax, ebx, ecx, edx, base; base = xen_cpuid_base(); @@ -635,7 +634,6 @@ static bool xen_strict_xenbus_quirk(void) if ((eax >> 16) < 4) return true; -#endif return false; } diff --git a/trunk/fs/bio.c b/trunk/fs/bio.c index b96fc6ce4855..9298c65ad9c7 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -75,7 +75,6 @@ static struct kmem_cache *bio_find_or_create_slab(unsigned int extra_size) unsigned int sz = sizeof(struct bio) + extra_size; struct kmem_cache *slab = NULL; struct bio_slab *bslab, *new_bio_slabs; - unsigned int new_bio_slab_max; unsigned int i, entry = -1; mutex_lock(&bio_slab_lock); @@ -98,13 +97,12 @@ static struct kmem_cache *bio_find_or_create_slab(unsigned int extra_size) goto out_unlock; if (bio_slab_nr == bio_slab_max && entry == -1) { - new_bio_slab_max = bio_slab_max << 1; + bio_slab_max <<= 1; new_bio_slabs = krealloc(bio_slabs, - new_bio_slab_max * sizeof(struct bio_slab), + bio_slab_max * sizeof(struct bio_slab), GFP_KERNEL); if (!new_bio_slabs) goto out_unlock; - bio_slab_max = new_bio_slab_max; bio_slabs = new_bio_slabs; } if (entry == -1) diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index ab3a456f6650..b3c1d3dae77d 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -70,6 +70,19 @@ static void bdev_inode_switch_bdi(struct inode *inode, spin_unlock(&dst->wb.list_lock); } +sector_t blkdev_max_block(struct block_device *bdev) +{ + sector_t retval = ~((sector_t)0); + loff_t sz = i_size_read(bdev->bd_inode); + + if (sz) { + unsigned int size = block_size(bdev); + unsigned int sizebits = blksize_bits(size); + retval = (sz >> sizebits); + } + return retval; +} + /* Kill _all_ buffers and pagecache , dirty or not.. */ void kill_bdev(struct block_device *bdev) { @@ -103,6 +116,8 @@ EXPORT_SYMBOL(invalidate_bdev); int set_blocksize(struct block_device *bdev, int size) { + struct address_space *mapping; + /* Size must be a power of two, and between 512 and PAGE_SIZE */ if (size > PAGE_SIZE || size < 512 || !is_power_of_2(size)) return -EINVAL; @@ -111,6 +126,19 @@ int set_blocksize(struct block_device *bdev, int size) if (size < bdev_logical_block_size(bdev)) return -EINVAL; + /* Prevent starting I/O or mapping the device */ + percpu_down_write(&bdev->bd_block_size_semaphore); + + /* Check that the block device is not memory mapped */ + mapping = bdev->bd_inode->i_mapping; + mutex_lock(&mapping->i_mmap_mutex); + if (mapping_mapped(mapping)) { + mutex_unlock(&mapping->i_mmap_mutex); + percpu_up_write(&bdev->bd_block_size_semaphore); + return -EBUSY; + } + mutex_unlock(&mapping->i_mmap_mutex); + /* Don't change the size if it is same as current */ if (bdev->bd_block_size != size) { sync_blockdev(bdev); @@ -118,6 +146,9 @@ int set_blocksize(struct block_device *bdev, int size) bdev->bd_inode->i_blkbits = blksize_bits(size); kill_bdev(bdev); } + + percpu_up_write(&bdev->bd_block_size_semaphore); + return 0; } @@ -150,12 +181,52 @@ static int blkdev_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh, int create) { + if (iblock >= blkdev_max_block(I_BDEV(inode))) { + if (create) + return -EIO; + + /* + * for reads, we're just trying to fill a partial page. + * return a hole, they will have to call get_block again + * before they can fill it, and they will get -EIO at that + * time + */ + return 0; + } bh->b_bdev = I_BDEV(inode); bh->b_blocknr = iblock; set_buffer_mapped(bh); return 0; } +static int +blkdev_get_blocks(struct inode *inode, sector_t iblock, + struct buffer_head *bh, int create) +{ + sector_t end_block = blkdev_max_block(I_BDEV(inode)); + unsigned long max_blocks = bh->b_size >> inode->i_blkbits; + + if ((iblock + max_blocks) > end_block) { + max_blocks = end_block - iblock; + if ((long)max_blocks <= 0) { + if (create) + return -EIO; /* write fully beyond EOF */ + /* + * It is a read which is fully beyond EOF. We return + * a !buffer_mapped buffer + */ + max_blocks = 0; + } + } + + bh->b_bdev = I_BDEV(inode); + bh->b_blocknr = iblock; + bh->b_size = max_blocks << inode->i_blkbits; + if (max_blocks) + set_buffer_mapped(bh); + return 0; +} + static ssize_t blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_t offset, unsigned long nr_segs) @@ -164,7 +235,7 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, struct inode *inode = file->f_mapping->host; return __blockdev_direct_IO(rw, iocb, inode, I_BDEV(inode), iov, offset, - nr_segs, blkdev_get_block, NULL, NULL, 0); + nr_segs, blkdev_get_blocks, NULL, NULL, 0); } int __sync_blockdev(struct block_device *bdev, int wait) @@ -388,6 +459,12 @@ static struct inode *bdev_alloc_inode(struct super_block *sb) struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, GFP_KERNEL); if (!ei) return NULL; + + if (unlikely(percpu_init_rwsem(&ei->bdev.bd_block_size_semaphore))) { + kmem_cache_free(bdev_cachep, ei); + return NULL; + } + return &ei->vfs_inode; } @@ -396,6 +473,8 @@ static void bdev_i_callback(struct rcu_head *head) struct inode *inode = container_of(head, struct inode, i_rcu); struct bdev_inode *bdi = BDEV_I(inode); + percpu_free_rwsem(&bdi->bdev.bd_block_size_semaphore); + kmem_cache_free(bdev_cachep, bdi); } @@ -1514,6 +1593,22 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) return blkdev_ioctl(bdev, mode, cmd, arg); } +ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) +{ + ssize_t ret; + struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host); + + percpu_down_read(&bdev->bd_block_size_semaphore); + + ret = generic_file_aio_read(iocb, iov, nr_segs, pos); + + percpu_up_read(&bdev->bd_block_size_semaphore); + + return ret; +} +EXPORT_SYMBOL_GPL(blkdev_aio_read); + /* * Write data to the block device. Only intended for the block device itself * and the raw driver which basically is a fake block device. @@ -1525,12 +1620,16 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos) { struct file *file = iocb->ki_filp; + struct block_device *bdev = I_BDEV(file->f_mapping->host); struct blk_plug plug; ssize_t ret; BUG_ON(iocb->ki_pos != pos); blk_start_plug(&plug); + + percpu_down_read(&bdev->bd_block_size_semaphore); + ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); if (ret > 0 || ret == -EIOCBQUEUED) { ssize_t err; @@ -1539,25 +1638,27 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, if (err < 0 && ret > 0) ret = err; } + + percpu_up_read(&bdev->bd_block_size_semaphore); + blk_finish_plug(&plug); + return ret; } EXPORT_SYMBOL_GPL(blkdev_aio_write); -static ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov, - unsigned long nr_segs, loff_t pos) +static int blkdev_mmap(struct file *file, struct vm_area_struct *vma) { - struct file *file = iocb->ki_filp; - struct inode *bd_inode = file->f_mapping->host; - loff_t size = i_size_read(bd_inode); + int ret; + struct block_device *bdev = I_BDEV(file->f_mapping->host); - if (pos >= size) - return 0; + percpu_down_read(&bdev->bd_block_size_semaphore); - size -= pos; - if (size < INT_MAX) - nr_segs = iov_shorten((struct iovec *)iov, nr_segs, size); - return generic_file_aio_read(iocb, iov, nr_segs, pos); + ret = generic_file_mmap(file, vma); + + percpu_up_read(&bdev->bd_block_size_semaphore); + + return ret; } /* @@ -1590,9 +1691,9 @@ const struct file_operations def_blk_fops = { .llseek = block_llseek, .read = do_sync_read, .write = do_sync_write, - .aio_read = blkdev_aio_read, + .aio_read = blkdev_aio_read, .aio_write = blkdev_aio_write, - .mmap = generic_file_mmap, + .mmap = blkdev_mmap, .fsync = blkdev_fsync, .unlocked_ioctl = block_ioctl, #ifdef CONFIG_COMPAT diff --git a/trunk/fs/btrfs/backref.c b/trunk/fs/btrfs/backref.c index 208d8aa5b07e..f3187938e081 100644 --- a/trunk/fs/btrfs/backref.c +++ b/trunk/fs/btrfs/backref.c @@ -283,7 +283,9 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, goto out; } - root_level = btrfs_old_root_level(root, time_seq); + rcu_read_lock(); + root_level = btrfs_header_level(root->node); + rcu_read_unlock(); if (root_level + 1 == level) goto out; @@ -1175,15 +1177,16 @@ int btrfs_find_one_extref(struct btrfs_root *root, u64 inode_objectid, return ret; } -char *btrfs_ref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path, - u32 name_len, unsigned long name_off, - struct extent_buffer *eb_in, u64 parent, - char *dest, u32 size) +static char *ref_to_path(struct btrfs_root *fs_root, + struct btrfs_path *path, + u32 name_len, unsigned long name_off, + struct extent_buffer *eb_in, u64 parent, + char *dest, u32 size) { int slot; u64 next_inum; int ret; - s64 bytes_left = ((s64)size) - 1; + s64 bytes_left = size - 1; struct extent_buffer *eb = eb_in; struct btrfs_key found_key; int leave_spinning = path->leave_spinning; @@ -1263,10 +1266,10 @@ char *btrfs_iref_to_path(struct btrfs_root *fs_root, struct extent_buffer *eb_in, u64 parent, char *dest, u32 size) { - return btrfs_ref_to_path(fs_root, path, - btrfs_inode_ref_name_len(eb_in, iref), - (unsigned long)(iref + 1), - eb_in, parent, dest, size); + return ref_to_path(fs_root, path, + btrfs_inode_ref_name_len(eb_in, iref), + (unsigned long)(iref + 1), + eb_in, parent, dest, size); } /* @@ -1712,8 +1715,9 @@ static int inode_to_path(u64 inum, u32 name_len, unsigned long name_off, ipath->fspath->bytes_left - s_ptr : 0; fspath_min = (char *)ipath->fspath->val + (i + 1) * s_ptr; - fspath = btrfs_ref_to_path(ipath->fs_root, ipath->btrfs_path, name_len, - name_off, eb, inum, fspath_min, bytes_left); + fspath = ref_to_path(ipath->fs_root, ipath->btrfs_path, name_len, + name_off, eb, inum, fspath_min, + bytes_left); if (IS_ERR(fspath)) return PTR_ERR(fspath); diff --git a/trunk/fs/btrfs/backref.h b/trunk/fs/btrfs/backref.h index d61feca79455..e75533043a5f 100644 --- a/trunk/fs/btrfs/backref.h +++ b/trunk/fs/btrfs/backref.h @@ -62,10 +62,6 @@ int btrfs_find_all_roots(struct btrfs_trans_handle *trans, char *btrfs_iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path, struct btrfs_inode_ref *iref, struct extent_buffer *eb, u64 parent, char *dest, u32 size); -char *btrfs_ref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path, - u32 name_len, unsigned long name_off, - struct extent_buffer *eb_in, u64 parent, - char *dest, u32 size); struct btrfs_data_container *init_data_container(u32 total_bytes); struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root, diff --git a/trunk/fs/btrfs/ctree.c b/trunk/fs/btrfs/ctree.c index cdfb4c49a806..b33436211000 100644 --- a/trunk/fs/btrfs/ctree.c +++ b/trunk/fs/btrfs/ctree.c @@ -596,11 +596,6 @@ tree_mod_log_insert_move(struct btrfs_fs_info *fs_info, if (tree_mod_dont_log(fs_info, eb)) return 0; - /* - * When we override something during the move, we log these removals. - * This can only happen when we move towards the beginning of the - * buffer, i.e. dst_slot < src_slot. - */ for (i = 0; i + dst_slot < src_slot && i < nr_items; i++) { ret = tree_mod_log_insert_key_locked(fs_info, eb, i + dst_slot, MOD_LOG_KEY_REMOVE_WHILE_MOVING); @@ -652,6 +647,8 @@ tree_mod_log_insert_root(struct btrfs_fs_info *fs_info, if (tree_mod_dont_log(fs_info, NULL)) return 0; + __tree_mod_log_free_eb(fs_info, old_root); + ret = tree_mod_alloc(fs_info, flags, &tm); if (ret < 0) goto out; @@ -929,7 +926,12 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, ret = btrfs_dec_ref(trans, root, buf, 1, 1); BUG_ON(ret); /* -ENOMEM */ } - tree_mod_log_free_eb(root->fs_info, buf); + /* + * don't log freeing in case we're freeing the root node, this + * is done by tree_mod_log_set_root_pointer later + */ + if (buf != root->node && btrfs_header_level(buf) != 0) + tree_mod_log_free_eb(root->fs_info, buf); clean_tree_block(trans, root, buf); *last_ref = 1; } @@ -1223,8 +1225,6 @@ tree_mod_log_rewind(struct btrfs_fs_info *fs_info, struct extent_buffer *eb, free_extent_buffer(eb); __tree_mod_log_rewind(eb_rewin, time_seq, tm); - WARN_ON(btrfs_header_nritems(eb_rewin) > - BTRFS_NODEPTRS_PER_BLOCK(fs_info->fs_root)); return eb_rewin; } @@ -1241,11 +1241,9 @@ get_old_root(struct btrfs_root *root, u64 time_seq) { struct tree_mod_elem *tm; struct extent_buffer *eb; - struct extent_buffer *old; struct tree_mod_root *old_root = NULL; u64 old_generation = 0; u64 logical; - u32 blocksize; eb = btrfs_read_lock_root_node(root); tm = __tree_mod_log_oldest_root(root->fs_info, root, time_seq); @@ -1261,32 +1259,14 @@ get_old_root(struct btrfs_root *root, u64 time_seq) } tm = tree_mod_log_search(root->fs_info, logical, time_seq); - if (old_root && tm && tm->op != MOD_LOG_KEY_REMOVE_WHILE_FREEING) { - btrfs_tree_read_unlock(root->node); - free_extent_buffer(root->node); - blocksize = btrfs_level_size(root, old_root->level); - old = read_tree_block(root, logical, blocksize, 0); - if (!old) { - pr_warn("btrfs: failed to read tree block %llu from get_old_root\n", - logical); - WARN_ON(1); - } else { - eb = btrfs_clone_extent_buffer(old); - free_extent_buffer(old); - } - } else if (old_root) { - btrfs_tree_read_unlock(root->node); - free_extent_buffer(root->node); + if (old_root) eb = alloc_dummy_extent_buffer(logical, root->nodesize); - } else { + else eb = btrfs_clone_extent_buffer(root->node); - btrfs_tree_read_unlock(root->node); - free_extent_buffer(root->node); - } - + btrfs_tree_read_unlock(root->node); + free_extent_buffer(root->node); if (!eb) return NULL; - extent_buffer_get(eb); btrfs_tree_read_lock(eb); if (old_root) { btrfs_set_header_bytenr(eb, eb->start); @@ -1299,28 +1279,11 @@ get_old_root(struct btrfs_root *root, u64 time_seq) __tree_mod_log_rewind(eb, time_seq, tm); else WARN_ON(btrfs_header_level(eb) != 0); - WARN_ON(btrfs_header_nritems(eb) > BTRFS_NODEPTRS_PER_BLOCK(root)); + extent_buffer_get(eb); return eb; } -int btrfs_old_root_level(struct btrfs_root *root, u64 time_seq) -{ - struct tree_mod_elem *tm; - int level; - - tm = __tree_mod_log_oldest_root(root->fs_info, root, time_seq); - if (tm && tm->op == MOD_LOG_ROOT_REPLACE) { - level = tm->old_root.level; - } else { - rcu_read_lock(); - level = btrfs_header_level(root->node); - rcu_read_unlock(); - } - - return level; -} - static inline int should_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf) @@ -1762,7 +1725,6 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, goto enospc; } - tree_mod_log_free_eb(root->fs_info, root->node); tree_mod_log_set_root_pointer(root, child); rcu_assign_pointer(root->node, child); @@ -3008,10 +2970,8 @@ static int push_node_left(struct btrfs_trans_handle *trans, push_items * sizeof(struct btrfs_key_ptr)); if (push_items < src_nritems) { - /* - * don't call tree_mod_log_eb_move here, key removal was already - * fully logged by tree_mod_log_eb_copy above. - */ + tree_mod_log_eb_move(root->fs_info, src, 0, push_items, + src_nritems - push_items); memmove_extent_buffer(src, btrfs_node_key_ptr_offset(0), btrfs_node_key_ptr_offset(push_items), (src_nritems - push_items) * diff --git a/trunk/fs/btrfs/ctree.h b/trunk/fs/btrfs/ctree.h index c72ead869507..926c9ffc66d9 100644 --- a/trunk/fs/btrfs/ctree.h +++ b/trunk/fs/btrfs/ctree.h @@ -3120,7 +3120,6 @@ static inline u64 btrfs_inc_tree_mod_seq(struct btrfs_fs_info *fs_info) { return atomic_inc_return(&fs_info->tree_mod_seq); } -int btrfs_old_root_level(struct btrfs_root *root, u64 time_seq); /* root-item.c */ int btrfs_find_root_ref(struct btrfs_root *tree_root, @@ -3339,8 +3338,6 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, int btrfs_update_inode(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct inode *inode); -int btrfs_update_inode_fallback(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct inode *inode); int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode); int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode); int btrfs_orphan_cleanup(struct btrfs_root *root); diff --git a/trunk/fs/btrfs/extent_io.c b/trunk/fs/btrfs/extent_io.c index 472873a94d96..8036d3a84853 100644 --- a/trunk/fs/btrfs/extent_io.c +++ b/trunk/fs/btrfs/extent_io.c @@ -4110,8 +4110,8 @@ struct extent_buffer *alloc_dummy_extent_buffer(u64 start, unsigned long len) return eb; err: - for (; i > 0; i--) - __free_page(eb->pages[i - 1]); + for (i--; i >= 0; i--) + __free_page(eb->pages[i]); __free_extent_buffer(eb); return NULL; } diff --git a/trunk/fs/btrfs/inode.c b/trunk/fs/btrfs/inode.c index 95542a1b3dfc..85a1e5053fe6 100644 --- a/trunk/fs/btrfs/inode.c +++ b/trunk/fs/btrfs/inode.c @@ -94,6 +94,8 @@ static noinline int cow_file_range(struct inode *inode, struct page *locked_page, u64 start, u64 end, int *page_started, unsigned long *nr_written, int unlock); +static noinline int btrfs_update_inode_fallback(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct inode *inode); static int btrfs_init_inode_security(struct btrfs_trans_handle *trans, struct inode *inode, struct inode *dir, @@ -2744,9 +2746,8 @@ noinline int btrfs_update_inode(struct btrfs_trans_handle *trans, return btrfs_update_inode_item(trans, root, inode); } -noinline int btrfs_update_inode_fallback(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct inode *inode) +static noinline int btrfs_update_inode_fallback(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct inode *inode) { int ret; diff --git a/trunk/fs/btrfs/ioctl.c b/trunk/fs/btrfs/ioctl.c index 8fcf9a59c28d..61168805f175 100644 --- a/trunk/fs/btrfs/ioctl.c +++ b/trunk/fs/btrfs/ioctl.c @@ -343,8 +343,7 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) return -EOPNOTSUPP; if (copy_from_user(&range, arg, sizeof(range))) return -EFAULT; - if (range.start > total_bytes || - range.len < fs_info->sb->s_blocksize) + if (range.start > total_bytes) return -EINVAL; range.len = min(range.len, total_bytes - range.start); @@ -571,8 +570,7 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, ret = btrfs_commit_transaction(trans, root->fs_info->extent_root); } - if (ret) - goto fail; + BUG_ON(ret); ret = pending_snapshot->error; if (ret) diff --git a/trunk/fs/btrfs/qgroup.c b/trunk/fs/btrfs/qgroup.c index fe9d02c45f8e..5039686df6ae 100644 --- a/trunk/fs/btrfs/qgroup.c +++ b/trunk/fs/btrfs/qgroup.c @@ -790,10 +790,8 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans, } path = btrfs_alloc_path(); - if (!path) { - ret = -ENOMEM; - goto out_free_root; - } + if (!path) + return -ENOMEM; key.objectid = 0; key.type = BTRFS_QGROUP_STATUS_KEY; @@ -802,7 +800,7 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans, ret = btrfs_insert_empty_item(trans, quota_root, path, &key, sizeof(*ptr)); if (ret) - goto out_free_path; + goto out; leaf = path->nodes[0]; ptr = btrfs_item_ptr(leaf, path->slots[0], @@ -820,15 +818,8 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans, fs_info->quota_root = quota_root; fs_info->pending_quota_state = 1; spin_unlock(&fs_info->qgroup_lock); -out_free_path: - btrfs_free_path(path); -out_free_root: - if (ret) { - free_extent_buffer(quota_root->node); - free_extent_buffer(quota_root->commit_root); - kfree(quota_root); - } out: + btrfs_free_path(path); return ret; } diff --git a/trunk/fs/btrfs/send.c b/trunk/fs/btrfs/send.c index e78b297b0b00..c7beb543a4a8 100644 --- a/trunk/fs/btrfs/send.c +++ b/trunk/fs/btrfs/send.c @@ -745,36 +745,31 @@ typedef int (*iterate_inode_ref_t)(int num, u64 dir, int index, void *ctx); /* - * Helper function to iterate the entries in ONE btrfs_inode_ref or - * btrfs_inode_extref. + * Helper function to iterate the entries in ONE btrfs_inode_ref. * The iterate callback may return a non zero value to stop iteration. This can * be a negative value for error codes or 1 to simply stop it. * - * path must point to the INODE_REF or INODE_EXTREF when called. + * path must point to the INODE_REF when called. */ static int iterate_inode_ref(struct send_ctx *sctx, struct btrfs_root *root, struct btrfs_path *path, struct btrfs_key *found_key, int resolve, iterate_inode_ref_t iterate, void *ctx) { - struct extent_buffer *eb = path->nodes[0]; + struct extent_buffer *eb; struct btrfs_item *item; struct btrfs_inode_ref *iref; - struct btrfs_inode_extref *extref; struct btrfs_path *tmp_path; struct fs_path *p; - u32 cur = 0; + u32 cur; + u32 len; u32 total; - int slot = path->slots[0]; + int slot; u32 name_len; char *start; int ret = 0; - int num = 0; + int num; int index; - u64 dir; - unsigned long name_off; - unsigned long elem_size; - unsigned long ptr; p = fs_path_alloc_reversed(sctx); if (!p) @@ -786,40 +781,24 @@ static int iterate_inode_ref(struct send_ctx *sctx, return -ENOMEM; } + eb = path->nodes[0]; + slot = path->slots[0]; + item = btrfs_item_nr(eb, slot); + iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref); + cur = 0; + len = 0; + total = btrfs_item_size(eb, item); - if (found_key->type == BTRFS_INODE_REF_KEY) { - ptr = (unsigned long)btrfs_item_ptr(eb, slot, - struct btrfs_inode_ref); - item = btrfs_item_nr(eb, slot); - total = btrfs_item_size(eb, item); - elem_size = sizeof(*iref); - } else { - ptr = btrfs_item_ptr_offset(eb, slot); - total = btrfs_item_size_nr(eb, slot); - elem_size = sizeof(*extref); - } - + num = 0; while (cur < total) { fs_path_reset(p); - if (found_key->type == BTRFS_INODE_REF_KEY) { - iref = (struct btrfs_inode_ref *)(ptr + cur); - name_len = btrfs_inode_ref_name_len(eb, iref); - name_off = (unsigned long)(iref + 1); - index = btrfs_inode_ref_index(eb, iref); - dir = found_key->offset; - } else { - extref = (struct btrfs_inode_extref *)(ptr + cur); - name_len = btrfs_inode_extref_name_len(eb, extref); - name_off = (unsigned long)&extref->name; - index = btrfs_inode_extref_index(eb, extref); - dir = btrfs_inode_extref_parent(eb, extref); - } - + name_len = btrfs_inode_ref_name_len(eb, iref); + index = btrfs_inode_ref_index(eb, iref); if (resolve) { - start = btrfs_ref_to_path(root, tmp_path, name_len, - name_off, eb, dir, - p->buf, p->buf_len); + start = btrfs_iref_to_path(root, tmp_path, iref, eb, + found_key->offset, p->buf, + p->buf_len); if (IS_ERR(start)) { ret = PTR_ERR(start); goto out; @@ -830,10 +809,9 @@ static int iterate_inode_ref(struct send_ctx *sctx, p->buf_len + p->buf - start); if (ret < 0) goto out; - start = btrfs_ref_to_path(root, tmp_path, - name_len, name_off, - eb, dir, - p->buf, p->buf_len); + start = btrfs_iref_to_path(root, tmp_path, iref, + eb, found_key->offset, p->buf, + p->buf_len); if (IS_ERR(start)) { ret = PTR_ERR(start); goto out; @@ -842,16 +820,21 @@ static int iterate_inode_ref(struct send_ctx *sctx, } p->start = start; } else { - ret = fs_path_add_from_extent_buffer(p, eb, name_off, - name_len); + ret = fs_path_add_from_extent_buffer(p, eb, + (unsigned long)(iref + 1), name_len); if (ret < 0) goto out; } - cur += elem_size + name_len; - ret = iterate(num, dir, index, p, ctx); + + len = sizeof(*iref) + name_len; + iref = (struct btrfs_inode_ref *)((char *)iref + len); + cur += len; + + ret = iterate(num, found_key->offset, index, p, ctx); if (ret) goto out; + num++; } @@ -1015,8 +998,7 @@ static int get_inode_path(struct send_ctx *sctx, struct btrfs_root *root, } btrfs_item_key_to_cpu(p->nodes[0], &found_key, p->slots[0]); if (found_key.objectid != ino || - (found_key.type != BTRFS_INODE_REF_KEY && - found_key.type != BTRFS_INODE_EXTREF_KEY)) { + found_key.type != BTRFS_INODE_REF_KEY) { ret = -ENOENT; goto out; } @@ -1569,8 +1551,8 @@ static int get_first_ref(struct send_ctx *sctx, struct btrfs_key key; struct btrfs_key found_key; struct btrfs_path *path; + struct btrfs_inode_ref *iref; int len; - u64 parent_dir; path = alloc_path_for_send(); if (!path) @@ -1586,41 +1568,27 @@ static int get_first_ref(struct send_ctx *sctx, if (!ret) btrfs_item_key_to_cpu(path->nodes[0], &found_key, path->slots[0]); - if (ret || found_key.objectid != ino || - (found_key.type != BTRFS_INODE_REF_KEY && - found_key.type != BTRFS_INODE_EXTREF_KEY)) { + if (ret || found_key.objectid != key.objectid || + found_key.type != key.type) { ret = -ENOENT; goto out; } - if (key.type == BTRFS_INODE_REF_KEY) { - struct btrfs_inode_ref *iref; - iref = btrfs_item_ptr(path->nodes[0], path->slots[0], - struct btrfs_inode_ref); - len = btrfs_inode_ref_name_len(path->nodes[0], iref); - ret = fs_path_add_from_extent_buffer(name, path->nodes[0], - (unsigned long)(iref + 1), - len); - parent_dir = found_key.offset; - } else { - struct btrfs_inode_extref *extref; - extref = btrfs_item_ptr(path->nodes[0], path->slots[0], - struct btrfs_inode_extref); - len = btrfs_inode_extref_name_len(path->nodes[0], extref); - ret = fs_path_add_from_extent_buffer(name, path->nodes[0], - (unsigned long)&extref->name, len); - parent_dir = btrfs_inode_extref_parent(path->nodes[0], extref); - } + iref = btrfs_item_ptr(path->nodes[0], path->slots[0], + struct btrfs_inode_ref); + len = btrfs_inode_ref_name_len(path->nodes[0], iref); + ret = fs_path_add_from_extent_buffer(name, path->nodes[0], + (unsigned long)(iref + 1), len); if (ret < 0) goto out; btrfs_release_path(path); - ret = get_inode_info(root, parent_dir, NULL, dir_gen, NULL, NULL, + ret = get_inode_info(root, found_key.offset, NULL, dir_gen, NULL, NULL, NULL, NULL); if (ret < 0) goto out; - *dir = parent_dir; + *dir = found_key.offset; out: btrfs_free_path(path); @@ -2462,8 +2430,7 @@ verbose_printk("btrfs: send_create_inode %llu\n", ino); TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_LINK, p); } else if (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) { - TLV_PUT_U64(sctx, BTRFS_SEND_A_RDEV, new_encode_dev(rdev)); - TLV_PUT_U64(sctx, BTRFS_SEND_A_MODE, mode); + TLV_PUT_U64(sctx, BTRFS_SEND_A_RDEV, rdev); } ret = send_cmd(sctx); @@ -3259,8 +3226,7 @@ static int process_all_refs(struct send_ctx *sctx, btrfs_item_key_to_cpu(eb, &found_key, slot); if (found_key.objectid != key.objectid || - (found_key.type != BTRFS_INODE_REF_KEY && - found_key.type != BTRFS_INODE_EXTREF_KEY)) + found_key.type != key.type) break; ret = iterate_inode_ref(sctx, root, path, &found_key, 0, cb, @@ -4021,7 +3987,7 @@ static int process_recorded_refs_if_needed(struct send_ctx *sctx, int at_end) if (sctx->cur_ino == 0) goto out; if (!at_end && sctx->cur_ino == sctx->cmp_key->objectid && - sctx->cmp_key->type <= BTRFS_INODE_EXTREF_KEY) + sctx->cmp_key->type <= BTRFS_INODE_REF_KEY) goto out; if (list_empty(&sctx->new_refs) && list_empty(&sctx->deleted_refs)) goto out; @@ -4067,21 +4033,22 @@ static int finish_inode_if_needed(struct send_ctx *sctx, int at_end) if (ret < 0) goto out; - if (!sctx->parent_root || sctx->cur_inode_new) { - need_chown = 1; - if (!S_ISLNK(sctx->cur_inode_mode)) + if (!S_ISLNK(sctx->cur_inode_mode)) { + if (!sctx->parent_root || sctx->cur_inode_new) { need_chmod = 1; - } else { - ret = get_inode_info(sctx->parent_root, sctx->cur_ino, - NULL, NULL, &right_mode, &right_uid, - &right_gid, NULL); - if (ret < 0) - goto out; - - if (left_uid != right_uid || left_gid != right_gid) need_chown = 1; - if (!S_ISLNK(sctx->cur_inode_mode) && left_mode != right_mode) - need_chmod = 1; + } else { + ret = get_inode_info(sctx->parent_root, sctx->cur_ino, + NULL, NULL, &right_mode, &right_uid, + &right_gid, NULL); + if (ret < 0) + goto out; + + if (left_uid != right_uid || left_gid != right_gid) + need_chown = 1; + if (left_mode != right_mode) + need_chmod = 1; + } } if (S_ISREG(sctx->cur_inode_mode)) { @@ -4368,8 +4335,7 @@ static int changed_cb(struct btrfs_root *left_root, if (key->type == BTRFS_INODE_ITEM_KEY) ret = changed_inode(sctx, result); - else if (key->type == BTRFS_INODE_REF_KEY || - key->type == BTRFS_INODE_EXTREF_KEY) + else if (key->type == BTRFS_INODE_REF_KEY) ret = changed_ref(sctx, result); else if (key->type == BTRFS_XATTR_ITEM_KEY) ret = changed_xattr(sctx, result); diff --git a/trunk/fs/btrfs/transaction.c b/trunk/fs/btrfs/transaction.c index 04bbfb1052eb..77db875b5116 100644 --- a/trunk/fs/btrfs/transaction.c +++ b/trunk/fs/btrfs/transaction.c @@ -1200,7 +1200,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, btrfs_i_size_write(parent_inode, parent_inode->i_size + dentry->d_name.len * 2); parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME; - ret = btrfs_update_inode_fallback(trans, parent_root, parent_inode); + ret = btrfs_update_inode(trans, parent_root, parent_inode); if (ret) btrfs_abort_transaction(trans, root, ret); fail: diff --git a/trunk/fs/btrfs/volumes.c b/trunk/fs/btrfs/volumes.c index 0f5ebb72a5ea..029b903a4ae3 100644 --- a/trunk/fs/btrfs/volumes.c +++ b/trunk/fs/btrfs/volumes.c @@ -1819,13 +1819,6 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) "Failed to relocate sys chunks after " "device initialization. This can be fixed " "using the \"btrfs balance\" command."); - trans = btrfs_attach_transaction(root); - if (IS_ERR(trans)) { - if (PTR_ERR(trans) == -ENOENT) - return 0; - return PTR_ERR(trans); - } - ret = btrfs_commit_transaction(trans, root); } return ret; diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c index ec0aca8ba6bf..b5f044283edb 100644 --- a/trunk/fs/buffer.c +++ b/trunk/fs/buffer.c @@ -911,18 +911,6 @@ link_dev_buffers(struct page *page, struct buffer_head *head) attach_page_buffers(page, head); } -static sector_t blkdev_max_block(struct block_device *bdev, unsigned int size) -{ - sector_t retval = ~((sector_t)0); - loff_t sz = i_size_read(bdev->bd_inode); - - if (sz) { - unsigned int sizebits = blksize_bits(size); - retval = (sz >> sizebits); - } - return retval; -} - /* * Initialise the state of a blockdev page's buffers. */ @@ -933,7 +921,7 @@ init_page_buffers(struct page *page, struct block_device *bdev, struct buffer_head *head = page_buffers(page); struct buffer_head *bh = head; int uptodate = PageUptodate(page); - sector_t end_block = blkdev_max_block(I_BDEV(bdev->bd_inode), size); + sector_t end_block = blkdev_max_block(I_BDEV(bdev->bd_inode)); do { if (!buffer_mapped(bh)) { @@ -1564,28 +1552,6 @@ void unmap_underlying_metadata(struct block_device *bdev, sector_t block) } EXPORT_SYMBOL(unmap_underlying_metadata); -/* - * Size is a power-of-two in the range 512..PAGE_SIZE, - * and the case we care about most is PAGE_SIZE. - * - * So this *could* possibly be written with those - * constraints in mind (relevant mostly if some - * architecture has a slow bit-scan instruction) - */ -static inline int block_size_bits(unsigned int blocksize) -{ - return ilog2(blocksize); -} - -static struct buffer_head *create_page_buffers(struct page *page, struct inode *inode, unsigned int b_state) -{ - BUG_ON(!PageLocked(page)); - - if (!page_has_buffers(page)) - create_empty_buffers(page, 1 << ACCESS_ONCE(inode->i_blkbits), b_state); - return page_buffers(page); -} - /* * NOTE! All mapped/uptodate combinations are valid: * @@ -1623,13 +1589,19 @@ static int __block_write_full_page(struct inode *inode, struct page *page, sector_t block; sector_t last_block; struct buffer_head *bh, *head; - unsigned int blocksize, bbits; + const unsigned blocksize = 1 << inode->i_blkbits; int nr_underway = 0; int write_op = (wbc->sync_mode == WB_SYNC_ALL ? WRITE_SYNC : WRITE); - head = create_page_buffers(page, inode, + BUG_ON(!PageLocked(page)); + + last_block = (i_size_read(inode) - 1) >> inode->i_blkbits; + + if (!page_has_buffers(page)) { + create_empty_buffers(page, blocksize, (1 << BH_Dirty)|(1 << BH_Uptodate)); + } /* * Be very careful. We have no exclusion from __set_page_dirty_buffers @@ -1641,12 +1613,9 @@ static int __block_write_full_page(struct inode *inode, struct page *page, * handle that here by just cleaning them. */ + block = (sector_t)page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits); + head = page_buffers(page); bh = head; - blocksize = bh->b_size; - bbits = block_size_bits(blocksize); - - block = (sector_t)page->index << (PAGE_CACHE_SHIFT - bbits); - last_block = (i_size_read(inode) - 1) >> bbits; /* * Get all the dirty buffers mapped to disk addresses and @@ -1837,10 +1806,12 @@ int __block_write_begin(struct page *page, loff_t pos, unsigned len, BUG_ON(to > PAGE_CACHE_SIZE); BUG_ON(from > to); - head = create_page_buffers(page, inode, 0); - blocksize = head->b_size; - bbits = block_size_bits(blocksize); + blocksize = 1 << inode->i_blkbits; + if (!page_has_buffers(page)) + create_empty_buffers(page, blocksize, 0); + head = page_buffers(page); + bbits = inode->i_blkbits; block = (sector_t)page->index << (PAGE_CACHE_SHIFT - bbits); for(bh = head, block_start = 0; bh != head || !block_start; @@ -1910,11 +1881,11 @@ static int __block_commit_write(struct inode *inode, struct page *page, unsigned blocksize; struct buffer_head *bh, *head; - bh = head = page_buffers(page); - blocksize = bh->b_size; + blocksize = 1 << inode->i_blkbits; - block_start = 0; - do { + for(bh = head = page_buffers(page), block_start = 0; + bh != head || !block_start; + block_start=block_end, bh = bh->b_this_page) { block_end = block_start + blocksize; if (block_end <= from || block_start >= to) { if (!buffer_uptodate(bh)) @@ -1924,10 +1895,7 @@ static int __block_commit_write(struct inode *inode, struct page *page, mark_buffer_dirty(bh); } clear_buffer_new(bh); - - block_start = block_end; - bh = bh->b_this_page; - } while (bh != head); + } /* * If this is a partial write which happened to make all buffers @@ -2052,6 +2020,7 @@ EXPORT_SYMBOL(generic_write_end); int block_is_partially_uptodate(struct page *page, read_descriptor_t *desc, unsigned long from) { + struct inode *inode = page->mapping->host; unsigned block_start, block_end, blocksize; unsigned to; struct buffer_head *bh, *head; @@ -2060,13 +2029,13 @@ int block_is_partially_uptodate(struct page *page, read_descriptor_t *desc, if (!page_has_buffers(page)) return 0; - head = page_buffers(page); - blocksize = head->b_size; + blocksize = 1 << inode->i_blkbits; to = min_t(unsigned, PAGE_CACHE_SIZE - from, desc->count); to = from + to; if (from < blocksize && to > PAGE_CACHE_SIZE - blocksize) return 0; + head = page_buffers(page); bh = head; block_start = 0; do { @@ -2099,16 +2068,18 @@ int block_read_full_page(struct page *page, get_block_t *get_block) struct inode *inode = page->mapping->host; sector_t iblock, lblock; struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE]; - unsigned int blocksize, bbits; + unsigned int blocksize; int nr, i; int fully_mapped = 1; - head = create_page_buffers(page, inode, 0); - blocksize = head->b_size; - bbits = block_size_bits(blocksize); + BUG_ON(!PageLocked(page)); + blocksize = 1 << inode->i_blkbits; + if (!page_has_buffers(page)) + create_empty_buffers(page, blocksize, 0); + head = page_buffers(page); - iblock = (sector_t)page->index << (PAGE_CACHE_SHIFT - bbits); - lblock = (i_size_read(inode)+blocksize-1) >> bbits; + iblock = (sector_t)page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits); + lblock = (i_size_read(inode)+blocksize-1) >> inode->i_blkbits; bh = head; nr = 0; i = 0; @@ -2893,55 +2864,6 @@ static void end_bio_bh_io_sync(struct bio *bio, int err) bio_put(bio); } -/* - * This allows us to do IO even on the odd last sectors - * of a device, even if the bh block size is some multiple - * of the physical sector size. - * - * We'll just truncate the bio to the size of the device, - * and clear the end of the buffer head manually. - * - * Truly out-of-range accesses will turn into actual IO - * errors, this only handles the "we need to be able to - * do IO at the final sector" case. - */ -static void guard_bh_eod(int rw, struct bio *bio, struct buffer_head *bh) -{ - sector_t maxsector; - unsigned bytes; - - maxsector = i_size_read(bio->bi_bdev->bd_inode) >> 9; - if (!maxsector) - return; - - /* - * If the *whole* IO is past the end of the device, - * let it through, and the IO layer will turn it into - * an EIO. - */ - if (unlikely(bio->bi_sector >= maxsector)) - return; - - maxsector -= bio->bi_sector; - bytes = bio->bi_size; - if (likely((bytes >> 9) <= maxsector)) - return; - - /* Uhhuh. We've got a bh that straddles the device size! */ - bytes = maxsector << 9; - - /* Truncate the bio.. */ - bio->bi_size = bytes; - bio->bi_io_vec[0].bv_len = bytes; - - /* ..and clear the end of the buffer for reads */ - if ((rw & RW_MASK) == READ) { - void *kaddr = kmap_atomic(bh->b_page); - memset(kaddr + bh_offset(bh) + bytes, 0, bh->b_size - bytes); - kunmap_atomic(kaddr); - } -} - int submit_bh(int rw, struct buffer_head * bh) { struct bio *bio; @@ -2978,9 +2900,6 @@ int submit_bh(int rw, struct buffer_head * bh) bio->bi_end_io = end_bio_bh_io_sync; bio->bi_private = bh; - /* Take care of bh's that straddle the end of the device */ - guard_bh_eod(rw, bio, bh); - bio_get(bio); submit_bio(rw, bio); diff --git a/trunk/fs/ceph/export.c b/trunk/fs/ceph/export.c index 9349bb37a2fe..02ce90972d81 100644 --- a/trunk/fs/ceph/export.c +++ b/trunk/fs/ceph/export.c @@ -90,8 +90,6 @@ static int ceph_encode_fh(struct inode *inode, u32 *rawfh, int *max_len, *max_len = handle_length; type = 255; } - if (dentry) - dput(dentry); return type; } diff --git a/trunk/fs/char_dev.c b/trunk/fs/char_dev.c index afc2bb691780..3f152b92a94a 100644 --- a/trunk/fs/char_dev.c +++ b/trunk/fs/char_dev.c @@ -471,19 +471,9 @@ static int exact_lock(dev_t dev, void *data) */ int cdev_add(struct cdev *p, dev_t dev, unsigned count) { - int error; - p->dev = dev; p->count = count; - - error = kobj_map(cdev_map, dev, count, NULL, - exact_match, exact_lock, p); - if (error) - return error; - - kobject_get(p->kobj.parent); - - return 0; + return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p); } static void cdev_unmap(dev_t dev, unsigned count) @@ -508,20 +498,14 @@ void cdev_del(struct cdev *p) static void cdev_default_release(struct kobject *kobj) { struct cdev *p = container_of(kobj, struct cdev, kobj); - struct kobject *parent = kobj->parent; - cdev_purge(p); - kobject_put(parent); } static void cdev_dynamic_release(struct kobject *kobj) { struct cdev *p = container_of(kobj, struct cdev, kobj); - struct kobject *parent = kobj->parent; - cdev_purge(p); kfree(p); - kobject_put(parent); } static struct kobj_type ktype_cdev_default = { diff --git a/trunk/fs/cifs/cifsacl.c b/trunk/fs/cifs/cifsacl.c index 0fb15bbbe43c..fc783e264420 100644 --- a/trunk/fs/cifs/cifsacl.c +++ b/trunk/fs/cifs/cifsacl.c @@ -224,13 +224,6 @@ sid_to_str(struct cifs_sid *sidptr, char *sidstr) } } -static void -cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src) -{ - memcpy(dst, src, sizeof(*dst)); - dst->num_subauth = min_t(u8, src->num_subauth, NUM_SUBAUTHS); -} - static void id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr, struct cifs_sid_id **psidid, char *typestr) @@ -255,7 +248,7 @@ id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr, } } - cifs_copy_sid(&(*psidid)->sid, sidptr); + memcpy(&(*psidid)->sid, sidptr, sizeof(struct cifs_sid)); (*psidid)->time = jiffies - (SID_MAP_RETRY + 1); (*psidid)->refcount = 0; @@ -361,7 +354,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) * any fields of the node after a reference is put . */ if (test_bit(SID_ID_MAPPED, &psidid->state)) { - cifs_copy_sid(ssid, &psidid->sid); + memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid)); psidid->time = jiffies; /* update ts for accessing */ goto id_sid_out; } @@ -377,14 +370,14 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) if (IS_ERR(sidkey)) { rc = -EINVAL; cFYI(1, "%s: Can't map and id to a SID", __func__); - } else if (sidkey->datalen < sizeof(struct cifs_sid)) { - rc = -EIO; - cFYI(1, "%s: Downcall contained malformed key " - "(datalen=%hu)", __func__, sidkey->datalen); } else { lsid = (struct cifs_sid *)sidkey->payload.data; - cifs_copy_sid(&psidid->sid, lsid); - cifs_copy_sid(ssid, &psidid->sid); + memcpy(&psidid->sid, lsid, + sidkey->datalen < sizeof(struct cifs_sid) ? + sidkey->datalen : sizeof(struct cifs_sid)); + memcpy(ssid, &psidid->sid, + sidkey->datalen < sizeof(struct cifs_sid) ? + sidkey->datalen : sizeof(struct cifs_sid)); set_bit(SID_ID_MAPPED, &psidid->state); key_put(sidkey); kfree(psidid->sidstr); @@ -403,7 +396,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) return rc; } if (test_bit(SID_ID_MAPPED, &psidid->state)) - cifs_copy_sid(ssid, &psidid->sid); + memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid)); else rc = -EINVAL; } @@ -682,6 +675,8 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) static void copy_sec_desc(const struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, __u32 sidsoffset) { + int i; + struct cifs_sid *owner_sid_ptr, *group_sid_ptr; struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr; @@ -697,14 +692,26 @@ static void copy_sec_desc(const struct cifs_ntsd *pntsd, owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + le32_to_cpu(pntsd->osidoffset)); nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset); - cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr); + + nowner_sid_ptr->revision = owner_sid_ptr->revision; + nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth; + for (i = 0; i < 6; i++) + nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i]; + for (i = 0; i < 5; i++) + nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i]; /* copy group sid */ group_sid_ptr = (struct cifs_sid *)((char *)pntsd + le32_to_cpu(pntsd->gsidoffset)); ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset + sizeof(struct cifs_sid)); - cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr); + + ngroup_sid_ptr->revision = group_sid_ptr->revision; + ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth; + for (i = 0; i < 6; i++) + ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i]; + for (i = 0; i < 5; i++) + ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i]; return; } @@ -1113,7 +1120,8 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, kfree(nowner_sid_ptr); return rc; } - cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr); + memcpy(owner_sid_ptr, nowner_sid_ptr, + sizeof(struct cifs_sid)); kfree(nowner_sid_ptr); *aclflag = CIFS_ACL_OWNER; } @@ -1131,7 +1139,8 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, kfree(ngroup_sid_ptr); return rc; } - cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr); + memcpy(group_sid_ptr, ngroup_sid_ptr, + sizeof(struct cifs_sid)); kfree(ngroup_sid_ptr); *aclflag = CIFS_ACL_GROUP; } diff --git a/trunk/fs/cifs/dir.c b/trunk/fs/cifs/dir.c index d3671f2acb29..7c0a81283645 100644 --- a/trunk/fs/cifs/dir.c +++ b/trunk/fs/cifs/dir.c @@ -398,16 +398,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, * in network traffic in the other paths. */ if (!(oflags & O_CREAT)) { - struct dentry *res; - - /* - * Check for hashed negative dentry. We have already revalidated - * the dentry and it is fine. No need to perform another lookup. - */ - if (!d_unhashed(direntry)) - return -ENOENT; - - res = cifs_lookup(inode, direntry, 0); + struct dentry *res = cifs_lookup(inode, direntry, 0); if (IS_ERR(res)) return PTR_ERR(res); diff --git a/trunk/fs/cifs/file.c b/trunk/fs/cifs/file.c index 70b6f4c3a0c1..edb25b4bbb95 100644 --- a/trunk/fs/cifs/file.c +++ b/trunk/fs/cifs/file.c @@ -1794,6 +1794,7 @@ static int cifs_writepages(struct address_space *mapping, struct TCP_Server_Info *server; struct page *page; int rc = 0; + loff_t isize = i_size_read(mapping->host); /* * If wsize is smaller than the page cache size, default to writing @@ -1898,7 +1899,7 @@ static int cifs_writepages(struct address_space *mapping, */ set_page_writeback(page); - if (page_offset(page) >= i_size_read(mapping->host)) { + if (page_offset(page) >= isize) { done = true; unlock_page(page); end_page_writeback(page); @@ -1931,8 +1932,7 @@ static int cifs_writepages(struct address_space *mapping, wdata->offset = page_offset(wdata->pages[0]); wdata->pagesz = PAGE_CACHE_SIZE; wdata->tailsz = - min(i_size_read(mapping->host) - - page_offset(wdata->pages[nr_pages - 1]), + min(isize - page_offset(wdata->pages[nr_pages - 1]), (loff_t)PAGE_CACHE_SIZE); wdata->bytes = ((nr_pages - 1) * PAGE_CACHE_SIZE) + wdata->tailsz; diff --git a/trunk/fs/cifs/readdir.c b/trunk/fs/cifs/readdir.c index 1c576e871366..f9b5d3d6cf33 100644 --- a/trunk/fs/cifs/readdir.c +++ b/trunk/fs/cifs/readdir.c @@ -86,17 +86,14 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name, dentry = d_lookup(parent, name); if (dentry) { - int err; inode = dentry->d_inode; /* update inode in place if i_ino didn't change */ if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) { cifs_fattr_to_inode(inode, fattr); return dentry; } - err = d_invalidate(dentry); + d_drop(dentry); dput(dentry); - if (err) - return NULL; } dentry = d_alloc(parent, name); diff --git a/trunk/fs/cifs/smb1ops.c b/trunk/fs/cifs/smb1ops.c index 34cea2798333..56cc4be87807 100644 --- a/trunk/fs/cifs/smb1ops.c +++ b/trunk/fs/cifs/smb1ops.c @@ -766,6 +766,7 @@ smb_set_file_info(struct inode *inode, const char *full_path, struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct tcon_link *tlink = NULL; struct cifs_tcon *tcon; + FILE_BASIC_INFO info_buf; /* if the file is already open for write, just use that fileid */ open_file = find_writable_file(cinode, true); @@ -816,7 +817,7 @@ smb_set_file_info(struct inode *inode, const char *full_path, netpid = current->tgid; set_via_filehandle: - rc = CIFSSMBSetFileInfo(xid, tcon, buf, netfid, netpid); + rc = CIFSSMBSetFileInfo(xid, tcon, &info_buf, netfid, netpid); if (!rc) cinode->cifsAttrs = le32_to_cpu(buf->Attributes); diff --git a/trunk/fs/compat_ioctl.c b/trunk/fs/compat_ioctl.c index 4c6285fff598..f5054025f9da 100644 --- a/trunk/fs/compat_ioctl.c +++ b/trunk/fs/compat_ioctl.c @@ -210,8 +210,6 @@ static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, err = get_user(palp, &up->palette); err |= get_user(length, &up->length); - if (err) - return -EFAULT; up_native = compat_alloc_user_space(sizeof(struct video_spu_palette)); err = put_user(compat_ptr(palp), &up_native->palette); diff --git a/trunk/fs/direct-io.c b/trunk/fs/direct-io.c index cf5b44b10c67..f86c720dba0e 100644 --- a/trunk/fs/direct-io.c +++ b/trunk/fs/direct-io.c @@ -540,7 +540,6 @@ static int get_more_blocks(struct dio *dio, struct dio_submit *sdio, sector_t fs_endblk; /* Into file, in filesystem-sized blocks */ unsigned long fs_count; /* Number of filesystem-sized blocks */ int create; - unsigned int i_blkbits = sdio->blkbits + sdio->blkfactor; /* * If there was a memory error and we've overwritten all the @@ -555,7 +554,7 @@ static int get_more_blocks(struct dio *dio, struct dio_submit *sdio, fs_count = fs_endblk - fs_startblk + 1; map_bh->b_state = 0; - map_bh->b_size = fs_count << i_blkbits; + map_bh->b_size = fs_count << dio->inode->i_blkbits; /* * For writes inside i_size on a DIO_SKIP_HOLES filesystem we @@ -1054,8 +1053,7 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, int seg; size_t size; unsigned long addr; - unsigned i_blkbits = ACCESS_ONCE(inode->i_blkbits); - unsigned blkbits = i_blkbits; + unsigned blkbits = inode->i_blkbits; unsigned blocksize_mask = (1 << blkbits) - 1; ssize_t retval = -EINVAL; loff_t end = offset; @@ -1151,7 +1149,7 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, dio->inode = inode; dio->rw = rw; sdio.blkbits = blkbits; - sdio.blkfactor = i_blkbits - blkbits; + sdio.blkfactor = inode->i_blkbits - blkbits; sdio.block_in_file = offset >> blkbits; sdio.get_block = get_block; diff --git a/trunk/fs/eventpoll.c b/trunk/fs/eventpoll.c index cd96649bfe62..da72250ddc1c 100644 --- a/trunk/fs/eventpoll.c +++ b/trunk/fs/eventpoll.c @@ -346,7 +346,7 @@ static inline struct epitem *ep_item_from_epqueue(poll_table *p) /* Tells if the epoll_ctl(2) operation needs an event copy from userspace */ static inline int ep_op_has_event(int op) { - return op != EPOLL_CTL_DEL; + return op == EPOLL_CTL_ADD || op == EPOLL_CTL_MOD; } /* Initialize the poll safe wake up structure */ @@ -676,6 +676,34 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi) return 0; } +/* + * Disables a "struct epitem" in the eventpoll set. Returns -EBUSY if the item + * had no event flags set, indicating that another thread may be currently + * handling that item's events (in the case that EPOLLONESHOT was being + * used). Otherwise a zero result indicates that the item has been disabled + * from receiving events. A disabled item may be re-enabled via + * EPOLL_CTL_MOD. Must be called with "mtx" held. + */ +static int ep_disable(struct eventpoll *ep, struct epitem *epi) +{ + int result = 0; + unsigned long flags; + + spin_lock_irqsave(&ep->lock, flags); + if (epi->event.events & ~EP_PRIVATE_BITS) { + if (ep_is_linked(&epi->rdllink)) + list_del_init(&epi->rdllink); + /* Ensure ep_poll_callback will not add epi back onto ready + list: */ + epi->event.events &= EP_PRIVATE_BITS; + } + else + result = -EBUSY; + spin_unlock_irqrestore(&ep->lock, flags); + + return result; +} + static void ep_free(struct eventpoll *ep) { struct rb_node *rbp; @@ -1020,8 +1048,6 @@ static void ep_rbtree_insert(struct eventpoll *ep, struct epitem *epi) rb_insert_color(&epi->rbn, &ep->rbr); } - - #define PATH_ARR_SIZE 5 /* * These are the number paths of length 1 to 5, that we are allowing to emanate @@ -1787,6 +1813,12 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, } else error = -ENOENT; break; + case EPOLL_CTL_DISABLE: + if (epi) + error = ep_disable(ep, epi); + else + error = -ENOENT; + break; } mutex_unlock(&ep->mtx); diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 0039055b1fc6..8b9011b67041 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -1083,8 +1083,7 @@ int flush_old_exec(struct linux_binprm * bprm) bprm->mm = NULL; /* We're using it now */ set_fs(USER_DS); - current->flags &= - ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD | PF_NOFREEZE); + current->flags &= ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD); flush_thread(); current->personality &= ~bprm->per_clear; diff --git a/trunk/fs/ext3/balloc.c b/trunk/fs/ext3/balloc.c index 22548f56197b..7320a66e958f 100644 --- a/trunk/fs/ext3/balloc.c +++ b/trunk/fs/ext3/balloc.c @@ -2101,9 +2101,8 @@ int ext3_trim_fs(struct super_block *sb, struct fstrim_range *range) end = start + (range->len >> sb->s_blocksize_bits) - 1; minlen = range->minlen >> sb->s_blocksize_bits; - if (minlen > EXT3_BLOCKS_PER_GROUP(sb) || - start >= max_blks || - range->len < sb->s_blocksize) + if (unlikely(minlen > EXT3_BLOCKS_PER_GROUP(sb)) || + unlikely(start >= max_blks)) return -EINVAL; if (end >= max_blks) end = max_blks - 1; diff --git a/trunk/fs/ext4/balloc.c b/trunk/fs/ext4/balloc.c index cf1821784a16..1b5089067d01 100644 --- a/trunk/fs/ext4/balloc.c +++ b/trunk/fs/ext4/balloc.c @@ -174,7 +174,8 @@ void ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, ext4_free_inodes_set(sb, gdp, 0); ext4_itable_unused_set(sb, gdp, 0); memset(bh->b_data, 0xff, sb->s_blocksize); - ext4_block_bitmap_csum_set(sb, block_group, gdp, bh); + ext4_block_bitmap_csum_set(sb, block_group, gdp, bh, + EXT4_BLOCKS_PER_GROUP(sb) / 8); return; } memset(bh->b_data, 0, sb->s_blocksize); @@ -211,7 +212,8 @@ void ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, */ ext4_mark_bitmap_end(num_clusters_in_group(sb, block_group), sb->s_blocksize * 8, bh->b_data); - ext4_block_bitmap_csum_set(sb, block_group, gdp, bh); + ext4_block_bitmap_csum_set(sb, block_group, gdp, bh, + EXT4_BLOCKS_PER_GROUP(sb) / 8); ext4_group_desc_csum_set(sb, block_group, gdp); } @@ -348,7 +350,7 @@ void ext4_validate_block_bitmap(struct super_block *sb, return; } if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group, - desc, bh))) { + desc, bh, EXT4_BLOCKS_PER_GROUP(sb) / 8))) { ext4_unlock_group(sb, block_group); ext4_error(sb, "bg %u: bad block bitmap checksum", block_group); return; diff --git a/trunk/fs/ext4/bitmap.c b/trunk/fs/ext4/bitmap.c index 3285aa5a706a..5c2d1813ebe9 100644 --- a/trunk/fs/ext4/bitmap.c +++ b/trunk/fs/ext4/bitmap.c @@ -58,12 +58,11 @@ void ext4_inode_bitmap_csum_set(struct super_block *sb, ext4_group_t group, int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, struct ext4_group_desc *gdp, - struct buffer_head *bh) + struct buffer_head *bh, int sz) { __u32 hi; __u32 provided, calculated; struct ext4_sb_info *sbi = EXT4_SB(sb); - int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8; if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) @@ -85,9 +84,8 @@ int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group, struct ext4_group_desc *gdp, - struct buffer_head *bh) + struct buffer_head *bh, int sz) { - int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8; __u32 csum; struct ext4_sb_info *sbi = EXT4_SB(sb); diff --git a/trunk/fs/ext4/ext4.h b/trunk/fs/ext4/ext4.h index 3c20de1d59d0..3ab2539b7b2e 100644 --- a/trunk/fs/ext4/ext4.h +++ b/trunk/fs/ext4/ext4.h @@ -1882,10 +1882,10 @@ int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, struct buffer_head *bh, int sz); void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group, struct ext4_group_desc *gdp, - struct buffer_head *bh); + struct buffer_head *bh, int sz); int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, struct ext4_group_desc *gdp, - struct buffer_head *bh); + struct buffer_head *bh, int sz); /* balloc.c */ extern void ext4_validate_block_bitmap(struct super_block *sb, @@ -2063,7 +2063,8 @@ extern int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count); extern int ext4_calculate_overhead(struct super_block *sb); extern int ext4_superblock_csum_verify(struct super_block *sb, struct ext4_super_block *es); -extern void ext4_superblock_csum_set(struct super_block *sb); +extern void ext4_superblock_csum_set(struct super_block *sb, + struct ext4_super_block *es); extern void *ext4_kvmalloc(size_t size, gfp_t flags); extern void *ext4_kvzalloc(size_t size, gfp_t flags); extern void ext4_kvfree(void *ptr); diff --git a/trunk/fs/ext4/ext4_jbd2.c b/trunk/fs/ext4/ext4_jbd2.c index b4323ba846b5..bfa65b49d424 100644 --- a/trunk/fs/ext4/ext4_jbd2.c +++ b/trunk/fs/ext4/ext4_jbd2.c @@ -143,13 +143,17 @@ int __ext4_handle_dirty_super(const char *where, unsigned int line, struct buffer_head *bh = EXT4_SB(sb)->s_sbh; int err = 0; - ext4_superblock_csum_set(sb); if (ext4_handle_valid(handle)) { + ext4_superblock_csum_set(sb, + (struct ext4_super_block *)bh->b_data); err = jbd2_journal_dirty_metadata(handle, bh); if (err) ext4_journal_abort_handle(where, line, __func__, bh, handle, err); - } else + } else { + ext4_superblock_csum_set(sb, + (struct ext4_super_block *)bh->b_data); mark_buffer_dirty(bh); + } return err; } diff --git a/trunk/fs/ext4/extents.c b/trunk/fs/ext4/extents.c index 7011ac967208..1c94cca35ed1 100644 --- a/trunk/fs/ext4/extents.c +++ b/trunk/fs/ext4/extents.c @@ -52,9 +52,6 @@ #define EXT4_EXT_MARK_UNINIT1 0x2 /* mark first half uninitialized */ #define EXT4_EXT_MARK_UNINIT2 0x4 /* mark second half uninitialized */ -#define EXT4_EXT_DATA_VALID1 0x8 /* first half contains valid data */ -#define EXT4_EXT_DATA_VALID2 0x10 /* second half contains valid data */ - static __le32 ext4_extent_block_csum(struct inode *inode, struct ext4_extent_header *eh) { @@ -2917,9 +2914,6 @@ static int ext4_split_extent_at(handle_t *handle, unsigned int ee_len, depth; int err = 0; - BUG_ON((split_flag & (EXT4_EXT_DATA_VALID1 | EXT4_EXT_DATA_VALID2)) == - (EXT4_EXT_DATA_VALID1 | EXT4_EXT_DATA_VALID2)); - ext_debug("ext4_split_extents_at: inode %lu, logical" "block %llu\n", inode->i_ino, (unsigned long long)split); @@ -2978,14 +2972,7 @@ static int ext4_split_extent_at(handle_t *handle, err = ext4_ext_insert_extent(handle, inode, path, &newex, flags); if (err == -ENOSPC && (EXT4_EXT_MAY_ZEROOUT & split_flag)) { - if (split_flag & (EXT4_EXT_DATA_VALID1|EXT4_EXT_DATA_VALID2)) { - if (split_flag & EXT4_EXT_DATA_VALID1) - err = ext4_ext_zeroout(inode, ex2); - else - err = ext4_ext_zeroout(inode, ex); - } else - err = ext4_ext_zeroout(inode, &orig_ex); - + err = ext4_ext_zeroout(inode, &orig_ex); if (err) goto fix_extent_len; /* update the extent length and mark as initialized */ @@ -3038,13 +3025,12 @@ static int ext4_split_extent(handle_t *handle, uninitialized = ext4_ext_is_uninitialized(ex); if (map->m_lblk + map->m_len < ee_block + ee_len) { - split_flag1 = split_flag & EXT4_EXT_MAY_ZEROOUT; + split_flag1 = split_flag & EXT4_EXT_MAY_ZEROOUT ? + EXT4_EXT_MAY_ZEROOUT : 0; flags1 = flags | EXT4_GET_BLOCKS_PRE_IO; if (uninitialized) split_flag1 |= EXT4_EXT_MARK_UNINIT1 | EXT4_EXT_MARK_UNINIT2; - if (split_flag & EXT4_EXT_DATA_VALID2) - split_flag1 |= EXT4_EXT_DATA_VALID1; err = ext4_split_extent_at(handle, inode, path, map->m_lblk + map->m_len, split_flag1, flags1); if (err) @@ -3057,8 +3043,8 @@ static int ext4_split_extent(handle_t *handle, return PTR_ERR(path); if (map->m_lblk >= ee_block) { - split_flag1 = split_flag & (EXT4_EXT_MAY_ZEROOUT | - EXT4_EXT_DATA_VALID2); + split_flag1 = split_flag & EXT4_EXT_MAY_ZEROOUT ? + EXT4_EXT_MAY_ZEROOUT : 0; if (uninitialized) split_flag1 |= EXT4_EXT_MARK_UNINIT1; if (split_flag & EXT4_EXT_MARK_UNINIT2) @@ -3337,47 +3323,26 @@ static int ext4_split_unwritten_extents(handle_t *handle, split_flag |= ee_block + ee_len <= eof_block ? EXT4_EXT_MAY_ZEROOUT : 0; split_flag |= EXT4_EXT_MARK_UNINIT2; - if (flags & EXT4_GET_BLOCKS_CONVERT) - split_flag |= EXT4_EXT_DATA_VALID2; + flags |= EXT4_GET_BLOCKS_PRE_IO; return ext4_split_extent(handle, inode, path, map, split_flag, flags); } static int ext4_convert_unwritten_extents_endio(handle_t *handle, - struct inode *inode, - struct ext4_map_blocks *map, - struct ext4_ext_path *path) + struct inode *inode, + struct ext4_ext_path *path) { struct ext4_extent *ex; - ext4_lblk_t ee_block; - unsigned int ee_len; int depth; int err = 0; depth = ext_depth(inode); ex = path[depth].p_ext; - ee_block = le32_to_cpu(ex->ee_block); - ee_len = ext4_ext_get_actual_len(ex); ext_debug("ext4_convert_unwritten_extents_endio: inode %lu, logical" "block %llu, max_blocks %u\n", inode->i_ino, - (unsigned long long)ee_block, ee_len); - - /* If extent is larger than requested then split is required */ - if (ee_block != map->m_lblk || ee_len > map->m_len) { - err = ext4_split_unwritten_extents(handle, inode, map, path, - EXT4_GET_BLOCKS_CONVERT); - if (err < 0) - goto out; - ext4_ext_drop_refs(path); - path = ext4_ext_find_extent(inode, map->m_lblk, path); - if (IS_ERR(path)) { - err = PTR_ERR(path); - goto out; - } - depth = ext_depth(inode); - ex = path[depth].p_ext; - } + (unsigned long long)le32_to_cpu(ex->ee_block), + ext4_ext_get_actual_len(ex)); err = ext4_ext_get_access(handle, inode, path + depth); if (err) @@ -3687,7 +3652,7 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, } /* IO end_io complete, convert the filled extent to written */ if ((flags & EXT4_GET_BLOCKS_CONVERT)) { - ret = ext4_convert_unwritten_extents_endio(handle, inode, map, + ret = ext4_convert_unwritten_extents_endio(handle, inode, path); if (ret >= 0) { ext4_update_inode_fsync_trans(handle, inode, 1); @@ -4463,9 +4428,6 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len) */ if (len <= EXT_UNINIT_MAX_LEN << blkbits) flags |= EXT4_GET_BLOCKS_NO_NORMALIZE; - - /* Prevent race condition between unwritten */ - ext4_flush_unwritten_io(inode); retry: while (ret >= 0 && ret < max_blocks) { map.m_lblk = map.m_lblk + ret; diff --git a/trunk/fs/ext4/ialloc.c b/trunk/fs/ext4/ialloc.c index 3a100e7a62a8..fa36372f3fdf 100644 --- a/trunk/fs/ext4/ialloc.c +++ b/trunk/fs/ext4/ialloc.c @@ -725,10 +725,6 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, umode_t mode, "inode=%lu", ino + 1); continue; } - BUFFER_TRACE(inode_bitmap_bh, "get_write_access"); - err = ext4_journal_get_write_access(handle, inode_bitmap_bh); - if (err) - goto fail; ext4_lock_group(sb, group); ret2 = ext4_test_and_set_bit(ino, inode_bitmap_bh->b_data); ext4_unlock_group(sb, group); @@ -742,11 +738,6 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, umode_t mode, goto out; got: - BUFFER_TRACE(inode_bitmap_bh, "call ext4_handle_dirty_metadata"); - err = ext4_handle_dirty_metadata(handle, NULL, inode_bitmap_bh); - if (err) - goto fail; - /* We may have to initialize the block bitmap if it isn't already */ if (ext4_has_group_desc_csum(sb) && gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { @@ -771,7 +762,9 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, umode_t mode, ext4_free_group_clusters_set(sb, gdp, ext4_free_clusters_after_init(sb, group, gdp)); ext4_block_bitmap_csum_set(sb, group, gdp, - block_bitmap_bh); + block_bitmap_bh, + EXT4_BLOCKS_PER_GROUP(sb) / + 8); ext4_group_desc_csum_set(sb, group, gdp); } ext4_unlock_group(sb, group); @@ -780,6 +773,11 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, umode_t mode, goto fail; } + BUFFER_TRACE(inode_bitmap_bh, "get_write_access"); + err = ext4_journal_get_write_access(handle, inode_bitmap_bh); + if (err) + goto fail; + BUFFER_TRACE(group_desc_bh, "get_write_access"); err = ext4_journal_get_write_access(handle, group_desc_bh); if (err) @@ -827,6 +825,11 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, umode_t mode, } ext4_unlock_group(sb, group); + BUFFER_TRACE(inode_bitmap_bh, "call ext4_handle_dirty_metadata"); + err = ext4_handle_dirty_metadata(handle, NULL, inode_bitmap_bh); + if (err) + goto fail; + BUFFER_TRACE(group_desc_bh, "call ext4_handle_dirty_metadata"); err = ext4_handle_dirty_metadata(handle, NULL, group_desc_bh); if (err) diff --git a/trunk/fs/ext4/mballoc.c b/trunk/fs/ext4/mballoc.c index 526e55358606..f8b27bf80aca 100644 --- a/trunk/fs/ext4/mballoc.c +++ b/trunk/fs/ext4/mballoc.c @@ -2805,7 +2805,8 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, } len = ext4_free_group_clusters(sb, gdp) - ac->ac_b_ex.fe_len; ext4_free_group_clusters_set(sb, gdp, len); - ext4_block_bitmap_csum_set(sb, ac->ac_b_ex.fe_group, gdp, bitmap_bh); + ext4_block_bitmap_csum_set(sb, ac->ac_b_ex.fe_group, gdp, bitmap_bh, + EXT4_BLOCKS_PER_GROUP(sb) / 8); ext4_group_desc_csum_set(sb, ac->ac_b_ex.fe_group, gdp); ext4_unlock_group(sb, ac->ac_b_ex.fe_group); @@ -4665,7 +4666,8 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, ret = ext4_free_group_clusters(sb, gdp) + count_clusters; ext4_free_group_clusters_set(sb, gdp, ret); - ext4_block_bitmap_csum_set(sb, block_group, gdp, bitmap_bh); + ext4_block_bitmap_csum_set(sb, block_group, gdp, bitmap_bh, + EXT4_BLOCKS_PER_GROUP(sb) / 8); ext4_group_desc_csum_set(sb, block_group, gdp); ext4_unlock_group(sb, block_group); percpu_counter_add(&sbi->s_freeclusters_counter, count_clusters); @@ -4809,7 +4811,8 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb, mb_free_blocks(NULL, &e4b, bit, count); blk_free_count = blocks_freed + ext4_free_group_clusters(sb, desc); ext4_free_group_clusters_set(sb, desc, blk_free_count); - ext4_block_bitmap_csum_set(sb, block_group, desc, bitmap_bh); + ext4_block_bitmap_csum_set(sb, block_group, desc, bitmap_bh, + EXT4_BLOCKS_PER_GROUP(sb) / 8); ext4_group_desc_csum_set(sb, block_group, desc); ext4_unlock_group(sb, block_group); percpu_counter_add(&sbi->s_freeclusters_counter, @@ -4990,9 +4993,8 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) minlen = EXT4_NUM_B2C(EXT4_SB(sb), range->minlen >> sb->s_blocksize_bits); - if (minlen > EXT4_CLUSTERS_PER_GROUP(sb) || - start >= max_blks || - range->len < sb->s_blocksize) + if (unlikely(minlen > EXT4_CLUSTERS_PER_GROUP(sb)) || + unlikely(start >= max_blks)) return -EINVAL; if (end >= max_blks) end = max_blks - 1; diff --git a/trunk/fs/ext4/resize.c b/trunk/fs/ext4/resize.c index 47bf06a2765d..7a75e1086961 100644 --- a/trunk/fs/ext4/resize.c +++ b/trunk/fs/ext4/resize.c @@ -1212,7 +1212,8 @@ static int ext4_set_bitmap_checksums(struct super_block *sb, bh = ext4_get_bitmap(sb, group_data->block_bitmap); if (!bh) return -EIO; - ext4_block_bitmap_csum_set(sb, group, gdp, bh); + ext4_block_bitmap_csum_set(sb, group, gdp, bh, + EXT4_BLOCKS_PER_GROUP(sb) / 8); brelse(bh); return 0; diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index 80928f716850..7265a0367476 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -143,10 +143,9 @@ int ext4_superblock_csum_verify(struct super_block *sb, return es->s_checksum == ext4_superblock_csum(sb, es); } -void ext4_superblock_csum_set(struct super_block *sb) +void ext4_superblock_csum_set(struct super_block *sb, + struct ext4_super_block *es) { - struct ext4_super_block *es = EXT4_SB(sb)->s_es; - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) return; @@ -1964,7 +1963,7 @@ static int ext4_fill_flex_info(struct super_block *sb) sbi->s_log_groups_per_flex = 0; return 1; } - groups_per_flex = 1U << sbi->s_log_groups_per_flex; + groups_per_flex = 1 << sbi->s_log_groups_per_flex; err = ext4_alloc_flex_bg_array(sb, sbi->s_groups_count); if (err) @@ -4382,7 +4381,7 @@ static int ext4_commit_super(struct super_block *sb, int sync) cpu_to_le32(percpu_counter_sum_positive( &EXT4_SB(sb)->s_freeinodes_counter)); BUFFER_TRACE(sbh, "marking dirty"); - ext4_superblock_csum_set(sb); + ext4_superblock_csum_set(sb, es); mark_buffer_dirty(sbh); if (sync) { error = sync_dirty_buffer(sbh); diff --git a/trunk/fs/file.c b/trunk/fs/file.c index eff23162485f..d3b5fa80b71b 100644 --- a/trunk/fs/file.c +++ b/trunk/fs/file.c @@ -685,6 +685,7 @@ void do_close_on_exec(struct files_struct *files) struct fdtable *fdt; /* exec unshares first */ + BUG_ON(atomic_read(&files->count) != 1); spin_lock(&files->file_lock); for (i = 0; ; i++) { unsigned long set; @@ -899,7 +900,7 @@ int replace_fd(unsigned fd, struct file *file, unsigned flags) return __close_fd(files, fd); if (fd >= rlimit(RLIMIT_NOFILE)) - return -EBADF; + return -EMFILE; spin_lock(&files->file_lock); err = expand_files(files, fd); @@ -925,7 +926,7 @@ SYSCALL_DEFINE3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags) return -EINVAL; if (newfd >= rlimit(RLIMIT_NOFILE)) - return -EBADF; + return -EMFILE; spin_lock(&files->file_lock); err = expand_files(files, newfd); @@ -994,18 +995,16 @@ int iterate_fd(struct files_struct *files, unsigned n, const void *p) { struct fdtable *fdt; + struct file *file; int res = 0; if (!files) return 0; spin_lock(&files->file_lock); - for (fdt = files_fdtable(files); n < fdt->max_fds; n++) { - struct file *file; - file = rcu_dereference_check_fdtable(files, fdt->fd[n]); - if (!file) - continue; - res = f(p, file, n); - if (res) - break; + fdt = files_fdtable(files); + while (!res && n < fdt->max_fds) { + file = rcu_dereference_check_fdtable(files, fdt->fd[n++]); + if (file) + res = f(p, file, n); } spin_unlock(&files->file_lock); return res; diff --git a/trunk/fs/fs-writeback.c b/trunk/fs/fs-writeback.c index 3e3422f7f0a4..51ea267d444c 100644 --- a/trunk/fs/fs-writeback.c +++ b/trunk/fs/fs-writeback.c @@ -228,8 +228,6 @@ static void requeue_io(struct inode *inode, struct bdi_writeback *wb) static void inode_sync_complete(struct inode *inode) { inode->i_state &= ~I_SYNC; - /* If inode is clean an unused, put it into LRU now... */ - inode_add_lru(inode); /* Waiters must see I_SYNC cleared before being woken up */ smp_mb(); wake_up_bit(&inode->i_state, __I_SYNC); diff --git a/trunk/fs/gfs2/file.c b/trunk/fs/gfs2/file.c index e056b4ce4877..0def0504afc1 100644 --- a/trunk/fs/gfs2/file.c +++ b/trunk/fs/gfs2/file.c @@ -516,13 +516,15 @@ static int gfs2_mmap(struct file *file, struct vm_area_struct *vma) struct gfs2_holder i_gh; int error; - error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, - &i_gh); + gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + error = gfs2_glock_nq(&i_gh); + if (error == 0) { + file_accessed(file); + gfs2_glock_dq(&i_gh); + } + gfs2_holder_uninit(&i_gh); if (error) return error; - /* grab lock to update inode */ - gfs2_glock_dq_uninit(&i_gh); - file_accessed(file); } vma->vm_ops = &gfs2_vm_ops; @@ -675,8 +677,10 @@ static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov, size_t writesize = iov_length(iov, nr_segs); struct dentry *dentry = file->f_dentry; struct gfs2_inode *ip = GFS2_I(dentry->d_inode); + struct gfs2_sbd *sdp; int ret; + sdp = GFS2_SB(file->f_mapping->host); ret = gfs2_rs_alloc(ip); if (ret) return ret; diff --git a/trunk/fs/gfs2/lops.c b/trunk/fs/gfs2/lops.c index 9ceccb1595a3..8ff95a2d54ee 100644 --- a/trunk/fs/gfs2/lops.c +++ b/trunk/fs/gfs2/lops.c @@ -393,10 +393,12 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) struct gfs2_meta_header *mh; struct gfs2_trans *tr; + lock_buffer(bd->bd_bh); + gfs2_log_lock(sdp); tr = current->journal_info; tr->tr_touched = 1; if (!list_empty(&bd->bd_list)) - return; + goto out; set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); mh = (struct gfs2_meta_header *)bd->bd_bh->b_data; @@ -412,6 +414,9 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) sdp->sd_log_num_buf++; list_add(&bd->bd_list, &sdp->sd_log_le_buf); tr->tr_num_buf_new++; +out: + gfs2_log_unlock(sdp); + unlock_buffer(bd->bd_bh); } static void gfs2_check_magic(struct buffer_head *bh) @@ -616,6 +621,7 @@ static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) static void revoke_lo_before_commit(struct gfs2_sbd *sdp) { + struct gfs2_log_descriptor *ld; struct gfs2_meta_header *mh; unsigned int offset; struct list_head *head = &sdp->sd_log_le_revoke; @@ -628,6 +634,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp) length = gfs2_struct2blk(sdp, sdp->sd_log_num_revoke, sizeof(u64)); page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_REVOKE, length, sdp->sd_log_num_revoke); + ld = page_address(page); offset = sizeof(struct gfs2_log_descriptor); list_for_each_entry(bd, head, bd_list) { @@ -770,10 +777,12 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) struct address_space *mapping = bd->bd_bh->b_page->mapping; struct gfs2_inode *ip = GFS2_I(mapping->host); + lock_buffer(bd->bd_bh); + gfs2_log_lock(sdp); if (tr) tr->tr_touched = 1; if (!list_empty(&bd->bd_list)) - return; + goto out; set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); if (gfs2_is_jdata(ip)) { @@ -784,6 +793,9 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) } else { list_add_tail(&bd->bd_list, &sdp->sd_log_le_ordered); } +out: + gfs2_log_unlock(sdp); + unlock_buffer(bd->bd_bh); } /** diff --git a/trunk/fs/gfs2/quota.c b/trunk/fs/gfs2/quota.c index c5af8e18f27a..40c4b0d42fa8 100644 --- a/trunk/fs/gfs2/quota.c +++ b/trunk/fs/gfs2/quota.c @@ -497,11 +497,8 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) struct gfs2_quota_data **qd; int error; - if (ip->i_res == NULL) { - error = gfs2_rs_alloc(ip); - if (error) - return error; - } + if (ip->i_res == NULL) + gfs2_rs_alloc(ip); qd = ip->i_res->rs_qa_qd; diff --git a/trunk/fs/gfs2/rgrp.c b/trunk/fs/gfs2/rgrp.c index 38fe18f2f055..3cc402ce6fea 100644 --- a/trunk/fs/gfs2/rgrp.c +++ b/trunk/fs/gfs2/rgrp.c @@ -553,6 +553,7 @@ void gfs2_free_clones(struct gfs2_rgrpd *rgd) */ int gfs2_rs_alloc(struct gfs2_inode *ip) { + int error = 0; struct gfs2_blkreserv *res; if (ip->i_res) @@ -560,7 +561,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip) res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS); if (!res) - return -ENOMEM; + error = -ENOMEM; RB_CLEAR_NODE(&res->rs_node); @@ -570,7 +571,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip) else ip->i_res = res; up_write(&ip->i_rw_mutex); - return 0; + return error; } static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs) @@ -1262,9 +1263,7 @@ int gfs2_fitrim(struct file *filp, void __user *argp) int ret = 0; u64 amt; u64 trimmed = 0; - u64 start, end, minlen; unsigned int x; - unsigned bs_shift = sdp->sd_sb.sb_bsize_shift; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -1272,25 +1271,19 @@ int gfs2_fitrim(struct file *filp, void __user *argp) if (!blk_queue_discard(q)) return -EOPNOTSUPP; - if (copy_from_user(&r, argp, sizeof(r))) + if (argp == NULL) { + r.start = 0; + r.len = ULLONG_MAX; + r.minlen = 0; + } else if (copy_from_user(&r, argp, sizeof(r))) return -EFAULT; ret = gfs2_rindex_update(sdp); if (ret) return ret; - start = r.start >> bs_shift; - end = start + (r.len >> bs_shift); - minlen = max_t(u64, r.minlen, - q->limits.discard_granularity) >> bs_shift; - - rgd = gfs2_blk2rgrpd(sdp, start, 0); - rgd_end = gfs2_blk2rgrpd(sdp, end - 1, 0); - - if (end <= start || - minlen > sdp->sd_max_rg_data || - start > rgd_end->rd_data0 + rgd_end->rd_data) - return -EINVAL; + rgd = gfs2_blk2rgrpd(sdp, r.start, 0); + rgd_end = gfs2_blk2rgrpd(sdp, r.start + r.len, 0); while (1) { @@ -1302,9 +1295,7 @@ int gfs2_fitrim(struct file *filp, void __user *argp) /* Trim each bitmap in the rgrp */ for (x = 0; x < rgd->rd_length; x++) { struct gfs2_bitmap *bi = rgd->rd_bits + x; - ret = gfs2_rgrp_send_discards(sdp, - rgd->rd_data0, NULL, bi, minlen, - &amt); + ret = gfs2_rgrp_send_discards(sdp, rgd->rd_data0, NULL, bi, r.minlen, &amt); if (ret) { gfs2_glock_dq_uninit(&gh); goto out; @@ -1333,7 +1324,7 @@ int gfs2_fitrim(struct file *filp, void __user *argp) out: r.len = trimmed << 9; - if (copy_to_user(argp, &r, sizeof(r))) + if (argp && copy_to_user(argp, &r, sizeof(r))) return -EFAULT; return ret; diff --git a/trunk/fs/gfs2/super.c b/trunk/fs/gfs2/super.c index d6488674d916..bc737261f234 100644 --- a/trunk/fs/gfs2/super.c +++ b/trunk/fs/gfs2/super.c @@ -810,8 +810,7 @@ static void gfs2_dirty_inode(struct inode *inode, int flags) return; } need_unlock = 1; - } else if (WARN_ON_ONCE(ip->i_gl->gl_state != LM_ST_EXCLUSIVE)) - return; + } if (current->journal_info == NULL) { ret = gfs2_trans_begin(sdp, RES_DINODE, 0); diff --git a/trunk/fs/gfs2/trans.c b/trunk/fs/gfs2/trans.c index 413627072f36..adbd27875ef9 100644 --- a/trunk/fs/gfs2/trans.c +++ b/trunk/fs/gfs2/trans.c @@ -155,22 +155,14 @@ void gfs2_trans_add_bh(struct gfs2_glock *gl, struct buffer_head *bh, int meta) struct gfs2_sbd *sdp = gl->gl_sbd; struct gfs2_bufdata *bd; - lock_buffer(bh); - gfs2_log_lock(sdp); bd = bh->b_private; if (bd) gfs2_assert(sdp, bd->bd_gl == gl); else { - gfs2_log_unlock(sdp); - unlock_buffer(bh); gfs2_attach_bufdata(gl, bh, meta); bd = bh->b_private; - lock_buffer(bh); - gfs2_log_lock(sdp); } lops_add(sdp, bd); - gfs2_log_unlock(sdp); - unlock_buffer(bh); } void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) diff --git a/trunk/fs/inode.c b/trunk/fs/inode.c index 64999f144153..b03c71957246 100644 --- a/trunk/fs/inode.c +++ b/trunk/fs/inode.c @@ -408,19 +408,6 @@ static void inode_lru_list_add(struct inode *inode) spin_unlock(&inode->i_sb->s_inode_lru_lock); } -/* - * Add inode to LRU if needed (inode is unused and clean). - * - * Needs inode->i_lock held. - */ -void inode_add_lru(struct inode *inode) -{ - if (!(inode->i_state & (I_DIRTY | I_SYNC | I_FREEING | I_WILL_FREE)) && - !atomic_read(&inode->i_count) && inode->i_sb->s_flags & MS_ACTIVE) - inode_lru_list_add(inode); -} - - static void inode_lru_list_del(struct inode *inode) { spin_lock(&inode->i_sb->s_inode_lru_lock); @@ -1403,7 +1390,8 @@ static void iput_final(struct inode *inode) if (!drop && (sb->s_flags & MS_ACTIVE)) { inode->i_state |= I_REFERENCED; - inode_add_lru(inode); + if (!(inode->i_state & (I_DIRTY|I_SYNC))) + inode_lru_list_add(inode); spin_unlock(&inode->i_lock); return; } diff --git a/trunk/fs/internal.h b/trunk/fs/internal.h index 2f6af7f645eb..916b7cbf3e3e 100644 --- a/trunk/fs/internal.h +++ b/trunk/fs/internal.h @@ -110,7 +110,6 @@ extern int open_check_o_direct(struct file *f); * inode.c */ extern spinlock_t inode_sb_list_lock; -extern void inode_add_lru(struct inode *inode); /* * fs-writeback.c diff --git a/trunk/fs/jbd/transaction.c b/trunk/fs/jbd/transaction.c index 7f5120bf0ec2..78b7f84241d4 100644 --- a/trunk/fs/jbd/transaction.c +++ b/trunk/fs/jbd/transaction.c @@ -1961,9 +1961,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh, spin_unlock(&journal->j_list_lock); jbd_unlock_bh_state(bh); spin_unlock(&journal->j_state_lock); - unlock_buffer(bh); log_wait_commit(journal, tid); - lock_buffer(bh); goto retry; } /* diff --git a/trunk/fs/jffs2/file.c b/trunk/fs/jffs2/file.c index 1506673c087e..60ef3fb707ff 100644 --- a/trunk/fs/jffs2/file.c +++ b/trunk/fs/jffs2/file.c @@ -138,39 +138,33 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, struct page *pg; struct inode *inode = mapping->host; struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); - struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); - struct jffs2_raw_inode ri; - uint32_t alloc_len = 0; pgoff_t index = pos >> PAGE_CACHE_SHIFT; uint32_t pageofs = index << PAGE_CACHE_SHIFT; int ret = 0; - jffs2_dbg(1, "%s()\n", __func__); - - if (pageofs > inode->i_size) { - ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len, - ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); - if (ret) - return ret; - } - - mutex_lock(&f->sem); pg = grab_cache_page_write_begin(mapping, index, flags); - if (!pg) { - if (alloc_len) - jffs2_complete_reservation(c); - mutex_unlock(&f->sem); + if (!pg) return -ENOMEM; - } *pagep = pg; - if (alloc_len) { + jffs2_dbg(1, "%s()\n", __func__); + + if (pageofs > inode->i_size) { /* Make new hole frag from old EOF to new page */ + struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); + struct jffs2_raw_inode ri; struct jffs2_full_dnode *fn; + uint32_t alloc_len; jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n", (unsigned int)inode->i_size, pageofs); + ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len, + ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); + if (ret) + goto out_page; + + mutex_lock(&f->sem); memset(&ri, 0, sizeof(ri)); ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); @@ -197,6 +191,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, if (IS_ERR(fn)) { ret = PTR_ERR(fn); jffs2_complete_reservation(c); + mutex_unlock(&f->sem); goto out_page; } ret = jffs2_add_full_dnode_to_inode(c, f, fn); @@ -211,10 +206,12 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, jffs2_mark_node_obsolete(c, fn->raw); jffs2_free_full_dnode(fn); jffs2_complete_reservation(c); + mutex_unlock(&f->sem); goto out_page; } jffs2_complete_reservation(c); inode->i_size = pageofs; + mutex_unlock(&f->sem); } /* @@ -223,18 +220,18 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, * case of a short-copy. */ if (!PageUptodate(pg)) { + mutex_lock(&f->sem); ret = jffs2_do_readpage_nolock(inode, pg); + mutex_unlock(&f->sem); if (ret) goto out_page; } - mutex_unlock(&f->sem); jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags); return ret; out_page: unlock_page(pg); page_cache_release(pg); - mutex_unlock(&f->sem); return ret; } diff --git a/trunk/fs/jfs/jfs_discard.c b/trunk/fs/jfs/jfs_discard.c index dfcd50304559..9947563e4175 100644 --- a/trunk/fs/jfs/jfs_discard.c +++ b/trunk/fs/jfs/jfs_discard.c @@ -83,7 +83,7 @@ int jfs_ioc_trim(struct inode *ip, struct fstrim_range *range) struct bmap *bmp = JFS_SBI(ip->i_sb)->bmap; struct super_block *sb = ipbmap->i_sb; int agno, agno_end; - u64 start, end, minlen; + s64 start, end, minlen; u64 trimmed = 0; /** @@ -93,18 +93,14 @@ int jfs_ioc_trim(struct inode *ip, struct fstrim_range *range) * minlen: minimum extent length in Bytes */ start = range->start >> sb->s_blocksize_bits; + if (start < 0) + start = 0; end = start + (range->len >> sb->s_blocksize_bits) - 1; - minlen = range->minlen >> sb->s_blocksize_bits; - if (minlen == 0) - minlen = 1; - - if (minlen > bmp->db_agsize || - start >= bmp->db_mapsize || - range->len < sb->s_blocksize) - return -EINVAL; - if (end >= bmp->db_mapsize) end = bmp->db_mapsize - 1; + minlen = range->minlen >> sb->s_blocksize_bits; + if (minlen <= 0) + minlen = 1; /** * we trim all ag's within the range diff --git a/trunk/fs/lockd/mon.c b/trunk/fs/lockd/mon.c index 3d7e09bcc0e9..e4fb3ba5a58a 100644 --- a/trunk/fs/lockd/mon.c +++ b/trunk/fs/lockd/mon.c @@ -85,38 +85,29 @@ static struct rpc_clnt *nsm_create(struct net *net) return rpc_create(&args); } -static struct rpc_clnt *nsm_client_set(struct lockd_net *ln, - struct rpc_clnt *clnt) -{ - spin_lock(&ln->nsm_clnt_lock); - if (ln->nsm_users == 0) { - if (clnt == NULL) - goto out; - ln->nsm_clnt = clnt; - } - clnt = ln->nsm_clnt; - ln->nsm_users++; -out: - spin_unlock(&ln->nsm_clnt_lock); - return clnt; -} - static struct rpc_clnt *nsm_client_get(struct net *net) { - struct rpc_clnt *clnt, *new; + static DEFINE_MUTEX(nsm_create_mutex); + struct rpc_clnt *clnt; struct lockd_net *ln = net_generic(net, lockd_net_id); - clnt = nsm_client_set(ln, NULL); - if (clnt != NULL) - goto out; - - clnt = new = nsm_create(net); - if (IS_ERR(clnt)) + spin_lock(&ln->nsm_clnt_lock); + if (ln->nsm_users) { + ln->nsm_users++; + clnt = ln->nsm_clnt; + spin_unlock(&ln->nsm_clnt_lock); goto out; + } + spin_unlock(&ln->nsm_clnt_lock); - clnt = nsm_client_set(ln, new); - if (clnt != new) - rpc_shutdown_client(new); + mutex_lock(&nsm_create_mutex); + clnt = nsm_create(net); + if (!IS_ERR(clnt)) { + ln->nsm_clnt = clnt; + smp_wmb(); + ln->nsm_users = 1; + } + mutex_unlock(&nsm_create_mutex); out: return clnt; } @@ -124,16 +115,18 @@ static struct rpc_clnt *nsm_client_get(struct net *net) static void nsm_client_put(struct net *net) { struct lockd_net *ln = net_generic(net, lockd_net_id); - struct rpc_clnt *clnt = NULL; + struct rpc_clnt *clnt = ln->nsm_clnt; + int shutdown = 0; spin_lock(&ln->nsm_clnt_lock); - ln->nsm_users--; - if (ln->nsm_users == 0) { - clnt = ln->nsm_clnt; - ln->nsm_clnt = NULL; + if (ln->nsm_users) { + if (--ln->nsm_users) + ln->nsm_clnt = NULL; + shutdown = !ln->nsm_users; } spin_unlock(&ln->nsm_clnt_lock); - if (clnt != NULL) + + if (shutdown) rpc_shutdown_client(clnt); } diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index 5f4cdf3ad913..d1895f308156 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -705,8 +705,8 @@ static inline void put_link(struct nameidata *nd, struct path *link, void *cooki path_put(link); } -int sysctl_protected_symlinks __read_mostly = 0; -int sysctl_protected_hardlinks __read_mostly = 0; +int sysctl_protected_symlinks __read_mostly = 1; +int sysctl_protected_hardlinks __read_mostly = 1; /** * may_follow_link - Check symlink following for unsafe situations @@ -2131,11 +2131,6 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) if (!len) return ERR_PTR(-EACCES); - if (unlikely(name[0] == '.')) { - if (len < 2 || (len == 2 && name[1] == '.')) - return ERR_PTR(-EACCES); - } - while (len--) { c = *(const unsigned char *)name++; if (c == '/' || c == '\0') diff --git a/trunk/fs/nfs/callback.c b/trunk/fs/nfs/callback.c index 5088b57b078a..9a521fb39869 100644 --- a/trunk/fs/nfs/callback.c +++ b/trunk/fs/nfs/callback.c @@ -241,7 +241,7 @@ static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt, svc_exit_thread(cb_info->rqst); cb_info->rqst = NULL; cb_info->task = NULL; - return ret; + return PTR_ERR(cb_info->task); } dprintk("nfs_callback_up: service started\n"); return 0; diff --git a/trunk/fs/nfs/dir.c b/trunk/fs/nfs/dir.c index b9e66b7e0c14..ce8cb926526b 100644 --- a/trunk/fs/nfs/dir.c +++ b/trunk/fs/nfs/dir.c @@ -450,8 +450,7 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) nfs_refresh_inode(dentry->d_inode, entry->fattr); goto out; } else { - if (d_invalidate(dentry) != 0) - goto out; + d_drop(dentry); dput(dentry); } } @@ -1101,8 +1100,6 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags) out_zap_parent: nfs_zap_caches(dir); out_bad: - nfs_free_fattr(fattr); - nfs_free_fhandle(fhandle); nfs_mark_for_revalidate(dir); if (inode && S_ISDIR(inode->i_mode)) { /* Purge readdir caches. */ @@ -1115,6 +1112,8 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags) shrink_dcache_parent(dentry); } d_drop(dentry); + nfs_free_fattr(fattr); + nfs_free_fhandle(fhandle); dput(parent); dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n", __func__, dentry->d_parent->d_name.name, diff --git a/trunk/fs/nfs/dns_resolve.c b/trunk/fs/nfs/dns_resolve.c index ca4b11ec87a2..31c26c4dcc23 100644 --- a/trunk/fs/nfs/dns_resolve.c +++ b/trunk/fs/nfs/dns_resolve.c @@ -217,7 +217,7 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen) { char buf1[NFS_DNS_HOSTNAME_MAXLEN+1]; struct nfs_dns_ent key, *item; - unsigned int ttl; + unsigned long ttl; ssize_t len; int ret = -EINVAL; @@ -240,8 +240,7 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen) key.namelen = len; memset(&key.h, 0, sizeof(key.h)); - if (get_uint(&buf, &ttl) < 0) - goto out; + ttl = get_expiry(&buf); if (ttl == 0) goto out; key.h.expiry_time = ttl + seconds_since_boot(); diff --git a/trunk/fs/nfs/inode.c b/trunk/fs/nfs/inode.c index 6fa01aea2488..5c7325c5c5e6 100644 --- a/trunk/fs/nfs/inode.c +++ b/trunk/fs/nfs/inode.c @@ -685,10 +685,7 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync) if (ctx->cred != NULL) put_rpccred(ctx->cred); dput(ctx->dentry); - if (is_sync) - nfs_sb_deactive(sb); - else - nfs_sb_deactive_async(sb); + nfs_sb_deactive(sb); kfree(ctx->mdsthreshold); kfree(ctx); } diff --git a/trunk/fs/nfs/internal.h b/trunk/fs/nfs/internal.h index 05521cadac2e..59b133c5d652 100644 --- a/trunk/fs/nfs/internal.h +++ b/trunk/fs/nfs/internal.h @@ -351,12 +351,10 @@ extern int __init register_nfs_fs(void); extern void __exit unregister_nfs_fs(void); extern void nfs_sb_active(struct super_block *sb); extern void nfs_sb_deactive(struct super_block *sb); -extern void nfs_sb_deactive_async(struct super_block *sb); /* namespace.c */ -#define NFS_PATH_CANONICAL 1 extern char *nfs_path(char **p, struct dentry *dentry, - char *buffer, ssize_t buflen, unsigned flags); + char *buffer, ssize_t buflen); extern struct vfsmount *nfs_d_automount(struct path *path); struct vfsmount *nfs_submount(struct nfs_server *, struct dentry *, struct nfs_fh *, struct nfs_fattr *); @@ -500,7 +498,7 @@ static inline char *nfs_devname(struct dentry *dentry, char *buffer, ssize_t buflen) { char *dummy; - return nfs_path(&dummy, dentry, buffer, buflen, NFS_PATH_CANONICAL); + return nfs_path(&dummy, dentry, buffer, buflen); } /* diff --git a/trunk/fs/nfs/mount_clnt.c b/trunk/fs/nfs/mount_clnt.c index 015f71f8f62c..8e65c7f1f87c 100644 --- a/trunk/fs/nfs/mount_clnt.c +++ b/trunk/fs/nfs/mount_clnt.c @@ -181,7 +181,7 @@ int nfs_mount(struct nfs_mount_request *info) else msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC_MNT]; - status = rpc_call_sync(mnt_clnt, &msg, RPC_TASK_SOFT|RPC_TASK_TIMEOUT); + status = rpc_call_sync(mnt_clnt, &msg, 0); rpc_shutdown_client(mnt_clnt); if (status < 0) diff --git a/trunk/fs/nfs/namespace.c b/trunk/fs/nfs/namespace.c index dd057bc6b65b..655925373b91 100644 --- a/trunk/fs/nfs/namespace.c +++ b/trunk/fs/nfs/namespace.c @@ -33,7 +33,6 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ; * @dentry - pointer to dentry * @buffer - result buffer * @buflen - length of buffer - * @flags - options (see below) * * Helper function for constructing the server pathname * by arbitrary hashed dentry. @@ -41,14 +40,8 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ; * This is mainly for use in figuring out the path on the * server side when automounting on top of an existing partition * and in generating /proc/mounts and friends. - * - * Supported flags: - * NFS_PATH_CANONICAL: ensure there is exactly one slash after - * the original device (export) name - * (if unset, the original name is returned verbatim) */ -char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen, - unsigned flags) +char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen) { char *end; int namelen; @@ -81,7 +74,7 @@ char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen, rcu_read_unlock(); goto rename_retry; } - if ((flags & NFS_PATH_CANONICAL) && *end != '/') { + if (*end != '/') { if (--buflen < 0) { spin_unlock(&dentry->d_lock); rcu_read_unlock(); @@ -98,11 +91,9 @@ char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen, return end; } namelen = strlen(base); - if (flags & NFS_PATH_CANONICAL) { - /* Strip off excess slashes in base string */ - while (namelen > 0 && base[namelen - 1] == '/') - namelen--; - } + /* Strip off excess slashes in base string */ + while (namelen > 0 && base[namelen - 1] == '/') + namelen--; buflen -= namelen; if (buflen < 0) { spin_unlock(&dentry->d_lock); diff --git a/trunk/fs/nfs/nfs4filelayout.c b/trunk/fs/nfs/nfs4filelayout.c index 2e45fd9c02a3..52d847212066 100644 --- a/trunk/fs/nfs/nfs4filelayout.c +++ b/trunk/fs/nfs/nfs4filelayout.c @@ -122,21 +122,12 @@ static void filelayout_reset_read(struct nfs_read_data *data) } } -static void filelayout_fenceme(struct inode *inode, struct pnfs_layout_hdr *lo) -{ - if (!test_and_clear_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) - return; - clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags); - pnfs_return_layout(inode); -} - static int filelayout_async_handle_error(struct rpc_task *task, struct nfs4_state *state, struct nfs_client *clp, struct pnfs_layout_segment *lseg) { - struct pnfs_layout_hdr *lo = lseg->pls_layout; - struct inode *inode = lo->plh_inode; + struct inode *inode = lseg->pls_layout->plh_inode; struct nfs_server *mds_server = NFS_SERVER(inode); struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg); struct nfs_client *mds_client = mds_server->nfs_client; @@ -213,8 +204,10 @@ static int filelayout_async_handle_error(struct rpc_task *task, dprintk("%s DS connection error %d\n", __func__, task->tk_status); nfs4_mark_deviceid_unavailable(devid); - set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags); + clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags); + _pnfs_return_layout(inode); rpc_wake_up(&tbl->slot_tbl_waitq); + nfs4_ds_disconnect(clp); /* fall through */ default: reset: @@ -338,9 +331,7 @@ static void filelayout_read_count_stats(struct rpc_task *task, void *data) static void filelayout_read_release(void *data) { struct nfs_read_data *rdata = data; - struct pnfs_layout_hdr *lo = rdata->header->lseg->pls_layout; - filelayout_fenceme(lo->plh_inode, lo); nfs_put_client(rdata->ds_clp); rdata->header->mds_ops->rpc_release(data); } @@ -438,9 +429,7 @@ static void filelayout_write_count_stats(struct rpc_task *task, void *data) static void filelayout_write_release(void *data) { struct nfs_write_data *wdata = data; - struct pnfs_layout_hdr *lo = wdata->header->lseg->pls_layout; - filelayout_fenceme(lo->plh_inode, lo); nfs_put_client(wdata->ds_clp); wdata->header->mds_ops->rpc_release(data); } @@ -750,7 +739,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, goto out_err; if (fl->num_fh > 0) { - fl->fh_array = kcalloc(fl->num_fh, sizeof(fl->fh_array[0]), + fl->fh_array = kzalloc(fl->num_fh * sizeof(struct nfs_fh *), gfp_flags); if (!fl->fh_array) goto out_err; diff --git a/trunk/fs/nfs/nfs4filelayout.h b/trunk/fs/nfs/nfs4filelayout.h index 8c07241fe52b..dca47d786710 100644 --- a/trunk/fs/nfs/nfs4filelayout.h +++ b/trunk/fs/nfs/nfs4filelayout.h @@ -149,5 +149,6 @@ extern void nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr); extern void nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr); struct nfs4_file_layout_dsaddr * filelayout_get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags); +void nfs4_ds_disconnect(struct nfs_client *clp); #endif /* FS_NFS_NFS4FILELAYOUT_H */ diff --git a/trunk/fs/nfs/nfs4filelayoutdev.c b/trunk/fs/nfs/nfs4filelayoutdev.c index a8eaa9b7bb0f..3336d5eaf879 100644 --- a/trunk/fs/nfs/nfs4filelayoutdev.c +++ b/trunk/fs/nfs/nfs4filelayoutdev.c @@ -148,6 +148,28 @@ _data_server_lookup_locked(const struct list_head *dsaddrs) return NULL; } +/* + * Lookup DS by nfs_client pointer. Zero data server client pointer + */ +void nfs4_ds_disconnect(struct nfs_client *clp) +{ + struct nfs4_pnfs_ds *ds; + struct nfs_client *found = NULL; + + dprintk("%s clp %p\n", __func__, clp); + spin_lock(&nfs4_ds_cache_lock); + list_for_each_entry(ds, &nfs4_data_server_cache, ds_node) + if (ds->ds_clp && ds->ds_clp == clp) { + found = ds->ds_clp; + ds->ds_clp = NULL; + } + spin_unlock(&nfs4_ds_cache_lock); + if (found) { + set_bit(NFS_CS_STOP_RENEW, &clp->cl_res_state); + nfs_put_client(clp); + } +} + /* * Create an rpc connection to the nfs4_pnfs_ds data server * Currently only supports IPv4 and IPv6 addresses diff --git a/trunk/fs/nfs/nfs4getroot.c b/trunk/fs/nfs/nfs4getroot.c index 549462e5b9b0..6a83780e0ce6 100644 --- a/trunk/fs/nfs/nfs4getroot.c +++ b/trunk/fs/nfs/nfs4getroot.c @@ -5,7 +5,6 @@ #include #include "nfs4_fs.h" -#include "internal.h" #define NFSDBG_FACILITY NFSDBG_CLIENT diff --git a/trunk/fs/nfs/nfs4namespace.c b/trunk/fs/nfs/nfs4namespace.c index 1e09eb78543b..79fbb61ce202 100644 --- a/trunk/fs/nfs/nfs4namespace.c +++ b/trunk/fs/nfs/nfs4namespace.c @@ -81,8 +81,7 @@ static char *nfs_path_component(const char *nfspath, const char *end) static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen) { char *limit; - char *path = nfs_path(&limit, dentry, buffer, buflen, - NFS_PATH_CANONICAL); + char *path = nfs_path(&limit, dentry, buffer, buflen); if (!IS_ERR(path)) { char *path_component = nfs_path_component(path, limit); if (path_component) diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index 5eec4429970c..68b21d81b7ac 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -339,7 +339,8 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc dprintk("%s ERROR: %d Reset session\n", __func__, errorcode); nfs4_schedule_session_recovery(clp->cl_session, errorcode); - goto wait_on_recovery; + exception->retry = 1; + break; #endif /* defined(CONFIG_NFS_V4_1) */ case -NFS4ERR_FILE_OPEN: if (exception->timeout > HZ) { @@ -1571,11 +1572,9 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) data->timestamp = jiffies; if (nfs4_setup_sequence(data->o_arg.server, &data->o_arg.seq_args, - &data->o_res.seq_res, - task) != 0) - nfs_release_seqid(data->o_arg.seqid); - else - rpc_call_start(task); + &data->o_res.seq_res, task)) + return; + rpc_call_start(task); return; unlock_no_action: rcu_read_unlock(); @@ -1749,7 +1748,7 @@ static int nfs4_opendata_access(struct rpc_cred *cred, /* even though OPEN succeeded, access is denied. Close the file */ nfs4_close_state(state, fmode); - return -EACCES; + return -NFS4ERR_ACCESS; } /* @@ -2197,7 +2196,7 @@ static void nfs4_free_closedata(void *data) nfs4_put_open_state(calldata->state); nfs_free_seqid(calldata->arg.seqid); nfs4_put_state_owner(sp); - nfs_sb_deactive_async(sb); + nfs_sb_deactive(sb); kfree(calldata); } @@ -2297,10 +2296,9 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) if (nfs4_setup_sequence(NFS_SERVER(inode), &calldata->arg.seq_args, &calldata->res.seq_res, - task) != 0) - nfs_release_seqid(calldata->arg.seqid); - else - rpc_call_start(task); + task)) + goto out; + rpc_call_start(task); out: dprintk("%s: done!\n", __func__); } @@ -4531,7 +4529,6 @@ static void nfs4_locku_done(struct rpc_task *task, void *data) if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN) rpc_restart_call_prepare(task); } - nfs_release_seqid(calldata->arg.seqid); } static void nfs4_locku_prepare(struct rpc_task *task, void *data) @@ -4548,11 +4545,9 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data) calldata->timestamp = jiffies; if (nfs4_setup_sequence(calldata->server, &calldata->arg.seq_args, - &calldata->res.seq_res, - task) != 0) - nfs_release_seqid(calldata->arg.seqid); - else - rpc_call_start(task); + &calldata->res.seq_res, task)) + return; + rpc_call_start(task); } static const struct rpc_call_ops nfs4_locku_ops = { @@ -4697,7 +4692,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) /* Do we need to do an open_to_lock_owner? */ if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) { if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0) - goto out_release_lock_seqid; + return; data->arg.open_stateid = &state->stateid; data->arg.new_lock_owner = 1; data->res.open_seqid = data->arg.open_seqid; @@ -4706,15 +4701,10 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) data->timestamp = jiffies; if (nfs4_setup_sequence(data->server, &data->arg.seq_args, - &data->res.seq_res, - task) == 0) { - rpc_call_start(task); + &data->res.seq_res, task)) return; - } - nfs_release_seqid(data->arg.open_seqid); -out_release_lock_seqid: - nfs_release_seqid(data->arg.lock_seqid); - dprintk("%s: done!, ret = %d\n", __func__, task->tk_status); + rpc_call_start(task); + dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status); } static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata) @@ -5677,7 +5667,7 @@ static void nfs4_add_and_init_slots(struct nfs4_slot_table *tbl, tbl->slots = new; tbl->max_slots = max_slots; } - tbl->highest_used_slotid = NFS4_NO_SLOT; + tbl->highest_used_slotid = -1; /* no slot is currently used */ for (i = 0; i < tbl->max_slots; i++) tbl->slots[i].seq_nr = ivalue; spin_unlock(&tbl->slot_tbl_lock); diff --git a/trunk/fs/nfs/objlayout/objio_osd.c b/trunk/fs/nfs/objlayout/objio_osd.c index c6f990656f89..be731e6b7b9c 100644 --- a/trunk/fs/nfs/objlayout/objio_osd.c +++ b/trunk/fs/nfs/objlayout/objio_osd.c @@ -369,7 +369,7 @@ void objio_free_result(struct objlayout_io_res *oir) kfree(objios); } -static enum pnfs_osd_errno osd_pri_2_pnfs_err(enum osd_err_priority oep) +enum pnfs_osd_errno osd_pri_2_pnfs_err(enum osd_err_priority oep) { switch (oep) { case OSD_ERR_PRI_NO_ERROR: @@ -574,7 +574,7 @@ static bool objio_pg_test(struct nfs_pageio_descriptor *pgio, (unsigned long)pgio->pg_layout_private; } -static void objio_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) +void objio_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) { pnfs_generic_pg_init_read(pgio, req); if (unlikely(pgio->pg_lseg == NULL)) @@ -604,7 +604,7 @@ static bool aligned_on_raid_stripe(u64 offset, struct ore_layout *layout, return false; } -static void objio_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) +void objio_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) { unsigned long stripe_end = 0; u64 wb_size; diff --git a/trunk/fs/nfs/pnfs.c b/trunk/fs/nfs/pnfs.c index 2878f97bd78d..fe624c91bd00 100644 --- a/trunk/fs/nfs/pnfs.c +++ b/trunk/fs/nfs/pnfs.c @@ -925,8 +925,8 @@ pnfs_find_alloc_layout(struct inode *ino, if (likely(nfsi->layout == NULL)) { /* Won the race? */ nfsi->layout = new; return new; - } else if (new != NULL) - pnfs_free_layout_hdr(new); + } + pnfs_free_layout_hdr(new); out_existing: pnfs_get_layout_hdr(nfsi->layout); return nfsi->layout; diff --git a/trunk/fs/nfs/pnfs.h b/trunk/fs/nfs/pnfs.h index dbf7bba52da0..2d722dba1111 100644 --- a/trunk/fs/nfs/pnfs.h +++ b/trunk/fs/nfs/pnfs.h @@ -62,7 +62,6 @@ enum { NFS_LAYOUT_RW_FAILED, /* get rw layout failed stop trying */ NFS_LAYOUT_BULK_RECALL, /* bulk recall affecting layout */ NFS_LAYOUT_ROC, /* some lseg had roc bit set */ - NFS_LAYOUT_RETURN, /* Return this layout ASAP */ }; enum layoutdriver_policy_flags { diff --git a/trunk/fs/nfs/super.c b/trunk/fs/nfs/super.c index 652d3f7176a9..e831bce49766 100644 --- a/trunk/fs/nfs/super.c +++ b/trunk/fs/nfs/super.c @@ -54,7 +54,6 @@ #include #include #include -#include #include @@ -416,54 +415,6 @@ void nfs_sb_deactive(struct super_block *sb) } EXPORT_SYMBOL_GPL(nfs_sb_deactive); -static int nfs_deactivate_super_async_work(void *ptr) -{ - struct super_block *sb = ptr; - - deactivate_super(sb); - module_put_and_exit(0); - return 0; -} - -/* - * same effect as deactivate_super, but will do final unmount in kthread - * context - */ -static void nfs_deactivate_super_async(struct super_block *sb) -{ - struct task_struct *task; - char buf[INET6_ADDRSTRLEN + 1]; - struct nfs_server *server = NFS_SB(sb); - struct nfs_client *clp = server->nfs_client; - - if (!atomic_add_unless(&sb->s_active, -1, 1)) { - rcu_read_lock(); - snprintf(buf, sizeof(buf), - rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR)); - rcu_read_unlock(); - - __module_get(THIS_MODULE); - task = kthread_run(nfs_deactivate_super_async_work, sb, - "%s-deactivate-super", buf); - if (IS_ERR(task)) { - pr_err("%s: kthread_run: %ld\n", - __func__, PTR_ERR(task)); - /* make synchronous call and hope for the best */ - deactivate_super(sb); - module_put(THIS_MODULE); - } - } -} - -void nfs_sb_deactive_async(struct super_block *sb) -{ - struct nfs_server *server = NFS_SB(sb); - - if (atomic_dec_and_test(&server->active)) - nfs_deactivate_super_async(sb); -} -EXPORT_SYMBOL_GPL(nfs_sb_deactive_async); - /* * Deliver file system statistics to userspace */ @@ -820,7 +771,7 @@ int nfs_show_devname(struct seq_file *m, struct dentry *root) int err = 0; if (!page) return -ENOMEM; - devname = nfs_path(&dummy, root, page, PAGE_SIZE, 0); + devname = nfs_path(&dummy, root, page, PAGE_SIZE); if (IS_ERR(devname)) err = PTR_ERR(devname); else diff --git a/trunk/fs/nfs/unlink.c b/trunk/fs/nfs/unlink.c index 3f79c77153b8..13cea637eff8 100644 --- a/trunk/fs/nfs/unlink.c +++ b/trunk/fs/nfs/unlink.c @@ -95,7 +95,7 @@ static void nfs_async_unlink_release(void *calldata) nfs_dec_sillycount(data->dir); nfs_free_unlinkdata(data); - nfs_sb_deactive_async(sb); + nfs_sb_deactive(sb); } static void nfs_unlink_prepare(struct rpc_task *task, void *calldata) diff --git a/trunk/fs/notify/fanotify/fanotify.c b/trunk/fs/notify/fanotify/fanotify.c index a50636025364..f35794b97e8e 100644 --- a/trunk/fs/notify/fanotify/fanotify.c +++ b/trunk/fs/notify/fanotify/fanotify.c @@ -21,7 +21,6 @@ static bool should_merge(struct fsnotify_event *old, struct fsnotify_event *new) if ((old->path.mnt == new->path.mnt) && (old->path.dentry == new->path.dentry)) return true; - break; case (FSNOTIFY_EVENT_NONE): return true; default: diff --git a/trunk/fs/notify/fanotify/fanotify_user.c b/trunk/fs/notify/fanotify/fanotify_user.c index 6fcaeb8c902e..721d692fa8d4 100644 --- a/trunk/fs/notify/fanotify/fanotify_user.c +++ b/trunk/fs/notify/fanotify/fanotify_user.c @@ -258,8 +258,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, if (ret) goto out_close_fd; - if (fd != FAN_NOFD) - fd_install(fd, f); + fd_install(fd, f); return fanotify_event_metadata.event_len; out_close_fd: diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index 9e28356a959a..144a96732dd7 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -873,113 +873,6 @@ static const struct file_operations proc_environ_operations = { .release = mem_release, }; -static ssize_t oom_adj_read(struct file *file, char __user *buf, size_t count, - loff_t *ppos) -{ - struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode); - char buffer[PROC_NUMBUF]; - int oom_adj = OOM_ADJUST_MIN; - size_t len; - unsigned long flags; - - if (!task) - return -ESRCH; - if (lock_task_sighand(task, &flags)) { - if (task->signal->oom_score_adj == OOM_SCORE_ADJ_MAX) - oom_adj = OOM_ADJUST_MAX; - else - oom_adj = (task->signal->oom_score_adj * -OOM_DISABLE) / - OOM_SCORE_ADJ_MAX; - unlock_task_sighand(task, &flags); - } - put_task_struct(task); - len = snprintf(buffer, sizeof(buffer), "%d\n", oom_adj); - return simple_read_from_buffer(buf, count, ppos, buffer, len); -} - -static ssize_t oom_adj_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct task_struct *task; - char buffer[PROC_NUMBUF]; - int oom_adj; - unsigned long flags; - int err; - - memset(buffer, 0, sizeof(buffer)); - if (count > sizeof(buffer) - 1) - count = sizeof(buffer) - 1; - if (copy_from_user(buffer, buf, count)) { - err = -EFAULT; - goto out; - } - - err = kstrtoint(strstrip(buffer), 0, &oom_adj); - if (err) - goto out; - if ((oom_adj < OOM_ADJUST_MIN || oom_adj > OOM_ADJUST_MAX) && - oom_adj != OOM_DISABLE) { - err = -EINVAL; - goto out; - } - - task = get_proc_task(file->f_path.dentry->d_inode); - if (!task) { - err = -ESRCH; - goto out; - } - - task_lock(task); - if (!task->mm) { - err = -EINVAL; - goto err_task_lock; - } - - if (!lock_task_sighand(task, &flags)) { - err = -ESRCH; - goto err_task_lock; - } - - /* - * Scale /proc/pid/oom_score_adj appropriately ensuring that a maximum - * value is always attainable. - */ - if (oom_adj == OOM_ADJUST_MAX) - oom_adj = OOM_SCORE_ADJ_MAX; - else - oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE; - - if (oom_adj < task->signal->oom_score_adj && - !capable(CAP_SYS_RESOURCE)) { - err = -EACCES; - goto err_sighand; - } - - /* - * /proc/pid/oom_adj is provided for legacy purposes, ask users to use - * /proc/pid/oom_score_adj instead. - */ - printk_once(KERN_WARNING "%s (%d): /proc/%d/oom_adj is deprecated, please use /proc/%d/oom_score_adj instead.\n", - current->comm, task_pid_nr(current), task_pid_nr(task), - task_pid_nr(task)); - - task->signal->oom_score_adj = oom_adj; - trace_oom_score_adj_update(task); -err_sighand: - unlock_task_sighand(task, &flags); -err_task_lock: - task_unlock(task); - put_task_struct(task); -out: - return err < 0 ? err : count; -} - -static const struct file_operations proc_oom_adj_operations = { - .read = oom_adj_read, - .write = oom_adj_write, - .llseek = generic_file_llseek, -}; - static ssize_t oom_score_adj_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { @@ -1877,9 +1770,8 @@ static struct dentry *proc_map_files_lookup(struct inode *dir, if (!vma) goto out_no_vma; - if (vma->vm_file) - result = proc_map_files_instantiate(dir, dentry, task, - (void *)(unsigned long)vma->vm_file->f_mode); + result = proc_map_files_instantiate(dir, dentry, task, + (void *)(unsigned long)vma->vm_file->f_mode); out_no_vma: up_read(&mm->mmap_sem); @@ -2706,7 +2598,6 @@ static const struct pid_entry tgid_base_stuff[] = { REG("cgroup", S_IRUGO, proc_cgroup_operations), #endif INF("oom_score", S_IRUGO, proc_oom_score), - REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations), REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations), #ifdef CONFIG_AUDITSYSCALL REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations), @@ -3073,7 +2964,6 @@ static const struct pid_entry tid_base_stuff[] = { REG("cgroup", S_IRUGO, proc_cgroup_operations), #endif INF("oom_score", S_IRUGO, proc_oom_score), - REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations), REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations), #ifdef CONFIG_AUDITSYSCALL REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations), diff --git a/trunk/fs/proc/stat.c b/trunk/fs/proc/stat.c index e296572c73ed..64c3b3172367 100644 --- a/trunk/fs/proc/stat.c +++ b/trunk/fs/proc/stat.c @@ -45,13 +45,10 @@ static cputime64_t get_iowait_time(int cpu) static u64 get_idle_time(int cpu) { - u64 idle, idle_time = -1ULL; - - if (cpu_online(cpu)) - idle_time = get_cpu_idle_time_us(cpu, NULL); + u64 idle, idle_time = get_cpu_idle_time_us(cpu, NULL); if (idle_time == -1ULL) - /* !NO_HZ or cpu offline so we can rely on cpustat.idle */ + /* !NO_HZ so we can rely on cpustat.idle */ idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE]; else idle = usecs_to_cputime64(idle_time); @@ -61,13 +58,10 @@ static u64 get_idle_time(int cpu) static u64 get_iowait_time(int cpu) { - u64 iowait, iowait_time = -1ULL; - - if (cpu_online(cpu)) - iowait_time = get_cpu_iowait_time_us(cpu, NULL); + u64 iowait, iowait_time = get_cpu_iowait_time_us(cpu, NULL); if (iowait_time == -1ULL) - /* !NO_HZ or cpu offline so we can rely on cpustat.iowait */ + /* !NO_HZ so we can rely on cpustat.iowait */ iowait = kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT]; else iowait = usecs_to_cputime64(iowait_time); diff --git a/trunk/fs/pstore/platform.c b/trunk/fs/pstore/platform.c index 947fbe06c3b1..a40da07e93d6 100644 --- a/trunk/fs/pstore/platform.c +++ b/trunk/fs/pstore/platform.c @@ -161,7 +161,6 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c) while (s < e) { unsigned long flags; - u64 id; if (c > psinfo->bufsize) c = psinfo->bufsize; @@ -173,7 +172,7 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c) spin_lock_irqsave(&psinfo->buf_lock, flags); } memcpy(psinfo->buf, s, c); - psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, c, psinfo); + psinfo->write(PSTORE_TYPE_CONSOLE, 0, NULL, 0, c, psinfo); spin_unlock_irqrestore(&psinfo->buf_lock, flags); s += c; c = e - s; diff --git a/trunk/fs/reiserfs/inode.c b/trunk/fs/reiserfs/inode.c index d83736fbc26c..f27f01a98aa2 100644 --- a/trunk/fs/reiserfs/inode.c +++ b/trunk/fs/reiserfs/inode.c @@ -1782,9 +1782,8 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, BUG_ON(!th->t_trans_id); - reiserfs_write_unlock(inode->i_sb); + dquot_initialize(inode); err = dquot_alloc_inode(inode); - reiserfs_write_lock(inode->i_sb); if (err) goto out_end_trans; if (!dir->i_nlink) { @@ -1980,10 +1979,8 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, out_end_trans: journal_end(th, th->t_super, th->t_blocks_allocated); - reiserfs_write_unlock(inode->i_sb); /* Drop can be outside and it needs more credits so it's better to have it outside */ dquot_drop(inode); - reiserfs_write_lock(inode->i_sb); inode->i_flags |= S_NOQUOTA; make_bad_inode(inode); @@ -3106,9 +3103,10 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) /* must be turned off for recursive notify_change calls */ ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); + depth = reiserfs_write_lock_once(inode->i_sb); if (is_quota_modification(inode, attr)) dquot_initialize(inode); - depth = reiserfs_write_lock_once(inode->i_sb); + if (attr->ia_valid & ATTR_SIZE) { /* version 2 items will be caught by the s_maxbytes check ** done for us in vmtruncate @@ -3172,9 +3170,7 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) error = journal_begin(&th, inode->i_sb, jbegin_count); if (error) goto out; - reiserfs_write_unlock_once(inode->i_sb, depth); error = dquot_transfer(inode, attr); - depth = reiserfs_write_lock_once(inode->i_sb); if (error) { journal_end(&th, inode->i_sb, jbegin_count); goto out; diff --git a/trunk/fs/reiserfs/stree.c b/trunk/fs/reiserfs/stree.c index 2f40a4c70a4d..f8afa4b162b8 100644 --- a/trunk/fs/reiserfs/stree.c +++ b/trunk/fs/reiserfs/stree.c @@ -1968,9 +1968,7 @@ int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct tree key2type(&(key->on_disk_key))); #endif - reiserfs_write_unlock(inode->i_sb); retval = dquot_alloc_space_nodirty(inode, pasted_size); - reiserfs_write_lock(inode->i_sb); if (retval) { pathrelse(search_path); return retval; @@ -2063,11 +2061,9 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th, "reiserquota insert_item(): allocating %u id=%u type=%c", quota_bytes, inode->i_uid, head2type(ih)); #endif - reiserfs_write_unlock(inode->i_sb); /* We can't dirty inode here. It would be immediately written but * appropriate stat item isn't inserted yet... */ retval = dquot_alloc_space_nodirty(inode, quota_bytes); - reiserfs_write_lock(inode->i_sb); if (retval) { pathrelse(path); return retval; diff --git a/trunk/fs/reiserfs/super.c b/trunk/fs/reiserfs/super.c index 418bdc3a57da..1078ae179993 100644 --- a/trunk/fs/reiserfs/super.c +++ b/trunk/fs/reiserfs/super.c @@ -298,9 +298,7 @@ static int finish_unfinished(struct super_block *s) retval = remove_save_link_only(s, &save_link_key, 0); continue; } - reiserfs_write_unlock(s); dquot_initialize(inode); - reiserfs_write_lock(s); if (truncate && S_ISDIR(inode->i_mode)) { /* We got a truncate request for a dir which is impossible. @@ -1337,7 +1335,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) kfree(qf_names[i]); #endif err = -EINVAL; - goto out_unlock; + goto out_err; } #ifdef CONFIG_QUOTA handle_quota_files(s, qf_names, &qfmt); @@ -1381,7 +1379,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) if (blocks) { err = reiserfs_resize(s, blocks); if (err != 0) - goto out_unlock; + goto out_err; } if (*mount_flags & MS_RDONLY) { @@ -1391,15 +1389,9 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) /* it is read-only already */ goto out_ok; - /* - * Drop write lock. Quota will retake it when needed and lock - * ordering requires calling dquot_suspend() without it. - */ - reiserfs_write_unlock(s); err = dquot_suspend(s, -1); if (err < 0) goto out_err; - reiserfs_write_lock(s); /* try to remount file system with read-only permissions */ if (sb_umount_state(rs) == REISERFS_VALID_FS @@ -1409,7 +1401,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) err = journal_begin(&th, s, 10); if (err) - goto out_unlock; + goto out_err; /* Mounting a rw partition read-only. */ reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); @@ -1424,7 +1416,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) if (reiserfs_is_journal_aborted(journal)) { err = journal->j_errno; - goto out_unlock; + goto out_err; } handle_data_mode(s, mount_options); @@ -1433,7 +1425,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) s->s_flags &= ~MS_RDONLY; /* now it is safe to call journal_begin */ err = journal_begin(&th, s, 10); if (err) - goto out_unlock; + goto out_err; /* Mount a partition which is read-only, read-write */ reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); @@ -1450,16 +1442,10 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) SB_JOURNAL(s)->j_must_wait = 1; err = journal_end(&th, s, 10); if (err) - goto out_unlock; + goto out_err; if (!(*mount_flags & MS_RDONLY)) { - /* - * Drop write lock. Quota will retake it when needed and lock - * ordering requires calling dquot_resume() without it. - */ - reiserfs_write_unlock(s); dquot_resume(s, -1); - reiserfs_write_lock(s); finish_unfinished(s); reiserfs_xattr_init(s, *mount_flags); } @@ -1469,10 +1455,9 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) reiserfs_write_unlock(s); return 0; -out_unlock: - reiserfs_write_unlock(s); out_err: kfree(new_opts); + reiserfs_write_unlock(s); return err; } @@ -2110,15 +2095,13 @@ static int reiserfs_write_dquot(struct dquot *dquot) REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); if (ret) goto out; - reiserfs_write_unlock(dquot->dq_sb); ret = dquot_commit(dquot); - reiserfs_write_lock(dquot->dq_sb); err = journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); if (!ret && err) ret = err; -out: + out: reiserfs_write_unlock(dquot->dq_sb); return ret; } @@ -2134,15 +2117,13 @@ static int reiserfs_acquire_dquot(struct dquot *dquot) REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); if (ret) goto out; - reiserfs_write_unlock(dquot->dq_sb); ret = dquot_acquire(dquot); - reiserfs_write_lock(dquot->dq_sb); err = journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); if (!ret && err) ret = err; -out: + out: reiserfs_write_unlock(dquot->dq_sb); return ret; } @@ -2156,21 +2137,19 @@ static int reiserfs_release_dquot(struct dquot *dquot) ret = journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); - reiserfs_write_unlock(dquot->dq_sb); if (ret) { /* Release dquot anyway to avoid endless cycle in dqput() */ dquot_release(dquot); goto out; } ret = dquot_release(dquot); - reiserfs_write_lock(dquot->dq_sb); err = journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); if (!ret && err) ret = err; + out: reiserfs_write_unlock(dquot->dq_sb); -out: return ret; } @@ -2195,13 +2174,11 @@ static int reiserfs_write_info(struct super_block *sb, int type) ret = journal_begin(&th, sb, 2); if (ret) goto out; - reiserfs_write_unlock(sb); ret = dquot_commit_info(sb, type); - reiserfs_write_lock(sb); err = journal_end(&th, sb, 2); if (!ret && err) ret = err; -out: + out: reiserfs_write_unlock(sb); return ret; } @@ -2226,11 +2203,8 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, struct reiserfs_transaction_handle th; int opt = type == USRQUOTA ? REISERFS_USRQUOTA : REISERFS_GRPQUOTA; - reiserfs_write_lock(sb); - if (!(REISERFS_SB(sb)->s_mount_opt & (1 << opt))) { - err = -EINVAL; - goto out; - } + if (!(REISERFS_SB(sb)->s_mount_opt & (1 << opt))) + return -EINVAL; /* Quotafile not on the same filesystem? */ if (path->dentry->d_sb != sb) { @@ -2272,10 +2246,8 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, if (err) goto out; } - reiserfs_write_unlock(sb); - return dquot_quota_on(sb, type, format_id, path); + err = dquot_quota_on(sb, type, format_id, path); out: - reiserfs_write_unlock(sb); return err; } @@ -2348,9 +2320,7 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type, tocopy = sb->s_blocksize - offset < towrite ? sb->s_blocksize - offset : towrite; tmp_bh.b_state = 0; - reiserfs_write_lock(sb); err = reiserfs_get_block(inode, blk, &tmp_bh, GET_BLOCK_CREATE); - reiserfs_write_unlock(sb); if (err) goto out; if (offset || tocopy != sb->s_blocksize) @@ -2366,12 +2336,10 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type, flush_dcache_page(bh->b_page); set_buffer_uptodate(bh); unlock_buffer(bh); - reiserfs_write_lock(sb); reiserfs_prepare_for_journal(sb, bh, 1); journal_mark_dirty(current->journal_info, sb, bh); if (!journal_quota) reiserfs_add_ordered_list(inode, bh); - reiserfs_write_unlock(sb); brelse(bh); offset = 0; towrite -= tocopy; diff --git a/trunk/fs/sysfs/dir.c b/trunk/fs/sysfs/dir.c index 2fbdff6be25c..6b0bb00d4d2b 100644 --- a/trunk/fs/sysfs/dir.c +++ b/trunk/fs/sysfs/dir.c @@ -485,18 +485,20 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) /** * sysfs_pathname - return full path to sysfs dirent * @sd: sysfs_dirent whose path we want - * @path: caller allocated buffer of size PATH_MAX + * @path: caller allocated buffer * * Gives the name "/" to the sysfs_root entry; any path returned * is relative to wherever sysfs is mounted. + * + * XXX: does no error checking on @path size */ static char *sysfs_pathname(struct sysfs_dirent *sd, char *path) { if (sd->s_parent) { sysfs_pathname(sd->s_parent, path); - strlcat(path, "/", PATH_MAX); + strcat(path, "/"); } - strlcat(path, sd->s_name, PATH_MAX); + strcat(path, sd->s_name); return path; } @@ -529,11 +531,9 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) char *path = kzalloc(PATH_MAX, GFP_KERNEL); WARN(1, KERN_WARNING "sysfs: cannot create duplicate filename '%s'\n", - (path == NULL) ? sd->s_name - : (sysfs_pathname(acxt->parent_sd, path), - strlcat(path, "/", PATH_MAX), - strlcat(path, sd->s_name, PATH_MAX), - path)); + (path == NULL) ? sd->s_name : + strcat(strcat(sysfs_pathname(acxt->parent_sd, path), "/"), + sd->s_name)); kfree(path); } diff --git a/trunk/fs/ubifs/find.c b/trunk/fs/ubifs/find.c index 2dcf3d473fec..28ec13af28d9 100644 --- a/trunk/fs/ubifs/find.c +++ b/trunk/fs/ubifs/find.c @@ -681,16 +681,8 @@ int ubifs_find_free_leb_for_idx(struct ubifs_info *c) if (!lprops) { lprops = ubifs_fast_find_freeable(c); if (!lprops) { - /* - * The first condition means the following: go scan the - * LPT if there are uncategorized lprops, which means - * there may be freeable LEBs there (UBIFS does not - * store the information about freeable LEBs in the - * master node). - */ - if (c->in_a_category_cnt != c->main_lebs || - c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) { - ubifs_assert(c->freeable_cnt == 0); + ubifs_assert(c->freeable_cnt == 0); + if (c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) { lprops = scan_for_leb_for_idx(c); if (IS_ERR(lprops)) { err = PTR_ERR(lprops); diff --git a/trunk/fs/ubifs/lprops.c b/trunk/fs/ubifs/lprops.c index 46190a7c42a6..e5a2a35a46dc 100644 --- a/trunk/fs/ubifs/lprops.c +++ b/trunk/fs/ubifs/lprops.c @@ -300,11 +300,8 @@ void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops, default: ubifs_assert(0); } - lprops->flags &= ~LPROPS_CAT_MASK; lprops->flags |= cat; - c->in_a_category_cnt += 1; - ubifs_assert(c->in_a_category_cnt <= c->main_lebs); } /** @@ -337,9 +334,6 @@ static void ubifs_remove_from_cat(struct ubifs_info *c, default: ubifs_assert(0); } - - c->in_a_category_cnt -= 1; - ubifs_assert(c->in_a_category_cnt >= 0); } /** diff --git a/trunk/fs/ubifs/ubifs.h b/trunk/fs/ubifs/ubifs.h index d133c276fe05..5486346d0a3f 100644 --- a/trunk/fs/ubifs/ubifs.h +++ b/trunk/fs/ubifs/ubifs.h @@ -1183,8 +1183,6 @@ struct ubifs_debug_info; * @freeable_list: list of freeable non-index LEBs (free + dirty == @leb_size) * @frdi_idx_list: list of freeable index LEBs (free + dirty == @leb_size) * @freeable_cnt: number of freeable LEBs in @freeable_list - * @in_a_category_cnt: count of lprops which are in a certain category, which - * basically meants that they were loaded from the flash * * @ltab_lnum: LEB number of LPT's own lprops table * @ltab_offs: offset of LPT's own lprops table @@ -1414,7 +1412,6 @@ struct ubifs_info { struct list_head freeable_list; struct list_head frdi_idx_list; int freeable_cnt; - int in_a_category_cnt; int ltab_lnum; int ltab_offs; diff --git a/trunk/fs/xfs/xfs_alloc.c b/trunk/fs/xfs/xfs_alloc.c index 335206a9c698..4f33c32affe3 100644 --- a/trunk/fs/xfs/xfs_alloc.c +++ b/trunk/fs/xfs/xfs_alloc.c @@ -1866,7 +1866,6 @@ xfs_alloc_fix_freelist( /* * Initialize the args structure. */ - memset(&targs, 0, sizeof(targs)); targs.tp = tp; targs.mp = mp; targs.agbp = agbp; @@ -2208,7 +2207,7 @@ xfs_alloc_read_agf( * group or loop over the allocation groups to find the result. */ int /* error */ -xfs_alloc_vextent( +__xfs_alloc_vextent( xfs_alloc_arg_t *args) /* allocation argument structure */ { xfs_agblock_t agsize; /* allocation group size */ @@ -2418,6 +2417,46 @@ xfs_alloc_vextent( return error; } +static void +xfs_alloc_vextent_worker( + struct work_struct *work) +{ + struct xfs_alloc_arg *args = container_of(work, + struct xfs_alloc_arg, work); + unsigned long pflags; + + /* we are in a transaction context here */ + current_set_flags_nested(&pflags, PF_FSTRANS); + + args->result = __xfs_alloc_vextent(args); + complete(args->done); + + current_restore_flags_nested(&pflags, PF_FSTRANS); +} + +/* + * Data allocation requests often come in with little stack to work on. Push + * them off to a worker thread so there is lots of stack to use. Metadata + * requests, OTOH, are generally from low stack usage paths, so avoid the + * context switch overhead here. + */ +int +xfs_alloc_vextent( + struct xfs_alloc_arg *args) +{ + DECLARE_COMPLETION_ONSTACK(done); + + if (!args->userdata) + return __xfs_alloc_vextent(args); + + + args->done = &done; + INIT_WORK_ONSTACK(&args->work, xfs_alloc_vextent_worker); + queue_work(xfs_alloc_wq, &args->work); + wait_for_completion(&done); + return args->result; +} + /* * Free an extent. * Just break up the extent address and hand off to xfs_free_ag_extent diff --git a/trunk/fs/xfs/xfs_alloc.h b/trunk/fs/xfs/xfs_alloc.h index feacb061bab7..93be4a667ca1 100644 --- a/trunk/fs/xfs/xfs_alloc.h +++ b/trunk/fs/xfs/xfs_alloc.h @@ -120,6 +120,9 @@ typedef struct xfs_alloc_arg { char isfl; /* set if is freelist blocks - !acctg */ char userdata; /* set if this is user data */ xfs_fsblock_t firstblock; /* io first block allocated */ + struct completion *done; + struct work_struct work; + int result; } xfs_alloc_arg_t; /* diff --git a/trunk/fs/xfs/xfs_alloc_btree.c b/trunk/fs/xfs/xfs_alloc_btree.c index f7876c6d6165..f1647caace8f 100644 --- a/trunk/fs/xfs/xfs_alloc_btree.c +++ b/trunk/fs/xfs/xfs_alloc_btree.c @@ -121,8 +121,6 @@ xfs_allocbt_free_block( xfs_extent_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1, XFS_EXTENT_BUSY_SKIP_DISCARD); xfs_trans_agbtree_delta(cur->bc_tp, -1); - - xfs_trans_binval(cur->bc_tp, bp); return 0; } diff --git a/trunk/fs/xfs/xfs_aops.c b/trunk/fs/xfs/xfs_aops.c index e57e2daa357c..e562dd43f41f 100644 --- a/trunk/fs/xfs/xfs_aops.c +++ b/trunk/fs/xfs/xfs_aops.c @@ -481,17 +481,11 @@ static inline int bio_add_buffer(struct bio *bio, struct buffer_head *bh) * * The fix is two passes across the ioend list - one to start writeback on the * buffer_heads, and then submit them for I/O on the second pass. - * - * If @fail is non-zero, it means that we have a situation where some part of - * the submission process has failed after we have marked paged for writeback - * and unlocked them. In this situation, we need to fail the ioend chain rather - * than submit it to IO. This typically only happens on a filesystem shutdown. */ STATIC void xfs_submit_ioend( struct writeback_control *wbc, - xfs_ioend_t *ioend, - int fail) + xfs_ioend_t *ioend) { xfs_ioend_t *head = ioend; xfs_ioend_t *next; @@ -512,18 +506,6 @@ xfs_submit_ioend( next = ioend->io_list; bio = NULL; - /* - * If we are failing the IO now, just mark the ioend with an - * error and finish it. This will run IO completion immediately - * as there is only one reference to the ioend at this point in - * time. - */ - if (fail) { - ioend->io_error = -fail; - xfs_finish_ioend(ioend); - continue; - } - for (bh = ioend->io_buffer_head; bh; bh = bh->b_private) { if (!bio) { @@ -1078,18 +1060,7 @@ xfs_vm_writepage( xfs_start_page_writeback(page, 1, count); - /* if there is no IO to be submitted for this page, we are done */ - if (!ioend) - return 0; - - ASSERT(iohead); - - /* - * Any errors from this point onwards need tobe reported through the IO - * completion path as we have marked the initial page as under writeback - * and unlocked it. - */ - if (imap_valid) { + if (ioend && imap_valid) { xfs_off_t end_index; end_index = imap.br_startoff + imap.br_blockcount; @@ -1108,15 +1079,20 @@ xfs_vm_writepage( wbc, end_index); } + if (iohead) { + /* + * Reserve log space if we might write beyond the on-disk + * inode size. + */ + if (ioend->io_type != XFS_IO_UNWRITTEN && + xfs_ioend_is_append(ioend)) { + err = xfs_setfilesize_trans_alloc(ioend); + if (err) + goto error; + } - /* - * Reserve log space if we might write beyond the on-disk inode size. - */ - err = 0; - if (ioend->io_type != XFS_IO_UNWRITTEN && xfs_ioend_is_append(ioend)) - err = xfs_setfilesize_trans_alloc(ioend); - - xfs_submit_ioend(wbc, iohead, err); + xfs_submit_ioend(wbc, iohead); + } return 0; diff --git a/trunk/fs/xfs/xfs_attr_leaf.c b/trunk/fs/xfs/xfs_attr_leaf.c index 70eec1829776..d330111ca738 100644 --- a/trunk/fs/xfs/xfs_attr_leaf.c +++ b/trunk/fs/xfs/xfs_attr_leaf.c @@ -1291,7 +1291,6 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, leaf2 = blk2->bp->b_addr; ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); - ASSERT(leaf2->hdr.count == 0); args = state->args; trace_xfs_attr_leaf_rebalance(args); @@ -1362,7 +1361,6 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, * I assert that since all callers pass in an empty * second buffer, this code should never execute. */ - ASSERT(0); /* * Figure the total bytes to be added to the destination leaf. @@ -1424,24 +1422,10 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, args->index2 = 0; args->blkno2 = blk2->blkno; } else { - /* - * On a double leaf split, the original attr location - * is already stored in blkno2/index2, so don't - * overwrite it overwise we corrupt the tree. - */ blk2->index = blk1->index - be16_to_cpu(leaf1->hdr.count); - args->index = blk2->index; - args->blkno = blk2->blkno; - if (!state->extravalid) { - /* - * set the new attr location to match the old - * one and let the higher level split code - * decide where in the leaf to place it. - */ - args->index2 = blk2->index; - args->blkno2 = blk2->blkno; - } + args->index = args->index2 = blk2->index; + args->blkno = args->blkno2 = blk2->blkno; } } else { ASSERT(state->inleaf == 1); diff --git a/trunk/fs/xfs/xfs_bmap.c b/trunk/fs/xfs/xfs_bmap.c index 83d0cf3df930..848ffa77707b 100644 --- a/trunk/fs/xfs/xfs_bmap.c +++ b/trunk/fs/xfs/xfs_bmap.c @@ -2437,7 +2437,6 @@ xfs_bmap_btalloc( * Normal allocation, done through xfs_alloc_vextent. */ tryagain = isaligned = 0; - memset(&args, 0, sizeof(args)); args.tp = ap->tp; args.mp = mp; args.fsbno = ap->blkno; @@ -3083,7 +3082,6 @@ xfs_bmap_extents_to_btree( * Convert to a btree with two levels, one record in root. */ XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); - memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = mp; args.firstblock = *firstblock; @@ -3239,7 +3237,6 @@ xfs_bmap_local_to_extents( xfs_buf_t *bp; /* buffer for extent block */ xfs_bmbt_rec_host_t *ep;/* extent record pointer */ - memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = ip->i_mount; args.firstblock = *firstblock; @@ -4619,11 +4616,12 @@ xfs_bmapi_delay( STATIC int -__xfs_bmapi_allocate( - struct xfs_bmalloca *bma) +xfs_bmapi_allocate( + struct xfs_bmalloca *bma, + int flags) { struct xfs_mount *mp = bma->ip->i_mount; - int whichfork = (bma->flags & XFS_BMAPI_ATTRFORK) ? + int whichfork = (flags & XFS_BMAPI_ATTRFORK) ? XFS_ATTR_FORK : XFS_DATA_FORK; struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork); int tmp_logflags = 0; @@ -4656,27 +4654,24 @@ __xfs_bmapi_allocate( * Indicate if this is the first user data in the file, or just any * user data. */ - if (!(bma->flags & XFS_BMAPI_METADATA)) { + if (!(flags & XFS_BMAPI_METADATA)) { bma->userdata = (bma->offset == 0) ? XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA; } - bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1; + bma->minlen = (flags & XFS_BMAPI_CONTIG) ? bma->length : 1; /* * Only want to do the alignment at the eof if it is userdata and * allocation length is larger than a stripe unit. */ if (mp->m_dalign && bma->length >= mp->m_dalign && - !(bma->flags & XFS_BMAPI_METADATA) && whichfork == XFS_DATA_FORK) { + !(flags & XFS_BMAPI_METADATA) && whichfork == XFS_DATA_FORK) { error = xfs_bmap_isaeof(bma, whichfork); if (error) return error; } - if (bma->flags & XFS_BMAPI_STACK_SWITCH) - bma->stack_switch = 1; - error = xfs_bmap_alloc(bma); if (error) return error; @@ -4711,7 +4706,7 @@ __xfs_bmapi_allocate( * A wasdelay extent has been initialized, so shouldn't be flagged * as unwritten. */ - if (!bma->wasdel && (bma->flags & XFS_BMAPI_PREALLOC) && + if (!bma->wasdel && (flags & XFS_BMAPI_PREALLOC) && xfs_sb_version_hasextflgbit(&mp->m_sb)) bma->got.br_state = XFS_EXT_UNWRITTEN; @@ -4739,45 +4734,6 @@ __xfs_bmapi_allocate( return 0; } -static void -xfs_bmapi_allocate_worker( - struct work_struct *work) -{ - struct xfs_bmalloca *args = container_of(work, - struct xfs_bmalloca, work); - unsigned long pflags; - - /* we are in a transaction context here */ - current_set_flags_nested(&pflags, PF_FSTRANS); - - args->result = __xfs_bmapi_allocate(args); - complete(args->done); - - current_restore_flags_nested(&pflags, PF_FSTRANS); -} - -/* - * Some allocation requests often come in with little stack to work on. Push - * them off to a worker thread so there is lots of stack to use. Otherwise just - * call directly to avoid the context switch overhead here. - */ -int -xfs_bmapi_allocate( - struct xfs_bmalloca *args) -{ - DECLARE_COMPLETION_ONSTACK(done); - - if (!args->stack_switch) - return __xfs_bmapi_allocate(args); - - - args->done = &done; - INIT_WORK_ONSTACK(&args->work, xfs_bmapi_allocate_worker); - queue_work(xfs_alloc_wq, &args->work); - wait_for_completion(&done); - return args->result; -} - STATIC int xfs_bmapi_convert_unwritten( struct xfs_bmalloca *bma, @@ -4963,7 +4919,6 @@ xfs_bmapi_write( bma.conv = !!(flags & XFS_BMAPI_CONVERT); bma.wasdel = wasdelay; bma.offset = bno; - bma.flags = flags; /* * There's a 32/64 bit type mismatch between the @@ -4979,7 +4934,7 @@ xfs_bmapi_write( ASSERT(len > 0); ASSERT(bma.length > 0); - error = xfs_bmapi_allocate(&bma); + error = xfs_bmapi_allocate(&bma, flags); if (error) goto error0; if (bma.blkno == NULLFSBLOCK) diff --git a/trunk/fs/xfs/xfs_bmap.h b/trunk/fs/xfs/xfs_bmap.h index 5f469c3516eb..803b56d7ce16 100644 --- a/trunk/fs/xfs/xfs_bmap.h +++ b/trunk/fs/xfs/xfs_bmap.h @@ -77,7 +77,6 @@ typedef struct xfs_bmap_free * from written to unwritten, otherwise convert from unwritten to written. */ #define XFS_BMAPI_CONVERT 0x040 -#define XFS_BMAPI_STACK_SWITCH 0x080 #define XFS_BMAPI_FLAGS \ { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ @@ -86,8 +85,7 @@ typedef struct xfs_bmap_free { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ { XFS_BMAPI_CONTIG, "CONTIG" }, \ - { XFS_BMAPI_CONVERT, "CONVERT" }, \ - { XFS_BMAPI_STACK_SWITCH, "STACK_SWITCH" } + { XFS_BMAPI_CONVERT, "CONVERT" } static inline int xfs_bmapi_aflag(int w) @@ -135,11 +133,6 @@ typedef struct xfs_bmalloca { char userdata;/* set if is user data */ char aeof; /* allocated space at eof */ char conv; /* overwriting unwritten extents */ - char stack_switch; - int flags; - struct completion *done; - struct work_struct work; - int result; } xfs_bmalloca_t; /* diff --git a/trunk/fs/xfs/xfs_buf.c b/trunk/fs/xfs/xfs_buf.c index 4b0b8dd1b7b0..933b7930b863 100644 --- a/trunk/fs/xfs/xfs_buf.c +++ b/trunk/fs/xfs/xfs_buf.c @@ -1197,14 +1197,9 @@ xfs_buf_bio_end_io( { xfs_buf_t *bp = (xfs_buf_t *)bio->bi_private; - /* - * don't overwrite existing errors - otherwise we can lose errors on - * buffers that require multiple bios to complete. - */ - if (!bp->b_error) - xfs_buf_ioerror(bp, -error); + xfs_buf_ioerror(bp, -error); - if (!bp->b_error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ)) + if (!error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ)) invalidate_kernel_vmap_range(bp->b_addr, xfs_buf_vmap_len(bp)); _xfs_buf_ioend(bp, 1); @@ -1284,11 +1279,6 @@ xfs_buf_ioapply_map( if (size) goto next_chunk; } else { - /* - * This is guaranteed not to be the last io reference count - * because the caller (xfs_buf_iorequest) holds a count itself. - */ - atomic_dec(&bp->b_io_remaining); xfs_buf_ioerror(bp, EIO); bio_put(bio); } diff --git a/trunk/fs/xfs/xfs_buf_item.c b/trunk/fs/xfs/xfs_buf_item.c index becf4a97efc6..a8d0ed911196 100644 --- a/trunk/fs/xfs/xfs_buf_item.c +++ b/trunk/fs/xfs/xfs_buf_item.c @@ -526,25 +526,7 @@ xfs_buf_item_unpin( } xfs_buf_relse(bp); } else if (freed && remove) { - /* - * There are currently two references to the buffer - the active - * LRU reference and the buf log item. What we are about to do - * here - simulate a failed IO completion - requires 3 - * references. - * - * The LRU reference is removed by the xfs_buf_stale() call. The - * buf item reference is removed by the xfs_buf_iodone() - * callback that is run by xfs_buf_do_callbacks() during ioend - * processing (via the bp->b_iodone callback), and then finally - * the ioend processing will drop the IO reference if the buffer - * is marked XBF_ASYNC. - * - * Hence we need to take an additional reference here so that IO - * completion processing doesn't free the buffer prematurely. - */ xfs_buf_lock(bp); - xfs_buf_hold(bp); - bp->b_flags |= XBF_ASYNC; xfs_buf_ioerror(bp, EIO); XFS_BUF_UNDONE(bp); xfs_buf_stale(bp); diff --git a/trunk/fs/xfs/xfs_fsops.c b/trunk/fs/xfs/xfs_fsops.c index 4beaede43277..c25b094efbf7 100644 --- a/trunk/fs/xfs/xfs_fsops.c +++ b/trunk/fs/xfs/xfs_fsops.c @@ -399,26 +399,9 @@ xfs_growfs_data_private( /* update secondary superblocks. */ for (agno = 1; agno < nagcount; agno++) { - error = 0; - /* - * new secondary superblocks need to be zeroed, not read from - * disk as the contents of the new area we are growing into is - * completely unknown. - */ - if (agno < oagcount) { - error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, + error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)), XFS_FSS_TO_BB(mp, 1), 0, &bp); - } else { - bp = xfs_trans_get_buf(NULL, mp->m_ddev_targp, - XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)), - XFS_FSS_TO_BB(mp, 1), 0); - if (bp) - xfs_buf_zero(bp, 0, BBTOB(bp->b_length)); - else - error = ENOMEM; - } - if (error) { xfs_warn(mp, "error %d reading secondary superblock for ag %d", @@ -440,7 +423,7 @@ xfs_growfs_data_private( break; /* no point in continuing */ } } - return error; + return 0; error0: xfs_trans_cancel(tp, XFS_TRANS_ABORT); diff --git a/trunk/fs/xfs/xfs_ialloc.c b/trunk/fs/xfs/xfs_ialloc.c index c5c4ef4f2bdb..445bf1aef31c 100644 --- a/trunk/fs/xfs/xfs_ialloc.c +++ b/trunk/fs/xfs/xfs_ialloc.c @@ -250,7 +250,6 @@ xfs_ialloc_ag_alloc( /* boundary */ struct xfs_perag *pag; - memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = tp->t_mountp; diff --git a/trunk/fs/xfs/xfs_inode.c b/trunk/fs/xfs/xfs_inode.c index 1938b41ee9f5..2778258fcfa2 100644 --- a/trunk/fs/xfs/xfs_inode.c +++ b/trunk/fs/xfs/xfs_inode.c @@ -1509,8 +1509,7 @@ xfs_ifree_cluster( * to mark all the active inodes on the buffer stale. */ bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno, - mp->m_bsize * blks_per_cluster, - XBF_UNMAPPED); + mp->m_bsize * blks_per_cluster, 0); if (!bp) return ENOMEM; diff --git a/trunk/fs/xfs/xfs_ioctl.c b/trunk/fs/xfs/xfs_ioctl.c index c1df3c623de2..8305f2ac6773 100644 --- a/trunk/fs/xfs/xfs_ioctl.c +++ b/trunk/fs/xfs/xfs_ioctl.c @@ -70,7 +70,7 @@ xfs_find_handle( int hsize; xfs_handle_t handle; struct inode *inode; - struct fd f = {0}; + struct fd f; struct path path; int error; struct xfs_inode *ip; diff --git a/trunk/fs/xfs/xfs_iomap.c b/trunk/fs/xfs/xfs_iomap.c index 7f537663365b..973dff6ad935 100644 --- a/trunk/fs/xfs/xfs_iomap.c +++ b/trunk/fs/xfs/xfs_iomap.c @@ -584,9 +584,7 @@ xfs_iomap_write_allocate( * pointer that the caller gave to us. */ error = xfs_bmapi_write(tp, ip, map_start_fsb, - count_fsb, - XFS_BMAPI_STACK_SWITCH, - &first_block, 1, + count_fsb, 0, &first_block, 1, imap, &nimaps, &free_list); if (error) goto trans_cancel; diff --git a/trunk/fs/xfs/xfs_log.c b/trunk/fs/xfs/xfs_log.c index 4dad756962d0..7f4f9370d0e7 100644 --- a/trunk/fs/xfs/xfs_log.c +++ b/trunk/fs/xfs/xfs_log.c @@ -2387,27 +2387,14 @@ xlog_state_do_callback( /* - * Completion of a iclog IO does not imply that - * a transaction has completed, as transactions - * can be large enough to span many iclogs. We - * cannot change the tail of the log half way - * through a transaction as this may be the only - * transaction in the log and moving th etail to - * point to the middle of it will prevent - * recovery from finding the start of the - * transaction. Hence we should only update the - * last_sync_lsn if this iclog contains - * transaction completion callbacks on it. - * - * We have to do this before we drop the + * update the last_sync_lsn before we drop the * icloglock to ensure we are the only one that * can update it. */ ASSERT(XFS_LSN_CMP(atomic64_read(&log->l_last_sync_lsn), be64_to_cpu(iclog->ic_header.h_lsn)) <= 0); - if (iclog->ic_callback) - atomic64_set(&log->l_last_sync_lsn, - be64_to_cpu(iclog->ic_header.h_lsn)); + atomic64_set(&log->l_last_sync_lsn, + be64_to_cpu(iclog->ic_header.h_lsn)); } else ioerrors++; diff --git a/trunk/fs/xfs/xfs_log_recover.c b/trunk/fs/xfs/xfs_log_recover.c index d308749fabf1..5da3ace352bf 100644 --- a/trunk/fs/xfs/xfs_log_recover.c +++ b/trunk/fs/xfs/xfs_log_recover.c @@ -3541,7 +3541,7 @@ xlog_do_recovery_pass( * - order is important. */ error = xlog_bread_offset(log, 0, - bblks - split_bblks, dbp, + bblks - split_bblks, hbp, offset + BBTOB(split_bblks)); if (error) goto bread_err2; diff --git a/trunk/include/asm-generic/gpio.h b/trunk/include/asm-generic/gpio.h index 9fd3093d855a..a9432fc6b8ba 100644 --- a/trunk/include/asm-generic/gpio.h +++ b/trunk/include/asm-generic/gpio.h @@ -5,7 +5,6 @@ #include #include #include -#include #ifdef CONFIG_GPIOLIB @@ -135,15 +134,6 @@ struct gpio_chip { int (*of_xlate)(struct gpio_chip *gc, const struct of_phandle_args *gpiospec, u32 *flags); #endif -#ifdef CONFIG_PINCTRL - /* - * If CONFIG_PINCTRL is enabled, then gpio controllers can optionally - * describe the actual pin range which they serve in an SoC. This - * information would be used by pinctrl subsystem to configure - * corresponding pins for gpio usage. - */ - struct list_head pin_ranges; -#endif }; extern const char *gpiochip_is_requested(struct gpio_chip *chip, @@ -267,41 +257,4 @@ static inline void gpio_unexport(unsigned gpio) } #endif /* CONFIG_GPIO_SYSFS */ -#ifdef CONFIG_PINCTRL - -/** - * struct gpio_pin_range - pin range controlled by a gpio chip - * @head: list for maintaining set of pin ranges, used internally - * @pctldev: pinctrl device which handles corresponding pins - * @range: actual range of pins controlled by a gpio controller - */ - -struct gpio_pin_range { - struct list_head node; - struct pinctrl_dev *pctldev; - struct pinctrl_gpio_range range; -}; - -int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int gpio_offset, unsigned int pin_offset, - unsigned int npins); -void gpiochip_remove_pin_ranges(struct gpio_chip *chip); - -#else - -static inline int -gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int gpio_offset, unsigned int pin_offset, - unsigned int npins) -{ - return 0; -} - -static inline void -gpiochip_remove_pin_ranges(struct gpio_chip *chip) -{ -} - -#endif /* CONFIG_PINCTRL */ - #endif /* _ASM_GENERIC_GPIO_H */ diff --git a/trunk/include/drm/drm_pciids.h b/trunk/include/drm/drm_pciids.h index c5c35e629426..c78bb997e2c6 100644 --- a/trunk/include/drm/drm_pciids.h +++ b/trunk/include/drm/drm_pciids.h @@ -205,12 +205,9 @@ {0x1002, 0x6788, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ {0x1002, 0x678A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6790, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6791, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6792, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6798, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6799, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ {0x1002, 0x679A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x679B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ {0x1002, 0x679E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ {0x1002, 0x679F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ @@ -220,7 +217,6 @@ {0x1002, 0x6808, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6809, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6810, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6811, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6816, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6817, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6818, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ diff --git a/trunk/include/linux/bug.h b/trunk/include/linux/bug.h index b1cf40de847e..aaac4bba6f5c 100644 --- a/trunk/include/linux/bug.h +++ b/trunk/include/linux/bug.h @@ -15,7 +15,6 @@ struct pt_regs; #define BUILD_BUG_ON_NOT_POWER_OF_2(n) #define BUILD_BUG_ON_ZERO(e) (0) #define BUILD_BUG_ON_NULL(e) ((void*)0) -#define BUILD_BUG_ON_INVALID(e) (0) #define BUILD_BUG_ON(condition) #define BUILD_BUG() (0) #else /* __CHECKER__ */ diff --git a/trunk/include/linux/clk-provider.h b/trunk/include/linux/clk-provider.h index 4989b8a7bed1..c12731582920 100644 --- a/trunk/include/linux/clk-provider.h +++ b/trunk/include/linux/clk-provider.h @@ -53,18 +53,9 @@ struct clk_hw; * @disable: Disable the clock atomically. Called with enable_lock held. * This function must not sleep. * - * @is_enabled: Queries the hardware to determine if the clock is enabled. - * This function must not sleep. Optional, if this op is not - * set then the enable count will be used. - * - * @disable_unused: Disable the clock atomically. Only called from - * clk_disable_unused for gate clocks with special needs. - * Called with enable_lock held. This function must not - * sleep. - * - * @recalc_rate Recalculate the rate of this clock, by querying hardware. The + * @recalc_rate Recalculate the rate of this clock, by quering hardware. The * parent rate is an input parameter. It is up to the caller to - * ensure that the prepare_mutex is held across this call. + * insure that the prepare_mutex is held across this call. * Returns the calculated rate. Optional, but recommended - if * this op is not set then clock rate will be initialized to 0. * @@ -98,7 +89,7 @@ struct clk_hw; * implementations to split any work between atomic (enable) and sleepable * (prepare) contexts. If enabling a clock requires code that might sleep, * this must be done in clk_prepare. Clock enable code that will never be - * called in a sleepable context may be implemented in clk_enable. + * called in a sleepable context may be implement in clk_enable. * * Typically, drivers will call clk_prepare when a clock may be needed later * (eg. when a device is opened), and clk_enable when the clock is actually @@ -111,7 +102,6 @@ struct clk_ops { int (*enable)(struct clk_hw *hw); void (*disable)(struct clk_hw *hw); int (*is_enabled)(struct clk_hw *hw); - void (*disable_unused)(struct clk_hw *hw); unsigned long (*recalc_rate)(struct clk_hw *hw, unsigned long parent_rate); long (*round_rate)(struct clk_hw *hw, unsigned long, @@ -337,21 +327,19 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name, * error code; drivers must test for an error code after calling clk_register. */ struct clk *clk_register(struct device *dev, struct clk_hw *hw); -struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw); void clk_unregister(struct clk *clk); -void devm_clk_unregister(struct device *dev, struct clk *clk); /* helper functions */ const char *__clk_get_name(struct clk *clk); struct clk_hw *__clk_get_hw(struct clk *clk); u8 __clk_get_num_parents(struct clk *clk); struct clk *__clk_get_parent(struct clk *clk); -unsigned int __clk_get_enable_count(struct clk *clk); -unsigned int __clk_get_prepare_count(struct clk *clk); +inline int __clk_get_enable_count(struct clk *clk); +inline int __clk_get_prepare_count(struct clk *clk); unsigned long __clk_get_rate(struct clk *clk); unsigned long __clk_get_flags(struct clk *clk); -bool __clk_is_enabled(struct clk *clk); +int __clk_is_enabled(struct clk *clk); struct clk *__clk_lookup(const char *name); /* diff --git a/trunk/include/linux/dma-contiguous.h b/trunk/include/linux/dma-contiguous.h index 01b5c84be828..2f303e4b7ed3 100644 --- a/trunk/include/linux/dma-contiguous.h +++ b/trunk/include/linux/dma-contiguous.h @@ -68,7 +68,7 @@ struct device; extern struct cma *dma_contiguous_default_area; void dma_contiguous_reserve(phys_addr_t addr_limit); -int dma_declare_contiguous(struct device *dev, phys_addr_t size, +int dma_declare_contiguous(struct device *dev, unsigned long size, phys_addr_t base, phys_addr_t limit); struct page *dma_alloc_from_contiguous(struct device *dev, int count, @@ -83,7 +83,7 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages, static inline void dma_contiguous_reserve(phys_addr_t limit) { } static inline -int dma_declare_contiguous(struct device *dev, phys_addr_t size, +int dma_declare_contiguous(struct device *dev, unsigned long size, phys_addr_t base, phys_addr_t limit) { return -ENOSYS; diff --git a/trunk/include/linux/dynamic_debug.h b/trunk/include/linux/dynamic_debug.h index 6dd4787a798a..c18257b0fa72 100644 --- a/trunk/include/linux/dynamic_debug.h +++ b/trunk/include/linux/dynamic_debug.h @@ -61,7 +61,7 @@ int __dynamic_netdev_dbg(struct _ddebug *descriptor, const char *fmt, ...); #define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \ - static struct _ddebug __aligned(8) \ + static struct _ddebug __used __aligned(8) \ __attribute__((section("__verbose"))) name = { \ .modname = KBUILD_MODNAME, \ .function = __func__, \ diff --git a/trunk/include/linux/edac.h b/trunk/include/linux/edac.h index 1b8c02b36f76..bab9f8473dc1 100644 --- a/trunk/include/linux/edac.h +++ b/trunk/include/linux/edac.h @@ -533,7 +533,6 @@ struct csrow_info { u32 ue_count; /* Uncorrectable Errors for this csrow */ u32 ce_count; /* Correctable Errors for this csrow */ - u32 nr_pages; /* combined pages count of all channels */ struct mem_ctl_info *mci; /* the parent */ @@ -668,8 +667,6 @@ struct mem_ctl_info { u32 fake_inject_ue; u16 fake_inject_count; #endif - __u8 csbased : 1, /* csrow-based memory controller */ - __resv : 7; }; #endif diff --git a/trunk/include/linux/extcon.h b/trunk/include/linux/extcon.h index 2c26c14cd710..7443a560c9d0 100644 --- a/trunk/include/linux/extcon.h +++ b/trunk/include/linux/extcon.h @@ -68,7 +68,7 @@ enum extcon_cable_name { EXTCON_VIDEO_OUT, EXTCON_MECHANICAL, }; -extern const char extcon_cable_name[][CABLE_NAME_MAX + 1]; +extern const char *extcon_cable_name[]; struct extcon_cable; diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 75fe9a134803..b33cfc97b9ca 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -462,6 +462,8 @@ struct block_device { int bd_fsfreeze_count; /* Mutex for freeze */ struct mutex bd_fsfreeze_mutex; + /* A semaphore that prevents I/O while block size is being changed */ + struct percpu_rw_semaphore bd_block_size_semaphore; }; /* @@ -2047,6 +2049,7 @@ extern void unregister_blkdev(unsigned int, const char *); extern struct block_device *bdget(dev_t); extern struct block_device *bdgrab(struct block_device *bdev); extern void bd_set_size(struct block_device *, loff_t size); +extern sector_t blkdev_max_block(struct block_device *bdev); extern void bd_forget(struct inode *inode); extern void bdput(struct block_device *); extern void invalidate_bdev(struct block_device *); @@ -2376,6 +2379,8 @@ extern int generic_segment_checks(const struct iovec *iov, unsigned long *nr_segs, size_t *count, int access_flags); /* fs/block_dev.c */ +extern ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos); extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos); extern int blkdev_fsync(struct file *filp, loff_t start, loff_t end, diff --git a/trunk/include/linux/gfp.h b/trunk/include/linux/gfp.h index d0a79678f169..02c1c9710be0 100644 --- a/trunk/include/linux/gfp.h +++ b/trunk/include/linux/gfp.h @@ -31,7 +31,6 @@ struct vm_area_struct; #define ___GFP_THISNODE 0x40000u #define ___GFP_RECLAIMABLE 0x80000u #define ___GFP_NOTRACK 0x200000u -#define ___GFP_NO_KSWAPD 0x400000u #define ___GFP_OTHER_NODE 0x800000u #define ___GFP_WRITE 0x1000000u @@ -86,7 +85,6 @@ struct vm_area_struct; #define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE) /* Page is reclaimable */ #define __GFP_NOTRACK ((__force gfp_t)___GFP_NOTRACK) /* Don't track with kmemcheck */ -#define __GFP_NO_KSWAPD ((__force gfp_t)___GFP_NO_KSWAPD) #define __GFP_OTHER_NODE ((__force gfp_t)___GFP_OTHER_NODE) /* On behalf of other node */ #define __GFP_WRITE ((__force gfp_t)___GFP_WRITE) /* Allocator intends to dirty page */ @@ -116,8 +114,7 @@ struct vm_area_struct; __GFP_MOVABLE) #define GFP_IOFS (__GFP_IO | __GFP_FS) #define GFP_TRANSHUGE (GFP_HIGHUSER_MOVABLE | __GFP_COMP | \ - __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN | \ - __GFP_NO_KSWAPD) + __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN) #ifdef CONFIG_NUMA #define GFP_THISNODE (__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY) diff --git a/trunk/include/linux/gpio.h b/trunk/include/linux/gpio.h index bfe665621536..2e31e8b3a190 100644 --- a/trunk/include/linux/gpio.h +++ b/trunk/include/linux/gpio.h @@ -72,9 +72,9 @@ static inline int irq_to_gpio(unsigned int irq) return -EINVAL; } -#endif /* ! CONFIG_ARCH_HAVE_CUSTOM_GPIO_H */ +#endif -#else /* ! CONFIG_GENERIC_GPIO */ +#else #include #include @@ -231,21 +231,6 @@ static inline int irq_to_gpio(unsigned irq) return -EINVAL; } -static inline int -gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int gpio_offset, unsigned int pin_offset, - unsigned int npins) -{ - WARN_ON(1); - return -EINVAL; -} - -static inline void -gpiochip_remove_pin_ranges(struct gpio_chip *chip) -{ - WARN_ON(1); -} - -#endif /* ! CONFIG_GENERIC_GPIO */ +#endif #endif /* __LINUX_GPIO_H */ diff --git a/trunk/include/linux/hashtable.h b/trunk/include/linux/hashtable.h deleted file mode 100644 index 227c62424f3c..000000000000 --- a/trunk/include/linux/hashtable.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Statically sized hash table implementation - * (C) 2012 Sasha Levin - */ - -#ifndef _LINUX_HASHTABLE_H -#define _LINUX_HASHTABLE_H - -#include -#include -#include -#include -#include - -#define DEFINE_HASHTABLE(name, bits) \ - struct hlist_head name[1 << (bits)] = \ - { [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT } - -#define DECLARE_HASHTABLE(name, bits) \ - struct hlist_head name[1 << (bits)] - -#define HASH_SIZE(name) (ARRAY_SIZE(name)) -#define HASH_BITS(name) ilog2(HASH_SIZE(name)) - -/* Use hash_32 when possible to allow for fast 32bit hashing in 64bit kernels. */ -#define hash_min(val, bits) \ - (sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits)) - -static inline void __hash_init(struct hlist_head *ht, unsigned int sz) -{ - unsigned int i; - - for (i = 0; i < sz; i++) - INIT_HLIST_HEAD(&ht[i]); -} - -/** - * hash_init - initialize a hash table - * @hashtable: hashtable to be initialized - * - * Calculates the size of the hashtable from the given parameter, otherwise - * same as hash_init_size. - * - * This has to be a macro since HASH_BITS() will not work on pointers since - * it calculates the size during preprocessing. - */ -#define hash_init(hashtable) __hash_init(hashtable, HASH_SIZE(hashtable)) - -/** - * hash_add - add an object to a hashtable - * @hashtable: hashtable to add to - * @node: the &struct hlist_node of the object to be added - * @key: the key of the object to be added - */ -#define hash_add(hashtable, node, key) \ - hlist_add_head(node, &hashtable[hash_min(key, HASH_BITS(hashtable))]) - -/** - * hash_add_rcu - add an object to a rcu enabled hashtable - * @hashtable: hashtable to add to - * @node: the &struct hlist_node of the object to be added - * @key: the key of the object to be added - */ -#define hash_add_rcu(hashtable, node, key) \ - hlist_add_head_rcu(node, &hashtable[hash_min(key, HASH_BITS(hashtable))]) - -/** - * hash_hashed - check whether an object is in any hashtable - * @node: the &struct hlist_node of the object to be checked - */ -static inline bool hash_hashed(struct hlist_node *node) -{ - return !hlist_unhashed(node); -} - -static inline bool __hash_empty(struct hlist_head *ht, unsigned int sz) -{ - unsigned int i; - - for (i = 0; i < sz; i++) - if (!hlist_empty(&ht[i])) - return false; - - return true; -} - -/** - * hash_empty - check whether a hashtable is empty - * @hashtable: hashtable to check - * - * This has to be a macro since HASH_BITS() will not work on pointers since - * it calculates the size during preprocessing. - */ -#define hash_empty(hashtable) __hash_empty(hashtable, HASH_SIZE(hashtable)) - -/** - * hash_del - remove an object from a hashtable - * @node: &struct hlist_node of the object to remove - */ -static inline void hash_del(struct hlist_node *node) -{ - hlist_del_init(node); -} - -/** - * hash_del_rcu - remove an object from a rcu enabled hashtable - * @node: &struct hlist_node of the object to remove - */ -static inline void hash_del_rcu(struct hlist_node *node) -{ - hlist_del_init_rcu(node); -} - -/** - * hash_for_each - iterate over a hashtable - * @name: hashtable to iterate - * @bkt: integer to use as bucket loop cursor - * @node: the &struct list_head to use as a loop cursor for each entry - * @obj: the type * to use as a loop cursor for each entry - * @member: the name of the hlist_node within the struct - */ -#define hash_for_each(name, bkt, node, obj, member) \ - for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\ - hlist_for_each_entry(obj, node, &name[bkt], member) - -/** - * hash_for_each_rcu - iterate over a rcu enabled hashtable - * @name: hashtable to iterate - * @bkt: integer to use as bucket loop cursor - * @node: the &struct list_head to use as a loop cursor for each entry - * @obj: the type * to use as a loop cursor for each entry - * @member: the name of the hlist_node within the struct - */ -#define hash_for_each_rcu(name, bkt, node, obj, member) \ - for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\ - hlist_for_each_entry_rcu(obj, node, &name[bkt], member) - -/** - * hash_for_each_safe - iterate over a hashtable safe against removal of - * hash entry - * @name: hashtable to iterate - * @bkt: integer to use as bucket loop cursor - * @node: the &struct list_head to use as a loop cursor for each entry - * @tmp: a &struct used for temporary storage - * @obj: the type * to use as a loop cursor for each entry - * @member: the name of the hlist_node within the struct - */ -#define hash_for_each_safe(name, bkt, node, tmp, obj, member) \ - for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\ - hlist_for_each_entry_safe(obj, node, tmp, &name[bkt], member) - -/** - * hash_for_each_possible - iterate over all possible objects hashing to the - * same bucket - * @name: hashtable to iterate - * @obj: the type * to use as a loop cursor for each entry - * @node: the &struct list_head to use as a loop cursor for each entry - * @member: the name of the hlist_node within the struct - * @key: the key of the objects to iterate over - */ -#define hash_for_each_possible(name, obj, node, member, key) \ - hlist_for_each_entry(obj, node, &name[hash_min(key, HASH_BITS(name))], member) - -/** - * hash_for_each_possible_rcu - iterate over all possible objects hashing to the - * same bucket in an rcu enabled hashtable - * in a rcu enabled hashtable - * @name: hashtable to iterate - * @obj: the type * to use as a loop cursor for each entry - * @node: the &struct list_head to use as a loop cursor for each entry - * @member: the name of the hlist_node within the struct - * @key: the key of the objects to iterate over - */ -#define hash_for_each_possible_rcu(name, obj, node, member, key) \ - hlist_for_each_entry_rcu(obj, node, &name[hash_min(key, HASH_BITS(name))], member) - -/** - * hash_for_each_possible_safe - iterate over all possible objects hashing to the - * same bucket safe against removals - * @name: hashtable to iterate - * @obj: the type * to use as a loop cursor for each entry - * @node: the &struct list_head to use as a loop cursor for each entry - * @tmp: a &struct used for temporary storage - * @member: the name of the hlist_node within the struct - * @key: the key of the objects to iterate over - */ -#define hash_for_each_possible_safe(name, obj, node, tmp, member, key) \ - hlist_for_each_entry_safe(obj, node, tmp, \ - &name[hash_min(key, HASH_BITS(name))], member) - - -#endif diff --git a/trunk/include/linux/hw_breakpoint.h b/trunk/include/linux/hw_breakpoint.h index 0464c85e63fd..6ae9c631a1be 100644 --- a/trunk/include/linux/hw_breakpoint.h +++ b/trunk/include/linux/hw_breakpoint.h @@ -1,8 +1,35 @@ #ifndef _LINUX_HW_BREAKPOINT_H #define _LINUX_HW_BREAKPOINT_H +enum { + HW_BREAKPOINT_LEN_1 = 1, + HW_BREAKPOINT_LEN_2 = 2, + HW_BREAKPOINT_LEN_4 = 4, + HW_BREAKPOINT_LEN_8 = 8, +}; + +enum { + HW_BREAKPOINT_EMPTY = 0, + HW_BREAKPOINT_R = 1, + HW_BREAKPOINT_W = 2, + HW_BREAKPOINT_RW = HW_BREAKPOINT_R | HW_BREAKPOINT_W, + HW_BREAKPOINT_X = 4, + HW_BREAKPOINT_INVALID = HW_BREAKPOINT_RW | HW_BREAKPOINT_X, +}; + +enum bp_type_idx { + TYPE_INST = 0, +#ifdef CONFIG_HAVE_MIXED_BREAKPOINTS_REGS + TYPE_DATA = 0, +#else + TYPE_DATA = 1, +#endif + TYPE_MAX +}; + +#ifdef __KERNEL__ + #include -#include #ifdef CONFIG_HAVE_HW_BREAKPOINT @@ -124,4 +151,6 @@ static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp) } #endif /* CONFIG_HAVE_HW_BREAKPOINT */ +#endif /* __KERNEL__ */ + #endif /* _LINUX_HW_BREAKPOINT_H */ diff --git a/trunk/include/linux/i2c-omap.h b/trunk/include/linux/i2c-omap.h index 92a0dc75bc74..df804ba73e0b 100644 --- a/trunk/include/linux/i2c-omap.h +++ b/trunk/include/linux/i2c-omap.h @@ -34,7 +34,6 @@ struct omap_i2c_bus_platform_data { u32 clkrate; u32 rev; u32 flags; - void (*set_mpu_wkup_lat)(struct device *dev, long set); }; #endif diff --git a/trunk/include/linux/iio/iio.h b/trunk/include/linux/iio/iio.h index 7806c24e5bc8..c0ae76ac4e0b 100644 --- a/trunk/include/linux/iio/iio.h +++ b/trunk/include/linux/iio/iio.h @@ -618,20 +618,4 @@ static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev) }; #endif -/** - * IIO_DEGREE_TO_RAD() - Convert degree to rad - * @deg: A value in degree - * - * Returns the given value converted from degree to rad - */ -#define IIO_DEGREE_TO_RAD(deg) (((deg) * 314159ULL + 9000000ULL) / 18000000ULL) - -/** - * IIO_G_TO_M_S_2() - Convert g to meter / second**2 - * @g: A value in g - * - * Returns the given value converted from g to meter / second**2 - */ -#define IIO_G_TO_M_S_2(g) ((g) * 980665ULL / 100000ULL) - #endif /* _INDUSTRIAL_IO_H_ */ diff --git a/trunk/include/linux/kernel.h b/trunk/include/linux/kernel.h index 7d8dfc7392f1..a123b13b70fd 100644 --- a/trunk/include/linux/kernel.h +++ b/trunk/include/linux/kernel.h @@ -701,13 +701,6 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { } #define COMPACTION_BUILD 0 #endif -/* This helps us to avoid #ifdef CONFIG_SYMBOL_PREFIX */ -#ifdef CONFIG_SYMBOL_PREFIX -#define SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX -#else -#define SYMBOL_PREFIX "" -#endif - /* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */ #ifdef CONFIG_FTRACE_MCOUNT_RECORD # define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD diff --git a/trunk/include/linux/kvm_host.h b/trunk/include/linux/kvm_host.h index ecc554374e44..93bfc9f9815c 100644 --- a/trunk/include/linux/kvm_host.h +++ b/trunk/include/linux/kvm_host.h @@ -42,8 +42,19 @@ */ #define KVM_MEMSLOT_INVALID (1UL << 16) -/* Two fragments for cross MMIO pages. */ -#define KVM_MAX_MMIO_FRAGMENTS 2 +/* + * If we support unaligned MMIO, at most one fragment will be split into two: + */ +#ifdef KVM_UNALIGNED_MMIO +# define KVM_EXTRA_MMIO_FRAGMENTS 1 +#else +# define KVM_EXTRA_MMIO_FRAGMENTS 0 +#endif + +#define KVM_USER_MMIO_SIZE 8 + +#define KVM_MAX_MMIO_FRAGMENTS \ + (KVM_MMIO_SIZE / KVM_USER_MMIO_SIZE + KVM_EXTRA_MMIO_FRAGMENTS) /* * For the normal pfn, the highest 12 bits should be zero, diff --git a/trunk/include/linux/memblock.h b/trunk/include/linux/memblock.h index d452ee191066..569d67d4243e 100644 --- a/trunk/include/linux/memblock.h +++ b/trunk/include/linux/memblock.h @@ -57,7 +57,6 @@ int memblock_add(phys_addr_t base, phys_addr_t size); int memblock_remove(phys_addr_t base, phys_addr_t size); int memblock_free(phys_addr_t base, phys_addr_t size); int memblock_reserve(phys_addr_t base, phys_addr_t size); -void memblock_trim_memory(phys_addr_t align); #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn, diff --git a/trunk/include/linux/mempolicy.h b/trunk/include/linux/mempolicy.h index dbd212723b74..e5ccb9ddd90e 100644 --- a/trunk/include/linux/mempolicy.h +++ b/trunk/include/linux/mempolicy.h @@ -82,6 +82,16 @@ static inline void mpol_cond_put(struct mempolicy *pol) __mpol_put(pol); } +extern struct mempolicy *__mpol_cond_copy(struct mempolicy *tompol, + struct mempolicy *frompol); +static inline struct mempolicy *mpol_cond_copy(struct mempolicy *tompol, + struct mempolicy *frompol) +{ + if (!frompol) + return frompol; + return __mpol_cond_copy(tompol, frompol); +} + extern struct mempolicy *__mpol_dup(struct mempolicy *pol); static inline struct mempolicy *mpol_dup(struct mempolicy *pol) { @@ -205,6 +215,12 @@ static inline void mpol_cond_put(struct mempolicy *pol) { } +static inline struct mempolicy *mpol_cond_copy(struct mempolicy *to, + struct mempolicy *from) +{ + return from; +} + static inline void mpol_get(struct mempolicy *pol) { } diff --git a/trunk/include/linux/mfd/db8500-prcmu.h b/trunk/include/linux/mfd/db8500-prcmu.h index 6ee4247df11e..b82f6ee66a0b 100644 --- a/trunk/include/linux/mfd/db8500-prcmu.h +++ b/trunk/include/linux/mfd/db8500-prcmu.h @@ -515,6 +515,7 @@ enum romcode_read prcmu_get_rc_p2a(void); enum ap_pwrst prcmu_get_xp70_current_state(void); bool prcmu_has_arm_maxopp(void); struct prcmu_fw_version *prcmu_get_fw_version(void); +int prcmu_request_ape_opp_100_voltage(bool enable); int prcmu_release_usb_wakeup_state(void); void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep, struct prcmu_auto_pm_config *idle); @@ -563,7 +564,6 @@ int db8500_prcmu_set_arm_opp(u8 opp); int db8500_prcmu_get_arm_opp(void); int db8500_prcmu_set_ape_opp(u8 opp); int db8500_prcmu_get_ape_opp(void); -int db8500_prcmu_request_ape_opp_100_voltage(bool enable); int db8500_prcmu_set_ddr_opp(u8 opp); int db8500_prcmu_get_ddr_opp(void); @@ -610,7 +610,7 @@ static inline int db8500_prcmu_get_ape_opp(void) return APE_100_OPP; } -static inline int db8500_prcmu_request_ape_opp_100_voltage(bool enable) +static inline int prcmu_request_ape_opp_100_voltage(bool enable) { return 0; } diff --git a/trunk/include/linux/mfd/dbx500-prcmu.h b/trunk/include/linux/mfd/dbx500-prcmu.h index c202d6c4d879..c410d99bd667 100644 --- a/trunk/include/linux/mfd/dbx500-prcmu.h +++ b/trunk/include/linux/mfd/dbx500-prcmu.h @@ -336,11 +336,6 @@ static inline int prcmu_get_ape_opp(void) return db8500_prcmu_get_ape_opp(); } -static inline int prcmu_request_ape_opp_100_voltage(bool enable) -{ - return db8500_prcmu_request_ape_opp_100_voltage(enable); -} - static inline void prcmu_system_reset(u16 reset_code) { return db8500_prcmu_system_reset(reset_code); @@ -512,11 +507,6 @@ static inline int prcmu_get_ape_opp(void) return APE_100_OPP; } -static inline int prcmu_request_ape_opp_100_voltage(bool enable) -{ - return 0; -} - static inline int prcmu_set_arm_opp(u8 opp) { return 0; diff --git a/trunk/include/linux/mfd/max77693.h b/trunk/include/linux/mfd/max77693.h index fe03b2d35d4f..1d28ae90384e 100644 --- a/trunk/include/linux/mfd/max77693.h +++ b/trunk/include/linux/mfd/max77693.h @@ -30,20 +30,7 @@ #ifndef __LINUX_MFD_MAX77693_H #define __LINUX_MFD_MAX77693_H -struct max77693_reg_data { - u8 addr; - u8 data; -}; - -struct max77693_muic_platform_data { - struct max77693_reg_data *init_data; - int num_init_data; -}; - struct max77693_platform_data { int wakeup; - - /* muic data */ - struct max77693_muic_platform_data *muic_data; }; #endif /* __LINUX_MFD_MAX77693_H */ diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h index bcaab4e6fe91..fa0680402738 100644 --- a/trunk/include/linux/mm.h +++ b/trunk/include/linux/mm.h @@ -1684,5 +1684,9 @@ static inline unsigned int debug_guardpage_minorder(void) { return 0; } static inline bool page_is_guard(struct page *page) { return false; } #endif /* CONFIG_DEBUG_PAGEALLOC */ +extern void reset_zone_present_pages(void); +extern void fixup_zone_present_pages(int nid, unsigned long start_pfn, + unsigned long end_pfn); + #endif /* __KERNEL__ */ #endif /* _LINUX_MM_H */ diff --git a/trunk/include/linux/mmc/card.h b/trunk/include/linux/mmc/card.h index 5c69315d60cc..943550dfe9ea 100644 --- a/trunk/include/linux/mmc/card.h +++ b/trunk/include/linux/mmc/card.h @@ -85,7 +85,6 @@ struct mmc_ext_csd { bool boot_ro_lockable; u8 raw_exception_status; /* 53 */ u8 raw_partition_support; /* 160 */ - u8 raw_rpmb_size_mult; /* 168 */ u8 raw_erased_mem_count; /* 181 */ u8 raw_ext_csd_structure; /* 194 */ u8 raw_card_type; /* 196 */ @@ -207,7 +206,6 @@ struct mmc_part { #define MMC_BLK_DATA_AREA_MAIN (1<<0) #define MMC_BLK_DATA_AREA_BOOT (1<<1) #define MMC_BLK_DATA_AREA_GP (1<<2) -#define MMC_BLK_DATA_AREA_RPMB (1<<3) }; /* diff --git a/trunk/include/linux/mmc/core.h b/trunk/include/linux/mmc/core.h index 5bf7c2274fcb..9b9cdafc7737 100644 --- a/trunk/include/linux/mmc/core.h +++ b/trunk/include/linux/mmc/core.h @@ -170,8 +170,6 @@ extern int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from, extern unsigned int mmc_calc_max_discard(struct mmc_card *card); extern int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen); -extern int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount, - bool is_rel_write); extern int mmc_hw_reset(struct mmc_host *host); extern int mmc_hw_reset_check(struct mmc_host *host); extern int mmc_can_reset(struct mmc_card *card); diff --git a/trunk/include/linux/mmc/dw_mmc.h b/trunk/include/linux/mmc/dw_mmc.h index 34be4f47293c..7c6a1139d8fa 100644 --- a/trunk/include/linux/mmc/dw_mmc.h +++ b/trunk/include/linux/mmc/dw_mmc.h @@ -137,7 +137,7 @@ struct dw_mci { dma_addr_t sg_dma; void *sg_cpu; - const struct dw_mci_dma_ops *dma_ops; + struct dw_mci_dma_ops *dma_ops; #ifdef CONFIG_MMC_DW_IDMAC unsigned int ring_size; #else @@ -162,7 +162,7 @@ struct dw_mci { u16 data_offset; struct device *dev; struct dw_mci_board *pdata; - const struct dw_mci_drv_data *drv_data; + struct dw_mci_drv_data *drv_data; void *priv; struct clk *biu_clk; struct clk *ciu_clk; @@ -186,7 +186,7 @@ struct dw_mci { struct regulator *vmmc; /* Power regulator */ unsigned long irq_flags; /* IRQ flags */ - int irq; + unsigned int irq; }; /* DMA ops for Internal/External DMAC interface */ @@ -229,9 +229,8 @@ struct dw_mci_board { u32 quirks; /* Workaround / Quirk flags */ unsigned int bus_hz; /* Clock speed at the cclk_in pad */ - u32 caps; /* Capabilities */ - u32 caps2; /* More capabilities */ - u32 pm_caps; /* PM capabilities */ + unsigned int caps; /* Capabilities */ + unsigned int caps2; /* More capabilities */ /* * Override fifo depth. If 0, autodetect it from the FIFOTH register, * but note that this may not be reliable after a bootloader has used diff --git a/trunk/include/linux/mmc/host.h b/trunk/include/linux/mmc/host.h index 61a10c17aabd..7abb0e1f7bda 100644 --- a/trunk/include/linux/mmc/host.h +++ b/trunk/include/linux/mmc/host.h @@ -53,12 +53,12 @@ struct mmc_ios { #define MMC_TIMING_LEGACY 0 #define MMC_TIMING_MMC_HS 1 #define MMC_TIMING_SD_HS 2 -#define MMC_TIMING_UHS_SDR12 3 -#define MMC_TIMING_UHS_SDR25 4 -#define MMC_TIMING_UHS_SDR50 5 -#define MMC_TIMING_UHS_SDR104 6 -#define MMC_TIMING_UHS_DDR50 7 -#define MMC_TIMING_MMC_HS200 8 +#define MMC_TIMING_UHS_SDR12 MMC_TIMING_LEGACY +#define MMC_TIMING_UHS_SDR25 MMC_TIMING_SD_HS +#define MMC_TIMING_UHS_SDR50 3 +#define MMC_TIMING_UHS_SDR104 4 +#define MMC_TIMING_UHS_DDR50 5 +#define MMC_TIMING_MMC_HS200 6 #define MMC_SDR_MODE 0 #define MMC_1_2V_DDR_MODE 1 @@ -136,7 +136,6 @@ struct mmc_host_ops { void (*enable_preset_value)(struct mmc_host *host, bool enable); int (*select_drive_strength)(unsigned int max_dtr, int host_drv, int card_drv); void (*hw_reset)(struct mmc_host *host); - void (*card_event)(struct mmc_host *host); }; struct mmc_card; @@ -212,7 +211,7 @@ struct mmc_host { #define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */ #define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */ - u32 caps; /* Host capabilities */ + unsigned long caps; /* Host capabilities */ #define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */ #define MMC_CAP_MMC_HIGHSPEED (1 << 1) /* Can do MMC high-speed timing */ @@ -242,7 +241,7 @@ struct mmc_host { #define MMC_CAP_CMD23 (1 << 30) /* CMD23 supported. */ #define MMC_CAP_HW_RESET (1 << 31) /* Hardware reset */ - u32 caps2; /* More host capabilities */ + unsigned int caps2; /* More host capabilities */ #define MMC_CAP2_BOOTPART_NOACC (1 << 0) /* Boot partition no access */ #define MMC_CAP2_CACHE_CTRL (1 << 1) /* Allow cache control */ diff --git a/trunk/include/linux/mmc/mmc.h b/trunk/include/linux/mmc/mmc.h index 94d532e41c61..01e4b394029b 100644 --- a/trunk/include/linux/mmc/mmc.h +++ b/trunk/include/linux/mmc/mmc.h @@ -286,7 +286,6 @@ struct _mmc_csd { #define EXT_CSD_BKOPS_START 164 /* W */ #define EXT_CSD_SANITIZE_START 165 /* W */ #define EXT_CSD_WR_REL_PARAM 166 /* RO */ -#define EXT_CSD_RPMB_MULT 168 /* RO */ #define EXT_CSD_BOOT_WP 173 /* R/W */ #define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */ #define EXT_CSD_PART_CONFIG 179 /* R/W */ @@ -340,7 +339,6 @@ struct _mmc_csd { #define EXT_CSD_PART_CONFIG_ACC_MASK (0x7) #define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1) -#define EXT_CSD_PART_CONFIG_ACC_RPMB (0x3) #define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4) #define EXT_CSD_PART_SUPPORT_PART_EN (0x1) diff --git a/trunk/include/linux/mmc/mxs-mmc.h b/trunk/include/linux/mmc/mxs-mmc.h new file mode 100644 index 000000000000..7c2ad3a7f2f3 --- /dev/null +++ b/trunk/include/linux/mmc/mxs-mmc.h @@ -0,0 +1,19 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved. + * + * 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. + */ + +#ifndef __LINUX_MMC_MXS_MMC_H__ +#define __LINUX_MMC_MXS_MMC_H__ + +struct mxs_mmc_platform_data { + int wp_gpio; /* write protect pin */ + unsigned int flags; +#define SLOTF_4_BIT_CAPABLE (1 << 0) +#define SLOTF_8_BIT_CAPABLE (1 << 1) +}; + +#endif /* __LINUX_MMC_MXS_MMC_H__ */ diff --git a/trunk/include/linux/mmc/sdhci.h b/trunk/include/linux/mmc/sdhci.h index 4bbc3301fbbf..fa8529a859b8 100644 --- a/trunk/include/linux/mmc/sdhci.h +++ b/trunk/include/linux/mmc/sdhci.h @@ -91,9 +91,6 @@ struct sdhci_host { unsigned int quirks2; /* More deviations from spec. */ #define SDHCI_QUIRK2_HOST_OFF_CARD_ON (1<<0) -#define SDHCI_QUIRK2_HOST_NO_CMD23 (1<<1) -/* The system physically doesn't support 1.8v, even if the host does */ -#define SDHCI_QUIRK2_NO_1_8_V (1<<2) int irq; /* Device IRQ */ void __iomem *ioaddr; /* Mapped address */ @@ -160,8 +157,8 @@ struct sdhci_host { struct timer_list timer; /* Timer for timeouts */ - u32 caps; /* Alternative CAPABILITY_0 */ - u32 caps1; /* Alternative CAPABILITY_1 */ + unsigned int caps; /* Alternative CAPABILITY_0 */ + unsigned int caps1; /* Alternative CAPABILITY_1 */ unsigned int ocr_avail_sdio; /* OCR bit masks */ unsigned int ocr_avail_sd; diff --git a/trunk/include/linux/mmzone.h b/trunk/include/linux/mmzone.h index a23923ba8263..50aaca81f63d 100644 --- a/trunk/include/linux/mmzone.h +++ b/trunk/include/linux/mmzone.h @@ -752,7 +752,7 @@ extern int init_currently_empty_zone(struct zone *zone, unsigned long start_pfn, unsigned long size, enum memmap_context context); -extern void lruvec_init(struct lruvec *lruvec); +extern void lruvec_init(struct lruvec *lruvec, struct zone *zone); static inline struct zone *lruvec_zone(struct lruvec *lruvec) { diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index a848ffc327f4..f8eda0276f03 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -1488,9 +1488,6 @@ struct napi_gro_cb { /* Used in ipv6_gro_receive() */ int proto; - - /* used in skb_gro_receive() slow path */ - struct sk_buff *last; }; #define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb) diff --git a/trunk/include/linux/of_address.h b/trunk/include/linux/of_address.h index 0506eb53519b..a1984dd037da 100644 --- a/trunk/include/linux/of_address.h +++ b/trunk/include/linux/of_address.h @@ -28,13 +28,11 @@ static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; } #endif #else /* CONFIG_OF_ADDRESS */ -#ifndef of_address_to_resource static inline int of_address_to_resource(struct device_node *dev, int index, struct resource *r) { return -EINVAL; } -#endif static inline struct device_node *of_find_matching_node_by_address( struct device_node *from, const struct of_device_id *matches, @@ -42,12 +40,10 @@ static inline struct device_node *of_find_matching_node_by_address( { return NULL; } -#ifndef of_iomap static inline void __iomem *of_iomap(struct device_node *device, int index) { return NULL; } -#endif static inline const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, unsigned int *flags) { diff --git a/trunk/include/linux/percpu-rwsem.h b/trunk/include/linux/percpu-rwsem.h index bd1e86071e57..cf80f7e5277f 100644 --- a/trunk/include/linux/percpu-rwsem.h +++ b/trunk/include/linux/percpu-rwsem.h @@ -12,27 +12,34 @@ struct percpu_rw_semaphore { struct mutex mtx; }; -#define light_mb() barrier() -#define heavy_mb() synchronize_sched_expedited() - static inline void percpu_down_read(struct percpu_rw_semaphore *p) { - rcu_read_lock_sched(); + rcu_read_lock(); if (unlikely(p->locked)) { - rcu_read_unlock_sched(); + rcu_read_unlock(); mutex_lock(&p->mtx); this_cpu_inc(*p->counters); mutex_unlock(&p->mtx); return; } this_cpu_inc(*p->counters); - rcu_read_unlock_sched(); - light_mb(); /* A, between read of p->locked and read of data, paired with D */ + rcu_read_unlock(); } static inline void percpu_up_read(struct percpu_rw_semaphore *p) { - light_mb(); /* B, between read of the data and write to p->counter, paired with C */ + /* + * On X86, write operation in this_cpu_dec serves as a memory unlock + * barrier (i.e. memory accesses may be moved before the write, but + * no memory accesses are moved past the write). + * On other architectures this may not be the case, so we need smp_mb() + * there. + */ +#if defined(CONFIG_X86) && (!defined(CONFIG_X86_PPRO_FENCE) && !defined(CONFIG_X86_OOSTORE)) + barrier(); +#else + smp_mb(); +#endif this_cpu_dec(*p->counters); } @@ -51,15 +58,14 @@ static inline void percpu_down_write(struct percpu_rw_semaphore *p) { mutex_lock(&p->mtx); p->locked = true; - synchronize_sched_expedited(); /* make sure that all readers exit the rcu_read_lock_sched region */ + synchronize_rcu(); while (__percpu_count(p->counters)) msleep(1); - heavy_mb(); /* C, between read of p->counter and write to data, paired with B */ + smp_rmb(); /* paired with smp_mb() in percpu_sem_up_read() */ } static inline void percpu_up_write(struct percpu_rw_semaphore *p) { - heavy_mb(); /* D, between write to data and write to p->locked, paired with A */ p->locked = false; mutex_unlock(&p->mtx); } diff --git a/trunk/include/linux/perf_event.h b/trunk/include/linux/perf_event.h index 6bfb2faa0b19..2e902359aee5 100644 --- a/trunk/include/linux/perf_event.h +++ b/trunk/include/linux/perf_event.h @@ -803,16 +803,12 @@ static inline void perf_event_task_tick(void) { } do { \ static struct notifier_block fn##_nb __cpuinitdata = \ { .notifier_call = fn, .priority = CPU_PRI_PERF }; \ - unsigned long cpu = smp_processor_id(); \ - unsigned long flags; \ fn(&fn##_nb, (unsigned long)CPU_UP_PREPARE, \ - (void *)(unsigned long)cpu); \ - local_irq_save(flags); \ + (void *)(unsigned long)smp_processor_id()); \ fn(&fn##_nb, (unsigned long)CPU_STARTING, \ - (void *)(unsigned long)cpu); \ - local_irq_restore(flags); \ + (void *)(unsigned long)smp_processor_id()); \ fn(&fn##_nb, (unsigned long)CPU_ONLINE, \ - (void *)(unsigned long)cpu); \ + (void *)(unsigned long)smp_processor_id()); \ register_cpu_notifier(&fn##_nb); \ } while (0) diff --git a/trunk/include/linux/pinctrl/pinconf-generic.h b/trunk/include/linux/pinctrl/pinconf-generic.h index 47a1bdd88878..4f0abb9f1c09 100644 --- a/trunk/include/linux/pinctrl/pinconf-generic.h +++ b/trunk/include/linux/pinctrl/pinconf-generic.h @@ -46,11 +46,11 @@ * @PIN_CONFIG_DRIVE_OPEN_SOURCE: the pin will be driven with open source * (open emitter). Sending this config will enabale open drain mode, the * argument is ignored. - * @PIN_CONFIG_INPUT_SCHMITT_DISABLE: disable schmitt-trigger mode on the pin. * @PIN_CONFIG_INPUT_SCHMITT: this will configure an input pin to run in * schmitt-trigger mode. If the schmitt-trigger has adjustable hysteresis, * the threshold value is given on a custom format as argument when - * setting pins to this mode. + * setting pins to this mode. The argument zero turns the schmitt trigger + * off. * @PIN_CONFIG_INPUT_DEBOUNCE: this will configure the pin to debounce mode, * which means it will wait for signals to settle when reading inputs. The * argument gives the debounce time on a custom format. Setting the @@ -74,7 +74,6 @@ enum pin_config_param { PIN_CONFIG_DRIVE_PUSH_PULL, PIN_CONFIG_DRIVE_OPEN_DRAIN, PIN_CONFIG_DRIVE_OPEN_SOURCE, - PIN_CONFIG_INPUT_SCHMITT_DISABLE, PIN_CONFIG_INPUT_SCHMITT, PIN_CONFIG_INPUT_DEBOUNCE, PIN_CONFIG_POWER_SOURCE, diff --git a/trunk/include/linux/pinctrl/pinctrl.h b/trunk/include/linux/pinctrl/pinctrl.h index 04d6700d99af..7d087f03e91e 100644 --- a/trunk/include/linux/pinctrl/pinctrl.h +++ b/trunk/include/linux/pinctrl/pinctrl.h @@ -134,25 +134,6 @@ extern void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev, extern void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *ranges, unsigned nranges); -extern void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range); - -extern struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname, - struct pinctrl_gpio_range *range); -extern struct pinctrl_gpio_range * -pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev, - unsigned int pin); - -#ifdef CONFIG_OF -extern struct pinctrl_dev *of_pinctrl_get(struct device_node *np); -#else -static inline -struct pinctrl_dev *of_pinctrl_get(struct device_node *np) -{ - return NULL; -} -#endif /* CONFIG_OF */ - extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev); extern void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev); #else diff --git a/trunk/include/linux/platform_data/ads7828.h b/trunk/include/linux/platform_data/ads7828.h deleted file mode 100644 index 3245f45f9d77..000000000000 --- a/trunk/include/linux/platform_data/ads7828.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * TI ADS7828 A/D Converter platform data definition - * - * Copyright (c) 2012 Savoir-faire Linux Inc. - * Vivien Didelot - * - * For further information, see the Documentation/hwmon/ads7828 file. - * - * 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. - */ - -#ifndef _PDATA_ADS7828_H -#define _PDATA_ADS7828_H - -/** - * struct ads7828_platform_data - optional ADS7828 connectivity info - * @diff_input: Differential input mode. - * @ext_vref: Use an external voltage reference. - * @vref_mv: Voltage reference value, if external. - */ -struct ads7828_platform_data { - bool diff_input; - bool ext_vref; - unsigned int vref_mv; -}; - -#endif /* _PDATA_ADS7828_H */ diff --git a/trunk/include/linux/platform_data/clk-integrator.h b/trunk/include/linux/platform_data/clk-integrator.h index 280edac9d0a5..83fe9c283bb8 100644 --- a/trunk/include/linux/platform_data/clk-integrator.h +++ b/trunk/include/linux/platform_data/clk-integrator.h @@ -1,3 +1 @@ void integrator_clk_init(bool is_cp); -void integrator_impd1_clk_init(void __iomem *base, unsigned int id); -void integrator_impd1_clk_exit(unsigned int id); diff --git a/trunk/include/linux/platform_data/omap_ocp2scp.h b/trunk/include/linux/platform_data/omap_ocp2scp.h deleted file mode 100644 index 5c6c3939355f..000000000000 --- a/trunk/include/linux/platform_data/omap_ocp2scp.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * omap_ocp2scp.h -- ocp2scp header file - * - * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.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. - * - * Author: Kishon Vijay Abraham I - * - * 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. - * - */ - -#ifndef __DRIVERS_OMAP_OCP2SCP_H -#define __DRIVERS_OMAP_OCP2SCP_H - -struct omap_ocp2scp_dev { - const char *drv_name; - struct resource *res; -}; - -struct omap_ocp2scp_platform_data { - int dev_cnt; - struct omap_ocp2scp_dev **devices; -}; -#endif /* __DRIVERS_OMAP_OCP2SCP_H */ diff --git a/trunk/include/linux/platform_data/pinctrl-coh901.h b/trunk/include/linux/platform_data/pinctrl-coh901.h index dfbc65d10484..30dea251b835 100644 --- a/trunk/include/linux/platform_data/pinctrl-coh901.h +++ b/trunk/include/linux/platform_data/pinctrl-coh901.h @@ -13,10 +13,14 @@ * struct u300_gpio_platform - U300 GPIO platform data * @ports: number of GPIO block ports * @gpio_base: first GPIO number for this block (use a free range) + * @gpio_irq_base: first GPIO IRQ number for this block (use a free range) + * @pinctrl_device: pin control device to spawn as child */ struct u300_gpio_platform { u8 ports; int gpio_base; + int gpio_irq_base; + struct platform_device *pinctrl_device; }; #endif /* __MACH_U300_GPIO_U300_H */ diff --git a/trunk/include/linux/platform_data/pxa_sdhci.h b/trunk/include/linux/platform_data/pxa_sdhci.h index 27d3156d093a..59acd987ed34 100644 --- a/trunk/include/linux/platform_data/pxa_sdhci.h +++ b/trunk/include/linux/platform_data/pxa_sdhci.h @@ -38,7 +38,6 @@ * @max_speed: the maximum speed supported * @host_caps: Standard MMC host capabilities bit field. * @quirks: quirks of platfrom - * @quirks2: quirks2 of platfrom * @pm_caps: pm_caps of platfrom */ struct sdhci_pxa_platdata { @@ -49,10 +48,9 @@ struct sdhci_pxa_platdata { unsigned int ext_cd_gpio; bool ext_cd_gpio_invert; unsigned int max_speed; - u32 host_caps; - u32 host_caps2; + unsigned int host_caps; + unsigned int host_caps2; unsigned int quirks; - unsigned int quirks2; unsigned int pm_caps; }; diff --git a/trunk/include/linux/ptp_clock_kernel.h b/trunk/include/linux/ptp_clock_kernel.h index 38a993508327..f2dc6d8fc680 100644 --- a/trunk/include/linux/ptp_clock_kernel.h +++ b/trunk/include/linux/ptp_clock_kernel.h @@ -54,8 +54,7 @@ struct ptp_clock_request { * clock operations * * @adjfreq: Adjusts the frequency of the hardware clock. - * parameter delta: Desired frequency offset from nominal frequency - * in parts per billion + * parameter delta: Desired period change in parts per billion. * * @adjtime: Shifts the time of the hardware clock. * parameter delta: Desired change in nanoseconds. diff --git a/trunk/include/linux/raid/Kbuild b/trunk/include/linux/raid/Kbuild index e69de29bb2d1..2415a64c5e51 100644 --- a/trunk/include/linux/raid/Kbuild +++ b/trunk/include/linux/raid/Kbuild @@ -0,0 +1,2 @@ +header-y += md_p.h +header-y += md_u.h diff --git a/trunk/include/uapi/linux/raid/md_p.h b/trunk/include/linux/raid/md_p.h similarity index 100% rename from trunk/include/uapi/linux/raid/md_p.h rename to trunk/include/linux/raid/md_p.h diff --git a/trunk/include/linux/raid/md_u.h b/trunk/include/linux/raid/md_u.h index 358c04bfbe2a..fb1abb3367e9 100644 --- a/trunk/include/linux/raid/md_u.h +++ b/trunk/include/linux/raid/md_u.h @@ -11,10 +11,149 @@ (for example /usr/src/linux/COPYING); if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + #ifndef _MD_U_H #define _MD_U_H -#include +/* + * Different major versions are not compatible. + * Different minor versions are only downward compatible. + * Different patchlevel versions are downward and upward compatible. + */ +#define MD_MAJOR_VERSION 0 +#define MD_MINOR_VERSION 90 +/* + * MD_PATCHLEVEL_VERSION indicates kernel functionality. + * >=1 means different superblock formats are selectable using SET_ARRAY_INFO + * and major_version/minor_version accordingly + * >=2 means that Internal bitmaps are supported by setting MD_SB_BITMAP_PRESENT + * in the super status byte + * >=3 means that bitmap superblock version 4 is supported, which uses + * little-ending representation rather than host-endian + */ +#define MD_PATCHLEVEL_VERSION 3 + +/* ioctls */ + +/* status */ +#define RAID_VERSION _IOR (MD_MAJOR, 0x10, mdu_version_t) +#define GET_ARRAY_INFO _IOR (MD_MAJOR, 0x11, mdu_array_info_t) +#define GET_DISK_INFO _IOR (MD_MAJOR, 0x12, mdu_disk_info_t) +#define PRINT_RAID_DEBUG _IO (MD_MAJOR, 0x13) +#define RAID_AUTORUN _IO (MD_MAJOR, 0x14) +#define GET_BITMAP_FILE _IOR (MD_MAJOR, 0x15, mdu_bitmap_file_t) + +/* configuration */ +#define CLEAR_ARRAY _IO (MD_MAJOR, 0x20) +#define ADD_NEW_DISK _IOW (MD_MAJOR, 0x21, mdu_disk_info_t) +#define HOT_REMOVE_DISK _IO (MD_MAJOR, 0x22) +#define SET_ARRAY_INFO _IOW (MD_MAJOR, 0x23, mdu_array_info_t) +#define SET_DISK_INFO _IO (MD_MAJOR, 0x24) +#define WRITE_RAID_INFO _IO (MD_MAJOR, 0x25) +#define UNPROTECT_ARRAY _IO (MD_MAJOR, 0x26) +#define PROTECT_ARRAY _IO (MD_MAJOR, 0x27) +#define HOT_ADD_DISK _IO (MD_MAJOR, 0x28) +#define SET_DISK_FAULTY _IO (MD_MAJOR, 0x29) +#define HOT_GENERATE_ERROR _IO (MD_MAJOR, 0x2a) +#define SET_BITMAP_FILE _IOW (MD_MAJOR, 0x2b, int) +/* usage */ +#define RUN_ARRAY _IOW (MD_MAJOR, 0x30, mdu_param_t) +/* 0x31 was START_ARRAY */ +#define STOP_ARRAY _IO (MD_MAJOR, 0x32) +#define STOP_ARRAY_RO _IO (MD_MAJOR, 0x33) +#define RESTART_ARRAY_RW _IO (MD_MAJOR, 0x34) + +/* 63 partitions with the alternate major number (mdp) */ +#define MdpMinorShift 6 +#ifdef __KERNEL__ extern int mdp_major; +#endif + +typedef struct mdu_version_s { + int major; + int minor; + int patchlevel; +} mdu_version_t; + +typedef struct mdu_array_info_s { + /* + * Generic constant information + */ + int major_version; + int minor_version; + int patch_version; + int ctime; + int level; + int size; + int nr_disks; + int raid_disks; + int md_minor; + int not_persistent; + + /* + * Generic state information + */ + int utime; /* 0 Superblock update time */ + int state; /* 1 State bits (clean, ...) */ + int active_disks; /* 2 Number of currently active disks */ + int working_disks; /* 3 Number of working disks */ + int failed_disks; /* 4 Number of failed disks */ + int spare_disks; /* 5 Number of spare disks */ + + /* + * Personality information + */ + int layout; /* 0 the array's physical layout */ + int chunk_size; /* 1 chunk size in bytes */ + +} mdu_array_info_t; + +/* non-obvious values for 'level' */ +#define LEVEL_MULTIPATH (-4) +#define LEVEL_LINEAR (-1) +#define LEVEL_FAULTY (-5) + +/* we need a value for 'no level specified' and 0 + * means 'raid0', so we need something else. This is + * for internal use only + */ +#define LEVEL_NONE (-1000000) + +typedef struct mdu_disk_info_s { + /* + * configuration/status of one particular disk + */ + int number; + int major; + int minor; + int raid_disk; + int state; + +} mdu_disk_info_t; + +typedef struct mdu_start_info_s { + /* + * configuration/status of one particular disk + */ + int major; + int minor; + int raid_disk; + int state; + +} mdu_start_info_t; + +typedef struct mdu_bitmap_file_s +{ + char pathname[4096]; +} mdu_bitmap_file_t; + +typedef struct mdu_param_s +{ + int personality; /* 1,2,3,4 */ + int chunk_size; /* in bytes */ + int max_fault; /* unused for now */ +} mdu_param_t; + #endif + diff --git a/trunk/include/linux/rbtree_augmented.h b/trunk/include/linux/rbtree_augmented.h index 2ac60c9cf644..214caa33433b 100644 --- a/trunk/include/linux/rbtree_augmented.h +++ b/trunk/include/linux/rbtree_augmented.h @@ -24,7 +24,6 @@ #ifndef _LINUX_RBTREE_AUGMENTED_H #define _LINUX_RBTREE_AUGMENTED_H -#include #include /* diff --git a/trunk/include/linux/rio.h b/trunk/include/linux/rio.h index a3e784278667..4187da511006 100644 --- a/trunk/include/linux/rio.h +++ b/trunk/include/linux/rio.h @@ -275,11 +275,9 @@ struct rio_id_table { * struct rio_net - RIO network info * @node: Node in global list of RIO networks * @devices: List of devices in this network - * @switches: List of switches in this netowrk * @mports: List of master ports accessing this network * @hport: Default port for accessing this network * @id: RIO network ID - * @destid_table: destID allocation table */ struct rio_net { struct list_head node; /* node in list of networks */ diff --git a/trunk/include/linux/spi/ads7846.h b/trunk/include/linux/spi/ads7846.h index 2f694f3846a9..c64de9dd7631 100644 --- a/trunk/include/linux/spi/ads7846.h +++ b/trunk/include/linux/spi/ads7846.h @@ -46,9 +46,8 @@ struct ads7846_platform_data { u16 debounce_rep; /* additional consecutive good readings * required after the first two */ int gpio_pendown; /* the GPIO used to decide the pendown - * state if get_pendown_state == NULL */ - int gpio_pendown_debounce; /* platform specific debounce time for - * the gpio_pendown */ + * state if get_pendown_state == NULL + */ int (*get_pendown_state)(void); int (*filter_init) (const struct ads7846_platform_data *pdata, void **filter_data); diff --git a/trunk/include/linux/spi/tsc2005.h b/trunk/include/linux/spi/tsc2005.h index 8f721e465e05..d9b0c84220c7 100644 --- a/trunk/include/linux/spi/tsc2005.h +++ b/trunk/include/linux/spi/tsc2005.h @@ -3,6 +3,8 @@ * * Copyright (C) 2009-2010 Nokia Corporation * + * Contact: Aaro Koskinen + * * 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 diff --git a/trunk/include/linux/tcp.h b/trunk/include/linux/tcp.h index 60b7aac15e0e..8a7fc4be2d75 100644 --- a/trunk/include/linux/tcp.h +++ b/trunk/include/linux/tcp.h @@ -191,8 +191,7 @@ struct tcp_sock { u8 do_early_retrans:1,/* Enable RFC5827 early-retransmit */ early_retrans_delayed:1, /* Delayed ER timer installed */ syn_data:1, /* SYN includes data */ - syn_fastopen:1, /* SYN includes Fast Open option */ - syn_data_acked:1;/* data in SYN is acked by SYN-ACK */ + syn_fastopen:1; /* SYN includes Fast Open option */ /* RTT measurement */ u32 srtt; /* smoothed round trip time << 3 */ diff --git a/trunk/include/linux/uprobes.h b/trunk/include/linux/uprobes.h index 24594571c5a3..e6f0331e3d45 100644 --- a/trunk/include/linux/uprobes.h +++ b/trunk/include/linux/uprobes.h @@ -35,6 +35,16 @@ struct inode; # include #endif +/* flags that denote/change uprobes behaviour */ + +/* Have a copy of original instruction */ +#define UPROBE_COPY_INSN 0x1 + +/* Dont run handlers when first register/ last unregister in progress*/ +#define UPROBE_RUN_HANDLER 0x2 +/* Can skip singlestep */ +#define UPROBE_SKIP_SSTEP 0x4 + struct uprobe_consumer { int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs); /* @@ -49,6 +59,7 @@ struct uprobe_consumer { #ifdef CONFIG_UPROBES enum uprobe_task_state { UTASK_RUNNING, + UTASK_BP_HIT, UTASK_SSTEP, UTASK_SSTEP_ACK, UTASK_SSTEP_TRAPPED, diff --git a/trunk/include/media/adv7604.h b/trunk/include/media/adv7604.h index dc004bc926c9..171b957db743 100644 --- a/trunk/include/media/adv7604.h +++ b/trunk/include/media/adv7604.h @@ -40,6 +40,14 @@ enum adv7604_op_ch_sel { ADV7604_OP_CH_SEL_RBG = 5, }; +/* Primary mode (IO register 0x01, [3:0]) */ +enum adv7604_prim_mode { + ADV7604_PRIM_MODE_COMP = 1, + ADV7604_PRIM_MODE_RGB = 2, + ADV7604_PRIM_MODE_HDMI_COMP = 5, + ADV7604_PRIM_MODE_HDMI_GR = 6, +}; + /* Input Color Space (IO register 0x02, [7:4]) */ enum adv7604_inp_color_space { ADV7604_INP_COLOR_SPACE_LIM_RGB = 0, @@ -95,6 +103,9 @@ struct adv7604_platform_data { /* Bus rotation and reordering */ enum adv7604_op_ch_sel op_ch_sel; + /* Primary mode */ + enum adv7604_prim_mode prim_mode; + /* Select output format */ enum adv7604_op_format_sel op_format_sel; @@ -131,16 +142,6 @@ struct adv7604_platform_data { u8 i2c_vdp; }; -/* - * Mode of operation. - * This is used as the input argument of the s_routing video op. - */ -enum adv7604_mode { - ADV7604_MODE_COMP, - ADV7604_MODE_GR, - ADV7604_MODE_HDMI, -}; - #define V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE (V4L2_CID_DV_CLASS_BASE + 0x1000) #define V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL (V4L2_CID_DV_CLASS_BASE + 0x1001) #define V4L2_CID_ADV_RX_FREE_RUN_COLOR (V4L2_CID_DV_CLASS_BASE + 0x1002) diff --git a/trunk/include/net/cfg80211.h b/trunk/include/net/cfg80211.h index 7d5b6000378b..1b4989082244 100644 --- a/trunk/include/net/cfg80211.h +++ b/trunk/include/net/cfg80211.h @@ -1218,7 +1218,6 @@ struct cfg80211_deauth_request { const u8 *ie; size_t ie_len; u16 reason_code; - bool local_state_change; }; /** @@ -2651,15 +2650,6 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); */ unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc); -/** - * ieee80211_get_mesh_hdrlen - get mesh extension header length - * @meshhdr: the mesh extension header, only the flags field - * (first byte) will be accessed - * Returns the length of the extension header, which is always at - * least 6 bytes and at most 18 if address 5 and 6 are present. - */ -unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); - /** * DOC: Data path helpers * diff --git a/trunk/include/net/tcp.h b/trunk/include/net/tcp.h index 4af45e33105d..6feeccd83dd7 100644 --- a/trunk/include/net/tcp.h +++ b/trunk/include/net/tcp.h @@ -525,7 +525,6 @@ static inline __u32 cookie_v6_init_sequence(struct sock *sk, extern void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss, int nonagle); extern bool tcp_may_send_now(struct sock *sk); -extern int __tcp_retransmit_skb(struct sock *, struct sk_buff *); extern int tcp_retransmit_skb(struct sock *, struct sk_buff *); extern void tcp_retransmit_timer(struct sock *sk); extern void tcp_xmit_retransmit_queue(struct sock *); diff --git a/trunk/include/net/xfrm.h b/trunk/include/net/xfrm.h index 63445ede48bb..6f0ba01afe73 100644 --- a/trunk/include/net/xfrm.h +++ b/trunk/include/net/xfrm.h @@ -1351,7 +1351,7 @@ struct xfrm6_tunnel { }; extern void xfrm_init(void); -extern void xfrm4_init(void); +extern void xfrm4_init(int rt_hash_size); extern int xfrm_state_init(struct net *net); extern void xfrm_state_fini(struct net *net); extern void xfrm4_state_init(void); diff --git a/trunk/include/scsi/scsi_device.h b/trunk/include/scsi/scsi_device.h index 55367b04dc94..88fae8d20154 100644 --- a/trunk/include/scsi/scsi_device.h +++ b/trunk/include/scsi/scsi_device.h @@ -135,8 +135,6 @@ struct scsi_device { * because we did a bus reset. */ unsigned use_10_for_rw:1; /* first try 10-byte read / write */ unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ - unsigned no_report_opcodes:1; /* no REPORT SUPPORTED OPERATION CODES */ - unsigned no_write_same:1; /* no WRITE SAME command */ unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */ unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */ unsigned skip_vpd_pages:1; /* do not read VPD pages */ @@ -364,8 +362,6 @@ extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries, struct scsi_sense_hdr *sshdr); extern int scsi_get_vpd_page(struct scsi_device *, u8 page, unsigned char *buf, int buf_len); -extern int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, - unsigned int len, unsigned char opcode); extern int scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state); extern struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type, diff --git a/trunk/include/sound/core.h b/trunk/include/sound/core.h index 93896ad1fcdd..bc056687f647 100644 --- a/trunk/include/sound/core.h +++ b/trunk/include/sound/core.h @@ -132,7 +132,6 @@ struct snd_card { int shutdown; /* this card is going down */ int free_on_last_close; /* free in context of file_release */ wait_queue_head_t shutdown_sleep; - atomic_t refcount; /* refcount for disconnection */ struct device *dev; /* device assigned to this card */ struct device *card_dev; /* cardX object for sysfs */ @@ -190,7 +189,6 @@ struct snd_minor { const struct file_operations *f_ops; /* file operations */ void *private_data; /* private data for f_ops->open */ struct device *dev; /* device for sysfs */ - struct snd_card *card_ptr; /* assigned card instance */ }; /* return a device pointer linked to each sound device as a parent */ @@ -297,7 +295,6 @@ int snd_card_info_done(void); int snd_component_add(struct snd_card *card, const char *component); int snd_card_file_add(struct snd_card *card, struct file *file); int snd_card_file_remove(struct snd_card *card, struct file *file); -void snd_card_unref(struct snd_card *card); #define snd_card_set_dev(card, devptr) ((card)->dev = (devptr)) diff --git a/trunk/include/trace/events/gfpflags.h b/trunk/include/trace/events/gfpflags.h index d6fd8e5b14b7..9391706e9254 100644 --- a/trunk/include/trace/events/gfpflags.h +++ b/trunk/include/trace/events/gfpflags.h @@ -36,7 +36,6 @@ {(unsigned long)__GFP_RECLAIMABLE, "GFP_RECLAIMABLE"}, \ {(unsigned long)__GFP_MOVABLE, "GFP_MOVABLE"}, \ {(unsigned long)__GFP_NOTRACK, "GFP_NOTRACK"}, \ - {(unsigned long)__GFP_NO_KSWAPD, "GFP_NO_KSWAPD"}, \ {(unsigned long)__GFP_OTHER_NODE, "GFP_OTHER_NODE"} \ ) : "GFP_NOWAIT" diff --git a/trunk/include/trace/events/xen.h b/trunk/include/trace/events/xen.h index d06b6da5c1e3..15ba03bdd7c6 100644 --- a/trunk/include/trace/events/xen.h +++ b/trunk/include/trace/events/xen.h @@ -377,14 +377,6 @@ DECLARE_EVENT_CLASS(xen_mmu_pgd, DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_pin); DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_unpin); -TRACE_EVENT(xen_mmu_flush_tlb_all, - TP_PROTO(int x), - TP_ARGS(x), - TP_STRUCT__entry(__array(char, x, 0)), - TP_fast_assign((void)x), - TP_printk("%s", "") - ); - TRACE_EVENT(xen_mmu_flush_tlb, TP_PROTO(int x), TP_ARGS(x), diff --git a/trunk/include/uapi/linux/Kbuild b/trunk/include/uapi/linux/Kbuild index 19e765fbfef7..e194387ef784 100644 --- a/trunk/include/uapi/linux/Kbuild +++ b/trunk/include/uapi/linux/Kbuild @@ -415,4 +415,3 @@ header-y += wireless.h header-y += x25.h header-y += xattr.h header-y += xfrm.h -header-y += hw_breakpoint.h diff --git a/trunk/include/uapi/linux/eventpoll.h b/trunk/include/uapi/linux/eventpoll.h index 2c267bcbb85c..8c99ce7202c5 100644 --- a/trunk/include/uapi/linux/eventpoll.h +++ b/trunk/include/uapi/linux/eventpoll.h @@ -25,6 +25,7 @@ #define EPOLL_CTL_ADD 1 #define EPOLL_CTL_DEL 2 #define EPOLL_CTL_MOD 3 +#define EPOLL_CTL_DISABLE 4 /* * Request the handling of system wakeup events so as to prevent system suspends diff --git a/trunk/include/uapi/linux/hw_breakpoint.h b/trunk/include/uapi/linux/hw_breakpoint.h deleted file mode 100644 index b04000a2296a..000000000000 --- a/trunk/include/uapi/linux/hw_breakpoint.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _UAPI_LINUX_HW_BREAKPOINT_H -#define _UAPI_LINUX_HW_BREAKPOINT_H - -enum { - HW_BREAKPOINT_LEN_1 = 1, - HW_BREAKPOINT_LEN_2 = 2, - HW_BREAKPOINT_LEN_4 = 4, - HW_BREAKPOINT_LEN_8 = 8, -}; - -enum { - HW_BREAKPOINT_EMPTY = 0, - HW_BREAKPOINT_R = 1, - HW_BREAKPOINT_W = 2, - HW_BREAKPOINT_RW = HW_BREAKPOINT_R | HW_BREAKPOINT_W, - HW_BREAKPOINT_X = 4, - HW_BREAKPOINT_INVALID = HW_BREAKPOINT_RW | HW_BREAKPOINT_X, -}; - -enum bp_type_idx { - TYPE_INST = 0, -#ifdef CONFIG_HAVE_MIXED_BREAKPOINTS_REGS - TYPE_DATA = 0, -#else - TYPE_DATA = 1, -#endif - TYPE_MAX -}; - -#endif /* _UAPI_LINUX_HW_BREAKPOINT_H */ diff --git a/trunk/include/uapi/linux/oom.h b/trunk/include/uapi/linux/oom.h index b29272d621ce..a49c4afc7060 100644 --- a/trunk/include/uapi/linux/oom.h +++ b/trunk/include/uapi/linux/oom.h @@ -8,13 +8,4 @@ #define OOM_SCORE_ADJ_MIN (-1000) #define OOM_SCORE_ADJ_MAX 1000 -/* - * /proc//oom_adj set to -17 protects from the oom killer for legacy - * purposes. - */ -#define OOM_DISABLE (-17) -/* inclusive */ -#define OOM_ADJUST_MIN (-16) -#define OOM_ADJUST_MAX 15 - #endif /* _UAPI__INCLUDE_LINUX_OOM_H */ diff --git a/trunk/include/uapi/linux/raid/Kbuild b/trunk/include/uapi/linux/raid/Kbuild index e2c3d25405d7..aafaa5aa54d4 100644 --- a/trunk/include/uapi/linux/raid/Kbuild +++ b/trunk/include/uapi/linux/raid/Kbuild @@ -1,3 +1 @@ # UAPI Header export list -header-y += md_p.h -header-y += md_u.h diff --git a/trunk/include/uapi/linux/raid/md_u.h b/trunk/include/uapi/linux/raid/md_u.h deleted file mode 100644 index 4133e744e4e6..000000000000 --- a/trunk/include/uapi/linux/raid/md_u.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - md_u.h : user <=> kernel API between Linux raidtools and RAID drivers - Copyright (C) 1998 Ingo Molnar - - 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, or (at your option) - any later version. - - You should have received a copy of the GNU General Public License - (for example /usr/src/linux/COPYING); if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef _UAPI_MD_U_H -#define _UAPI_MD_U_H - -/* - * Different major versions are not compatible. - * Different minor versions are only downward compatible. - * Different patchlevel versions are downward and upward compatible. - */ -#define MD_MAJOR_VERSION 0 -#define MD_MINOR_VERSION 90 -/* - * MD_PATCHLEVEL_VERSION indicates kernel functionality. - * >=1 means different superblock formats are selectable using SET_ARRAY_INFO - * and major_version/minor_version accordingly - * >=2 means that Internal bitmaps are supported by setting MD_SB_BITMAP_PRESENT - * in the super status byte - * >=3 means that bitmap superblock version 4 is supported, which uses - * little-ending representation rather than host-endian - */ -#define MD_PATCHLEVEL_VERSION 3 - -/* ioctls */ - -/* status */ -#define RAID_VERSION _IOR (MD_MAJOR, 0x10, mdu_version_t) -#define GET_ARRAY_INFO _IOR (MD_MAJOR, 0x11, mdu_array_info_t) -#define GET_DISK_INFO _IOR (MD_MAJOR, 0x12, mdu_disk_info_t) -#define PRINT_RAID_DEBUG _IO (MD_MAJOR, 0x13) -#define RAID_AUTORUN _IO (MD_MAJOR, 0x14) -#define GET_BITMAP_FILE _IOR (MD_MAJOR, 0x15, mdu_bitmap_file_t) - -/* configuration */ -#define CLEAR_ARRAY _IO (MD_MAJOR, 0x20) -#define ADD_NEW_DISK _IOW (MD_MAJOR, 0x21, mdu_disk_info_t) -#define HOT_REMOVE_DISK _IO (MD_MAJOR, 0x22) -#define SET_ARRAY_INFO _IOW (MD_MAJOR, 0x23, mdu_array_info_t) -#define SET_DISK_INFO _IO (MD_MAJOR, 0x24) -#define WRITE_RAID_INFO _IO (MD_MAJOR, 0x25) -#define UNPROTECT_ARRAY _IO (MD_MAJOR, 0x26) -#define PROTECT_ARRAY _IO (MD_MAJOR, 0x27) -#define HOT_ADD_DISK _IO (MD_MAJOR, 0x28) -#define SET_DISK_FAULTY _IO (MD_MAJOR, 0x29) -#define HOT_GENERATE_ERROR _IO (MD_MAJOR, 0x2a) -#define SET_BITMAP_FILE _IOW (MD_MAJOR, 0x2b, int) - -/* usage */ -#define RUN_ARRAY _IOW (MD_MAJOR, 0x30, mdu_param_t) -/* 0x31 was START_ARRAY */ -#define STOP_ARRAY _IO (MD_MAJOR, 0x32) -#define STOP_ARRAY_RO _IO (MD_MAJOR, 0x33) -#define RESTART_ARRAY_RW _IO (MD_MAJOR, 0x34) - -/* 63 partitions with the alternate major number (mdp) */ -#define MdpMinorShift 6 - -typedef struct mdu_version_s { - int major; - int minor; - int patchlevel; -} mdu_version_t; - -typedef struct mdu_array_info_s { - /* - * Generic constant information - */ - int major_version; - int minor_version; - int patch_version; - int ctime; - int level; - int size; - int nr_disks; - int raid_disks; - int md_minor; - int not_persistent; - - /* - * Generic state information - */ - int utime; /* 0 Superblock update time */ - int state; /* 1 State bits (clean, ...) */ - int active_disks; /* 2 Number of currently active disks */ - int working_disks; /* 3 Number of working disks */ - int failed_disks; /* 4 Number of failed disks */ - int spare_disks; /* 5 Number of spare disks */ - - /* - * Personality information - */ - int layout; /* 0 the array's physical layout */ - int chunk_size; /* 1 chunk size in bytes */ - -} mdu_array_info_t; - -/* non-obvious values for 'level' */ -#define LEVEL_MULTIPATH (-4) -#define LEVEL_LINEAR (-1) -#define LEVEL_FAULTY (-5) - -/* we need a value for 'no level specified' and 0 - * means 'raid0', so we need something else. This is - * for internal use only - */ -#define LEVEL_NONE (-1000000) - -typedef struct mdu_disk_info_s { - /* - * configuration/status of one particular disk - */ - int number; - int major; - int minor; - int raid_disk; - int state; - -} mdu_disk_info_t; - -typedef struct mdu_start_info_s { - /* - * configuration/status of one particular disk - */ - int major; - int minor; - int raid_disk; - int state; - -} mdu_start_info_t; - -typedef struct mdu_bitmap_file_s -{ - char pathname[4096]; -} mdu_bitmap_file_t; - -typedef struct mdu_param_s -{ - int personality; /* 1,2,3,4 */ - int chunk_size; /* in bytes */ - int max_fault; /* unused for now */ -} mdu_param_t; - -#endif /* _UAPI_MD_U_H */ diff --git a/trunk/include/uapi/linux/tcp.h b/trunk/include/uapi/linux/tcp.h index e962faa5ab0d..c4b89a5cb7df 100644 --- a/trunk/include/uapi/linux/tcp.h +++ b/trunk/include/uapi/linux/tcp.h @@ -130,7 +130,6 @@ enum { #define TCPI_OPT_WSCALE 4 #define TCPI_OPT_ECN 8 /* ECN was negociated at TCP session init */ #define TCPI_OPT_ECN_SEEN 16 /* we received at least one packet with ECT */ -#define TCPI_OPT_SYN_DATA 32 /* SYN-ACK acked data in SYN sent or rcvd */ enum tcp_ca_state { TCP_CA_Open = 0, diff --git a/trunk/include/xen/grant_table.h b/trunk/include/xen/grant_table.h index 694dcaf266e6..aecee9d112cb 100644 --- a/trunk/include/xen/grant_table.h +++ b/trunk/include/xen/grant_table.h @@ -170,7 +170,7 @@ gnttab_set_unmap_op(struct gnttab_unmap_grant_ref *unmap, phys_addr_t addr, unmap->dev_bus_addr = 0; } -int arch_gnttab_map_shared(xen_pfn_t *frames, unsigned long nr_gframes, +int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes, unsigned long max_nr_gframes, void **__shared); int arch_gnttab_map_status(uint64_t *frames, unsigned long nr_gframes, diff --git a/trunk/include/xen/hvm.h b/trunk/include/xen/hvm.h index 13e43e41637d..b193fa2f9fdd 100644 --- a/trunk/include/xen/hvm.h +++ b/trunk/include/xen/hvm.h @@ -5,36 +5,6 @@ #include #include -static const char *param_name(int op) -{ -#define PARAM(x) [HVM_PARAM_##x] = #x - static const char *const names[] = { - PARAM(CALLBACK_IRQ), - PARAM(STORE_PFN), - PARAM(STORE_EVTCHN), - PARAM(PAE_ENABLED), - PARAM(IOREQ_PFN), - PARAM(BUFIOREQ_PFN), - PARAM(TIMER_MODE), - PARAM(HPET_ENABLED), - PARAM(IDENT_PT), - PARAM(DM_DOMAIN), - PARAM(ACPI_S_STATE), - PARAM(VM86_TSS), - PARAM(VPT_ALIGN), - PARAM(CONSOLE_PFN), - PARAM(CONSOLE_EVTCHN), - }; -#undef PARAM - - if (op >= ARRAY_SIZE(names)) - return "unknown"; - - if (!names[op]) - return "reserved"; - - return names[op]; -} static inline int hvm_get_parameter(int idx, uint64_t *value) { struct xen_hvm_param xhv; @@ -44,8 +14,8 @@ static inline int hvm_get_parameter(int idx, uint64_t *value) xhv.index = idx; r = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv); if (r < 0) { - printk(KERN_ERR "Cannot get hvm parameter %s (%d): %d!\n", - param_name(idx), idx, r); + printk(KERN_ERR "Cannot get hvm parameter %d: %d!\n", + idx, r); return r; } *value = xhv.value; diff --git a/trunk/include/xen/interface/grant_table.h b/trunk/include/xen/interface/grant_table.h index e40fae9bf11a..f9f8b975ae74 100644 --- a/trunk/include/xen/interface/grant_table.h +++ b/trunk/include/xen/interface/grant_table.h @@ -310,7 +310,7 @@ struct gnttab_setup_table { uint32_t nr_frames; /* OUT parameters. */ int16_t status; /* GNTST_* */ - GUEST_HANDLE(xen_pfn_t) frame_list; + GUEST_HANDLE(ulong) frame_list; }; DEFINE_GUEST_HANDLE_STRUCT(gnttab_setup_table); diff --git a/trunk/include/xen/interface/memory.h b/trunk/include/xen/interface/memory.h index 90712e2072d5..b66d04ce6957 100644 --- a/trunk/include/xen/interface/memory.h +++ b/trunk/include/xen/interface/memory.h @@ -179,8 +179,28 @@ struct xen_add_to_physmap { }; DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_physmap); -/*** REMOVED ***/ -/*#define XENMEM_translate_gpfn_list 8*/ +/* + * Translates a list of domain-specific GPFNs into MFNs. Returns a -ve error + * code on failure. This call only works for auto-translated guests. + */ +#define XENMEM_translate_gpfn_list 8 +struct xen_translate_gpfn_list { + /* Which domain to translate for? */ + domid_t domid; + + /* Length of list. */ + xen_ulong_t nr_gpfns; + + /* List of GPFNs to translate. */ + GUEST_HANDLE(ulong) gpfn_list; + + /* + * Output list to contain MFN translations. May be the same as the input + * list (in which case each input GPFN is overwritten with the output MFN). + */ + GUEST_HANDLE(ulong) mfn_list; +}; +DEFINE_GUEST_HANDLE_STRUCT(xen_translate_gpfn_list); /* * Returns the pseudo-physical memory map as it was when the domain diff --git a/trunk/init/main.c b/trunk/init/main.c index e33e09df3cbc..9cf77ab138a6 100644 --- a/trunk/init/main.c +++ b/trunk/init/main.c @@ -442,11 +442,9 @@ void __init __weak smp_setup_processor_id(void) { } -# if THREAD_SIZE >= PAGE_SIZE void __init __weak thread_info_cache_init(void) { } -#endif /* * Set up kernel memory allocators diff --git a/trunk/kernel/Makefile b/trunk/kernel/Makefile index 86e3285ae7e5..0dfeca4324ee 100644 --- a/trunk/kernel/Makefile +++ b/trunk/kernel/Makefile @@ -174,8 +174,10 @@ signing_key.priv signing_key.x509: x509.genkey @echo "###" @echo "### If this takes a long time, you might wish to run rngd in the" @echo "### background to keep the supply of entropy topped up. It" - @echo "### needs to be run as root, and uses a hardware random" - @echo "### number generator if one is available." + @echo "### needs to be run as root, and should use a hardware random" + @echo "### number generator if one is available, eg:" + @echo "###" + @echo "### rngd -r /dev/hwrandom" @echo "###" openssl req -new -nodes -utf8 $(sign_key_with_hash) -days 36500 -batch \ -x509 -config x509.genkey \ diff --git a/trunk/kernel/cgroup.c b/trunk/kernel/cgroup.c index f24f724620dd..13774b3b39aa 100644 --- a/trunk/kernel/cgroup.c +++ b/trunk/kernel/cgroup.c @@ -1962,8 +1962,9 @@ static void cgroup_task_migrate(struct cgroup *cgrp, struct cgroup *oldcgrp, * trading it for newcg is protected by cgroup_mutex, we're safe to drop * it here; it will be freed under RCU. */ - set_bit(CGRP_RELEASABLE, &oldcgrp->flags); put_css_set(oldcg); + + set_bit(CGRP_RELEASABLE, &oldcgrp->flags); } /** @@ -4814,20 +4815,31 @@ static const struct file_operations proc_cgroupstats_operations = { * * A pointer to the shared css_set was automatically copied in * fork.c by dup_task_struct(). However, we ignore that copy, since - * it was not made under the protection of RCU or cgroup_mutex, so - * might no longer be a valid cgroup pointer. cgroup_attach_task() might - * have already changed current->cgroups, allowing the previously - * referenced cgroup group to be removed and freed. + * it was not made under the protection of RCU, cgroup_mutex or + * threadgroup_change_begin(), so it might no longer be a valid + * cgroup pointer. cgroup_attach_task() might have already changed + * current->cgroups, allowing the previously referenced cgroup + * group to be removed and freed. + * + * Outside the pointer validity we also need to process the css_set + * inheritance between threadgoup_change_begin() and + * threadgoup_change_end(), this way there is no leak in any process + * wide migration performed by cgroup_attach_proc() that could otherwise + * miss a thread because it is too early or too late in the fork stage. * * At the point that cgroup_fork() is called, 'current' is the parent * task, and the passed argument 'child' points to the child task. */ void cgroup_fork(struct task_struct *child) { - task_lock(current); + /* + * We don't need to task_lock() current because current->cgroups + * can't be changed concurrently here. The parent obviously hasn't + * exited and called cgroup_exit(), and we are synchronized against + * cgroup migration through threadgroup_change_begin(). + */ child->cgroups = current->cgroups; get_css_set(child->cgroups); - task_unlock(current); INIT_LIST_HEAD(&child->cg_list); } @@ -4883,10 +4895,19 @@ void cgroup_post_fork(struct task_struct *child) */ if (use_task_css_set_links) { write_lock(&css_set_lock); - task_lock(child); - if (list_empty(&child->cg_list)) + if (list_empty(&child->cg_list)) { + /* + * It's safe to use child->cgroups without task_lock() + * here because we are protected through + * threadgroup_change_begin() against concurrent + * css_set change in cgroup_task_migrate(). Also + * the task can't exit at that point until + * wake_up_new_task() is called, so we are protected + * against cgroup_exit() setting child->cgroup to + * init_css_set. + */ list_add(&child->cg_list, &child->cgroups->tasks); - task_unlock(child); + } write_unlock(&css_set_lock); } } diff --git a/trunk/kernel/events/hw_breakpoint.c b/trunk/kernel/events/hw_breakpoint.c index fe8a916507ed..9a7b487c6fe2 100644 --- a/trunk/kernel/events/hw_breakpoint.c +++ b/trunk/kernel/events/hw_breakpoint.c @@ -111,16 +111,14 @@ static unsigned int max_task_bp_pinned(int cpu, enum bp_type_idx type) * Count the number of breakpoints of the same type and same task. * The given event must be not on the list. */ -static int task_bp_pinned(int cpu, struct perf_event *bp, enum bp_type_idx type) +static int task_bp_pinned(struct perf_event *bp, enum bp_type_idx type) { struct task_struct *tsk = bp->hw.bp_target; struct perf_event *iter; int count = 0; list_for_each_entry(iter, &bp_task_head, hw.bp_list) { - if (iter->hw.bp_target == tsk && - find_slot_idx(iter) == type && - cpu == iter->cpu) + if (iter->hw.bp_target == tsk && find_slot_idx(iter) == type) count += hw_breakpoint_weight(iter); } @@ -143,7 +141,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp, if (!tsk) slots->pinned += max_task_bp_pinned(cpu, type); else - slots->pinned += task_bp_pinned(cpu, bp, type); + slots->pinned += task_bp_pinned(bp, type); slots->flexible = per_cpu(nr_bp_flexible[type], cpu); return; @@ -156,7 +154,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp, if (!tsk) nr += max_task_bp_pinned(cpu, type); else - nr += task_bp_pinned(cpu, bp, type); + nr += task_bp_pinned(bp, type); if (nr > slots->pinned) slots->pinned = nr; @@ -190,7 +188,7 @@ static void toggle_bp_task_slot(struct perf_event *bp, int cpu, bool enable, int old_idx = 0; int idx = 0; - old_count = task_bp_pinned(cpu, bp, type); + old_count = task_bp_pinned(bp, type); old_idx = old_count - 1; idx = old_idx + weight; diff --git a/trunk/kernel/events/uprobes.c b/trunk/kernel/events/uprobes.c index 5cc4e7e42e68..98256bc71ee1 100644 --- a/trunk/kernel/events/uprobes.c +++ b/trunk/kernel/events/uprobes.c @@ -78,23 +78,15 @@ static struct mutex uprobes_mmap_mutex[UPROBES_HASH_SZ]; */ static atomic_t uprobe_events = ATOMIC_INIT(0); -/* Have a copy of original instruction */ -#define UPROBE_COPY_INSN 0 -/* Dont run handlers when first register/ last unregister in progress*/ -#define UPROBE_RUN_HANDLER 1 -/* Can skip singlestep */ -#define UPROBE_SKIP_SSTEP 2 - struct uprobe { struct rb_node rb_node; /* node in the rb tree */ atomic_t ref; struct rw_semaphore consumer_rwsem; - struct mutex copy_mutex; /* TODO: kill me and UPROBE_COPY_INSN */ struct list_head pending_list; struct uprobe_consumer *consumers; struct inode *inode; /* Also hold a ref to inode */ loff_t offset; - unsigned long flags; + int flags; struct arch_uprobe arch; }; @@ -108,12 +100,17 @@ struct uprobe { */ static bool valid_vma(struct vm_area_struct *vma, bool is_register) { - vm_flags_t flags = VM_HUGETLB | VM_MAYEXEC | VM_SHARED; + if (!vma->vm_file) + return false; + + if (!is_register) + return true; - if (is_register) - flags |= VM_WRITE; + if ((vma->vm_flags & (VM_HUGETLB|VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)) + == (VM_READ|VM_EXEC)) + return true; - return vma->vm_file && (vma->vm_flags & flags) == VM_MAYEXEC; + return false; } static unsigned long offset_to_vaddr(struct vm_area_struct *vma, loff_t offset) @@ -196,44 +193,19 @@ bool __weak is_swbp_insn(uprobe_opcode_t *insn) return *insn == UPROBE_SWBP_INSN; } -static void copy_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t *opcode) -{ - void *kaddr = kmap_atomic(page); - memcpy(opcode, kaddr + (vaddr & ~PAGE_MASK), UPROBE_SWBP_INSN_SIZE); - kunmap_atomic(kaddr); -} - -static int verify_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t *new_opcode) -{ - uprobe_opcode_t old_opcode; - bool is_swbp; - - copy_opcode(page, vaddr, &old_opcode); - is_swbp = is_swbp_insn(&old_opcode); - - if (is_swbp_insn(new_opcode)) { - if (is_swbp) /* register: already installed? */ - return 0; - } else { - if (!is_swbp) /* unregister: was it changed by us? */ - return 0; - } - - return 1; -} - /* * NOTE: * Expect the breakpoint instruction to be the smallest size instruction for * the architecture. If an arch has variable length instruction and the * breakpoint instruction is not of the smallest length instruction - * supported by that architecture then we need to modify is_swbp_at_addr and + * supported by that architecture then we need to modify read_opcode / * write_opcode accordingly. This would never be a problem for archs that * have fixed length instructions. */ /* * write_opcode - write the opcode at a given virtual address. + * @auprobe: arch breakpointing information. * @mm: the probed process address space. * @vaddr: the virtual address to store the opcode. * @opcode: opcode to be written at @vaddr. @@ -244,8 +216,8 @@ static int verify_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t * For mm @mm, write the opcode at @vaddr. * Return 0 (success) or a negative errno. */ -static int write_opcode(struct mm_struct *mm, unsigned long vaddr, - uprobe_opcode_t opcode) +static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, + unsigned long vaddr, uprobe_opcode_t opcode) { struct page *old_page, *new_page; void *vaddr_old, *vaddr_new; @@ -254,14 +226,10 @@ static int write_opcode(struct mm_struct *mm, unsigned long vaddr, retry: /* Read the page with vaddr into memory */ - ret = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &old_page, &vma); + ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &old_page, &vma); if (ret <= 0) return ret; - ret = verify_opcode(old_page, vaddr, &opcode); - if (ret <= 0) - goto put_old; - ret = -ENOMEM; new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr); if (!new_page) @@ -295,6 +263,63 @@ static int write_opcode(struct mm_struct *mm, unsigned long vaddr, return ret; } +/** + * read_opcode - read the opcode at a given virtual address. + * @mm: the probed process address space. + * @vaddr: the virtual address to read the opcode. + * @opcode: location to store the read opcode. + * + * Called with mm->mmap_sem held (for read and with a reference to + * mm. + * + * For mm @mm, read the opcode at @vaddr and store it in @opcode. + * Return 0 (success) or a negative errno. + */ +static int read_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t *opcode) +{ + struct page *page; + void *vaddr_new; + int ret; + + ret = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &page, NULL); + if (ret <= 0) + return ret; + + vaddr_new = kmap_atomic(page); + vaddr &= ~PAGE_MASK; + memcpy(opcode, vaddr_new + vaddr, UPROBE_SWBP_INSN_SIZE); + kunmap_atomic(vaddr_new); + + put_page(page); + + return 0; +} + +static int is_swbp_at_addr(struct mm_struct *mm, unsigned long vaddr) +{ + uprobe_opcode_t opcode; + int result; + + if (current->mm == mm) { + pagefault_disable(); + result = __copy_from_user_inatomic(&opcode, (void __user*)vaddr, + sizeof(opcode)); + pagefault_enable(); + + if (likely(result == 0)) + goto out; + } + + result = read_opcode(mm, vaddr, &opcode); + if (result) + return result; +out: + if (is_swbp_insn(&opcode)) + return 1; + + return 0; +} + /** * set_swbp - store breakpoint at a given address. * @auprobe: arch specific probepoint information. @@ -306,7 +331,18 @@ static int write_opcode(struct mm_struct *mm, unsigned long vaddr, */ int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr) { - return write_opcode(mm, vaddr, UPROBE_SWBP_INSN); + int result; + /* + * See the comment near uprobes_hash(). + */ + result = is_swbp_at_addr(mm, vaddr); + if (result == 1) + return 0; + + if (result) + return result; + + return write_opcode(auprobe, mm, vaddr, UPROBE_SWBP_INSN); } /** @@ -321,7 +357,16 @@ int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned int __weak set_orig_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr) { - return write_opcode(mm, vaddr, *(uprobe_opcode_t *)auprobe->insn); + int result; + + result = is_swbp_at_addr(mm, vaddr); + if (!result) + return -EINVAL; + + if (result != 1) + return result; + + return write_opcode(auprobe, mm, vaddr, *(uprobe_opcode_t *)auprobe->insn); } static int match_uprobe(struct uprobe *l, struct uprobe *r) @@ -428,7 +473,7 @@ static struct uprobe *insert_uprobe(struct uprobe *uprobe) spin_unlock(&uprobes_treelock); /* For now assume that the instruction need not be single-stepped */ - __set_bit(UPROBE_SKIP_SSTEP, &uprobe->flags); + uprobe->flags |= UPROBE_SKIP_SSTEP; return u; } @@ -450,7 +495,6 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset) uprobe->inode = igrab(inode); uprobe->offset = offset; init_rwsem(&uprobe->consumer_rwsem); - mutex_init(&uprobe->copy_mutex); /* add to uprobes_tree, sorted on inode:offset */ cur_uprobe = insert_uprobe(uprobe); @@ -471,7 +515,7 @@ static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs) { struct uprobe_consumer *uc; - if (!test_bit(UPROBE_RUN_HANDLER, &uprobe->flags)) + if (!(uprobe->flags & UPROBE_RUN_HANDLER)) return; down_read(&uprobe->consumer_rwsem); @@ -577,43 +621,29 @@ static int copy_insn(struct uprobe *uprobe, struct file *filp) return __copy_insn(mapping, filp, uprobe->arch.insn, bytes, uprobe->offset); } -static int prepare_uprobe(struct uprobe *uprobe, struct file *file, - struct mm_struct *mm, unsigned long vaddr) -{ - int ret = 0; - - if (test_bit(UPROBE_COPY_INSN, &uprobe->flags)) - return ret; - - mutex_lock(&uprobe->copy_mutex); - if (test_bit(UPROBE_COPY_INSN, &uprobe->flags)) - goto out; - - ret = copy_insn(uprobe, file); - if (ret) - goto out; - - ret = -ENOTSUPP; - if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn)) - goto out; - - ret = arch_uprobe_analyze_insn(&uprobe->arch, mm, vaddr); - if (ret) - goto out; - - /* write_opcode() assumes we don't cross page boundary */ - BUG_ON((uprobe->offset & ~PAGE_MASK) + - UPROBE_SWBP_INSN_SIZE > PAGE_SIZE); - - smp_wmb(); /* pairs with rmb() in find_active_uprobe() */ - set_bit(UPROBE_COPY_INSN, &uprobe->flags); - - out: - mutex_unlock(&uprobe->copy_mutex); - - return ret; -} - +/* + * How mm->uprobes_state.count gets updated + * uprobe_mmap() increments the count if + * - it successfully adds a breakpoint. + * - it cannot add a breakpoint, but sees that there is a underlying + * breakpoint (via a is_swbp_at_addr()). + * + * uprobe_munmap() decrements the count if + * - it sees a underlying breakpoint, (via is_swbp_at_addr) + * (Subsequent uprobe_unregister wouldnt find the breakpoint + * unless a uprobe_mmap kicks in, since the old vma would be + * dropped just after uprobe_munmap.) + * + * uprobe_register increments the count if: + * - it successfully adds a breakpoint. + * + * uprobe_unregister decrements the count if: + * - it sees a underlying breakpoint and removes successfully. + * (via is_swbp_at_addr) + * (Subsequent uprobe_munmap wouldnt find the breakpoint + * since there is no underlying breakpoint after the + * breakpoint removal.) + */ static int install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, struct vm_area_struct *vma, unsigned long vaddr) @@ -631,9 +661,24 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, if (!uprobe->consumers) return 0; - ret = prepare_uprobe(uprobe, vma->vm_file, mm, vaddr); - if (ret) - return ret; + if (!(uprobe->flags & UPROBE_COPY_INSN)) { + ret = copy_insn(uprobe, vma->vm_file); + if (ret) + return ret; + + if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn)) + return -ENOTSUPP; + + ret = arch_uprobe_analyze_insn(&uprobe->arch, mm, vaddr); + if (ret) + return ret; + + /* write_opcode() assumes we don't cross page boundary */ + BUG_ON((uprobe->offset & ~PAGE_MASK) + + UPROBE_SWBP_INSN_SIZE > PAGE_SIZE); + + uprobe->flags |= UPROBE_COPY_INSN; + } /* * set MMF_HAS_UPROBES in advance for uprobe_pre_sstep_notifier(), @@ -652,15 +697,15 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, return ret; } -static int +static void remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, unsigned long vaddr) { /* can happen if uprobe_register() fails */ if (!test_bit(MMF_HAS_UPROBES, &mm->flags)) - return 0; + return; set_bit(MMF_RECALC_UPROBES, &mm->flags); - return set_orig_insn(&uprobe->arch, mm, vaddr); + set_orig_insn(&uprobe->arch, mm, vaddr); } /* @@ -775,7 +820,7 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register) struct mm_struct *mm = info->mm; struct vm_area_struct *vma; - if (err && is_register) + if (err) goto free; down_write(&mm->mmap_sem); @@ -791,7 +836,7 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register) if (is_register) err = install_breakpoint(uprobe, mm, vma, info->vaddr); else - err |= remove_breakpoint(uprobe, mm, info->vaddr); + remove_breakpoint(uprobe, mm, info->vaddr); unlock: up_write(&mm->mmap_sem); @@ -848,15 +893,13 @@ int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer * mutex_lock(uprobes_hash(inode)); uprobe = alloc_uprobe(inode, offset); - if (!uprobe) { - ret = -ENOMEM; - } else if (!consumer_add(uprobe, uc)) { + if (uprobe && !consumer_add(uprobe, uc)) { ret = __uprobe_register(uprobe); if (ret) { uprobe->consumers = NULL; __uprobe_unregister(uprobe); } else { - set_bit(UPROBE_RUN_HANDLER, &uprobe->flags); + uprobe->flags |= UPROBE_RUN_HANDLER; } } @@ -889,7 +932,7 @@ void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consume if (consumer_del(uprobe, uc)) { if (!uprobe->consumers) { __uprobe_unregister(uprobe); - clear_bit(UPROBE_RUN_HANDLER, &uprobe->flags); + uprobe->flags &= ~UPROBE_RUN_HANDLER; } } @@ -1350,11 +1393,10 @@ bool uprobe_deny_signal(void) */ static bool can_skip_sstep(struct uprobe *uprobe, struct pt_regs *regs) { - if (test_bit(UPROBE_SKIP_SSTEP, &uprobe->flags)) { - if (arch_uprobe_skip_sstep(&uprobe->arch, regs)) - return true; - clear_bit(UPROBE_SKIP_SSTEP, &uprobe->flags); - } + if (arch_uprobe_skip_sstep(&uprobe->arch, regs)) + return true; + + uprobe->flags &= ~UPROBE_SKIP_SSTEP; return false; } @@ -1377,30 +1419,6 @@ static void mmf_recalc_uprobes(struct mm_struct *mm) clear_bit(MMF_HAS_UPROBES, &mm->flags); } -static int is_swbp_at_addr(struct mm_struct *mm, unsigned long vaddr) -{ - struct page *page; - uprobe_opcode_t opcode; - int result; - - pagefault_disable(); - result = __copy_from_user_inatomic(&opcode, (void __user*)vaddr, - sizeof(opcode)); - pagefault_enable(); - - if (likely(result == 0)) - goto out; - - result = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &page, NULL); - if (result < 0) - return result; - - copy_opcode(page, vaddr, &opcode); - put_page(page); - out: - return is_swbp_insn(&opcode); -} - static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp) { struct mm_struct *mm = current->mm; @@ -1471,41 +1489,38 @@ static void handle_swbp(struct pt_regs *regs) } return; } - /* - * TODO: move copy_insn/etc into _register and remove this hack. - * After we hit the bp, _unregister + _register can install the - * new and not-yet-analyzed uprobe at the same address, restart. - */ - smp_rmb(); /* pairs with wmb() in install_breakpoint() */ - if (unlikely(!test_bit(UPROBE_COPY_INSN, &uprobe->flags))) - goto restart; utask = current->utask; if (!utask) { utask = add_utask(); /* Cannot allocate; re-execute the instruction. */ if (!utask) - goto restart; + goto cleanup_ret; } - + utask->active_uprobe = uprobe; handler_chain(uprobe, regs); - if (can_skip_sstep(uprobe, regs)) - goto out; + if (uprobe->flags & UPROBE_SKIP_SSTEP && can_skip_sstep(uprobe, regs)) + goto cleanup_ret; + utask->state = UTASK_SSTEP; if (!pre_ssout(uprobe, regs, bp_vaddr)) { arch_uprobe_enable_step(&uprobe->arch); - utask->active_uprobe = uprobe; - utask->state = UTASK_SSTEP; return; } -restart: - /* - * cannot singlestep; cannot skip instruction; - * re-execute the instruction. - */ - instruction_pointer_set(regs, bp_vaddr); -out: +cleanup_ret: + if (utask) { + utask->active_uprobe = NULL; + utask->state = UTASK_RUNNING; + } + if (!(uprobe->flags & UPROBE_SKIP_SSTEP)) + + /* + * cannot singlestep; cannot skip instruction; + * re-execute the instruction. + */ + instruction_pointer_set(regs, bp_vaddr); + put_uprobe(uprobe); } @@ -1537,12 +1552,13 @@ static void handle_singlestep(struct uprobe_task *utask, struct pt_regs *regs) } /* - * On breakpoint hit, breakpoint notifier sets the TIF_UPROBE flag and - * allows the thread to return from interrupt. After that handle_swbp() - * sets utask->active_uprobe. + * On breakpoint hit, breakpoint notifier sets the TIF_UPROBE flag. (and on + * subsequent probe hits on the thread sets the state to UTASK_BP_HIT) and + * allows the thread to return from interrupt. * - * On singlestep exception, singlestep notifier sets the TIF_UPROBE flag - * and allows the thread to return from interrupt. + * On singlestep exception, singlestep notifier sets the TIF_UPROBE flag and + * also sets the state to UTASK_SSTEP_ACK and allows the thread to return from + * interrupt. * * While returning to userspace, thread notices the TIF_UPROBE flag and calls * uprobe_notify_resume(). @@ -1551,13 +1567,11 @@ void uprobe_notify_resume(struct pt_regs *regs) { struct uprobe_task *utask; - clear_thread_flag(TIF_UPROBE); - utask = current->utask; - if (utask && utask->active_uprobe) - handle_singlestep(utask, regs); - else + if (!utask || utask->state == UTASK_BP_HIT) handle_swbp(regs); + else + handle_singlestep(utask, regs); } /* @@ -1566,10 +1580,17 @@ void uprobe_notify_resume(struct pt_regs *regs) */ int uprobe_pre_sstep_notifier(struct pt_regs *regs) { + struct uprobe_task *utask; + if (!current->mm || !test_bit(MMF_HAS_UPROBES, ¤t->mm->flags)) return 0; + utask = current->utask; + if (utask) + utask->state = UTASK_BP_HIT; + set_thread_flag(TIF_UPROBE); + return 1; } diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index 19eb089ca003..3717e7b306e0 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -716,7 +716,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, struct futex_pi_state **ps, struct task_struct *task, int set_waiters) { - int lock_taken, ret, force_take = 0; + int lock_taken, ret, ownerdied = 0; u32 uval, newval, curval, vpid = task_pid_vnr(task); retry: @@ -755,15 +755,17 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, newval = curval | FUTEX_WAITERS; /* - * Should we force take the futex? See below. + * There are two cases, where a futex might have no owner (the + * owner TID is 0): OWNER_DIED. We take over the futex in this + * case. We also do an unconditional take over, when the owner + * of the futex died. + * + * This is safe as we are protected by the hash bucket lock ! */ - if (unlikely(force_take)) { - /* - * Keep the OWNER_DIED and the WAITERS bit and set the - * new TID value. - */ + if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) { + /* Keep the OWNER_DIED bit */ newval = (curval & ~FUTEX_TID_MASK) | vpid; - force_take = 0; + ownerdied = 0; lock_taken = 1; } @@ -773,7 +775,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, goto retry; /* - * We took the lock due to forced take over. + * We took the lock due to owner died take over. */ if (unlikely(lock_taken)) return 1; @@ -788,25 +790,20 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, switch (ret) { case -ESRCH: /* - * We failed to find an owner for this - * futex. So we have no pi_state to block - * on. This can happen in two cases: - * - * 1) The owner died - * 2) A stale FUTEX_WAITERS bit - * - * Re-read the futex value. + * No owner found for this futex. Check if the + * OWNER_DIED bit is set to figure out whether + * this is a robust futex or not. */ if (get_futex_value_locked(&curval, uaddr)) return -EFAULT; /* - * If the owner died or we have a stale - * WAITERS bit the owner TID in the user space - * futex is 0. + * We simply start over in case of a robust + * futex. The code above will take the futex + * and return happy. */ - if (!(curval & FUTEX_TID_MASK)) { - force_take = 1; + if (curval & FUTEX_OWNER_DIED) { + ownerdied = 1; goto retry; } default: @@ -843,9 +840,6 @@ static void wake_futex(struct futex_q *q) { struct task_struct *p = q->task; - if (WARN(q->pi_state || q->rt_waiter, "refusing to wake PI futex\n")) - return; - /* * We set q->lock_ptr = NULL _before_ we wake up the task. If * a non-futex wake up happens on another CPU then the task @@ -1081,10 +1075,6 @@ futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2, plist_for_each_entry_safe(this, next, head, list) { if (match_futex (&this->key, &key1)) { - if (this->pi_state || this->rt_waiter) { - ret = -EINVAL; - goto out_unlock; - } wake_futex(this); if (++ret >= nr_wake) break; @@ -1097,10 +1087,6 @@ futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2, op_ret = 0; plist_for_each_entry_safe(this, next, head, list) { if (match_futex (&this->key, &key2)) { - if (this->pi_state || this->rt_waiter) { - ret = -EINVAL; - goto out_unlock; - } wake_futex(this); if (++op_ret >= nr_wake2) break; @@ -1109,7 +1095,6 @@ futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2, ret += op_ret; } -out_unlock: double_unlock_hb(hb1, hb2); out_put_keys: put_futex_key(&key2); @@ -1399,13 +1384,9 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags, /* * FUTEX_WAIT_REQEUE_PI and FUTEX_CMP_REQUEUE_PI should always * be paired with each other and no other futex ops. - * - * We should never be requeueing a futex_q with a pi_state, - * which is awaiting a futex_unlock_pi(). */ if ((requeue_pi && !this->rt_waiter) || - (!requeue_pi && this->rt_waiter) || - this->pi_state) { + (!requeue_pi && this->rt_waiter)) { ret = -EINVAL; break; } diff --git a/trunk/kernel/irq/irqdomain.c b/trunk/kernel/irq/irqdomain.c index 96f3a1d9c379..4e69e24d3d7d 100644 --- a/trunk/kernel/irq/irqdomain.c +++ b/trunk/kernel/irq/irqdomain.c @@ -177,8 +177,8 @@ struct irq_domain *irq_domain_add_simple(struct device_node *of_node, irq_base = irq_alloc_descs(first_irq, first_irq, size, of_node_to_nid(of_node)); if (irq_base < 0) { - pr_info("Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n", - first_irq); + WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n", + first_irq); irq_base = first_irq; } } else diff --git a/trunk/kernel/modsign_pubkey.c b/trunk/kernel/modsign_pubkey.c index 767e559dfb10..4646eb2c3820 100644 --- a/trunk/kernel/modsign_pubkey.c +++ b/trunk/kernel/modsign_pubkey.c @@ -21,10 +21,10 @@ struct key *modsign_keyring; extern __initdata const u8 modsign_certificate_list[]; extern __initdata const u8 modsign_certificate_list_end[]; asm(".section .init.data,\"aw\"\n" - SYMBOL_PREFIX "modsign_certificate_list:\n" + "modsign_certificate_list:\n" ".incbin \"signing_key.x509\"\n" ".incbin \"extra_certificates\"\n" - SYMBOL_PREFIX "modsign_certificate_list_end:" + "modsign_certificate_list_end:" ); /* diff --git a/trunk/kernel/module.c b/trunk/kernel/module.c index 6e48c3a43599..6085f5ef88ea 100644 --- a/trunk/kernel/module.c +++ b/trunk/kernel/module.c @@ -2293,17 +2293,12 @@ static void layout_symtab(struct module *mod, struct load_info *info) src = (void *)info->hdr + symsect->sh_offset; nsrc = symsect->sh_size / sizeof(*src); - /* strtab always starts with a nul, so offset 0 is the empty string. */ - strtab_size = 1; - /* Compute total space required for the core symbols' strtab. */ - for (ndst = i = 0; i < nsrc; i++) { - if (i == 0 || - is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { - strtab_size += strlen(&info->strtab[src[i].st_name])+1; + for (ndst = i = strtab_size = 1; i < nsrc; ++i, ++src) + if (is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) { + strtab_size += strlen(&info->strtab[src->st_name]) + 1; ndst++; } - } /* Append room for core symbols at end of core part. */ info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1); @@ -2337,15 +2332,15 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) mod->core_symtab = dst = mod->module_core + info->symoffs; mod->core_strtab = s = mod->module_core + info->stroffs; src = mod->symtab; + *dst = *src; *s++ = 0; - for (ndst = i = 0; i < mod->num_symtab; i++) { - if (i == 0 || - is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { - dst[ndst] = src[i]; - dst[ndst++].st_name = s - mod->core_strtab; - s += strlcpy(s, &mod->strtab[src[i].st_name], - KSYM_NAME_LEN) + 1; - } + for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) { + if (!is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) + continue; + + dst[ndst] = *src; + dst[ndst++].st_name = s - mod->core_strtab; + s += strlcpy(s, &mod->strtab[src->st_name], KSYM_NAME_LEN) + 1; } mod->core_num_syms = ndst; } diff --git a/trunk/kernel/module_signing.c b/trunk/kernel/module_signing.c index f2970bddc5ea..d492a23df99c 100644 --- a/trunk/kernel/module_signing.c +++ b/trunk/kernel/module_signing.c @@ -27,13 +27,13 @@ * - Information block */ struct module_signature { - u8 algo; /* Public-key crypto algorithm [enum pkey_algo] */ - u8 hash; /* Digest algorithm [enum pkey_hash_algo] */ - u8 id_type; /* Key identifier type [enum pkey_id_type] */ - u8 signer_len; /* Length of signer's name */ - u8 key_id_len; /* Length of key identifier */ - u8 __pad[3]; - __be32 sig_len; /* Length of signature data */ + enum pkey_algo algo : 8; /* Public-key crypto algorithm */ + enum pkey_hash_algo hash : 8; /* Digest algorithm */ + enum pkey_id_type id_type : 8; /* Key identifier type */ + u8 signer_len; /* Length of signer's name */ + u8 key_id_len; /* Length of key identifier */ + u8 __pad[3]; + __be32 sig_len; /* Length of signature data */ }; /* @@ -192,7 +192,7 @@ int mod_verify_sig(const void *mod, unsigned long *_modlen) size_t modlen = *_modlen, sig_len; int ret; - pr_devel("==>%s(,%zu)\n", __func__, modlen); + pr_devel("==>%s(,%lu)\n", __func__, modlen); if (modlen <= sizeof(ms)) return -EBADMSG; diff --git a/trunk/kernel/pid_namespace.c b/trunk/kernel/pid_namespace.c index 7b07cc0dfb75..eb00be205811 100644 --- a/trunk/kernel/pid_namespace.c +++ b/trunk/kernel/pid_namespace.c @@ -71,22 +71,12 @@ static struct kmem_cache *create_pid_cachep(int nr_ids) return NULL; } -/* MAX_PID_NS_LEVEL is needed for limiting size of 'struct pid' */ -#define MAX_PID_NS_LEVEL 32 - static struct pid_namespace *create_pid_namespace(struct pid_namespace *parent_pid_ns) { struct pid_namespace *ns; unsigned int level = parent_pid_ns->level + 1; - int i; - int err; - - if (level > MAX_PID_NS_LEVEL) { - err = -EINVAL; - goto out; - } + int i, err = -ENOMEM; - err = -ENOMEM; ns = kmem_cache_zalloc(pid_ns_cachep, GFP_KERNEL); if (ns == NULL) goto out; diff --git a/trunk/kernel/sched/auto_group.c b/trunk/kernel/sched/auto_group.c index 15f60d01198b..0984a21076a3 100644 --- a/trunk/kernel/sched/auto_group.c +++ b/trunk/kernel/sched/auto_group.c @@ -143,11 +143,15 @@ autogroup_move_group(struct task_struct *p, struct autogroup *ag) p->signal->autogroup = autogroup_kref_get(ag); + if (!ACCESS_ONCE(sysctl_sched_autogroup_enabled)) + goto out; + t = p; do { sched_move_task(t); } while_each_thread(p, t); +out: unlock_task_sighand(p, &flags); autogroup_kref_put(prev); } diff --git a/trunk/kernel/sched/auto_group.h b/trunk/kernel/sched/auto_group.h index 443232ebbb53..8bd047142816 100644 --- a/trunk/kernel/sched/auto_group.h +++ b/trunk/kernel/sched/auto_group.h @@ -4,6 +4,11 @@ #include struct autogroup { + /* + * reference doesn't mean how many thread attach to this + * autogroup now. It just stands for the number of task + * could use this autogroup. + */ struct kref kref; struct task_group *tg; struct rw_semaphore lock; diff --git a/trunk/kernel/trace/ring_buffer.c b/trunk/kernel/trace/ring_buffer.c index b979426d16c6..b32ed0e385a5 100644 --- a/trunk/kernel/trace/ring_buffer.c +++ b/trunk/kernel/trace/ring_buffer.c @@ -1567,10 +1567,6 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size, put_online_cpus(); } else { - /* Make sure this CPU has been intitialized */ - if (!cpumask_test_cpu(cpu_id, buffer->cpumask)) - goto out; - cpu_buffer = buffer->buffers[cpu_id]; if (nr_pages == cpu_buffer->nr_pages) diff --git a/trunk/kernel/watchdog.c b/trunk/kernel/watchdog.c index c8c21be11ab4..9d4c8d5a1f53 100644 --- a/trunk/kernel/watchdog.c +++ b/trunk/kernel/watchdog.c @@ -116,7 +116,7 @@ static unsigned long get_timestamp(int this_cpu) return cpu_clock(this_cpu) >> 30LL; /* 2^30 ~= 10^9 */ } -static u64 get_sample_period(void) +static unsigned long get_sample_period(void) { /* * convert watchdog_thresh from seconds to ns @@ -125,7 +125,7 @@ static u64 get_sample_period(void) * and hard thresholds) to increment before the * hardlockup detector generates a warning */ - return get_softlockup_thresh() * ((u64)NSEC_PER_SEC / 5); + return get_softlockup_thresh() * (NSEC_PER_SEC / 5); } /* Commands for resetting the watchdog */ @@ -368,9 +368,6 @@ static void watchdog_disable(unsigned int cpu) { struct hrtimer *hrtimer = &__raw_get_cpu_var(watchdog_hrtimer); - if (!watchdog_enabled) - return; - watchdog_set_prio(SCHED_NORMAL, 0); hrtimer_cancel(hrtimer); /* disable the perf event */ diff --git a/trunk/kernel/workqueue.c b/trunk/kernel/workqueue.c index 1dae900df798..d951daa0ca9a 100644 --- a/trunk/kernel/workqueue.c +++ b/trunk/kernel/workqueue.c @@ -1361,19 +1361,8 @@ static void __queue_delayed_work(int cpu, struct workqueue_struct *wq, WARN_ON_ONCE(timer->function != delayed_work_timer_fn || timer->data != (unsigned long)dwork); - WARN_ON_ONCE(timer_pending(timer)); - WARN_ON_ONCE(!list_empty(&work->entry)); - - /* - * If @delay is 0, queue @dwork->work immediately. This is for - * both optimization and correctness. The earliest @timer can - * expire is on the closest next tick and delayed_work users depend - * on that there's no such delay when @delay is 0. - */ - if (!delay) { - __queue_work(cpu, wq, &dwork->work); - return; - } + BUG_ON(timer_pending(timer)); + BUG_ON(!list_empty(&work->entry)); timer_stats_timer_set_start_info(&dwork->timer); @@ -1428,6 +1417,9 @@ bool queue_delayed_work_on(int cpu, struct workqueue_struct *wq, bool ret = false; unsigned long flags; + if (!delay) + return queue_work_on(cpu, wq, &dwork->work); + /* read the comment in __queue_work() */ local_irq_save(flags); @@ -2415,10 +2407,8 @@ static int rescuer_thread(void *__wq) repeat: set_current_state(TASK_INTERRUPTIBLE); - if (kthread_should_stop()) { - __set_current_state(TASK_RUNNING); + if (kthread_should_stop()) return 0; - } /* * See whether any cpu is asking for help. Unbounded @@ -2992,7 +2982,7 @@ bool cancel_delayed_work(struct delayed_work *dwork) set_work_cpu_and_clear_pending(&dwork->work, work_cpu(&dwork->work)); local_irq_restore(flags); - return ret; + return true; } EXPORT_SYMBOL(cancel_delayed_work); diff --git a/trunk/lib/Makefile b/trunk/lib/Makefile index a08b791200f3..821a16229111 100644 --- a/trunk/lib/Makefile +++ b/trunk/lib/Makefile @@ -163,7 +163,7 @@ $(obj)/crc32table.h: $(obj)/gen_crc32table # obj-$(CONFIG_OID_REGISTRY) += oid_registry.o -$(obj)/oid_registry.o: $(obj)/oid_registry_data.c +$(obj)/oid_registry.c: $(obj)/oid_registry_data.c $(obj)/oid_registry_data.c: $(srctree)/include/linux/oid_registry.h \ $(src)/build_OID_registry diff --git a/trunk/lib/asn1_decoder.c b/trunk/lib/asn1_decoder.c index 5293d2433029..de2c8b5a715b 100644 --- a/trunk/lib/asn1_decoder.c +++ b/trunk/lib/asn1_decoder.c @@ -91,7 +91,7 @@ static int asn1_find_indefinite_length(const unsigned char *data, size_t datalen /* Extract the length */ len = data[dp++]; - if (len <= 0x7f) { + if (len < 0x7f) { dp += len; goto next_tag; } diff --git a/trunk/lib/genalloc.c b/trunk/lib/genalloc.c index 54920433705a..ca208a92628c 100644 --- a/trunk/lib/genalloc.c +++ b/trunk/lib/genalloc.c @@ -178,7 +178,7 @@ int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phy struct gen_pool_chunk *chunk; int nbits = size >> pool->min_alloc_order; int nbytes = sizeof(struct gen_pool_chunk) + - BITS_TO_LONGS(nbits) * sizeof(long); + (nbits + BITS_PER_BYTE - 1) / BITS_PER_BYTE; chunk = kmalloc_node(nbytes, GFP_KERNEL | __GFP_ZERO, nid); if (unlikely(chunk == NULL)) diff --git a/trunk/lib/mpi/longlong.h b/trunk/lib/mpi/longlong.h index 095ab157a521..678ce4f1e124 100644 --- a/trunk/lib/mpi/longlong.h +++ b/trunk/lib/mpi/longlong.h @@ -641,14 +641,7 @@ do { \ ************** MIPS ***************** ***************************************/ #if defined(__mips__) && W_TYPE_SIZE == 32 -#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 -#define umul_ppmm(w1, w0, u, v) \ -do { \ - UDItype __ll = (UDItype)(u) * (v); \ - w1 = __ll >> 32; \ - w0 = __ll; \ -} while (0) -#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 +#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7 #define umul_ppmm(w1, w0, u, v) \ __asm__ ("multu %2,%3" \ : "=l" ((USItype)(w0)), \ @@ -673,15 +666,7 @@ do { \ ************** MIPS/64 ************** ***************************************/ #if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64 -#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 -#define umul_ppmm(w1, w0, u, v) \ -do { \ - typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \ - __ll_UTItype __ll = (__ll_UTItype)(u) * (v); \ - w1 = __ll >> 64; \ - w0 = __ll; \ -} while (0) -#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 +#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7 #define umul_ppmm(w1, w0, u, v) \ __asm__ ("dmultu %2,%3" \ : "=l" ((UDItype)(w0)), \ diff --git a/trunk/mm/bootmem.c b/trunk/mm/bootmem.c index f468185b3b28..434be4ae7a04 100644 --- a/trunk/mm/bootmem.c +++ b/trunk/mm/bootmem.c @@ -198,6 +198,8 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) int order = ilog2(BITS_PER_LONG); __free_pages_bootmem(pfn_to_page(start), order); + fixup_zone_present_pages(page_to_nid(pfn_to_page(start)), + start, start + BITS_PER_LONG); count += BITS_PER_LONG; start += BITS_PER_LONG; } else { @@ -208,6 +210,9 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) if (vec & 1) { page = pfn_to_page(start + off); __free_pages_bootmem(page, 0); + fixup_zone_present_pages( + page_to_nid(page), + start + off, start + off + 1); count++; } vec >>= 1; @@ -221,8 +226,11 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) pages = bdata->node_low_pfn - bdata->node_min_pfn; pages = bootmem_bootmap_pages(pages); count += pages; - while (pages--) + while (pages--) { + fixup_zone_present_pages(page_to_nid(page), + page_to_pfn(page), page_to_pfn(page) + 1); __free_pages_bootmem(page++, 0); + } bdebug("nid=%td released=%lx\n", bdata - bootmem_node_data, count); diff --git a/trunk/mm/compaction.c b/trunk/mm/compaction.c index 694eaabaaebd..9eef55838fca 100644 --- a/trunk/mm/compaction.c +++ b/trunk/mm/compaction.c @@ -713,15 +713,7 @@ static void isolate_freepages(struct zone *zone, /* Found a block suitable for isolating free pages from */ isolated = 0; - - /* - * As pfn may not start aligned, pfn+pageblock_nr_page - * may cross a MAX_ORDER_NR_PAGES boundary and miss - * a pfn_valid check. Ensure isolate_freepages_block() - * only scans within a pageblock - */ - end_pfn = ALIGN(pfn + 1, pageblock_nr_pages); - end_pfn = min(end_pfn, zone_end_pfn); + end_pfn = min(pfn + pageblock_nr_pages, zone_end_pfn); isolated = isolate_freepages_block(cc, pfn, end_pfn, freelist, false); nr_freepages += isolated; diff --git a/trunk/mm/dmapool.c b/trunk/mm/dmapool.c index da1b0f0b8709..c5ab33bca0a8 100644 --- a/trunk/mm/dmapool.c +++ b/trunk/mm/dmapool.c @@ -50,6 +50,7 @@ struct dma_pool { /* the pool */ size_t allocation; size_t boundary; char name[32]; + wait_queue_head_t waitq; struct list_head pools; }; @@ -61,6 +62,8 @@ struct dma_page { /* cacheable header for 'allocation' bytes */ unsigned int offset; }; +#define POOL_TIMEOUT_JIFFIES ((100 /* msec */ * HZ) / 1000) + static DEFINE_MUTEX(pools_lock); static ssize_t @@ -169,6 +172,7 @@ struct dma_pool *dma_pool_create(const char *name, struct device *dev, retval->size = size; retval->boundary = boundary; retval->allocation = allocation; + init_waitqueue_head(&retval->waitq); if (dev) { int ret; @@ -223,6 +227,7 @@ static struct dma_page *pool_alloc_page(struct dma_pool *pool, gfp_t mem_flags) memset(page->vaddr, POOL_POISON_FREED, pool->allocation); #endif pool_initialise_page(pool, page); + list_add(&page->page_list, &pool->page_list); page->in_use = 0; page->offset = 0; } else { @@ -310,21 +315,30 @@ void *dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags, might_sleep_if(mem_flags & __GFP_WAIT); spin_lock_irqsave(&pool->lock, flags); + restart: list_for_each_entry(page, &pool->page_list, page_list) { if (page->offset < pool->allocation) goto ready; } + page = pool_alloc_page(pool, GFP_ATOMIC); + if (!page) { + if (mem_flags & __GFP_WAIT) { + DECLARE_WAITQUEUE(wait, current); - /* pool_alloc_page() might sleep, so temporarily drop &pool->lock */ - spin_unlock_irqrestore(&pool->lock, flags); + __set_current_state(TASK_UNINTERRUPTIBLE); + __add_wait_queue(&pool->waitq, &wait); + spin_unlock_irqrestore(&pool->lock, flags); - page = pool_alloc_page(pool, mem_flags); - if (!page) - return NULL; + schedule_timeout(POOL_TIMEOUT_JIFFIES); - spin_lock_irqsave(&pool->lock, flags); + spin_lock_irqsave(&pool->lock, flags); + __remove_wait_queue(&pool->waitq, &wait); + goto restart; + } + retval = NULL; + goto done; + } - list_add(&page->page_list, &pool->page_list); ready: page->in_use++; offset = page->offset; @@ -334,6 +348,7 @@ void *dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags, #ifdef DMAPOOL_DEBUG memset(retval, POOL_POISON_ALLOCATED, pool->size); #endif + done: spin_unlock_irqrestore(&pool->lock, flags); return retval; } @@ -420,6 +435,8 @@ void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma) page->in_use--; *(int *)vaddr = page->offset; page->offset = offset; + if (waitqueue_active(&pool->waitq)) + wake_up_locked(&pool->waitq); /* * Resist a temptation to do * if (!is_page_busy(page)) pool_free_page(pool, page); diff --git a/trunk/mm/highmem.c b/trunk/mm/highmem.c index 2da13a5c50e2..d517cd16a6eb 100644 --- a/trunk/mm/highmem.c +++ b/trunk/mm/highmem.c @@ -98,7 +98,7 @@ struct page *kmap_to_page(void *vaddr) { unsigned long addr = (unsigned long)vaddr; - if (addr >= PKMAP_ADDR(0) && addr < PKMAP_ADDR(LAST_PKMAP)) { + if (addr >= PKMAP_ADDR(0) && addr <= PKMAP_ADDR(LAST_PKMAP)) { int i = (addr - PKMAP_ADDR(0)) >> PAGE_SHIFT; return pte_page(pkmap_page_table[i]); } diff --git a/trunk/mm/memblock.c b/trunk/mm/memblock.c index 625905523c2a..931eef145af5 100644 --- a/trunk/mm/memblock.c +++ b/trunk/mm/memblock.c @@ -930,30 +930,6 @@ int __init_memblock memblock_is_region_reserved(phys_addr_t base, phys_addr_t si return memblock_overlaps_region(&memblock.reserved, base, size) >= 0; } -void __init_memblock memblock_trim_memory(phys_addr_t align) -{ - int i; - phys_addr_t start, end, orig_start, orig_end; - struct memblock_type *mem = &memblock.memory; - - for (i = 0; i < mem->cnt; i++) { - orig_start = mem->regions[i].base; - orig_end = mem->regions[i].base + mem->regions[i].size; - start = round_up(orig_start, align); - end = round_down(orig_end, align); - - if (start == orig_start && end == orig_end) - continue; - - if (start < end) { - mem->regions[i].base = start; - mem->regions[i].size = end - start; - } else { - memblock_remove_region(mem, i); - i--; - } - } -} void __init_memblock memblock_set_current_limit(phys_addr_t limit) { diff --git a/trunk/mm/memcontrol.c b/trunk/mm/memcontrol.c index dd39ba000b31..7acf43bf04a2 100644 --- a/trunk/mm/memcontrol.c +++ b/trunk/mm/memcontrol.c @@ -1055,24 +1055,12 @@ struct lruvec *mem_cgroup_zone_lruvec(struct zone *zone, struct mem_cgroup *memcg) { struct mem_cgroup_per_zone *mz; - struct lruvec *lruvec; - if (mem_cgroup_disabled()) { - lruvec = &zone->lruvec; - goto out; - } + if (mem_cgroup_disabled()) + return &zone->lruvec; mz = mem_cgroup_zoneinfo(memcg, zone_to_nid(zone), zone_idx(zone)); - lruvec = &mz->lruvec; -out: - /* - * Since a node can be onlined after the mem_cgroup was created, - * we have to be prepared to initialize lruvec->zone here; - * and if offlined then reonlined, we need to reinitialize it. - */ - if (unlikely(lruvec->zone != zone)) - lruvec->zone = zone; - return lruvec; + return &mz->lruvec; } /* @@ -1099,12 +1087,9 @@ struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct zone *zone) struct mem_cgroup_per_zone *mz; struct mem_cgroup *memcg; struct page_cgroup *pc; - struct lruvec *lruvec; - if (mem_cgroup_disabled()) { - lruvec = &zone->lruvec; - goto out; - } + if (mem_cgroup_disabled()) + return &zone->lruvec; pc = lookup_page_cgroup(page); memcg = pc->mem_cgroup; @@ -1122,16 +1107,7 @@ struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct zone *zone) pc->mem_cgroup = memcg = root_mem_cgroup; mz = page_cgroup_zoneinfo(memcg, page); - lruvec = &mz->lruvec; -out: - /* - * Since a node can be onlined after the mem_cgroup was created, - * we have to be prepared to initialize lruvec->zone here; - * and if offlined then reonlined, we need to reinitialize it. - */ - if (unlikely(lruvec->zone != zone)) - lruvec->zone = zone; - return lruvec; + return &mz->lruvec; } /** @@ -1476,26 +1452,17 @@ static int mem_cgroup_count_children(struct mem_cgroup *memcg) static u64 mem_cgroup_get_limit(struct mem_cgroup *memcg) { u64 limit; + u64 memsw; limit = res_counter_read_u64(&memcg->res, RES_LIMIT); + limit += total_swap_pages << PAGE_SHIFT; + memsw = res_counter_read_u64(&memcg->memsw, RES_LIMIT); /* - * Do not consider swap space if we cannot swap due to swappiness + * If memsw is finite and limits the amount of swap space available + * to this memcg, return that limit. */ - if (mem_cgroup_swappiness(memcg)) { - u64 memsw; - - limit += total_swap_pages << PAGE_SHIFT; - memsw = res_counter_read_u64(&memcg->memsw, RES_LIMIT); - - /* - * If memsw is finite and limits the amount of swap space - * available to this memcg, return that limit. - */ - limit = min(limit, memsw); - } - - return limit; + return min(limit, memsw); } void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask, @@ -3721,17 +3688,17 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, static bool mem_cgroup_force_empty_list(struct mem_cgroup *memcg, int node, int zid, enum lru_list lru) { - struct lruvec *lruvec; + struct mem_cgroup_per_zone *mz; unsigned long flags, loop; struct list_head *list; struct page *busy; struct zone *zone; zone = &NODE_DATA(node)->node_zones[zid]; - lruvec = mem_cgroup_zone_lruvec(zone, memcg); - list = &lruvec->lists[lru]; + mz = mem_cgroup_zoneinfo(memcg, node, zid); + list = &mz->lruvec.lists[lru]; - loop = mem_cgroup_get_lru_size(lruvec, lru); + loop = mz->lru_size[lru]; /* give some margin against EBUSY etc...*/ loop += 256; busy = NULL; @@ -4769,7 +4736,7 @@ static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node) for (zone = 0; zone < MAX_NR_ZONES; zone++) { mz = &pn->zoneinfo[zone]; - lruvec_init(&mz->lruvec); + lruvec_init(&mz->lruvec, &NODE_DATA(node)->node_zones[zone]); mz->usage_in_excess = 0; mz->on_tree = false; mz->memcg = memcg; diff --git a/trunk/mm/memory-failure.c b/trunk/mm/memory-failure.c index 8b20278be6a6..6c5899b9034a 100644 --- a/trunk/mm/memory-failure.c +++ b/trunk/mm/memory-failure.c @@ -1476,17 +1476,9 @@ int soft_offline_page(struct page *page, int flags) { int ret; unsigned long pfn = page_to_pfn(page); - struct page *hpage = compound_trans_head(page); if (PageHuge(page)) return soft_offline_huge_page(page, flags); - if (PageTransHuge(hpage)) { - if (PageAnon(hpage) && unlikely(split_huge_page(hpage))) { - pr_info("soft offline: %#lx: failed to split THP\n", - pfn); - return -EBUSY; - } - } ret = get_any_page(page, pfn, flags); if (ret < 0) diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index 221fc9ffcab1..fb135ba4aba9 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -2527,8 +2527,9 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, int ret = 0; int page_mkwrite = 0; struct page *dirty_page = NULL; - unsigned long mmun_start = 0; /* For mmu_notifiers */ - unsigned long mmun_end = 0; /* For mmu_notifiers */ + unsigned long mmun_start; /* For mmu_notifiers */ + unsigned long mmun_end; /* For mmu_notifiers */ + bool mmun_called = false; /* For mmu_notifiers */ old_page = vm_normal_page(vma, address, orig_pte); if (!old_page) { @@ -2707,7 +2708,8 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, goto oom_free_new; mmun_start = address & PAGE_MASK; - mmun_end = mmun_start + PAGE_SIZE; + mmun_end = (address & PAGE_MASK) + PAGE_SIZE; + mmun_called = true; mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end); /* @@ -2776,7 +2778,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, page_cache_release(new_page); unlock: pte_unmap_unlock(page_table, ptl); - if (mmun_end > mmun_start) + if (mmun_called) mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end); if (old_page) { /* diff --git a/trunk/mm/memory_hotplug.c b/trunk/mm/memory_hotplug.c index e4eeacae2b91..56b758ae57d2 100644 --- a/trunk/mm/memory_hotplug.c +++ b/trunk/mm/memory_hotplug.c @@ -106,6 +106,7 @@ static void get_page_bootmem(unsigned long info, struct page *page, void __ref put_page_bootmem(struct page *page) { unsigned long type; + struct zone *zone; type = (unsigned long) page->lru.next; BUG_ON(type < MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE || @@ -116,6 +117,12 @@ void __ref put_page_bootmem(struct page *page) set_page_private(page, 0); INIT_LIST_HEAD(&page->lru); __free_pages_bootmem(page, 0); + + zone = page_zone(page); + zone_span_writelock(zone); + zone->present_pages++; + zone_span_writeunlock(zone); + totalram_pages++; } } diff --git a/trunk/mm/mempolicy.c b/trunk/mm/mempolicy.c index 4ea600da8940..d04a8a54c294 100644 --- a/trunk/mm/mempolicy.c +++ b/trunk/mm/mempolicy.c @@ -2037,6 +2037,28 @@ struct mempolicy *__mpol_dup(struct mempolicy *old) return new; } +/* + * If *frompol needs [has] an extra ref, copy *frompol to *tompol , + * eliminate the * MPOL_F_* flags that require conditional ref and + * [NOTE!!!] drop the extra ref. Not safe to reference *frompol directly + * after return. Use the returned value. + * + * Allows use of a mempolicy for, e.g., multiple allocations with a single + * policy lookup, even if the policy needs/has extra ref on lookup. + * shmem_readahead needs this. + */ +struct mempolicy *__mpol_cond_copy(struct mempolicy *tompol, + struct mempolicy *frompol) +{ + if (!mpol_needs_cond_ref(frompol)) + return frompol; + + *tompol = *frompol; + tompol->flags &= ~MPOL_F_SHARED; /* copy doesn't need unref */ + __mpol_put(frompol); + return tompol; +} + /* Slow path of a mempolicy comparison */ bool __mpol_equal(struct mempolicy *a, struct mempolicy *b) { diff --git a/trunk/mm/mmap.c b/trunk/mm/mmap.c index 9a796c41e7d9..2d942353d681 100644 --- a/trunk/mm/mmap.c +++ b/trunk/mm/mmap.c @@ -334,10 +334,8 @@ void validate_mm(struct mm_struct *mm) struct vm_area_struct *vma = mm->mmap; while (vma) { struct anon_vma_chain *avc; - vma_lock_anon_vma(vma); list_for_each_entry(avc, &vma->anon_vma_chain, same_vma) anon_vma_interval_tree_verify(avc); - vma_unlock_anon_vma(vma); vma = vma->vm_next; i++; } diff --git a/trunk/mm/mmu_notifier.c b/trunk/mm/mmu_notifier.c index 8a5ac8c686b0..479a1e751a73 100644 --- a/trunk/mm/mmu_notifier.c +++ b/trunk/mm/mmu_notifier.c @@ -196,28 +196,28 @@ static int do_mmu_notifier_register(struct mmu_notifier *mn, BUG_ON(atomic_read(&mm->mm_users) <= 0); /* - * Verify that mmu_notifier_init() already run and the global srcu is - * initialized. - */ + * Verify that mmu_notifier_init() already run and the global srcu is + * initialized. + */ BUG_ON(!srcu.per_cpu_ref); - ret = -ENOMEM; - mmu_notifier_mm = kmalloc(sizeof(struct mmu_notifier_mm), GFP_KERNEL); - if (unlikely(!mmu_notifier_mm)) - goto out; - if (take_mmap_sem) down_write(&mm->mmap_sem); ret = mm_take_all_locks(mm); if (unlikely(ret)) - goto out_clean; + goto out; if (!mm_has_notifiers(mm)) { + mmu_notifier_mm = kmalloc(sizeof(struct mmu_notifier_mm), + GFP_KERNEL); + if (unlikely(!mmu_notifier_mm)) { + ret = -ENOMEM; + goto out_of_mem; + } INIT_HLIST_HEAD(&mmu_notifier_mm->list); spin_lock_init(&mmu_notifier_mm->lock); mm->mmu_notifier_mm = mmu_notifier_mm; - mmu_notifier_mm = NULL; } atomic_inc(&mm->mm_count); @@ -233,12 +233,12 @@ static int do_mmu_notifier_register(struct mmu_notifier *mn, hlist_add_head(&mn->hlist, &mm->mmu_notifier_mm->list); spin_unlock(&mm->mmu_notifier_mm->lock); +out_of_mem: mm_drop_all_locks(mm); -out_clean: +out: if (take_mmap_sem) up_write(&mm->mmap_sem); - kfree(mmu_notifier_mm); -out: + BUG_ON(atomic_read(&mm->mm_users) <= 0); return ret; } diff --git a/trunk/mm/mmzone.c b/trunk/mm/mmzone.c index 4596d81b89b1..3cef80f6ac79 100644 --- a/trunk/mm/mmzone.c +++ b/trunk/mm/mmzone.c @@ -87,7 +87,7 @@ int memmap_valid_within(unsigned long pfn, } #endif /* CONFIG_ARCH_HAS_HOLES_MEMORYMODEL */ -void lruvec_init(struct lruvec *lruvec) +void lruvec_init(struct lruvec *lruvec, struct zone *zone) { enum lru_list lru; @@ -95,4 +95,8 @@ void lruvec_init(struct lruvec *lruvec) for_each_lru(lru) INIT_LIST_HEAD(&lruvec->lists[lru]); + +#ifdef CONFIG_MEMCG + lruvec->zone = zone; +#endif } diff --git a/trunk/mm/nobootmem.c b/trunk/mm/nobootmem.c index bd82f6b31411..714d5d650470 100644 --- a/trunk/mm/nobootmem.c +++ b/trunk/mm/nobootmem.c @@ -116,6 +116,8 @@ static unsigned long __init __free_memory_core(phys_addr_t start, return 0; __free_pages_memory(start_pfn, end_pfn); + fixup_zone_present_pages(pfn_to_nid(start >> PAGE_SHIFT), + start_pfn, end_pfn); return end_pfn - start_pfn; } @@ -126,6 +128,7 @@ unsigned long __init free_low_memory_core_early(int nodeid) phys_addr_t start, end, size; u64 i; + reset_zone_present_pages(); for_each_free_mem_range(i, MAX_NUMNODES, &start, &end, NULL) count += __free_memory_core(start, end); diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index 7e208f0ad68c..bb90971182bd 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -1405,7 +1405,7 @@ int capture_free_page(struct page *page, int alloc_order, int migratetype) mt = get_pageblock_migratetype(page); if (unlikely(mt != MIGRATE_ISOLATE)) - __mod_zone_freepage_state(zone, -(1UL << alloc_order), mt); + __mod_zone_freepage_state(zone, -(1UL << order), mt); if (alloc_order != order) expand(zone, page, alloc_order, order, @@ -1422,7 +1422,7 @@ int capture_free_page(struct page *page, int alloc_order, int migratetype) } } - return 1UL << alloc_order; + return 1UL << order; } /* @@ -1809,10 +1809,10 @@ static void __paginginit init_zone_allows_reclaim(int nid) int i; for_each_online_node(i) - if (node_distance(nid, i) <= RECLAIM_DISTANCE) + if (node_distance(nid, i) <= RECLAIM_DISTANCE) { node_set(i, NODE_DATA(nid)->reclaim_nodes); - else zone_reclaim_mode = 1; + } } #else /* CONFIG_NUMA */ @@ -2416,9 +2416,8 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, goto nopage; restart: - if (!(gfp_mask & __GFP_NO_KSWAPD)) - wake_all_kswapd(order, zonelist, high_zoneidx, - zone_idx(preferred_zone)); + wake_all_kswapd(order, zonelist, high_zoneidx, + zone_idx(preferred_zone)); /* * OK, we're below the kswapd watermark and have kicked background @@ -2495,7 +2494,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, * system then fail the allocation instead of entering direct reclaim. */ if ((deferred_compaction || contended_compaction) && - (gfp_mask & __GFP_NO_KSWAPD)) + (gfp_mask & (__GFP_MOVABLE|__GFP_REPEAT)) == __GFP_MOVABLE) goto nopage; /* Try direct reclaim and then allocating */ @@ -4506,7 +4505,7 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat, zone->zone_pgdat = pgdat; zone_pcp_init(zone); - lruvec_init(&zone->lruvec); + lruvec_init(&zone->lruvec, zone); if (!size) continue; @@ -5826,7 +5825,7 @@ int alloc_contig_range(unsigned long start, unsigned long end, ret = start_isolate_page_range(pfn_max_align_down(start), pfn_max_align_up(end), migratetype); if (ret) - return ret; + goto done; ret = __alloc_contig_migrate_range(&cc, start, end); if (ret) @@ -6099,3 +6098,37 @@ void dump_page(struct page *page) dump_page_flags(page->flags); mem_cgroup_print_bad_page(page); } + +/* reset zone->present_pages */ +void reset_zone_present_pages(void) +{ + struct zone *z; + int i, nid; + + for_each_node_state(nid, N_HIGH_MEMORY) { + for (i = 0; i < MAX_NR_ZONES; i++) { + z = NODE_DATA(nid)->node_zones + i; + z->present_pages = 0; + } + } +} + +/* calculate zone's present pages in buddy system */ +void fixup_zone_present_pages(int nid, unsigned long start_pfn, + unsigned long end_pfn) +{ + struct zone *z; + unsigned long zone_start_pfn, zone_end_pfn; + int i; + + for (i = 0; i < MAX_NR_ZONES; i++) { + z = NODE_DATA(nid)->node_zones + i; + zone_start_pfn = z->zone_start_pfn; + zone_end_pfn = zone_start_pfn + z->spanned_pages; + + /* if the two regions intersect */ + if (!(zone_start_pfn >= end_pfn || zone_end_pfn <= start_pfn)) + z->present_pages += min(end_pfn, zone_end_pfn) - + max(start_pfn, zone_start_pfn); + } +} diff --git a/trunk/mm/rmap.c b/trunk/mm/rmap.c index 2ee1ef0f317b..7df7984d476c 100644 --- a/trunk/mm/rmap.c +++ b/trunk/mm/rmap.c @@ -56,7 +56,6 @@ #include #include #include -#include #include @@ -927,8 +926,11 @@ int page_mkclean(struct page *page) if (page_mapped(page)) { struct address_space *mapping = page_mapping(page); - if (mapping) + if (mapping) { ret = page_mkclean_file(mapping, page); + if (page_test_and_clear_dirty(page_to_pfn(page), 1)) + ret = 1; + } } return ret; @@ -1114,7 +1116,6 @@ void page_add_file_rmap(struct page *page) */ void page_remove_rmap(struct page *page) { - struct address_space *mapping = page_mapping(page); bool anon = PageAnon(page); bool locked; unsigned long flags; @@ -1137,19 +1138,8 @@ void page_remove_rmap(struct page *page) * this if the page is anon, so about to be freed; but perhaps * not if it's in swapcache - there might be another pte slot * containing the swap entry, but page not yet written to swap. - * - * And we can skip it on file pages, so long as the filesystem - * participates in dirty tracking; but need to catch shm and tmpfs - * and ramfs pages which have been modified since creation by read - * fault. - * - * Note that mapping must be decided above, before decrementing - * mapcount (which luckily provides a barrier): once page is unmapped, - * it could be truncated and page->mapping reset to NULL at any moment. - * Note also that we are relying on page_mapping(page) to set mapping - * to &swapper_space when PageSwapCache(page). */ - if (mapping && !mapping_cap_account_dirty(mapping) && + if ((!anon || PageSwapCache(page)) && page_test_and_clear_dirty(page_to_pfn(page), 1)) set_page_dirty(page); /* diff --git a/trunk/mm/shmem.c b/trunk/mm/shmem.c index 50c5b8f3a359..67afba5117f2 100644 --- a/trunk/mm/shmem.c +++ b/trunk/mm/shmem.c @@ -643,7 +643,7 @@ static void shmem_evict_inode(struct inode *inode) kfree(info->symlink); simple_xattrs_free(&info->xattrs); - WARN_ON(inode->i_blocks); + BUG_ON(inode->i_blocks); shmem_free_inode(inode->i_sb); clear_inode(inode); } @@ -910,29 +910,25 @@ static struct mempolicy *shmem_get_sbmpol(struct shmem_sb_info *sbinfo) static struct page *shmem_swapin(swp_entry_t swap, gfp_t gfp, struct shmem_inode_info *info, pgoff_t index) { + struct mempolicy mpol, *spol; struct vm_area_struct pvma; - struct page *page; + + spol = mpol_cond_copy(&mpol, + mpol_shared_policy_lookup(&info->policy, index)); /* Create a pseudo vma that just contains the policy */ pvma.vm_start = 0; /* Bias interleave by inode number to distribute better across nodes */ pvma.vm_pgoff = index + info->vfs_inode.i_ino; pvma.vm_ops = NULL; - pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, index); - - page = swapin_readahead(swap, gfp, &pvma, 0); - - /* Drop reference taken by mpol_shared_policy_lookup() */ - mpol_cond_put(pvma.vm_policy); - - return page; + pvma.vm_policy = spol; + return swapin_readahead(swap, gfp, &pvma, 0); } static struct page *shmem_alloc_page(gfp_t gfp, struct shmem_inode_info *info, pgoff_t index) { struct vm_area_struct pvma; - struct page *page; /* Create a pseudo vma that just contains the policy */ pvma.vm_start = 0; @@ -941,12 +937,10 @@ static struct page *shmem_alloc_page(gfp_t gfp, pvma.vm_ops = NULL; pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, index); - page = alloc_page_vma(gfp, &pvma, 0); - - /* Drop reference taken by mpol_shared_policy_lookup() */ - mpol_cond_put(pvma.vm_policy); - - return page; + /* + * alloc_page_vma() will drop the shared policy reference + */ + return alloc_page_vma(gfp, &pvma, 0); } #else /* !CONFIG_NUMA */ #ifdef CONFIG_TMPFS @@ -1151,20 +1145,8 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t index, if (!error) { error = shmem_add_to_page_cache(page, mapping, index, gfp, swp_to_radix_entry(swap)); - /* - * We already confirmed swap under page lock, and make - * no memory allocation here, so usually no possibility - * of error; but free_swap_and_cache() only trylocks a - * page, so it is just possible that the entry has been - * truncated or holepunched since swap was confirmed. - * shmem_undo_range() will have done some of the - * unaccounting, now delete_from_swap_cache() will do - * the rest (including mem_cgroup_uncharge_swapcache). - * Reset swap.val? No, leave it so "failed" goes back to - * "repeat": reading a hole and writing should succeed. - */ - if (error) - delete_from_swap_cache(page); + /* We already confirmed swap, and make no allocation */ + VM_BUG_ON(error); } if (error) goto failed; diff --git a/trunk/mm/sparse.c b/trunk/mm/sparse.c index a83de2f72b30..fac95f2888f2 100644 --- a/trunk/mm/sparse.c +++ b/trunk/mm/sparse.c @@ -617,7 +617,7 @@ static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages) { return; /* XXX: Not implemented yet */ } -static void free_map_bootmem(struct page *memmap, unsigned long nr_pages) +static void free_map_bootmem(struct page *page, unsigned long nr_pages) { } #else @@ -658,11 +658,10 @@ static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages) get_order(sizeof(struct page) * nr_pages)); } -static void free_map_bootmem(struct page *memmap, unsigned long nr_pages) +static void free_map_bootmem(struct page *page, unsigned long nr_pages) { unsigned long maps_section_nr, removing_section_nr, i; unsigned long magic; - struct page *page = virt_to_page(memmap); for (i = 0; i < nr_pages; i++, page++) { magic = (unsigned long) page->lru.next; @@ -711,10 +710,13 @@ static void free_section_usemap(struct page *memmap, unsigned long *usemap) */ if (memmap) { + struct page *memmap_page; + memmap_page = virt_to_page(memmap); + nr_pages = PAGE_ALIGN(PAGES_PER_SECTION * sizeof(struct page)) >> PAGE_SHIFT; - free_map_bootmem(memmap, nr_pages); + free_map_bootmem(memmap_page, nr_pages); } } diff --git a/trunk/mm/swapfile.c b/trunk/mm/swapfile.c index f91a25547ffe..71cd288b2001 100644 --- a/trunk/mm/swapfile.c +++ b/trunk/mm/swapfile.c @@ -1494,8 +1494,9 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) BUG_ON(!current->mm); pathname = getname(specialfile); + err = PTR_ERR(pathname); if (IS_ERR(pathname)) - return PTR_ERR(pathname); + goto out; victim = file_open_name(pathname, O_RDWR|O_LARGEFILE, 0); err = PTR_ERR(victim); @@ -1607,7 +1608,6 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) out_dput: filp_close(victim, NULL); out: - putname(pathname); return err; } diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index b7ed37675644..2624edcfb420 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -1760,6 +1760,28 @@ static bool in_reclaim_compaction(struct scan_control *sc) return false; } +#ifdef CONFIG_COMPACTION +/* + * If compaction is deferred for sc->order then scale the number of pages + * reclaimed based on the number of consecutive allocation failures + */ +static unsigned long scale_for_compaction(unsigned long pages_for_compaction, + struct lruvec *lruvec, struct scan_control *sc) +{ + struct zone *zone = lruvec_zone(lruvec); + + if (zone->compact_order_failed <= sc->order) + pages_for_compaction <<= zone->compact_defer_shift; + return pages_for_compaction; +} +#else +static unsigned long scale_for_compaction(unsigned long pages_for_compaction, + struct lruvec *lruvec, struct scan_control *sc) +{ + return pages_for_compaction; +} +#endif + /* * Reclaim/compaction is used for high-order allocation requests. It reclaims * order-0 pages before compacting the zone. should_continue_reclaim() returns @@ -1807,6 +1829,9 @@ static inline bool should_continue_reclaim(struct lruvec *lruvec, * inactive lists are large enough, continue reclaiming */ pages_for_compaction = (2UL << sc->order); + + pages_for_compaction = scale_for_compaction(pages_for_compaction, + lruvec, sc); inactive_lru_pages = get_lru_size(lruvec, LRU_INACTIVE_FILE); if (nr_swap_pages > 0) inactive_lru_pages += get_lru_size(lruvec, LRU_INACTIVE_ANON); @@ -2207,12 +2232,9 @@ static bool pfmemalloc_watermark_ok(pg_data_t *pgdat) * Throttle direct reclaimers if backing storage is backed by the network * and the PFMEMALLOC reserve for the preferred node is getting dangerously * depleted. kswapd will continue to make progress and wake the processes - * when the low watermark is reached. - * - * Returns true if a fatal signal was delivered during throttling. If this - * happens, the page allocator should not consider triggering the OOM killer. + * when the low watermark is reached */ -static bool throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist, +static void throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist, nodemask_t *nodemask) { struct zone *zone; @@ -2227,20 +2249,13 @@ static bool throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist, * processes to block on log_wait_commit(). */ if (current->flags & PF_KTHREAD) - goto out; - - /* - * If a fatal signal is pending, this process should not throttle. - * It should return quickly so it can exit and free its memory - */ - if (fatal_signal_pending(current)) - goto out; + return; /* Check if the pfmemalloc reserves are ok */ first_zones_zonelist(zonelist, high_zoneidx, NULL, &zone); pgdat = zone->zone_pgdat; if (pfmemalloc_watermark_ok(pgdat)) - goto out; + return; /* Account for the throttling */ count_vm_event(PGSCAN_DIRECT_THROTTLE); @@ -2256,20 +2271,12 @@ static bool throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist, if (!(gfp_mask & __GFP_FS)) { wait_event_interruptible_timeout(pgdat->pfmemalloc_wait, pfmemalloc_watermark_ok(pgdat), HZ); - - goto check_pending; + return; } /* Throttle until kswapd wakes the process */ wait_event_killable(zone->zone_pgdat->pfmemalloc_wait, pfmemalloc_watermark_ok(pgdat)); - -check_pending: - if (fatal_signal_pending(current)) - return true; - -out: - return false; } unsigned long try_to_free_pages(struct zonelist *zonelist, int order, @@ -2291,12 +2298,13 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order, .gfp_mask = sc.gfp_mask, }; + throttle_direct_reclaim(gfp_mask, zonelist, nodemask); + /* - * Do not enter reclaim if fatal signal was delivered while throttled. - * 1 is returned so that the page allocator does not OOM kill at this - * point. + * Do not enter reclaim if fatal signal is pending. 1 is returned so + * that the page allocator does not consider triggering OOM */ - if (throttle_direct_reclaim(gfp_mask, zonelist, nodemask)) + if (fatal_signal_pending(current)) return 1; trace_mm_vmscan_direct_reclaim_begin(order, @@ -2414,19 +2422,6 @@ static void age_active_anon(struct zone *zone, struct scan_control *sc) } while (memcg); } -static bool zone_balanced(struct zone *zone, int order, - unsigned long balance_gap, int classzone_idx) -{ - if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone) + - balance_gap, classzone_idx, 0)) - return false; - - if (COMPACTION_BUILD && order && !compaction_suitable(zone, order)) - return false; - - return true; -} - /* * pgdat_balanced is used when checking if a node is balanced for high-order * allocations. Only zones that meet watermarks and are in a zone allowed @@ -2505,7 +2500,8 @@ static bool prepare_kswapd_sleep(pg_data_t *pgdat, int order, long remaining, continue; } - if (!zone_balanced(zone, order, 0, i)) + if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone), + i, 0)) all_zones_ok = false; else balanced += zone->present_pages; @@ -2614,7 +2610,8 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order, break; } - if (!zone_balanced(zone, order, 0, 0)) { + if (!zone_watermark_ok_safe(zone, order, + high_wmark_pages(zone), 0, 0)) { end_zone = i; break; } else { @@ -2690,8 +2687,9 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order, testorder = 0; if ((buffer_heads_over_limit && is_highmem_idx(i)) || - !zone_balanced(zone, testorder, - balance_gap, end_zone)) { + !zone_watermark_ok_safe(zone, testorder, + high_wmark_pages(zone) + balance_gap, + end_zone, 0)) { shrink_zone(zone, &sc); reclaim_state->reclaimed_slab = 0; @@ -2718,7 +2716,8 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order, continue; } - if (!zone_balanced(zone, testorder, 0, end_zone)) { + if (!zone_watermark_ok_safe(zone, testorder, + high_wmark_pages(zone), end_zone, 0)) { all_zones_ok = 0; /* * We are still under min water mark. This @@ -2823,10 +2822,29 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order, if (!populated_zone(zone)) continue; + if (zone->all_unreclaimable && + sc.priority != DEF_PRIORITY) + continue; + + /* Would compaction fail due to lack of free memory? */ + if (COMPACTION_BUILD && + compaction_suitable(zone, order) == COMPACT_SKIPPED) + goto loop_again; + + /* Confirm the zone is balanced for order-0 */ + if (!zone_watermark_ok(zone, 0, + high_wmark_pages(zone), 0, 0)) { + order = sc.order = 0; + goto loop_again; + } + /* Check if the memory needs to be defragmented. */ if (zone_watermark_ok(zone, order, low_wmark_pages(zone), *classzone_idx, 0)) zones_need_compaction = 0; + + /* If balanced, clear the congested flag */ + zone_clear_flag(zone, ZONE_CONGESTED); } if (zones_need_compaction) @@ -2999,8 +3017,6 @@ static int kswapd(void *p) &balanced_classzone_idx); } } - - current->reclaim_state = NULL; return 0; } diff --git a/trunk/net/8021q/vlan.c b/trunk/net/8021q/vlan.c index ee070722a3a3..9096bcb08132 100644 --- a/trunk/net/8021q/vlan.c +++ b/trunk/net/8021q/vlan.c @@ -463,9 +463,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, case NETDEV_PRE_TYPE_CHANGE: /* Forbid underlaying device to change its type. */ - if (vlan_uses_dev(dev)) - return NOTIFY_BAD; - break; + return NOTIFY_BAD; case NETDEV_NOTIFY_PEERS: case NETDEV_BONDING_FAILOVER: diff --git a/trunk/net/batman-adv/bridge_loop_avoidance.c b/trunk/net/batman-adv/bridge_loop_avoidance.c index fd8d5afec0dd..0a9084ad19a6 100644 --- a/trunk/net/batman-adv/bridge_loop_avoidance.c +++ b/trunk/net/batman-adv/bridge_loop_avoidance.c @@ -1167,8 +1167,6 @@ int batadv_bla_init(struct batadv_priv *bat_priv) uint16_t crc; unsigned long entrytime; - spin_lock_init(&bat_priv->bla.bcast_duplist_lock); - batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hash registering\n"); /* setting claim destination address */ @@ -1212,8 +1210,8 @@ int batadv_bla_init(struct batadv_priv *bat_priv) /** * batadv_bla_check_bcast_duplist * @bat_priv: the bat priv with all the soft interface information - * @bcast_packet: encapsulated broadcast frame plus batman header - * @bcast_packet_len: length of encapsulated broadcast frame plus batman header + * @bcast_packet: originator mac address + * @hdr_size: maximum length of the frame * * check if it is on our broadcast list. Another gateway might * have sent the same packet because it is connected to the same backbone, @@ -1226,22 +1224,20 @@ int batadv_bla_init(struct batadv_priv *bat_priv) */ int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, struct batadv_bcast_packet *bcast_packet, - int bcast_packet_len) + int hdr_size) { - int i, length, curr, ret = 0; + int i, length, curr; uint8_t *content; uint16_t crc; struct batadv_bcast_duplist_entry *entry; - length = bcast_packet_len - sizeof(*bcast_packet); + length = hdr_size - sizeof(*bcast_packet); content = (uint8_t *)bcast_packet; content += sizeof(*bcast_packet); /* calculate the crc ... */ crc = crc16(0, content, length); - spin_lock_bh(&bat_priv->bla.bcast_duplist_lock); - for (i = 0; i < BATADV_DUPLIST_SIZE; i++) { curr = (bat_priv->bla.bcast_duplist_curr + i); curr %= BATADV_DUPLIST_SIZE; @@ -1263,12 +1259,9 @@ int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, /* this entry seems to match: same crc, not too old, * and from another gw. therefore return 1 to forbid it. */ - ret = 1; - goto out; + return 1; } - /* not found, add a new entry (overwrite the oldest entry) - * and allow it, its the first occurence. - */ + /* not found, add a new entry (overwrite the oldest entry) */ curr = (bat_priv->bla.bcast_duplist_curr + BATADV_DUPLIST_SIZE - 1); curr %= BATADV_DUPLIST_SIZE; entry = &bat_priv->bla.bcast_duplist[curr]; @@ -1277,10 +1270,8 @@ int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, memcpy(entry->orig, bcast_packet->orig, ETH_ALEN); bat_priv->bla.bcast_duplist_curr = curr; -out: - spin_unlock_bh(&bat_priv->bla.bcast_duplist_lock); - - return ret; + /* allow it, its the first occurence. */ + return 0; } diff --git a/trunk/net/batman-adv/routing.c b/trunk/net/batman-adv/routing.c index 376b4cc6ca82..939fc01371df 100644 --- a/trunk/net/batman-adv/routing.c +++ b/trunk/net/batman-adv/routing.c @@ -1124,14 +1124,8 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, spin_unlock_bh(&orig_node->bcast_seqno_lock); - /* keep skb linear for crc calculation */ - if (skb_linearize(skb) < 0) - goto out; - - bcast_packet = (struct batadv_bcast_packet *)skb->data; - /* check whether this has been sent by another originator before */ - if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, skb->len)) + if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, hdr_size)) goto out; /* rebroadcast packet */ diff --git a/trunk/net/batman-adv/soft-interface.c b/trunk/net/batman-adv/soft-interface.c index ce0684a1fc83..b9a28d2dd3e8 100644 --- a/trunk/net/batman-adv/soft-interface.c +++ b/trunk/net/batman-adv/soft-interface.c @@ -325,12 +325,6 @@ void batadv_interface_rx(struct net_device *soft_iface, soft_iface->last_rx = jiffies; - /* Let the bridge loop avoidance check the packet. If will - * not handle it, we can safely push it up. - */ - if (batadv_bla_rx(bat_priv, skb, vid, is_bcast)) - goto out; - if (orig_node) batadv_tt_add_temporary_global_entry(bat_priv, orig_node, ethhdr->h_source); @@ -338,6 +332,12 @@ void batadv_interface_rx(struct net_device *soft_iface, if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) goto dropped; + /* Let the bridge loop avoidance check the packet. If will + * not handle it, we can safely push it up. + */ + if (batadv_bla_rx(bat_priv, skb, vid, is_bcast)) + goto out; + netif_rx(skb); goto out; diff --git a/trunk/net/batman-adv/translation-table.c b/trunk/net/batman-adv/translation-table.c index baae71585804..112edd371b2f 100644 --- a/trunk/net/batman-adv/translation-table.c +++ b/trunk/net/batman-adv/translation-table.c @@ -769,12 +769,6 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, */ tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_TEMP; - /* the change can carry possible "attribute" flags like the - * TT_CLIENT_WIFI, therefore they have to be copied in the - * client entry - */ - tt_global_entry->common.flags |= flags; - /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only * one originator left in the list and we previously received a * delete + roaming change for this originator. @@ -1502,7 +1496,7 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, memcpy(tt_change->addr, tt_common_entry->addr, ETH_ALEN); - tt_change->flags = tt_common_entry->flags; + tt_change->flags = BATADV_NO_FLAGS; tt_count++; tt_change++; @@ -2456,13 +2450,6 @@ bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, { bool ret = false; - /* if the originator is a backbone node (meaning it belongs to the same - * LAN of this node) the temporary client must not be added because to - * reach such destination the node must use the LAN instead of the mesh - */ - if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig)) - goto out; - if (!batadv_tt_global_add(bat_priv, orig_node, addr, BATADV_TT_CLIENT_TEMP, atomic_read(&orig_node->last_ttvn))) diff --git a/trunk/net/batman-adv/types.h b/trunk/net/batman-adv/types.h index ac1e07a80454..2ed82caacdca 100644 --- a/trunk/net/batman-adv/types.h +++ b/trunk/net/batman-adv/types.h @@ -205,8 +205,6 @@ struct batadv_priv_bla { struct batadv_hashtable *backbone_hash; struct batadv_bcast_duplist_entry bcast_duplist[BATADV_DUPLIST_SIZE]; int bcast_duplist_curr; - /* protects bcast_duplist and bcast_duplist_curr */ - spinlock_t bcast_duplist_lock; struct batadv_bla_claim_dst claim_dest; struct delayed_work work; }; diff --git a/trunk/net/bluetooth/hci_core.c b/trunk/net/bluetooth/hci_core.c index a0a2f97b9c62..8a0ce706aebd 100644 --- a/trunk/net/bluetooth/hci_core.c +++ b/trunk/net/bluetooth/hci_core.c @@ -1754,11 +1754,11 @@ int hci_register_dev(struct hci_dev *hdev) if (hdev->dev_type != HCI_AMP) set_bit(HCI_AUTO_OFF, &hdev->dev_flags); + schedule_work(&hdev->power_on); + hci_notify(hdev, HCI_DEV_REG); hci_dev_hold(hdev); - schedule_work(&hdev->power_on); - return id; err_wqueue: diff --git a/trunk/net/bluetooth/mgmt.c b/trunk/net/bluetooth/mgmt.c index 91de4239da66..aa2ea0a8142c 100644 --- a/trunk/net/bluetooth/mgmt.c +++ b/trunk/net/bluetooth/mgmt.c @@ -326,7 +326,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, struct hci_dev *d; size_t rp_len; u16 count; - int err; + int i, err; BT_DBG("sock %p", sk); @@ -347,7 +347,9 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, return -ENOMEM; } - count = 0; + rp->num_controllers = cpu_to_le16(count); + + i = 0; list_for_each_entry(d, &hci_dev_list, list) { if (test_bit(HCI_SETUP, &d->dev_flags)) continue; @@ -355,13 +357,10 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, if (!mgmt_valid_hdev(d)) continue; - rp->index[count++] = cpu_to_le16(d->id); + rp->index[i++] = cpu_to_le16(d->id); BT_DBG("Added hci%u", d->id); } - rp->num_controllers = cpu_to_le16(count); - rp_len = sizeof(*rp) + (2 * count); - read_unlock(&hci_dev_list_lock); err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, 0, rp, @@ -1367,7 +1366,6 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, continue; list_del(&match->list); - kfree(match); found++; } diff --git a/trunk/net/bluetooth/smp.c b/trunk/net/bluetooth/smp.c index a5923378bdf0..8c225ef349cd 100644 --- a/trunk/net/bluetooth/smp.c +++ b/trunk/net/bluetooth/smp.c @@ -32,8 +32,6 @@ #define SMP_TIMEOUT msecs_to_jiffies(30000) -#define AUTH_REQ_MASK 0x07 - static inline void swap128(u8 src[16], u8 dst[16]) { int i; @@ -232,7 +230,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn, req->max_key_size = SMP_MAX_ENC_KEY_SIZE; req->init_key_dist = 0; req->resp_key_dist = dist_keys; - req->auth_req = (authreq & AUTH_REQ_MASK); + req->auth_req = authreq; return; } @@ -241,7 +239,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn, rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE; rsp->init_key_dist = 0; rsp->resp_key_dist = req->resp_key_dist & dist_keys; - rsp->auth_req = (authreq & AUTH_REQ_MASK); + rsp->auth_req = authreq; } static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) @@ -267,7 +265,7 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send) clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->flags); mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type, - hcon->dst_type, HCI_ERROR_AUTH_FAILURE); + hcon->dst_type, reason); cancel_delayed_work_sync(&conn->security_timer); diff --git a/trunk/net/can/bcm.c b/trunk/net/can/bcm.c index 969b7cdff59d..6f747582718e 100644 --- a/trunk/net/can/bcm.c +++ b/trunk/net/can/bcm.c @@ -1084,9 +1084,6 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, op->sk = sk; op->ifindex = ifindex; - /* ifindex for timeout events w/o previous frame reception */ - op->rx_ifindex = ifindex; - /* initialize uninitialized (kzalloc) structure */ hrtimer_init(&op->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); op->timer.function = bcm_rx_timeout_handler; diff --git a/trunk/net/ceph/messenger.c b/trunk/net/ceph/messenger.c index 3ef1759403b4..159aa8bef9e7 100644 --- a/trunk/net/ceph/messenger.c +++ b/trunk/net/ceph/messenger.c @@ -2300,11 +2300,10 @@ static void con_work(struct work_struct *work) mutex_unlock(&con->mutex); return; } else { + con->ops->put(con); dout("con_work %p FAILED to back off %lu\n", con, con->delay); - set_bit(CON_FLAG_BACKOFF, &con->flags); } - goto done; } if (con->state == CON_STATE_STANDBY) { @@ -2750,8 +2749,7 @@ static int ceph_con_in_msg_alloc(struct ceph_connection *con, int *skip) msg = con->ops->alloc_msg(con, hdr, skip); mutex_lock(&con->mutex); if (con->state != CON_STATE_OPEN) { - if (msg) - ceph_msg_put(msg); + ceph_msg_put(msg); return -EAGAIN; } con->in_msg = msg; diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index e5942bf45a6d..09cb3f6dc40c 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1666,7 +1666,7 @@ static inline int deliver_skb(struct sk_buff *skb, static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb) { - if (!ptype->af_packet_priv || !skb->sk) + if (ptype->af_packet_priv == NULL) return false; if (ptype->id_match) @@ -2818,10 +2818,8 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, if (unlikely(tcpu != next_cpu) && (tcpu == RPS_NO_CPU || !cpu_online(tcpu) || ((int)(per_cpu(softnet_data, tcpu).input_queue_head - - rflow->last_qtail)) >= 0)) { - tcpu = next_cpu; + rflow->last_qtail)) >= 0)) rflow = set_rps_cpu(dev, skb, rflow, next_cpu); - } if (tcpu != RPS_NO_CPU && cpu_online(tcpu)) { *rflowp = rflow; @@ -3451,8 +3449,6 @@ static int napi_gro_complete(struct sk_buff *skb) struct list_head *head = &ptype_base[ntohs(type) & PTYPE_HASH_MASK]; int err = -ENOENT; - BUILD_BUG_ON(sizeof(struct napi_gro_cb) > sizeof(skb->cb)); - if (NAPI_GRO_CB(skb)->count == 1) { skb_shinfo(skb)->gso_size = 0; goto out; diff --git a/trunk/net/core/dev_addr_lists.c b/trunk/net/core/dev_addr_lists.c index b079c7bbc157..87cc17db2d56 100644 --- a/trunk/net/core/dev_addr_lists.c +++ b/trunk/net/core/dev_addr_lists.c @@ -319,8 +319,7 @@ int dev_addr_del(struct net_device *dev, const unsigned char *addr, */ ha = list_first_entry(&dev->dev_addrs.list, struct netdev_hw_addr, list); - if (!memcmp(ha->addr, addr, dev->addr_len) && - ha->type == addr_type && ha->refcount == 1) + if (ha->addr == dev->dev_addr && ha->refcount == 1) return -ENOENT; err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len, diff --git a/trunk/net/core/net-sysfs.c b/trunk/net/core/net-sysfs.c index 017a8bacfb27..bcf02f608cbf 100644 --- a/trunk/net/core/net-sysfs.c +++ b/trunk/net/core/net-sysfs.c @@ -429,17 +429,6 @@ static struct attribute_group netstat_group = { .name = "statistics", .attrs = netstat_attrs, }; - -#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) -static struct attribute *wireless_attrs[] = { - NULL -}; - -static struct attribute_group wireless_group = { - .name = "wireless", - .attrs = wireless_attrs, -}; -#endif #endif /* CONFIG_SYSFS */ #ifdef CONFIG_RPS @@ -1420,15 +1409,6 @@ int netdev_register_kobject(struct net_device *net) groups++; *groups++ = &netstat_group; - -#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) - if (net->ieee80211_ptr) - *groups++ = &wireless_group; -#if IS_ENABLED(CONFIG_WIRELESS_EXT) - else if (net->wireless_handlers) - *groups++ = &wireless_group; -#endif -#endif #endif /* CONFIG_SYSFS */ error = device_add(dev); diff --git a/trunk/net/core/rtnetlink.c b/trunk/net/core/rtnetlink.c index fad649ae4dec..76d4c2c3c89b 100644 --- a/trunk/net/core/rtnetlink.c +++ b/trunk/net/core/rtnetlink.c @@ -2192,8 +2192,7 @@ static int nlmsg_populate_fdb(struct sk_buff *skb, goto skip; err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, - portid, seq, - RTM_NEWNEIGH, NTF_SELF); + portid, seq, 0, NTF_SELF); if (err < 0) return err; skip: diff --git a/trunk/net/core/skbuff.c b/trunk/net/core/skbuff.c index 3f0636cd76cd..6e04b1fa11f2 100644 --- a/trunk/net/core/skbuff.c +++ b/trunk/net/core/skbuff.c @@ -3004,7 +3004,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) skb_shinfo(nskb)->gso_size = pinfo->gso_size; pinfo->gso_size = 0; skb_header_release(p); - NAPI_GRO_CB(nskb)->last = p; + nskb->prev = p; nskb->data_len += p->len; nskb->truesize += p->truesize; @@ -3030,8 +3030,8 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) __skb_pull(skb, offset); - NAPI_GRO_CB(p)->last->next = skb; - NAPI_GRO_CB(p)->last = skb; + p->prev->next = skb; + p->prev = skb; skb_header_release(skb); done: @@ -3379,12 +3379,10 @@ EXPORT_SYMBOL(__skb_warn_lro_forwarding); void kfree_skb_partial(struct sk_buff *skb, bool head_stolen) { - if (head_stolen) { - skb_release_head_state(skb); + if (head_stolen) kmem_cache_free(skbuff_head_cache, skb); - } else { + else __kfree_skb(skb); - } } EXPORT_SYMBOL(kfree_skb_partial); diff --git a/trunk/net/ipv4/icmp.c b/trunk/net/ipv4/icmp.c index 17ff9fd7cdda..f2eccd531746 100644 --- a/trunk/net/ipv4/icmp.c +++ b/trunk/net/ipv4/icmp.c @@ -257,8 +257,7 @@ static inline bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt, struct inet_peer *peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr, 1); rc = inet_peer_xrlim_allow(peer, net->ipv4.sysctl_icmp_ratelimit); - if (peer) - inet_putpeer(peer); + inet_putpeer(peer); } out: return rc; diff --git a/trunk/net/ipv4/inet_diag.c b/trunk/net/ipv4/inet_diag.c index e23e16dc501d..535584c00f91 100644 --- a/trunk/net/ipv4/inet_diag.c +++ b/trunk/net/ipv4/inet_diag.c @@ -44,10 +44,6 @@ struct inet_diag_entry { u16 dport; u16 family; u16 userlocks; -#if IS_ENABLED(CONFIG_IPV6) - struct in6_addr saddr_storage; /* for IPv4-mapped-IPv6 addresses */ - struct in6_addr daddr_storage; /* for IPv4-mapped-IPv6 addresses */ -#endif }; static DEFINE_MUTEX(inet_diag_table_mutex); @@ -432,31 +428,25 @@ static int inet_diag_bc_run(const struct nlattr *_bc, break; } + if (cond->prefix_len == 0) + break; + if (op->code == INET_DIAG_BC_S_COND) addr = entry->saddr; else addr = entry->daddr; - if (cond->family != AF_UNSPEC && - cond->family != entry->family) { - if (entry->family == AF_INET6 && - cond->family == AF_INET) { - if (addr[0] == 0 && addr[1] == 0 && - addr[2] == htonl(0xffff) && - bitstring_match(addr + 3, - cond->addr, - cond->prefix_len)) - break; - } - yes = 0; - break; - } - - if (cond->prefix_len == 0) - break; if (bitstring_match(addr, cond->addr, cond->prefix_len)) break; + if (entry->family == AF_INET6 && + cond->family == AF_INET) { + if (addr[0] == 0 && addr[1] == 0 && + addr[2] == htonl(0xffff) && + bitstring_match(addr + 3, cond->addr, + cond->prefix_len)) + break; + } yes = 0; break; } @@ -519,55 +509,6 @@ static int valid_cc(const void *bc, int len, int cc) return 0; } -/* Validate an inet_diag_hostcond. */ -static bool valid_hostcond(const struct inet_diag_bc_op *op, int len, - int *min_len) -{ - int addr_len; - struct inet_diag_hostcond *cond; - - /* Check hostcond space. */ - *min_len += sizeof(struct inet_diag_hostcond); - if (len < *min_len) - return false; - cond = (struct inet_diag_hostcond *)(op + 1); - - /* Check address family and address length. */ - switch (cond->family) { - case AF_UNSPEC: - addr_len = 0; - break; - case AF_INET: - addr_len = sizeof(struct in_addr); - break; - case AF_INET6: - addr_len = sizeof(struct in6_addr); - break; - default: - return false; - } - *min_len += addr_len; - if (len < *min_len) - return false; - - /* Check prefix length (in bits) vs address length (in bytes). */ - if (cond->prefix_len > 8 * addr_len) - return false; - - return true; -} - -/* Validate a port comparison operator. */ -static inline bool valid_port_comparison(const struct inet_diag_bc_op *op, - int len, int *min_len) -{ - /* Port comparisons put the port in a follow-on inet_diag_bc_op. */ - *min_len += sizeof(struct inet_diag_bc_op); - if (len < *min_len) - return false; - return true; -} - static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) { const void *bc = bytecode; @@ -575,39 +516,29 @@ static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) while (len > 0) { const struct inet_diag_bc_op *op = bc; - int min_len = sizeof(struct inet_diag_bc_op); //printk("BC: %d %d %d {%d} / %d\n", op->code, op->yes, op->no, op[1].no, len); switch (op->code) { + case INET_DIAG_BC_AUTO: case INET_DIAG_BC_S_COND: case INET_DIAG_BC_D_COND: - if (!valid_hostcond(bc, len, &min_len)) - return -EINVAL; - break; case INET_DIAG_BC_S_GE: case INET_DIAG_BC_S_LE: case INET_DIAG_BC_D_GE: case INET_DIAG_BC_D_LE: - if (!valid_port_comparison(bc, len, &min_len)) + case INET_DIAG_BC_JMP: + if (op->no < 4 || op->no > len + 4 || op->no & 3) + return -EINVAL; + if (op->no < len && + !valid_cc(bytecode, bytecode_len, len - op->no)) return -EINVAL; break; - case INET_DIAG_BC_AUTO: - case INET_DIAG_BC_JMP: case INET_DIAG_BC_NOP: break; default: return -EINVAL; } - - if (op->code != INET_DIAG_BC_NOP) { - if (op->no < min_len || op->no > len + 4 || op->no & 3) - return -EINVAL; - if (op->no < len && - !valid_cc(bytecode, bytecode_len, len - op->no)) - return -EINVAL; - } - - if (op->yes < min_len || op->yes > len + 4 || op->yes & 3) + if (op->yes < 4 || op->yes > len + 4 || op->yes & 3) return -EINVAL; bc += op->yes; len -= op->yes; @@ -665,36 +596,6 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); } -/* Get the IPv4, IPv6, or IPv4-mapped-IPv6 local and remote addresses - * from a request_sock. For IPv4-mapped-IPv6 we must map IPv4 to IPv6. - */ -static inline void inet_diag_req_addrs(const struct sock *sk, - const struct request_sock *req, - struct inet_diag_entry *entry) -{ - struct inet_request_sock *ireq = inet_rsk(req); - -#if IS_ENABLED(CONFIG_IPV6) - if (sk->sk_family == AF_INET6) { - if (req->rsk_ops->family == AF_INET6) { - entry->saddr = inet6_rsk(req)->loc_addr.s6_addr32; - entry->daddr = inet6_rsk(req)->rmt_addr.s6_addr32; - } else if (req->rsk_ops->family == AF_INET) { - ipv6_addr_set_v4mapped(ireq->loc_addr, - &entry->saddr_storage); - ipv6_addr_set_v4mapped(ireq->rmt_addr, - &entry->daddr_storage); - entry->saddr = entry->saddr_storage.s6_addr32; - entry->daddr = entry->daddr_storage.s6_addr32; - } - } else -#endif - { - entry->saddr = &ireq->loc_addr; - entry->daddr = &ireq->rmt_addr; - } -} - static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, struct request_sock *req, struct user_namespace *user_ns, @@ -736,10 +637,8 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, r->idiag_inode = 0; #if IS_ENABLED(CONFIG_IPV6) if (r->idiag_family == AF_INET6) { - struct inet_diag_entry entry; - inet_diag_req_addrs(sk, req, &entry); - memcpy(r->id.idiag_src, entry.saddr, sizeof(struct in6_addr)); - memcpy(r->id.idiag_dst, entry.daddr, sizeof(struct in6_addr)); + *(struct in6_addr *)r->id.idiag_src = inet6_rsk(req)->loc_addr; + *(struct in6_addr *)r->id.idiag_dst = inet6_rsk(req)->rmt_addr; } #endif @@ -792,7 +691,18 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, continue; if (bc) { - inet_diag_req_addrs(sk, req, &entry); + entry.saddr = +#if IS_ENABLED(CONFIG_IPV6) + (entry.family == AF_INET6) ? + inet6_rsk(req)->loc_addr.s6_addr32 : +#endif + &ireq->loc_addr; + entry.daddr = +#if IS_ENABLED(CONFIG_IPV6) + (entry.family == AF_INET6) ? + inet6_rsk(req)->rmt_addr.s6_addr32 : +#endif + &ireq->rmt_addr; entry.dport = ntohs(ireq->rmt_port); if (!inet_diag_bc_run(bc, &entry)) @@ -982,16 +892,13 @@ static int __inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, struct inet_diag_req_v2 *r, struct nlattr *bc) { const struct inet_diag_handler *handler; - int err = 0; handler = inet_diag_lock_handler(r->sdiag_protocol); if (!IS_ERR(handler)) handler->dump(skb, cb, r, bc); - else - err = PTR_ERR(handler); inet_diag_unlock_handler(handler); - return err ? : skb->len; + return skb->len; } static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) diff --git a/trunk/net/ipv4/ip_fragment.c b/trunk/net/ipv4/ip_fragment.c index 8d5cc75dac88..448e68546827 100644 --- a/trunk/net/ipv4/ip_fragment.c +++ b/trunk/net/ipv4/ip_fragment.c @@ -707,27 +707,28 @@ EXPORT_SYMBOL(ip_defrag); struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user) { - struct iphdr iph; + const struct iphdr *iph; u32 len; if (skb->protocol != htons(ETH_P_IP)) return skb; - if (!skb_copy_bits(skb, 0, &iph, sizeof(iph))) + if (!pskb_may_pull(skb, sizeof(struct iphdr))) return skb; - if (iph.ihl < 5 || iph.version != 4) + iph = ip_hdr(skb); + if (iph->ihl < 5 || iph->version != 4) return skb; - - len = ntohs(iph.tot_len); - if (skb->len < len || len < (iph.ihl * 4)) + if (!pskb_may_pull(skb, iph->ihl*4)) + return skb; + iph = ip_hdr(skb); + len = ntohs(iph->tot_len); + if (skb->len < len || len < (iph->ihl * 4)) return skb; - if (ip_is_fragment(&iph)) { + if (ip_is_fragment(ip_hdr(skb))) { skb = skb_share_check(skb, GFP_ATOMIC); if (skb) { - if (!pskb_may_pull(skb, iph.ihl*4)) - return skb; if (pskb_trim_rcsum(skb, len)) return skb; memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); diff --git a/trunk/net/ipv4/ip_sockglue.c b/trunk/net/ipv4/ip_sockglue.c index 14bbfcf717ac..5eea4a811042 100644 --- a/trunk/net/ipv4/ip_sockglue.c +++ b/trunk/net/ipv4/ip_sockglue.c @@ -457,28 +457,19 @@ static int do_ip_setsockopt(struct sock *sk, int level, struct inet_sock *inet = inet_sk(sk); int val = 0, err; - switch (optname) { - case IP_PKTINFO: - case IP_RECVTTL: - case IP_RECVOPTS: - case IP_RECVTOS: - case IP_RETOPTS: - case IP_TOS: - case IP_TTL: - case IP_HDRINCL: - case IP_MTU_DISCOVER: - case IP_RECVERR: - case IP_ROUTER_ALERT: - case IP_FREEBIND: - case IP_PASSSEC: - case IP_TRANSPARENT: - case IP_MINTTL: - case IP_NODEFRAG: - case IP_UNICAST_IF: - case IP_MULTICAST_TTL: - case IP_MULTICAST_ALL: - case IP_MULTICAST_LOOP: - case IP_RECVORIGDSTADDR: + if (((1<= sizeof(int)) { if (get_user(val, (int __user *) optval)) return -EFAULT; diff --git a/trunk/net/ipv4/ip_vti.c b/trunk/net/ipv4/ip_vti.c index 858fddf6482a..1831092f999f 100644 --- a/trunk/net/ipv4/ip_vti.c +++ b/trunk/net/ipv4/ip_vti.c @@ -338,17 +338,12 @@ static int vti_rcv(struct sk_buff *skb) if (tunnel != NULL) { struct pcpu_tstats *tstats; - if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) - return -1; - tstats = this_cpu_ptr(tunnel->dev->tstats); u64_stats_update_begin(&tstats->syncp); tstats->rx_packets++; tstats->rx_bytes += skb->len; u64_stats_update_end(&tstats->syncp); - skb->mark = 0; - secpath_reset(skb); skb->dev = tunnel->dev; return 1; } diff --git a/trunk/net/ipv4/ipmr.c b/trunk/net/ipv4/ipmr.c index 3eab2b2ffd34..6168c4dc58b1 100644 --- a/trunk/net/ipv4/ipmr.c +++ b/trunk/net/ipv4/ipmr.c @@ -1318,10 +1318,6 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi if (get_user(v, (u32 __user *)optval)) return -EFAULT; - /* "pimreg%u" should not exceed 16 bytes (IFNAMSIZ) */ - if (v != RT_TABLE_DEFAULT && v >= 1000000000) - return -EINVAL; - rtnl_lock(); ret = 0; if (sk == rtnl_dereference(mrt->mroute_sk)) { diff --git a/trunk/net/ipv4/netfilter/iptable_nat.c b/trunk/net/ipv4/netfilter/iptable_nat.c index a82047282dbb..9e0ffaf1d942 100644 --- a/trunk/net/ipv4/netfilter/iptable_nat.c +++ b/trunk/net/ipv4/netfilter/iptable_nat.c @@ -184,8 +184,7 @@ nf_nat_ipv4_out(unsigned int hooknum, if ((ct->tuplehash[dir].tuple.src.u3.ip != ct->tuplehash[!dir].tuple.dst.u3.ip) || - (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP && - ct->tuplehash[dir].tuple.src.u.all != + (ct->tuplehash[dir].tuple.src.u.all != ct->tuplehash[!dir].tuple.dst.u.all)) if (nf_xfrm_me_harder(skb, AF_INET) < 0) ret = NF_DROP; @@ -222,7 +221,6 @@ nf_nat_ipv4_local_fn(unsigned int hooknum, } #ifdef CONFIG_XFRM else if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) && - ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP && ct->tuplehash[dir].tuple.dst.u.all != ct->tuplehash[!dir].tuple.src.u.all) if (nf_xfrm_me_harder(skb, AF_INET) < 0) diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index df251424d816..432f4bb77238 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -1163,12 +1163,8 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe, spin_lock_bh(&fnhe_lock); if (daddr == fnhe->fnhe_daddr) { - struct rtable *orig = rcu_dereference(fnhe->fnhe_rth); - if (orig && rt_is_expired(orig)) { - fnhe->fnhe_gw = 0; - fnhe->fnhe_pmtu = 0; - fnhe->fnhe_expires = 0; - } + struct rtable *orig; + if (fnhe->fnhe_pmtu) { unsigned long expires = fnhe->fnhe_expires; unsigned long diff = expires - jiffies; @@ -1185,6 +1181,7 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe, } else if (!rt->rt_gateway) rt->rt_gateway = daddr; + orig = rcu_dereference(fnhe->fnhe_rth); rcu_assign_pointer(fnhe->fnhe_rth, rt); if (orig) rt_free(orig); @@ -1785,7 +1782,6 @@ static struct rtable *__mkroute_output(const struct fib_result *res, if (dev_out->flags & IFF_LOOPBACK) flags |= RTCF_LOCAL; - do_cache = true; if (type == RTN_BROADCAST) { flags |= RTCF_BROADCAST | RTCF_LOCAL; fi = NULL; @@ -1794,8 +1790,6 @@ static struct rtable *__mkroute_output(const struct fib_result *res, if (!ip_check_mc_rcu(in_dev, fl4->daddr, fl4->saddr, fl4->flowi4_proto)) flags &= ~RTCF_LOCAL; - else - do_cache = false; /* If multicast route do not exist use * default one, but do not gateway in this case. * Yes, it is hack. @@ -1805,8 +1799,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res, } fnhe = NULL; - do_cache &= fi != NULL; - if (do_cache) { + do_cache = fi != NULL; + if (fi) { struct rtable __rcu **prth; struct fib_nh *nh = &FIB_RES_NH(*res); @@ -2600,7 +2594,7 @@ int __init ip_rt_init(void) pr_err("Unable to create route proc files\n"); #ifdef CONFIG_XFRM xfrm_init(); - xfrm4_init(); + xfrm4_init(ip_rt_max_size); #endif rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL, NULL); diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index e457c7ab2e28..f32c02e2a543 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -549,12 +549,14 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) !tp->urg_data || before(tp->urg_seq, tp->copied_seq) || !before(tp->urg_seq, tp->rcv_nxt)) { + struct sk_buff *skb; answ = tp->rcv_nxt - tp->copied_seq; - /* Subtract 1, if FIN was received */ - if (answ && sock_flag(sk, SOCK_DONE)) - answ--; + /* Subtract 1, if FIN is in queue. */ + skb = skb_peek_tail(&sk->sk_receive_queue); + if (answ && skb) + answ -= tcp_hdr(skb)->fin; } else answ = tp->urg_seq - tp->copied_seq; release_sock(sk); @@ -830,8 +832,8 @@ static int tcp_send_mss(struct sock *sk, int *size_goal, int flags) return mss_now; } -static ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset, - size_t size, int flags) +static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, + size_t psize, int flags) { struct tcp_sock *tp = tcp_sk(sk); int mss_now, size_goal; @@ -858,9 +860,12 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset, if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) goto out_err; - while (size > 0) { + while (psize > 0) { struct sk_buff *skb = tcp_write_queue_tail(sk); + struct page *page = pages[poffset / PAGE_SIZE]; int copy, i; + int offset = poffset % PAGE_SIZE; + int size = min_t(size_t, psize, PAGE_SIZE - offset); bool can_coalesce; if (!tcp_send_head(sk) || (copy = size_goal - skb->len) <= 0) { @@ -909,8 +914,8 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset, TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_PSH; copied += copy; - offset += copy; - if (!(size -= copy)) + poffset += copy; + if (!(psize -= copy)) goto out; if (skb->len < size_goal || (flags & MSG_OOB)) @@ -957,7 +962,7 @@ int tcp_sendpage(struct sock *sk, struct page *page, int offset, flags); lock_sock(sk); - res = do_tcp_sendpages(sk, page, offset, size, flags); + res = do_tcp_sendpages(sk, &page, offset, size, flags); release_sock(sk); return res; } @@ -1209,7 +1214,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, wait_for_sndbuf: set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); wait_for_memory: - if (copied) + if (copied && likely(!tp->repair)) tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) @@ -1220,7 +1225,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, } out: - if (copied) + if (copied && likely(!tp->repair)) tcp_push(sk, flags, mss_now, tp->nonagle); release_sock(sk); return copied + copied_syn; @@ -2761,8 +2766,6 @@ void tcp_get_info(const struct sock *sk, struct tcp_info *info) info->tcpi_options |= TCPI_OPT_ECN; if (tp->ecn_flags & TCP_ECN_SEEN) info->tcpi_options |= TCPI_OPT_ECN_SEEN; - if (tp->syn_data_acked) - info->tcpi_options |= TCPI_OPT_SYN_DATA; info->tcpi_rto = jiffies_to_usecs(icsk->icsk_rto); info->tcpi_ato = jiffies_to_usecs(icsk->icsk_ack.ato); diff --git a/trunk/net/ipv4/tcp_illinois.c b/trunk/net/ipv4/tcp_illinois.c index 834857f3c871..813b43a76fec 100644 --- a/trunk/net/ipv4/tcp_illinois.c +++ b/trunk/net/ipv4/tcp_illinois.c @@ -313,13 +313,11 @@ static void tcp_illinois_info(struct sock *sk, u32 ext, .tcpv_rttcnt = ca->cnt_rtt, .tcpv_minrtt = ca->base_rtt, }; + u64 t = ca->sum_rtt; - if (info.tcpv_rttcnt > 0) { - u64 t = ca->sum_rtt; + do_div(t, ca->cnt_rtt); + info.tcpv_rtt = t; - do_div(t, info.tcpv_rttcnt); - info.tcpv_rtt = t; - } nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info); } } diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 181fc8234a52..432c36649db3 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -4529,9 +4529,6 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) struct tcphdr *th; bool fragstolen; - if (size == 0) - return 0; - skb = alloc_skb(size + sizeof(*th), sk->sk_allocation); if (!skb) goto err; @@ -5313,6 +5310,11 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, goto discard; } + /* ts_recent update must be made after we are sure that the packet + * is in window. + */ + tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); + /* step 3: check security and precedence [ignored] */ /* step 4: Check for a SYN @@ -5547,11 +5549,6 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) goto discard; - /* ts_recent update must be made after we are sure that the packet - * is in window. - */ - tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); - tcp_rcv_rtt_measure_ts(sk, skb); /* Process urgent data. */ @@ -5645,15 +5642,10 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, tcp_fastopen_cache_set(sk, mss, cookie, syn_drop); if (data) { /* Retransmit unacked data in SYN */ - tcp_for_write_queue_from(data, sk) { - if (data == tcp_send_head(sk) || - __tcp_retransmit_skb(sk, data)) - break; - } + tcp_retransmit_skb(sk, data); tcp_rearm_rto(sk); return true; } - tp->syn_data_acked = tp->syn_data; return false; } @@ -5971,7 +5963,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, req = tp->fastopen_rsk; if (req != NULL) { - WARN_ON_ONCE(sk->sk_state != TCP_SYN_RECV && + BUG_ON(sk->sk_state != TCP_SYN_RECV && sk->sk_state != TCP_FIN_WAIT1); if (tcp_check_req(sk, skb, req, NULL, true) == NULL) @@ -6060,15 +6052,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, * ACK we have received, this would have acknowledged * our SYNACK so stop the SYNACK timer. */ - if (req != NULL) { - /* Return RST if ack_seq is invalid. - * Note that RFC793 only says to generate a - * DUPACK for it but for TCP Fast Open it seems - * better to treat this case like TCP_SYN_RECV - * above. - */ - if (!acceptable) - return 1; + if (acceptable && req != NULL) { /* We no longer need the request sock. */ reqsk_fastopen_remove(sk, req, false); tcp_rearm_rto(sk); @@ -6134,11 +6118,6 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, } else goto discard; - /* ts_recent update must be made after we are sure that the packet - * is in window. - */ - tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); - /* step 6: check the URG bit */ tcp_urg(sk, skb, th); diff --git a/trunk/net/ipv4/tcp_ipv4.c b/trunk/net/ipv4/tcp_ipv4.c index 0c4a64355603..ef998b008a57 100644 --- a/trunk/net/ipv4/tcp_ipv4.c +++ b/trunk/net/ipv4/tcp_ipv4.c @@ -1461,7 +1461,6 @@ static int tcp_v4_conn_req_fastopen(struct sock *sk, skb_set_owner_r(skb, child); __skb_queue_tail(&child->sk_receive_queue, skb); tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; - tp->syn_data_acked = 1; } sk->sk_data_ready(sk, 0); bh_unlock_sock(child); diff --git a/trunk/net/ipv4/tcp_metrics.c b/trunk/net/ipv4/tcp_metrics.c index f696d7c2e9fa..4c752a6e0bcd 100644 --- a/trunk/net/ipv4/tcp_metrics.c +++ b/trunk/net/ipv4/tcp_metrics.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -8,7 +9,6 @@ #include #include #include -#include #include #include @@ -864,7 +864,7 @@ static int parse_nl_addr(struct genl_info *info, struct inetpeer_addr *addr, } a = info->attrs[TCP_METRICS_ATTR_ADDR_IPV6]; if (a) { - if (nla_len(a) != sizeof(struct in6_addr)) + if (nla_len(a) != sizeof(sizeof(struct in6_addr))) return -EINVAL; addr->family = AF_INET6; memcpy(addr->addr.a6, nla_data(a), sizeof(addr->addr.a6)); @@ -1034,10 +1034,7 @@ static int __net_init tcp_net_metrics_init(struct net *net) net->ipv4.tcp_metrics_hash_log = order_base_2(slots); size = sizeof(struct tcpm_hash_bucket) << net->ipv4.tcp_metrics_hash_log; - net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL | __GFP_NOWARN); - if (!net->ipv4.tcp_metrics_hash) - net->ipv4.tcp_metrics_hash = vzalloc(size); - + net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL); if (!net->ipv4.tcp_metrics_hash) return -ENOMEM; @@ -1058,10 +1055,7 @@ static void __net_exit tcp_net_metrics_exit(struct net *net) tm = next; } } - if (is_vmalloc_addr(net->ipv4.tcp_metrics_hash)) - vfree(net->ipv4.tcp_metrics_hash); - else - kfree(net->ipv4.tcp_metrics_hash); + kfree(net->ipv4.tcp_metrics_hash); } static __net_initdata struct pernet_operations tcp_net_metrics_ops = { diff --git a/trunk/net/ipv4/tcp_minisocks.c b/trunk/net/ipv4/tcp_minisocks.c index a7302d974f32..27536ba16c9d 100644 --- a/trunk/net/ipv4/tcp_minisocks.c +++ b/trunk/net/ipv4/tcp_minisocks.c @@ -510,7 +510,6 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, newtp->rx_opt.mss_clamp = req->mss; TCP_ECN_openreq_child(newtp, req); newtp->fastopen_rsk = NULL; - newtp->syn_data_acked = 0; TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_PASSIVEOPENS); } diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index 948ac275b9b5..cfe6ffe1c177 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -1986,9 +1986,6 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, tso_segs = tcp_init_tso_segs(sk, skb, mss_now); BUG_ON(!tso_segs); - if (unlikely(tp->repair) && tp->repair_queue == TCP_SEND_QUEUE) - goto repair; /* Skip network transmission */ - cwnd_quota = tcp_cwnd_test(tp, skb); if (!cwnd_quota) break; @@ -2029,7 +2026,6 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp))) break; -repair: /* Advance the send_head. This one is sent out. * This call will increment packets_out. */ @@ -2309,11 +2305,12 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *to, * state updates are done by the caller. Returns non-zero if an * error occurred which prevented the send. */ -int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) +int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) { struct tcp_sock *tp = tcp_sk(sk); struct inet_connection_sock *icsk = inet_csk(sk); unsigned int cur_mss; + int err; /* Inconslusive MTU probe */ if (icsk->icsk_mtup.probe_size) { @@ -2386,17 +2383,11 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) { struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER, GFP_ATOMIC); - return nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : - -ENOBUFS; + err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : + -ENOBUFS; } else { - return tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); + err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); } -} - -int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) -{ - struct tcp_sock *tp = tcp_sk(sk); - int err = __tcp_retransmit_skb(sk, skb); if (err == 0) { /* Update global TCP statistics. */ diff --git a/trunk/net/ipv4/tcp_timer.c b/trunk/net/ipv4/tcp_timer.c index d47c1b4421a3..fc04711e80c8 100644 --- a/trunk/net/ipv4/tcp_timer.c +++ b/trunk/net/ipv4/tcp_timer.c @@ -347,8 +347,8 @@ void tcp_retransmit_timer(struct sock *sk) return; } if (tp->fastopen_rsk) { - WARN_ON_ONCE(sk->sk_state != TCP_SYN_RECV && - sk->sk_state != TCP_FIN_WAIT1); + BUG_ON(sk->sk_state != TCP_SYN_RECV && + sk->sk_state != TCP_FIN_WAIT1); tcp_fastopen_synack_timer(sk); /* Before we receive ACK to our SYN-ACK don't retransmit * anything else (e.g., data or FIN segments). diff --git a/trunk/net/ipv4/xfrm4_policy.c b/trunk/net/ipv4/xfrm4_policy.c index 3be0ac2c1920..05c5ab8d983c 100644 --- a/trunk/net/ipv4/xfrm4_policy.c +++ b/trunk/net/ipv4/xfrm4_policy.c @@ -279,8 +279,19 @@ static void __exit xfrm4_policy_fini(void) xfrm_policy_unregister_afinfo(&xfrm4_policy_afinfo); } -void __init xfrm4_init(void) +void __init xfrm4_init(int rt_max_size) { + /* + * Select a default value for the gc_thresh based on the main route + * table hash size. It seems to me the worst case scenario is when + * we have ipsec operating in transport mode, in which we create a + * dst_entry per socket. The xfrm gc algorithm starts trying to remove + * entries at gc_thresh, and prevents new allocations as 2*gc_thresh + * so lets set an initial xfrm gc_thresh value at the rt_max_size/2. + * That will let us store an ipsec connection per route table entry, + * and start cleaning when were 1/2 full + */ + xfrm4_dst_ops.gc_thresh = rt_max_size/2; dst_entries_init(&xfrm4_dst_ops); xfrm4_state_init(); diff --git a/trunk/net/ipv6/inet6_connection_sock.c b/trunk/net/ipv6/inet6_connection_sock.c index 30647857a375..c4f934176cab 100644 --- a/trunk/net/ipv6/inet6_connection_sock.c +++ b/trunk/net/ipv6/inet6_connection_sock.c @@ -252,7 +252,6 @@ struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu) return NULL; dst->ops->update_pmtu(dst, sk, NULL, mtu); - dst = inet6_csk_route_socket(sk, &fl6); - return IS_ERR(dst) ? NULL : dst; + return inet6_csk_route_socket(sk, &fl6); } EXPORT_SYMBOL_GPL(inet6_csk_update_pmtu); diff --git a/trunk/net/ipv6/ip6_gre.c b/trunk/net/ipv6/ip6_gre.c index d5cb3c4e66f8..0185679c5f53 100644 --- a/trunk/net/ipv6/ip6_gre.c +++ b/trunk/net/ipv6/ip6_gre.c @@ -1633,9 +1633,9 @@ static size_t ip6gre_get_size(const struct net_device *dev) /* IFLA_GRE_OKEY */ nla_total_size(4) + /* IFLA_GRE_LOCAL */ - nla_total_size(sizeof(struct in6_addr)) + + nla_total_size(4) + /* IFLA_GRE_REMOTE */ - nla_total_size(sizeof(struct in6_addr)) + + nla_total_size(4) + /* IFLA_GRE_TTL */ nla_total_size(1) + /* IFLA_GRE_TOS */ @@ -1659,8 +1659,8 @@ static int ip6gre_fill_info(struct sk_buff *skb, const struct net_device *dev) nla_put_be16(skb, IFLA_GRE_OFLAGS, p->o_flags) || nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) || nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) || - nla_put(skb, IFLA_GRE_LOCAL, sizeof(struct in6_addr), &p->laddr) || - nla_put(skb, IFLA_GRE_REMOTE, sizeof(struct in6_addr), &p->raddr) || + nla_put(skb, IFLA_GRE_LOCAL, sizeof(struct in6_addr), &p->raddr) || + nla_put(skb, IFLA_GRE_REMOTE, sizeof(struct in6_addr), &p->laddr) || nla_put_u8(skb, IFLA_GRE_TTL, p->hop_limit) || /*nla_put_u8(skb, IFLA_GRE_TOS, t->priority) ||*/ nla_put_u8(skb, IFLA_GRE_ENCAP_LIMIT, p->encap_limit) || diff --git a/trunk/net/ipv6/ipv6_sockglue.c b/trunk/net/ipv6/ipv6_sockglue.c index e02faed6d17e..ba6d13d1f1e1 100644 --- a/trunk/net/ipv6/ipv6_sockglue.c +++ b/trunk/net/ipv6/ipv6_sockglue.c @@ -827,7 +827,6 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, if (val < 0 || val > 255) goto e_inval; np->min_hopcount = val; - retv = 0; break; case IPV6_DONTFRAG: np->dontfrag = valbool; diff --git a/trunk/net/ipv6/ndisc.c b/trunk/net/ipv6/ndisc.c index 2edce30ef733..ff36194a71aa 100644 --- a/trunk/net/ipv6/ndisc.c +++ b/trunk/net/ipv6/ndisc.c @@ -535,7 +535,7 @@ static void ndisc_send_unsol_na(struct net_device *dev) { struct inet6_dev *idev; struct inet6_ifaddr *ifa; - struct in6_addr mcaddr = IN6ADDR_LINKLOCAL_ALLNODES_INIT; + struct in6_addr mcaddr; idev = in6_dev_get(dev); if (!idev) @@ -543,6 +543,7 @@ static void ndisc_send_unsol_na(struct net_device *dev) read_lock_bh(&idev->lock); list_for_each_entry(ifa, &idev->addr_list, if_list) { + addrconf_addr_solict_mult(&ifa->addr, &mcaddr); ndisc_send_na(dev, NULL, &mcaddr, &ifa->addr, /*router=*/ !!idev->cnf.forwarding, /*solicited=*/ false, /*override=*/ true, diff --git a/trunk/net/ipv6/netfilter/ip6table_nat.c b/trunk/net/ipv6/netfilter/ip6table_nat.c index d57dab17a182..e418bd6350a4 100644 --- a/trunk/net/ipv6/netfilter/ip6table_nat.c +++ b/trunk/net/ipv6/netfilter/ip6table_nat.c @@ -186,8 +186,7 @@ nf_nat_ipv6_out(unsigned int hooknum, if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3, &ct->tuplehash[!dir].tuple.dst.u3) || - (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 && - ct->tuplehash[dir].tuple.src.u.all != + (ct->tuplehash[dir].tuple.src.u.all != ct->tuplehash[!dir].tuple.dst.u.all)) if (nf_xfrm_me_harder(skb, AF_INET6) < 0) ret = NF_DROP; @@ -223,7 +222,6 @@ nf_nat_ipv6_local_fn(unsigned int hooknum, } #ifdef CONFIG_XFRM else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && - ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 && ct->tuplehash[dir].tuple.dst.u.all != ct->tuplehash[!dir].tuple.src.u.all) if (nf_xfrm_me_harder(skb, AF_INET6)) diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c index 22c8ea951185..18bd9bbbd1c6 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -85,7 +85,7 @@ static struct ctl_table nf_ct_frag6_sysctl_table[] = { { } }; -static int nf_ct_frag6_sysctl_register(struct net *net) +static int __net_init nf_ct_frag6_sysctl_register(struct net *net) { struct ctl_table *table; struct ctl_table_header *hdr; @@ -127,7 +127,7 @@ static void __net_exit nf_ct_frags6_sysctl_unregister(struct net *net) } #else -static int nf_ct_frag6_sysctl_register(struct net *net) +static int __net_init nf_ct_frag6_sysctl_register(struct net *net) { return 0; } diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index b1e6cf0b95fd..7c7e963260e1 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -219,7 +219,7 @@ static struct dst_ops ip6_dst_blackhole_ops = { }; static const u32 ip6_template_metrics[RTAX_MAX] = { - [RTAX_HOPLIMIT - 1] = 0, + [RTAX_HOPLIMIT - 1] = 255, }; static const struct rt6_info ip6_null_entry_template = { @@ -1232,7 +1232,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, rt->rt6i_dst.addr = fl6->daddr; rt->rt6i_dst.plen = 128; rt->rt6i_idev = idev; - dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 0); + dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); spin_lock_bh(&icmp6_dst_lock); rt->dst.next = icmp6_dst_gc_list; diff --git a/trunk/net/irda/irttp.c b/trunk/net/irda/irttp.c index ae43c62f9045..1002e3396f72 100644 --- a/trunk/net/irda/irttp.c +++ b/trunk/net/irda/irttp.c @@ -441,7 +441,6 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify) lsap = irlmp_open_lsap(stsap_sel, &ttp_notify, 0); if (lsap == NULL) { IRDA_DEBUG(0, "%s: unable to allocate LSAP!!\n", __func__); - __irttp_close_tsap(self); return NULL; } diff --git a/trunk/net/l2tp/l2tp_eth.c b/trunk/net/l2tp/l2tp_eth.c index 76125c57ee6d..37b8b8ba31f7 100644 --- a/trunk/net/l2tp/l2tp_eth.c +++ b/trunk/net/l2tp/l2tp_eth.c @@ -291,7 +291,6 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p out_del_dev: free_netdev(dev); - spriv->dev = NULL; out_del_session: l2tp_session_delete(session); out: diff --git a/trunk/net/mac80211/cfg.c b/trunk/net/mac80211/cfg.c index 7371f676cf41..05f3a313db88 100644 --- a/trunk/net/mac80211/cfg.c +++ b/trunk/net/mac80211/cfg.c @@ -2594,9 +2594,6 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, else local->probe_req_reg--; - if (!local->open_count) - break; - ieee80211_queue_work(&local->hw, &local->reconfig_filter); break; default: diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index c21e33d1abd0..5f3620f0bc0a 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -1108,7 +1108,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; sdata->u.ibss.ibss_join_req = jiffies; - memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); + memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); sdata->u.ibss.ssid_len = params->ssid_len; mutex_unlock(&sdata->u.ibss.mtx); @@ -1151,6 +1151,10 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) mutex_lock(&sdata->u.ibss.mtx); + sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; + memset(sdata->u.ibss.bssid, 0, ETH_ALEN); + sdata->u.ibss.ssid_len = 0; + active_ibss = ieee80211_sta_active_ibss(sdata); if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { @@ -1171,10 +1175,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) } } - ifibss->state = IEEE80211_IBSS_MLME_SEARCH; - memset(ifibss->bssid, 0, ETH_ALEN); - ifibss->ssid_len = 0; - sta_info_flush(sdata->local, sdata); spin_lock_bh(&ifibss->incomplete_lock); diff --git a/trunk/net/mac80211/ieee80211_i.h b/trunk/net/mac80211/ieee80211_i.h index 156e5835e37f..8c804550465b 100644 --- a/trunk/net/mac80211/ieee80211_i.h +++ b/trunk/net/mac80211/ieee80211_i.h @@ -1314,8 +1314,6 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); -void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, - struct sk_buff_head *skbs); /* HT */ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, diff --git a/trunk/net/mac80211/iface.c b/trunk/net/mac80211/iface.c index 7de7717ad67d..6f8a73c64fb3 100644 --- a/trunk/net/mac80211/iface.c +++ b/trunk/net/mac80211/iface.c @@ -853,7 +853,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); if (info->control.vif == &sdata->vif) { __skb_unlink(skb, &local->pending[i]); - ieee80211_free_txskb(&local->hw, skb); + dev_kfree_skb_irq(skb); } } } diff --git a/trunk/net/mac80211/main.c b/trunk/net/mac80211/main.c index f57f597972f8..c80c4490351c 100644 --- a/trunk/net/mac80211/main.c +++ b/trunk/net/mac80211/main.c @@ -871,10 +871,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) local->hw.wiphy->cipher_suites, sizeof(u32) * local->hw.wiphy->n_cipher_suites, GFP_KERNEL); - if (!suites) { - result = -ENOMEM; - goto fail_wiphy_register; - } + if (!suites) + return -ENOMEM; for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) { u32 suite = local->hw.wiphy->cipher_suites[r]; if (suite == WLAN_CIPHER_SUITE_WEP40 || diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index 1b7eed252fe9..e714ed8bb198 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -3099,32 +3099,22 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, ht_cfreq, ht_oper->primary_chan, cbss->channel->band); ht_oper = NULL; - } else { - channel_type = NL80211_CHAN_HT20; } } - if (ht_oper && sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { - /* - * cfg80211 already verified that the channel itself can - * be used, but it didn't check that we can do the right - * HT type, so do that here as well. If HT40 isn't allowed - * on this channel, disable 40 MHz operation. - */ + if (ht_oper) { + channel_type = NL80211_CHAN_HT20; - switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { - case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: - if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40PLUS) - ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; - else + if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { + switch (ht_oper->ht_param & + IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { + case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: channel_type = NL80211_CHAN_HT40PLUS; - break; - case IEEE80211_HT_PARAM_CHA_SEC_BELOW: - if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40MINUS) - ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; - else + break; + case IEEE80211_HT_PARAM_CHA_SEC_BELOW: channel_type = NL80211_CHAN_HT40MINUS; - break; + break; + } } } @@ -3559,7 +3549,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, { struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; - bool tx = !req->local_state_change; mutex_lock(&ifmgd->mtx); @@ -3576,12 +3565,12 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, if (ifmgd->associated && ether_addr_equal(ifmgd->associated->bssid, req->bssid)) { ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, - req->reason_code, tx, frame_buf); + req->reason_code, true, frame_buf); } else { drv_mgd_prepare_tx(sdata->local, sdata); ieee80211_send_deauth_disassoc(sdata, req->bssid, IEEE80211_STYPE_DEAUTH, - req->reason_code, tx, + req->reason_code, true, frame_buf); } diff --git a/trunk/net/mac80211/offchannel.c b/trunk/net/mac80211/offchannel.c index 2c84185dfdb0..83608ac16780 100644 --- a/trunk/net/mac80211/offchannel.c +++ b/trunk/net/mac80211/offchannel.c @@ -458,6 +458,8 @@ void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata) list_move_tail(&roc->list, &tmp_list); roc->abort = true; } + + ieee80211_start_next_roc(local); mutex_unlock(&local->mtx); list_for_each_entry_safe(roc, tmp, &tmp_list, list) { diff --git a/trunk/net/mac80211/rx.c b/trunk/net/mac80211/rx.c index 00ade7feb2e3..61c621e9273f 100644 --- a/trunk/net/mac80211/rx.c +++ b/trunk/net/mac80211/rx.c @@ -531,11 +531,6 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) if (ieee80211_is_action(hdr->frame_control)) { u8 category; - - /* make sure category field is present */ - if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE) - return RX_DROP_MONITOR; - mgmt = (struct ieee80211_mgmt *)hdr; category = mgmt->u.action.category; if (category != WLAN_CATEGORY_MESH_ACTION && @@ -888,16 +883,14 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) */ if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION && ieee80211_is_data_present(hdr->frame_control)) { - unsigned int hdrlen; - __be16 ethertype; - - hdrlen = ieee80211_hdrlen(hdr->frame_control); - - if (rx->skb->len < hdrlen + 8) - return RX_DROP_MONITOR; - - skb_copy_bits(rx->skb, hdrlen + 6, ðertype, 2); - if (ethertype == rx->sdata->control_port_protocol) + u16 ethertype; + u8 *payload; + + payload = rx->skb->data + + ieee80211_hdrlen(hdr->frame_control); + ethertype = (payload[6] << 8) | payload[7]; + if (cpu_to_be16(ethertype) == + rx->sdata->control_port_protocol) return RX_CONTINUE; } @@ -1469,14 +1462,11 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) hdr = (struct ieee80211_hdr *)rx->skb->data; fc = hdr->frame_control; - - if (ieee80211_is_ctl(fc)) - return RX_CONTINUE; - sc = le16_to_cpu(hdr->seq_ctrl); frag = sc & IEEE80211_SCTL_FRAG; if (likely((!ieee80211_has_morefrags(fc) && frag == 0) || + (rx->skb)->len < 24 || is_multicast_ether_addr(hdr->addr1))) { /* not fragmented */ goto out; @@ -1899,20 +1889,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) hdr = (struct ieee80211_hdr *) skb->data; hdrlen = ieee80211_hdrlen(hdr->frame_control); - - /* make sure fixed part of mesh header is there, also checks skb len */ - if (!pskb_may_pull(rx->skb, hdrlen + 6)) - return RX_DROP_MONITOR; - - mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); - - /* make sure full mesh header is there, also checks skb len */ - if (!pskb_may_pull(rx->skb, - hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr))) - return RX_DROP_MONITOR; - - /* reload pointers */ - hdr = (struct ieee80211_hdr *) skb->data; mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); /* frame is in RMC, don't forward */ @@ -1921,8 +1897,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata)) return RX_DROP_MONITOR; - if (!ieee80211_is_data(hdr->frame_control) || - !(status->rx_flags & IEEE80211_RX_RA_MATCH)) + if (!ieee80211_is_data(hdr->frame_control)) return RX_CONTINUE; if (!mesh_hdr->ttl) @@ -1936,12 +1911,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) if (is_multicast_ether_addr(hdr->addr1)) { mpp_addr = hdr->addr3; proxied_addr = mesh_hdr->eaddr1; - } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) { - /* has_a4 already checked in ieee80211_rx_mesh_check */ + } else { mpp_addr = hdr->addr4; proxied_addr = mesh_hdr->eaddr2; - } else { - return RX_DROP_MONITOR; } rcu_read_lock(); @@ -1969,9 +1941,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) } skb_set_queue_mapping(skb, q); + if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) + goto out; + if (!--mesh_hdr->ttl) { IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); - goto out; + return RX_DROP_MONITOR; } if (!ifmsh->mshcfg.dot11MeshForwarding) @@ -2378,10 +2353,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) } break; case WLAN_CATEGORY_SELF_PROTECTED: - if (len < (IEEE80211_MIN_ACTION_SIZE + - sizeof(mgmt->u.action.u.self_prot.action_code))) - break; - switch (mgmt->u.action.u.self_prot.action_code) { case WLAN_SP_MESH_PEERING_OPEN: case WLAN_SP_MESH_PEERING_CLOSE: @@ -2400,10 +2371,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) } break; case WLAN_CATEGORY_MESH_ACTION: - if (len < (IEEE80211_MIN_ACTION_SIZE + - sizeof(mgmt->u.action.u.mesh_action.action_code))) - break; - if (!ieee80211_vif_is_mesh(&sdata->vif)) break; if (mesh_action_is_path_sel(mgmt) && @@ -2946,15 +2913,10 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) local->dot11ReceivedFragmentCount++; - if (ieee80211_is_mgmt(fc)) { - /* drop frame if too short for header */ - if (skb->len < ieee80211_hdrlen(fc)) - err = -ENOBUFS; - else - err = skb_linearize(skb); - } else { + if (ieee80211_is_mgmt(fc)) + err = skb_linearize(skb); + else err = !pskb_may_pull(skb, ieee80211_hdrlen(fc)); - } if (err) { dev_kfree_skb(skb); diff --git a/trunk/net/mac80211/scan.c b/trunk/net/mac80211/scan.c index 43e60b5a7546..c4cdbde24fd3 100644 --- a/trunk/net/mac80211/scan.c +++ b/trunk/net/mac80211/scan.c @@ -917,7 +917,7 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, struct cfg80211_sched_scan_request *req) { struct ieee80211_local *local = sdata->local; - struct ieee80211_sched_scan_ies sched_scan_ies = {}; + struct ieee80211_sched_scan_ies sched_scan_ies; int ret, i; mutex_lock(&local->mtx); diff --git a/trunk/net/mac80211/sta_info.c b/trunk/net/mac80211/sta_info.c index d2eb64e12353..797dd36a220d 100644 --- a/trunk/net/mac80211/sta_info.c +++ b/trunk/net/mac80211/sta_info.c @@ -117,8 +117,8 @@ static void free_sta_work(struct work_struct *wk) for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]); - ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]); - ieee80211_purge_tx_queue(&local->hw, &sta->tx_filtered[ac]); + __skb_queue_purge(&sta->ps_tx_buf[ac]); + __skb_queue_purge(&sta->tx_filtered[ac]); } #ifdef CONFIG_MAC80211_MESH @@ -141,7 +141,7 @@ static void free_sta_work(struct work_struct *wk) tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]); if (!tid_tx) continue; - ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending); + __skb_queue_purge(&tid_tx->pending); kfree(tid_tx); } @@ -650,7 +650,7 @@ static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, */ if (!skb) break; - ieee80211_free_txskb(&local->hw, skb); + dev_kfree_skb(skb); } /* @@ -679,7 +679,7 @@ static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, local->total_ps_buffered--; ps_dbg(sta->sdata, "Buffered frame expired (STA %pM)\n", sta->sta.addr); - ieee80211_free_txskb(&local->hw, skb); + dev_kfree_skb(skb); } /* @@ -961,7 +961,6 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) struct ieee80211_local *local = sdata->local; struct sk_buff_head pending; int filtered = 0, buffered = 0, ac; - unsigned long flags; clear_sta_flag(sta, WLAN_STA_SP); @@ -977,16 +976,12 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { int count = skb_queue_len(&pending), tmp; - spin_lock_irqsave(&sta->tx_filtered[ac].lock, flags); skb_queue_splice_tail_init(&sta->tx_filtered[ac], &pending); - spin_unlock_irqrestore(&sta->tx_filtered[ac].lock, flags); tmp = skb_queue_len(&pending); filtered += tmp - count; count = tmp; - spin_lock_irqsave(&sta->ps_tx_buf[ac].lock, flags); skb_queue_splice_tail_init(&sta->ps_tx_buf[ac], &pending); - spin_unlock_irqrestore(&sta->ps_tx_buf[ac].lock, flags); tmp = skb_queue_len(&pending); buffered += tmp - count; } diff --git a/trunk/net/mac80211/status.c b/trunk/net/mac80211/status.c index 101eb88a2b78..3af0cc4130f1 100644 --- a/trunk/net/mac80211/status.c +++ b/trunk/net/mac80211/status.c @@ -668,12 +668,3 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb) dev_kfree_skb_any(skb); } EXPORT_SYMBOL(ieee80211_free_txskb); - -void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, - struct sk_buff_head *skbs) -{ - struct sk_buff *skb; - - while ((skb = __skb_dequeue(skbs))) - ieee80211_free_txskb(hw, skb); -} diff --git a/trunk/net/mac80211/tx.c b/trunk/net/mac80211/tx.c index b858ebe41fda..c9bf83f36657 100644 --- a/trunk/net/mac80211/tx.c +++ b/trunk/net/mac80211/tx.c @@ -1358,7 +1358,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) if (tx->skb) ieee80211_free_txskb(&tx->local->hw, tx->skb); else - ieee80211_purge_tx_queue(&tx->local->hw, &tx->skbs); + __skb_queue_purge(&tx->skbs); return -1; } else if (unlikely(res == TX_QUEUED)) { I802_DEBUG_INC(tx->local->tx_handlers_queued); @@ -2120,13 +2120,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, */ void ieee80211_clear_tx_pending(struct ieee80211_local *local) { - struct sk_buff *skb; int i; - for (i = 0; i < local->hw.queues; i++) { - while ((skb = skb_dequeue(&local->pending[i])) != NULL) - ieee80211_free_txskb(&local->hw, skb); - } + for (i = 0; i < local->hw.queues; i++) + skb_queue_purge(&local->pending[i]); } /* diff --git a/trunk/net/mac80211/util.c b/trunk/net/mac80211/util.c index 0151ae33c4cd..22ca35054dd0 100644 --- a/trunk/net/mac80211/util.c +++ b/trunk/net/mac80211/util.c @@ -406,7 +406,7 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local, int queue = info->hw_queue; if (WARN_ON(!info->control.vif)) { - ieee80211_free_txskb(&local->hw, skb); + kfree_skb(skb); return; } @@ -431,7 +431,7 @@ void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); if (WARN_ON(!info->control.vif)) { - ieee80211_free_txskb(&local->hw, skb); + kfree_skb(skb); continue; } @@ -643,41 +643,13 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, break; } - switch (id) { - case WLAN_EID_SSID: - case WLAN_EID_SUPP_RATES: - case WLAN_EID_FH_PARAMS: - case WLAN_EID_DS_PARAMS: - case WLAN_EID_CF_PARAMS: - case WLAN_EID_TIM: - case WLAN_EID_IBSS_PARAMS: - case WLAN_EID_CHALLENGE: - case WLAN_EID_RSN: - case WLAN_EID_ERP_INFO: - case WLAN_EID_EXT_SUPP_RATES: - case WLAN_EID_HT_CAPABILITY: - case WLAN_EID_HT_OPERATION: - case WLAN_EID_VHT_CAPABILITY: - case WLAN_EID_VHT_OPERATION: - case WLAN_EID_MESH_ID: - case WLAN_EID_MESH_CONFIG: - case WLAN_EID_PEER_MGMT: - case WLAN_EID_PREQ: - case WLAN_EID_PREP: - case WLAN_EID_PERR: - case WLAN_EID_RANN: - case WLAN_EID_CHANNEL_SWITCH: - case WLAN_EID_EXT_CHANSWITCH_ANN: - case WLAN_EID_COUNTRY: - case WLAN_EID_PWR_CONSTRAINT: - case WLAN_EID_TIMEOUT_INTERVAL: - if (test_bit(id, seen_elems)) { - elems->parse_error = true; - left -= elen; - pos += elen; - continue; - } - break; + if (id != WLAN_EID_VENDOR_SPECIFIC && + id != WLAN_EID_QUIET && + test_bit(id, seen_elems)) { + elems->parse_error = true; + left -= elen; + pos += elen; + continue; } if (calc_crc && id < 64 && (filter & (1ULL << id))) @@ -1491,8 +1463,6 @@ int ieee80211_reconfig(struct ieee80211_local *local) list_for_each_entry(sdata, &local->interfaces, list) { if (sdata->vif.type != NL80211_IFTYPE_STATION) continue; - if (!sdata->u.mgd.associated) - continue; ieee80211_send_nullfunc(local, sdata, 0); } diff --git a/trunk/net/mac80211/wpa.c b/trunk/net/mac80211/wpa.c index 8bd2f5c6a56e..bdb53aba888e 100644 --- a/trunk/net/mac80211/wpa.c +++ b/trunk/net/mac80211/wpa.c @@ -106,8 +106,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) if (status->flag & RX_FLAG_MMIC_ERROR) goto mic_fail; - if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key && - rx->key->conf.cipher == WLAN_CIPHER_SUITE_TKIP) + if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key) goto update_iv; return RX_CONTINUE; @@ -546,19 +545,14 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) static void bip_aad(struct sk_buff *skb, u8 *aad) { - __le16 mask_fc; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - /* BIP AAD: FC(masked) || A1 || A2 || A3 */ /* FC type/subtype */ + aad[0] = skb->data[0]; /* Mask FC Retry, PwrMgt, MoreData flags to zero */ - mask_fc = hdr->frame_control; - mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY | IEEE80211_FCTL_PM | - IEEE80211_FCTL_MOREDATA); - put_unaligned(mask_fc, (__le16 *) &aad[0]); + aad[1] = skb->data[1] & ~(BIT(4) | BIT(5) | BIT(6)); /* A1 || A2 || A3 */ - memcpy(aad + 2, &hdr->addr1, 3 * ETH_ALEN); + memcpy(aad + 2, skb->data + 4, 3 * ETH_ALEN); } diff --git a/trunk/net/netfilter/ipset/ip_set_hash_ip.c b/trunk/net/netfilter/ipset/ip_set_hash_ip.c index 5c0b78528e55..ec3dba5dcd62 100644 --- a/trunk/net/netfilter/ipset/ip_set_hash_ip.c +++ b/trunk/net/netfilter/ipset/ip_set_hash_ip.c @@ -173,7 +173,6 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[], return adtfn(set, &nip, timeout, flags); } - ip_to = ip; if (tb[IPSET_ATTR_IP_TO]) { ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); if (ret) @@ -186,7 +185,8 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[], if (!cidr || cidr > 32) return -IPSET_ERR_INVALID_CIDR; ip_set_mask_from_to(ip, ip_to, cidr); - } + } else + ip_to = ip; hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1); diff --git a/trunk/net/netfilter/ipset/ip_set_hash_ipport.c b/trunk/net/netfilter/ipset/ip_set_hash_ipport.c index 6283351f4eeb..0171f7502fa5 100644 --- a/trunk/net/netfilter/ipset/ip_set_hash_ipport.c +++ b/trunk/net/netfilter/ipset/ip_set_hash_ipport.c @@ -162,7 +162,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], const struct ip_set_hash *h = set->data; ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_ipport4_elem data = { }; - u32 ip, ip_to, p = 0, port, port_to; + u32 ip, ip_to = 0, p = 0, port, port_to; u32 timeout = h->timeout; bool with_ports = false; int ret; @@ -210,7 +210,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], return ip_set_eexist(ret, flags) ? 0 : ret; } - ip_to = ip = ntohl(data.ip); + ip = ntohl(data.ip); if (tb[IPSET_ATTR_IP_TO]) { ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); if (ret) @@ -223,7 +223,8 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], if (!cidr || cidr > 32) return -IPSET_ERR_INVALID_CIDR; ip_set_mask_from_to(ip, ip_to, cidr); - } + } else + ip_to = ip; port_to = port = ntohs(data.port); if (with_ports && tb[IPSET_ATTR_PORT_TO]) { diff --git a/trunk/net/netfilter/ipset/ip_set_hash_ipportip.c b/trunk/net/netfilter/ipset/ip_set_hash_ipportip.c index 6a21271c8d5a..6344ef551ec8 100644 --- a/trunk/net/netfilter/ipset/ip_set_hash_ipportip.c +++ b/trunk/net/netfilter/ipset/ip_set_hash_ipportip.c @@ -166,7 +166,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], const struct ip_set_hash *h = set->data; ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_ipportip4_elem data = { }; - u32 ip, ip_to, p = 0, port, port_to; + u32 ip, ip_to = 0, p = 0, port, port_to; u32 timeout = h->timeout; bool with_ports = false; int ret; @@ -218,7 +218,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], return ip_set_eexist(ret, flags) ? 0 : ret; } - ip_to = ip = ntohl(data.ip); + ip = ntohl(data.ip); if (tb[IPSET_ATTR_IP_TO]) { ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); if (ret) @@ -231,7 +231,8 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], if (!cidr || cidr > 32) return -IPSET_ERR_INVALID_CIDR; ip_set_mask_from_to(ip, ip_to, cidr); - } + } else + ip_to = ip; port_to = port = ntohs(data.port); if (with_ports && tb[IPSET_ATTR_PORT_TO]) { diff --git a/trunk/net/netfilter/ipset/ip_set_hash_ipportnet.c b/trunk/net/netfilter/ipset/ip_set_hash_ipportnet.c index 2d5cd4ee30eb..cb71f9a774e7 100644 --- a/trunk/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/trunk/net/netfilter/ipset/ip_set_hash_ipportnet.c @@ -215,8 +215,8 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], const struct ip_set_hash *h = set->data; ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_ipportnet4_elem data = { .cidr = HOST_MASK - 1 }; - u32 ip, ip_to, p = 0, port, port_to; - u32 ip2_from, ip2_to, ip2_last, ip2; + u32 ip, ip_to = 0, p = 0, port, port_to; + u32 ip2_from = 0, ip2_to, ip2_last, ip2; u32 timeout = h->timeout; bool with_ports = false; u8 cidr; @@ -286,7 +286,6 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], return ip_set_eexist(ret, flags) ? 0 : ret; } - ip_to = ip; if (tb[IPSET_ATTR_IP_TO]) { ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); if (ret) @@ -307,8 +306,6 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], if (port > port_to) swap(port, port_to); } - - ip2_to = ip2_from; if (tb[IPSET_ATTR_IP2_TO]) { ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2_TO], &ip2_to); if (ret) diff --git a/trunk/net/netfilter/ipset/ip_set_hash_netiface.c b/trunk/net/netfilter/ipset/ip_set_hash_netiface.c index 45a101439bc5..b9a63381e349 100644 --- a/trunk/net/netfilter/ipset/ip_set_hash_netiface.c +++ b/trunk/net/netfilter/ipset/ip_set_hash_netiface.c @@ -793,7 +793,7 @@ static struct ip_set_type hash_netiface_type __read_mostly = { [IPSET_ATTR_IP] = { .type = NLA_NESTED }, [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, [IPSET_ATTR_IFACE] = { .type = NLA_NUL_STRING, - .len = IFNAMSIZ - 1 }, + .len = IPSET_MAXNAMELEN - 1 }, [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, diff --git a/trunk/net/netfilter/ipvs/ip_vs_ctl.c b/trunk/net/netfilter/ipvs/ip_vs_ctl.c index c4ee43710aab..7e7198b51c06 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_ctl.c +++ b/trunk/net/netfilter/ipvs/ip_vs_ctl.c @@ -2589,8 +2589,6 @@ __ip_vs_get_timeouts(struct net *net, struct ip_vs_timeout_user *u) struct ip_vs_proto_data *pd; #endif - memset(u, 0, sizeof (*u)); - #ifdef CONFIG_IP_VS_PROTO_TCP pd = ip_vs_proto_data_get(net, IPPROTO_TCP); u->tcp_timeout = pd->timeout_table[IP_VS_TCP_S_ESTABLISHED] / HZ; @@ -2768,6 +2766,7 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) { struct ip_vs_timeout_user t; + memset(&t, 0, sizeof(t)); __ip_vs_get_timeouts(net, &t); if (copy_to_user(user, &t, sizeof(t)) != 0) ret = -EFAULT; diff --git a/trunk/net/netfilter/nf_conntrack_h323_main.c b/trunk/net/netfilter/nf_conntrack_h323_main.c index 962795e839ab..1b30b0dee708 100644 --- a/trunk/net/netfilter/nf_conntrack_h323_main.c +++ b/trunk/net/netfilter/nf_conntrack_h323_main.c @@ -753,8 +753,7 @@ static int callforward_do_filter(const union nf_inet_addr *src, flowi4_to_flowi(&fl1), false)) { if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, flowi4_to_flowi(&fl2), false)) { - if (rt_nexthop(rt1, fl1.daddr) == - rt_nexthop(rt2, fl2.daddr) && + if (rt1->rt_gateway == rt2->rt_gateway && rt1->dst.dev == rt2->dst.dev) ret = 1; dst_release(&rt2->dst); diff --git a/trunk/net/netfilter/nfnetlink_cttimeout.c b/trunk/net/netfilter/nfnetlink_cttimeout.c index 701c88a20fea..8847b4d8be06 100644 --- a/trunk/net/netfilter/nfnetlink_cttimeout.c +++ b/trunk/net/netfilter/nfnetlink_cttimeout.c @@ -41,8 +41,7 @@ MODULE_DESCRIPTION("cttimeout: Extended Netfilter Connection Tracking timeout tu static LIST_HEAD(cttimeout_list); static const struct nla_policy cttimeout_nla_policy[CTA_TIMEOUT_MAX+1] = { - [CTA_TIMEOUT_NAME] = { .type = NLA_NUL_STRING, - .len = CTNL_TIMEOUT_NAME_MAX - 1}, + [CTA_TIMEOUT_NAME] = { .type = NLA_NUL_STRING }, [CTA_TIMEOUT_L3PROTO] = { .type = NLA_U16 }, [CTA_TIMEOUT_L4PROTO] = { .type = NLA_U8 }, [CTA_TIMEOUT_DATA] = { .type = NLA_NESTED }, diff --git a/trunk/net/netfilter/xt_CT.c b/trunk/net/netfilter/xt_CT.c index ae7f5daeee43..16c712563860 100644 --- a/trunk/net/netfilter/xt_CT.c +++ b/trunk/net/netfilter/xt_CT.c @@ -180,9 +180,9 @@ xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par, typeof(nf_ct_timeout_find_get_hook) timeout_find_get; struct ctnl_timeout *timeout; struct nf_conn_timeout *timeout_ext; + const struct ipt_entry *e = par->entryinfo; struct nf_conntrack_l4proto *l4proto; int ret = 0; - u8 proto; rcu_read_lock(); timeout_find_get = rcu_dereference(nf_ct_timeout_find_get_hook); @@ -192,11 +192,9 @@ xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par, goto out; } - proto = xt_ct_find_proto(par); - if (!proto) { + if (e->ip.invflags & IPT_INV_PROTO) { ret = -EINVAL; - pr_info("You must specify a L4 protocol, and not use " - "inversions on it.\n"); + pr_info("You cannot use inversion on L4 protocol\n"); goto out; } @@ -216,7 +214,7 @@ xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par, /* Make sure the timeout policy matches any existing protocol tracker, * otherwise default to generic. */ - l4proto = __nf_ct_l4proto_find(par->family, proto); + l4proto = __nf_ct_l4proto_find(par->family, e->ip.proto); if (timeout->l4proto->l4proto != l4proto->l4proto) { ret = -EINVAL; pr_info("Timeout policy `%s' can only be used by L4 protocol " diff --git a/trunk/net/netfilter/xt_TEE.c b/trunk/net/netfilter/xt_TEE.c index bd93e51d30ac..ee2e5bc5a8c7 100644 --- a/trunk/net/netfilter/xt_TEE.c +++ b/trunk/net/netfilter/xt_TEE.c @@ -70,7 +70,6 @@ tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info) fl4.daddr = info->gw.ip; fl4.flowi4_tos = RT_TOS(iph->tos); fl4.flowi4_scope = RT_SCOPE_UNIVERSE; - fl4.flowi4_flags = FLOWI_FLAG_KNOWN_NH; rt = ip_route_output_key(net, &fl4); if (IS_ERR(rt)) return false; diff --git a/trunk/net/netfilter/xt_nat.c b/trunk/net/netfilter/xt_nat.c index bea7464cc43f..81aafa8e4fef 100644 --- a/trunk/net/netfilter/xt_nat.c +++ b/trunk/net/netfilter/xt_nat.c @@ -111,7 +111,7 @@ static struct xt_target xt_nat_target_reg[] __read_mostly = { .family = NFPROTO_IPV4, .table = "nat", .hooks = (1 << NF_INET_POST_ROUTING) | - (1 << NF_INET_LOCAL_IN), + (1 << NF_INET_LOCAL_OUT), .me = THIS_MODULE, }, { @@ -123,7 +123,7 @@ static struct xt_target xt_nat_target_reg[] __read_mostly = { .family = NFPROTO_IPV4, .table = "nat", .hooks = (1 << NF_INET_PRE_ROUTING) | - (1 << NF_INET_LOCAL_OUT), + (1 << NF_INET_LOCAL_IN), .me = THIS_MODULE, }, { @@ -133,7 +133,7 @@ static struct xt_target xt_nat_target_reg[] __read_mostly = { .targetsize = sizeof(struct nf_nat_range), .table = "nat", .hooks = (1 << NF_INET_POST_ROUTING) | - (1 << NF_INET_LOCAL_IN), + (1 << NF_INET_LOCAL_OUT), .me = THIS_MODULE, }, { @@ -143,7 +143,7 @@ static struct xt_target xt_nat_target_reg[] __read_mostly = { .targetsize = sizeof(struct nf_nat_range), .table = "nat", .hooks = (1 << NF_INET_PRE_ROUTING) | - (1 << NF_INET_LOCAL_OUT), + (1 << NF_INET_LOCAL_IN), .me = THIS_MODULE, }, }; diff --git a/trunk/net/netlink/af_netlink.c b/trunk/net/netlink/af_netlink.c index 4da797fa5ec5..01e944a017a4 100644 --- a/trunk/net/netlink/af_netlink.c +++ b/trunk/net/netlink/af_netlink.c @@ -138,8 +138,6 @@ static int netlink_dump(struct sock *sk); static DEFINE_RWLOCK(nl_table_lock); static atomic_t nl_table_users = ATOMIC_INIT(0); -#define nl_deref_protected(X) rcu_dereference_protected(X, lockdep_is_held(&nl_table_lock)); - static ATOMIC_NOTIFIER_HEAD(netlink_chain); static inline u32 netlink_group_mask(u32 group) @@ -347,11 +345,6 @@ netlink_update_listeners(struct sock *sk) struct hlist_node *node; unsigned long mask; unsigned int i; - struct listeners *listeners; - - listeners = nl_deref_protected(tbl->listeners); - if (!listeners) - return; for (i = 0; i < NLGRPLONGS(tbl->groups); i++) { mask = 0; @@ -359,7 +352,7 @@ netlink_update_listeners(struct sock *sk) if (i < NLGRPLONGS(nlk_sk(sk)->ngroups)) mask |= nlk_sk(sk)->groups[i]; } - listeners->masks[i] = mask; + tbl->listeners->masks[i] = mask; } /* this function is only called with the netlink table "grabbed", which * makes sure updates are visible before bind or setsockopt return. */ @@ -543,11 +536,7 @@ static int netlink_release(struct socket *sock) if (netlink_is_kernel(sk)) { BUG_ON(nl_table[sk->sk_protocol].registered == 0); if (--nl_table[sk->sk_protocol].registered == 0) { - struct listeners *old; - - old = nl_deref_protected(nl_table[sk->sk_protocol].listeners); - RCU_INIT_POINTER(nl_table[sk->sk_protocol].listeners, NULL); - kfree_rcu(old, rcu); + kfree(nl_table[sk->sk_protocol].listeners); nl_table[sk->sk_protocol].module = NULL; nl_table[sk->sk_protocol].bind = NULL; nl_table[sk->sk_protocol].flags = 0; @@ -993,7 +982,7 @@ int netlink_has_listeners(struct sock *sk, unsigned int group) rcu_read_lock(); listeners = rcu_dereference(nl_table[sk->sk_protocol].listeners); - if (listeners && group - 1 < nl_table[sk->sk_protocol].groups) + if (group - 1 < nl_table[sk->sk_protocol].groups) res = test_bit(group - 1, listeners->masks); rcu_read_unlock(); @@ -1636,7 +1625,7 @@ int __netlink_change_ngroups(struct sock *sk, unsigned int groups) new = kzalloc(sizeof(*new) + NLGRPSZ(groups), GFP_ATOMIC); if (!new) return -ENOMEM; - old = nl_deref_protected(tbl->listeners); + old = rcu_dereference_protected(tbl->listeners, 1); memcpy(new->masks, old->masks, NLGRPSZ(tbl->groups)); rcu_assign_pointer(tbl->listeners, new); diff --git a/trunk/net/nfc/llcp/llcp.c b/trunk/net/nfc/llcp/llcp.c index 9e8f4b2801f6..cc10d073c338 100644 --- a/trunk/net/nfc/llcp/llcp.c +++ b/trunk/net/nfc/llcp/llcp.c @@ -1210,7 +1210,7 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) local->remote_miu = LLCP_DEFAULT_MIU; local->remote_lto = LLCP_DEFAULT_LTO; - list_add(&local->list, &llcp_devices); + list_add(&llcp_devices, &local->list); return 0; } diff --git a/trunk/net/openvswitch/flow.c b/trunk/net/openvswitch/flow.c index 733cbf49ed1f..98c70630ad06 100644 --- a/trunk/net/openvswitch/flow.c +++ b/trunk/net/openvswitch/flow.c @@ -702,11 +702,15 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key, /* We only match on the lower 8 bits of the opcode. */ if (ntohs(arp->ar_op) <= 0xff) key->ip.proto = ntohs(arp->ar_op); - memcpy(&key->ipv4.addr.src, arp->ar_sip, sizeof(key->ipv4.addr.src)); - memcpy(&key->ipv4.addr.dst, arp->ar_tip, sizeof(key->ipv4.addr.dst)); - memcpy(key->ipv4.arp.sha, arp->ar_sha, ETH_ALEN); - memcpy(key->ipv4.arp.tha, arp->ar_tha, ETH_ALEN); - key_len = SW_FLOW_KEY_OFFSET(ipv4.arp); + + if (key->ip.proto == ARPOP_REQUEST + || key->ip.proto == ARPOP_REPLY) { + memcpy(&key->ipv4.addr.src, arp->ar_sip, sizeof(key->ipv4.addr.src)); + memcpy(&key->ipv4.addr.dst, arp->ar_tip, sizeof(key->ipv4.addr.dst)); + memcpy(key->ipv4.arp.sha, arp->ar_sha, ETH_ALEN); + memcpy(key->ipv4.arp.tha, arp->ar_tha, ETH_ALEN); + key_len = SW_FLOW_KEY_OFFSET(ipv4.arp); + } } } else if (key->eth.type == htons(ETH_P_IPV6)) { int nh_len; /* IPv6 Header + Extensions */ diff --git a/trunk/net/openvswitch/vport-netdev.c b/trunk/net/openvswitch/vport-netdev.c index a9033481fa5e..3c1e58ba714b 100644 --- a/trunk/net/openvswitch/vport-netdev.c +++ b/trunk/net/openvswitch/vport-netdev.c @@ -158,7 +158,7 @@ static int netdev_send(struct vport *vport, struct sk_buff *skb) if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) { net_warn_ratelimited("%s: dropped over-mtu packet: %d > %d\n", - netdev_vport->dev->name, + ovs_dp_name(vport->dp), packet_length(skb), mtu); goto error; } diff --git a/trunk/net/sched/sch_qfq.c b/trunk/net/sched/sch_qfq.c index 9687fa1c2275..f0dd83cff906 100644 --- a/trunk/net/sched/sch_qfq.c +++ b/trunk/net/sched/sch_qfq.c @@ -84,19 +84,18 @@ * grp->index is the index of the group; and grp->slot_shift * is the shift for the corresponding (scaled) sigma_i. */ -#define QFQ_MAX_INDEX 24 -#define QFQ_MAX_WSHIFT 12 +#define QFQ_MAX_INDEX 19 +#define QFQ_MAX_WSHIFT 16 #define QFQ_MAX_WEIGHT (1<wsum += delta_w; } -static void qfq_update_reactivate_class(struct qfq_sched *q, - struct qfq_class *cl, - u32 inv_w, u32 lmax, int delta_w) -{ - bool need_reactivation = false; - int i = qfq_calc_index(inv_w, lmax); - - if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) { - /* - * shift cl->F back, to not charge the - * class for the not-yet-served head - * packet - */ - cl->F = cl->S; - /* remove class from its slot in the old group */ - qfq_deactivate_class(q, cl); - need_reactivation = true; - } - - qfq_update_class_params(q, cl, lmax, inv_w, delta_w); - - if (need_reactivation) /* activate in new group */ - qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc)); -} - - static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **tca, unsigned long *arg) { @@ -265,7 +238,7 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct qfq_class *cl = (struct qfq_class *)*arg; struct nlattr *tb[TCA_QFQ_MAX + 1]; u32 weight, lmax, inv_w; - int err; + int i, err; int delta_w; if (tca[TCA_OPTIONS] == NULL) { @@ -297,14 +270,16 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (tb[TCA_QFQ_LMAX]) { lmax = nla_get_u32(tb[TCA_QFQ_LMAX]); - if (lmax < QFQ_MIN_LMAX || lmax > (1UL << QFQ_MTU_SHIFT)) { + if (!lmax || lmax > (1UL << QFQ_MTU_SHIFT)) { pr_notice("qfq: invalid max length %u\n", lmax); return -EINVAL; } } else - lmax = psched_mtu(qdisc_dev(sch)); + lmax = 1UL << QFQ_MTU_SHIFT; if (cl != NULL) { + bool need_reactivation = false; + if (tca[TCA_RATE]) { err = gen_replace_estimator(&cl->bstats, &cl->rate_est, qdisc_root_sleeping_lock(sch), @@ -316,8 +291,24 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (lmax == cl->lmax && inv_w == cl->inv_w) return 0; /* nothing to update */ + i = qfq_calc_index(inv_w, lmax); sch_tree_lock(sch); - qfq_update_reactivate_class(q, cl, inv_w, lmax, delta_w); + if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) { + /* + * shift cl->F back, to not charge the + * class for the not-yet-served head + * packet + */ + cl->F = cl->S; + /* remove class from its slot in the old group */ + qfq_deactivate_class(q, cl); + need_reactivation = true; + } + + qfq_update_class_params(q, cl, lmax, inv_w, delta_w); + + if (need_reactivation) /* activate in new group */ + qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc)); sch_tree_unlock(sch); return 0; @@ -672,48 +663,15 @@ static void qfq_make_eligible(struct qfq_sched *q, u64 old_V) /* - * If the weight and lmax (max_pkt_size) of the classes do not change, - * then QFQ guarantees that the slot index is never higher than - * 2 + ((1<S rounded on grp->slot_shift bits. */ static void qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl, u64 roundedS) { u64 slot = (roundedS - grp->S) >> grp->slot_shift; - unsigned int i; /* slot index in the bucket list */ - - if (unlikely(slot > QFQ_MAX_SLOTS - 2)) { - u64 deltaS = roundedS - grp->S - - ((u64)(QFQ_MAX_SLOTS - 2)<slot_shift); - cl->S -= deltaS; - cl->F -= deltaS; - slot = QFQ_MAX_SLOTS - 2; - } - - i = (grp->front + slot) % QFQ_MAX_SLOTS; + unsigned int i = (grp->front + slot) % QFQ_MAX_SLOTS; hlist_add_head(&cl->next, &grp->slots[i]); __set_bit(slot, &grp->full_slots); @@ -934,13 +892,6 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) } pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid); - if (unlikely(cl->lmax < qdisc_pkt_len(skb))) { - pr_debug("qfq: increasing maxpkt from %u to %u for class %u", - cl->lmax, qdisc_pkt_len(skb), cl->common.classid); - qfq_update_reactivate_class(q, cl, cl->inv_w, - qdisc_pkt_len(skb), 0); - } - err = qdisc_enqueue(skb, cl->qdisc); if (unlikely(err != NET_XMIT_SUCCESS)) { pr_debug("qfq_enqueue: enqueue failed %d\n", err); diff --git a/trunk/net/sctp/chunk.c b/trunk/net/sctp/chunk.c index 69ce21e3716f..7c2df9c33df3 100644 --- a/trunk/net/sctp/chunk.c +++ b/trunk/net/sctp/chunk.c @@ -183,7 +183,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, msg = sctp_datamsg_new(GFP_KERNEL); if (!msg) - return ERR_PTR(-ENOMEM); + return NULL; /* Note: Calculate this outside of the loop, so that all fragments * have the same expiration. @@ -280,14 +280,11 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, chunk = sctp_make_datafrag_empty(asoc, sinfo, len, frag, 0); - if (!chunk) { - err = -ENOMEM; + if (!chunk) goto errout; - } - err = sctp_user_addto_chunk(chunk, offset, len, msgh->msg_iov); if (err < 0) - goto errout_chunk_free; + goto errout; offset += len; @@ -318,10 +315,8 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, chunk = sctp_make_datafrag_empty(asoc, sinfo, over, frag, 0); - if (!chunk) { - err = -ENOMEM; + if (!chunk) goto errout; - } err = sctp_user_addto_chunk(chunk, offset, over,msgh->msg_iov); @@ -329,7 +324,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr - (__u8 *)chunk->skb->data); if (err < 0) - goto errout_chunk_free; + goto errout; sctp_datamsg_assign(msg, chunk); list_add_tail(&chunk->frag_list, &msg->chunks); @@ -337,9 +332,6 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, return msg; -errout_chunk_free: - sctp_chunk_free(chunk); - errout: list_for_each_safe(pos, temp, &msg->chunks) { list_del_init(pos); @@ -347,7 +339,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, sctp_chunk_free(chunk); } sctp_datamsg_put(msg); - return ERR_PTR(err); + return NULL; } /* Check whether this message has expired. */ diff --git a/trunk/net/sctp/proc.c b/trunk/net/sctp/proc.c index 9966e7b16451..c3bea269faf4 100644 --- a/trunk/net/sctp/proc.c +++ b/trunk/net/sctp/proc.c @@ -102,7 +102,7 @@ static const struct file_operations sctp_snmp_seq_fops = { .open = sctp_snmp_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = single_release_net, + .release = single_release, }; /* Set up the proc fs entry for 'snmp' object. */ @@ -251,7 +251,7 @@ static const struct file_operations sctp_eps_seq_fops = { .open = sctp_eps_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release_net, + .release = seq_release, }; /* Set up the proc fs entry for 'eps' object. */ @@ -372,7 +372,7 @@ static const struct file_operations sctp_assocs_seq_fops = { .open = sctp_assocs_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release_net, + .release = seq_release, }; /* Set up the proc fs entry for 'assocs' object. */ @@ -517,7 +517,7 @@ static const struct file_operations sctp_remaddr_seq_fops = { .open = sctp_remaddr_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release_net, + .release = seq_release, }; int __net_init sctp_remaddr_proc_init(struct net *net) diff --git a/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index 406d957d08fb..59d16ea927f0 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/net/sctp/socket.c @@ -974,7 +974,7 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk, void *addr_buf; struct sctp_af *af; - SCTP_DEBUG_PRINTK("sctp_setsockopt_bindx: sk %p addrs %p" + SCTP_DEBUG_PRINTK("sctp_setsocktopt_bindx: sk %p addrs %p" " addrs_size %d opt %d\n", sk, addrs, addrs_size, op); if (unlikely(addrs_size <= 0)) @@ -1915,8 +1915,8 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, /* Break the message into multiple chunks of maximum size. */ datamsg = sctp_datamsg_from_user(asoc, sinfo, msg, msg_len); - if (IS_ERR(datamsg)) { - err = PTR_ERR(datamsg); + if (!datamsg) { + err = -ENOMEM; goto out_free; } diff --git a/trunk/net/sctp/transport.c b/trunk/net/sctp/transport.c index 206cf5238fd3..953c21e4af97 100644 --- a/trunk/net/sctp/transport.c +++ b/trunk/net/sctp/transport.c @@ -331,7 +331,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt) * 1/8, rto_alpha would be expressed as 3. */ tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta) - + (((__u32)abs64((__s64)tp->srtt - (__s64)rtt)) >> net->sctp.rto_beta); + + ((abs(tp->srtt - rtt)) >> net->sctp.rto_beta); tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha) + (rtt >> net->sctp.rto_alpha); } else { diff --git a/trunk/net/sunrpc/backchannel_rqst.c b/trunk/net/sunrpc/backchannel_rqst.c index a9c0bbccad6b..5a3d675d2f2f 100644 --- a/trunk/net/sunrpc/backchannel_rqst.c +++ b/trunk/net/sunrpc/backchannel_rqst.c @@ -172,7 +172,7 @@ int xprt_setup_backchannel(struct rpc_xprt *xprt, unsigned int min_reqs) xprt_free_allocation(req); dprintk("RPC: setup backchannel transport failed\n"); - return -ENOMEM; + return -1; } EXPORT_SYMBOL_GPL(xprt_setup_backchannel); diff --git a/trunk/net/sunrpc/xprtsock.c b/trunk/net/sunrpc/xprtsock.c index 75853cabf4c9..aaaadfbe36e9 100644 --- a/trunk/net/sunrpc/xprtsock.c +++ b/trunk/net/sunrpc/xprtsock.c @@ -254,6 +254,7 @@ struct sock_xprt { void (*old_data_ready)(struct sock *, int); void (*old_state_change)(struct sock *); void (*old_write_space)(struct sock *); + void (*old_error_report)(struct sock *); }; /* @@ -736,10 +737,10 @@ static int xs_tcp_send_request(struct rpc_task *task) dprintk("RPC: sendmsg returned unrecognized error %d\n", -status); case -ECONNRESET: + case -EPIPE: xs_tcp_shutdown(xprt); case -ECONNREFUSED: case -ENOTCONN: - case -EPIPE: clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); } @@ -780,6 +781,7 @@ static void xs_save_old_callbacks(struct sock_xprt *transport, struct sock *sk) transport->old_data_ready = sk->sk_data_ready; transport->old_state_change = sk->sk_state_change; transport->old_write_space = sk->sk_write_space; + transport->old_error_report = sk->sk_error_report; } static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *sk) @@ -787,6 +789,7 @@ static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *s sk->sk_data_ready = transport->old_data_ready; sk->sk_state_change = transport->old_state_change; sk->sk_write_space = transport->old_write_space; + sk->sk_error_report = transport->old_error_report; } static void xs_reset_transport(struct sock_xprt *transport) @@ -1450,7 +1453,7 @@ static void xs_tcp_cancel_linger_timeout(struct rpc_xprt *xprt) xprt_clear_connecting(xprt); } -static void xs_sock_reset_connection_flags(struct rpc_xprt *xprt) +static void xs_sock_mark_closed(struct rpc_xprt *xprt) { smp_mb__before_clear_bit(); clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); @@ -1458,11 +1461,6 @@ static void xs_sock_reset_connection_flags(struct rpc_xprt *xprt) clear_bit(XPRT_CLOSE_WAIT, &xprt->state); clear_bit(XPRT_CLOSING, &xprt->state); smp_mb__after_clear_bit(); -} - -static void xs_sock_mark_closed(struct rpc_xprt *xprt) -{ - xs_sock_reset_connection_flags(xprt); /* Mark transport as closed and wake up all pending tasks */ xprt_disconnect_done(xprt); } @@ -1518,7 +1516,6 @@ static void xs_tcp_state_change(struct sock *sk) case TCP_CLOSE_WAIT: /* The server initiated a shutdown of the socket */ xprt->connect_cookie++; - clear_bit(XPRT_CONNECTED, &xprt->state); xs_tcp_force_close(xprt); case TCP_CLOSING: /* @@ -1543,6 +1540,25 @@ static void xs_tcp_state_change(struct sock *sk) read_unlock_bh(&sk->sk_callback_lock); } +/** + * xs_error_report - callback mainly for catching socket errors + * @sk: socket + */ +static void xs_error_report(struct sock *sk) +{ + struct rpc_xprt *xprt; + + read_lock_bh(&sk->sk_callback_lock); + if (!(xprt = xprt_from_sock(sk))) + goto out; + dprintk("RPC: %s client %p...\n" + "RPC: error %d\n", + __func__, xprt, sk->sk_err); + xprt_wake_pending_tasks(xprt, -EAGAIN); +out: + read_unlock_bh(&sk->sk_callback_lock); +} + static void xs_write_space(struct sock *sk) { struct socket *sock; @@ -1842,6 +1858,7 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt, sk->sk_user_data = xprt; sk->sk_data_ready = xs_local_data_ready; sk->sk_write_space = xs_udp_write_space; + sk->sk_error_report = xs_error_report; sk->sk_allocation = GFP_ATOMIC; xprt_clear_connected(xprt); @@ -1966,6 +1983,7 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) sk->sk_user_data = xprt; sk->sk_data_ready = xs_udp_data_ready; sk->sk_write_space = xs_udp_write_space; + sk->sk_error_report = xs_error_report; sk->sk_no_check = UDP_CSUM_NORCV; sk->sk_allocation = GFP_ATOMIC; @@ -2032,8 +2050,10 @@ static void xs_abort_connection(struct sock_xprt *transport) any.sa_family = AF_UNSPEC; result = kernel_connect(transport->sock, &any, sizeof(any), 0); if (!result) - xs_sock_reset_connection_flags(&transport->xprt); - dprintk("RPC: AF_UNSPEC connect return code %d\n", result); + xs_sock_mark_closed(&transport->xprt); + else + dprintk("RPC: AF_UNSPEC connect return code %d\n", + result); } static void xs_tcp_reuse_connection(struct sock_xprt *transport) @@ -2078,6 +2098,7 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) sk->sk_data_ready = xs_tcp_data_ready; sk->sk_state_change = xs_tcp_state_change; sk->sk_write_space = xs_tcp_write_space; + sk->sk_error_report = xs_error_report; sk->sk_allocation = GFP_ATOMIC; /* socket options */ diff --git a/trunk/net/tipc/handler.c b/trunk/net/tipc/handler.c index b36f0fcd9bdf..111ff8300ae5 100644 --- a/trunk/net/tipc/handler.c +++ b/trunk/net/tipc/handler.c @@ -116,6 +116,7 @@ void tipc_handler_stop(void) return; handler_enabled = 0; + tasklet_disable(&tipc_tasklet); tasklet_kill(&tipc_tasklet); spin_lock_bh(&qitem_lock); diff --git a/trunk/net/wireless/core.c b/trunk/net/wireless/core.c index 3f7253052088..443d4d7deea2 100644 --- a/trunk/net/wireless/core.c +++ b/trunk/net/wireless/core.c @@ -526,7 +526,8 @@ int wiphy_register(struct wiphy *wiphy) for (i = 0; i < sband->n_channels; i++) { sband->channels[i].orig_flags = sband->channels[i].flags; - sband->channels[i].orig_mag = INT_MAX; + sband->channels[i].orig_mag = + sband->channels[i].max_antenna_gain; sband->channels[i].orig_mpwr = sband->channels[i].max_power; sband->channels[i].band = band; diff --git a/trunk/net/wireless/mlme.c b/trunk/net/wireless/mlme.c index 904a7f368325..8016fee0752b 100644 --- a/trunk/net/wireless/mlme.c +++ b/trunk/net/wireless/mlme.c @@ -457,14 +457,20 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, .reason_code = reason, .ie = ie, .ie_len = ie_len, - .local_state_change = local_state_change, }; ASSERT_WDEV_LOCK(wdev); - if (local_state_change && (!wdev->current_bss || - !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) + if (local_state_change) { + if (wdev->current_bss && + ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { + cfg80211_unhold_bss(wdev->current_bss); + cfg80211_put_bss(&wdev->current_bss->pub); + wdev->current_bss = NULL; + } + return 0; + } return rdev->ops->deauth(&rdev->wiphy, dev, &req); } diff --git a/trunk/net/wireless/reg.c b/trunk/net/wireless/reg.c index b75756b05af7..3b8cbbc214db 100644 --- a/trunk/net/wireless/reg.c +++ b/trunk/net/wireless/reg.c @@ -141,8 +141,9 @@ static const struct ieee80211_regdomain world_regdom = { .reg_rules = { /* IEEE 802.11b/g, channels 1..11 */ REG_RULE(2412-10, 2462+10, 40, 6, 20, 0), - /* IEEE 802.11b/g, channels 12..13. */ - REG_RULE(2467-10, 2472+10, 40, 6, 20, + /* IEEE 802.11b/g, channels 12..13. No HT40 + * channel fits here. */ + REG_RULE(2467-10, 2472+10, 20, 6, 20, NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), /* IEEE 802.11 channel 14 - Only JP enables @@ -907,7 +908,7 @@ static void handle_channel(struct wiphy *wiphy, map_regdom_flags(reg_rule->flags) | bw_flags; chan->max_antenna_gain = chan->orig_mag = (int) MBI_TO_DBI(power_rule->max_antenna_gain); - chan->max_reg_power = chan->max_power = chan->orig_mpwr = + chan->max_power = chan->orig_mpwr = (int) MBM_TO_DBM(power_rule->max_eirp); return; } @@ -1330,8 +1331,7 @@ static void handle_channel_custom(struct wiphy *wiphy, chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags; chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain); - chan->max_reg_power = chan->max_power = - (int) MBM_TO_DBM(power_rule->max_eirp); + chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp); } static void handle_band_custom(struct wiphy *wiphy, enum ieee80211_band band, diff --git a/trunk/net/wireless/util.c b/trunk/net/wireless/util.c index 2762e8329986..ef35f4ef2aa6 100644 --- a/trunk/net/wireless/util.c +++ b/trunk/net/wireless/util.c @@ -309,21 +309,23 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) } EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); -unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) +static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) { int ae = meshhdr->flags & MESH_FLAGS_AE; - /* 802.11-2012, 8.2.4.7.3 */ + /* 7.1.3.5a.2 */ switch (ae) { - default: case 0: return 6; case MESH_FLAGS_AE_A4: return 12; case MESH_FLAGS_AE_A5_A6: return 18; + case (MESH_FLAGS_AE_A4 | MESH_FLAGS_AE_A5_A6): + return 24; + default: + return 6; } } -EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, enum nl80211_iftype iftype) @@ -371,8 +373,6 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, /* make sure meshdr->flags is on the linear part */ if (!pskb_may_pull(skb, hdrlen + 1)) return -1; - if (meshdr->flags & MESH_FLAGS_AE_A4) - return -1; if (meshdr->flags & MESH_FLAGS_AE_A5_A6) { skb_copy_bits(skb, hdrlen + offsetof(struct ieee80211s_hdr, eaddr1), @@ -397,8 +397,6 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, /* make sure meshdr->flags is on the linear part */ if (!pskb_may_pull(skb, hdrlen + 1)) return -1; - if (meshdr->flags & MESH_FLAGS_AE_A5_A6) - return -1; if (meshdr->flags & MESH_FLAGS_AE_A4) skb_copy_bits(skb, hdrlen + offsetof(struct ieee80211s_hdr, eaddr1), diff --git a/trunk/scripts/Makefile.modinst b/trunk/scripts/Makefile.modinst index ecbb44797e28..dda4b2b61927 100644 --- a/trunk/scripts/Makefile.modinst +++ b/trunk/scripts/Makefile.modinst @@ -16,9 +16,8 @@ PHONY += $(modules) __modinst: $(modules) @: -# Don't stop modules_install if we can't sign external modules. quiet_cmd_modules_install = INSTALL $@ - cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) ; $(mod_sign_cmd) $(2)/$(notdir $@) $(patsubst %,|| true,$(KBUILD_EXTMOD)) + cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) ; $(mod_sign_cmd) $(2)/$(notdir $@) # Modules built outside the kernel source tree go into extra by default INSTALL_MOD_DIR ?= extra diff --git a/trunk/scripts/checkpatch.pl b/trunk/scripts/checkpatch.pl index f18750e3bd6c..21a9f5de0a21 100755 --- a/trunk/scripts/checkpatch.pl +++ b/trunk/scripts/checkpatch.pl @@ -1890,10 +1890,8 @@ sub process { } if ($realfile =~ m@^(drivers/net/|net/)@ && - $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ - $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ - $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ - $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ + $rawline !~ m@^\+[ \t]*(\/\*|\*\/)@ && + $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { WARN("NETWORKING_BLOCK_COMMENT_STYLE", "networking block comments put the trailing */ on a separate line\n" . $herecurr); } diff --git a/trunk/scripts/headers_install.pl b/trunk/scripts/headers_install.pl index 6c353ae8a451..239d22d4207b 100644 --- a/trunk/scripts/headers_install.pl +++ b/trunk/scripts/headers_install.pl @@ -42,9 +42,6 @@ $line =~ s/(^|\s)(inline)\b/$1__$2__/g; $line =~ s/(^|\s)(asm)\b(\s|[(]|$)/$1__$2__$3/g; $line =~ s/(^|\s|[(])(volatile)\b(\s|[(]|$)/$1__$2__$3/g; - $line =~ s/#ifndef _UAPI/#ifndef /; - $line =~ s/#define _UAPI/#define /; - $line =~ s!#endif /[*] _UAPI!#endif /* !; printf {$out} "%s", $line; } close $out; diff --git a/trunk/scripts/kconfig/expr.h b/trunk/scripts/kconfig/expr.h index cdd48600e02a..bd2e09895553 100644 --- a/trunk/scripts/kconfig/expr.h +++ b/trunk/scripts/kconfig/expr.h @@ -12,7 +12,7 @@ extern "C" { #include #include -#include "list.h" +#include #ifndef __cplusplus #include #endif @@ -175,11 +175,12 @@ struct menu { #define MENU_ROOT 0x0002 struct jump_key { - struct list_head entries; + CIRCLEQ_ENTRY(jump_key) entries; size_t offset; struct menu *target; int index; }; +CIRCLEQ_HEAD(jk_head, jump_key); #define JUMP_NB 9 diff --git a/trunk/scripts/kconfig/list.h b/trunk/scripts/kconfig/list.h deleted file mode 100644 index 0ae730be5f49..000000000000 --- a/trunk/scripts/kconfig/list.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef LIST_H -#define LIST_H - -/* - * Copied from include/linux/... - */ - -#undef offsetof -#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) - -/** - * container_of - cast a member of a structure out to the containing structure - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - * - */ -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) - - -struct list_head { - struct list_head *next, *prev; -}; - - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -/** - * list_entry - get the struct for this entry - * @ptr: the &struct list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) \ - container_of(ptr, type, member) - -/** - * list_for_each_entry - iterate over list of given type - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_empty - tests whether a list is empty - * @head: the list to test. - */ -static inline int list_empty(const struct list_head *head) -{ - return head->next == head; -} - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_add(struct list_head *_new, - struct list_head *prev, - struct list_head *next) -{ - next->prev = _new; - _new->next = next; - _new->prev = prev; - prev->next = _new; -} - -/** - * list_add_tail - add a new entry - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static inline void list_add_tail(struct list_head *_new, struct list_head *head) -{ - __list_add(_new, head->prev, head); -} - -#endif diff --git a/trunk/scripts/kconfig/lkc_proto.h b/trunk/scripts/kconfig/lkc_proto.h index ef1a7381f956..1d1c08537f1e 100644 --- a/trunk/scripts/kconfig/lkc_proto.h +++ b/trunk/scripts/kconfig/lkc_proto.h @@ -21,9 +21,9 @@ P(menu_get_root_menu,struct menu *,(struct menu *menu)); P(menu_get_parent_menu,struct menu *,(struct menu *menu)); P(menu_has_help,bool,(struct menu *menu)); P(menu_get_help,const char *,(struct menu *menu)); -P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct list_head +P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct jk_head *head)); -P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct list_head +P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct jk_head *head)); P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help)); diff --git a/trunk/scripts/kconfig/mconf.c b/trunk/scripts/kconfig/mconf.c index 53975cf87608..48f67448af7b 100644 --- a/trunk/scripts/kconfig/mconf.c +++ b/trunk/scripts/kconfig/mconf.c @@ -312,7 +312,7 @@ static void set_config_filename(const char *config_filename) struct search_data { - struct list_head *head; + struct jk_head *head; struct menu **targets; int *keys; }; @@ -323,7 +323,7 @@ static void update_text(char *buf, size_t start, size_t end, void *_data) struct jump_key *pos; int k = 0; - list_for_each_entry(pos, data->head, entries) { + CIRCLEQ_FOREACH(pos, data->head, entries) { if (pos->offset >= start && pos->offset < end) { char header[4]; @@ -375,7 +375,7 @@ static void search_conf(void) sym_arr = sym_re_search(dialog_input); do { - LIST_HEAD(head); + struct jk_head head = CIRCLEQ_HEAD_INITIALIZER(head); struct menu *targets[JUMP_NB]; int keys[JUMP_NB + 1], i; struct search_data data = { diff --git a/trunk/scripts/kconfig/menu.c b/trunk/scripts/kconfig/menu.c index e98a05c8e508..a3cade659f89 100644 --- a/trunk/scripts/kconfig/menu.c +++ b/trunk/scripts/kconfig/menu.c @@ -508,7 +508,7 @@ const char *menu_get_help(struct menu *menu) } static void get_prompt_str(struct gstr *r, struct property *prop, - struct list_head *head) + struct jk_head *head) { int i, j; struct menu *submenu[8], *menu, *location = NULL; @@ -544,13 +544,12 @@ static void get_prompt_str(struct gstr *r, struct property *prop, } else jump->target = location; - if (list_empty(head)) + if (CIRCLEQ_EMPTY(head)) jump->index = 0; else - jump->index = list_entry(head->prev, struct jump_key, - entries)->index + 1; + jump->index = CIRCLEQ_LAST(head)->index + 1; - list_add_tail(&jump->entries, head); + CIRCLEQ_INSERT_TAIL(head, jump, entries); } if (i > 0) { @@ -574,8 +573,7 @@ static void get_prompt_str(struct gstr *r, struct property *prop, /* * head is optional and may be NULL */ -void get_symbol_str(struct gstr *r, struct symbol *sym, - struct list_head *head) +void get_symbol_str(struct gstr *r, struct symbol *sym, struct jk_head *head) { bool hit; struct property *prop; @@ -614,7 +612,7 @@ void get_symbol_str(struct gstr *r, struct symbol *sym, str_append(r, "\n\n"); } -struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head) +struct gstr get_relations_str(struct symbol **sym_arr, struct jk_head *head) { struct symbol *sym; struct gstr res = str_new(); diff --git a/trunk/scripts/sign-file b/trunk/scripts/sign-file index 974a20b661b7..87ca59d36e7e 100755 --- a/trunk/scripts/sign-file +++ b/trunk/scripts/sign-file @@ -156,12 +156,12 @@ sub asn1_extract($$@) if ($l == 0x1) { $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)); - } elsif ($l == 0x2) { + } elsif ($l = 0x2) { $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0], 2)); - } elsif ($l == 0x3) { + } elsif ($l = 0x3) { $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)) << 16; $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0] + 1, 2)); - } elsif ($l == 0x4) { + } elsif ($l = 0x4) { $len = unpack("N", substr(${$cursor->[2]}, $cursor->[0], 4)); } else { die $x509, ": ", $cursor->[0], ": ASN.1 element too long (", $l, ")\n"; diff --git a/trunk/security/apparmor/policy.c b/trunk/security/apparmor/policy.c index 813200384d97..cf5fd220309b 100644 --- a/trunk/security/apparmor/policy.c +++ b/trunk/security/apparmor/policy.c @@ -724,8 +724,6 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat) */ static void free_profile(struct aa_profile *profile) { - struct aa_profile *p; - AA_DEBUG("%s(%p)\n", __func__, profile); if (!profile) @@ -753,27 +751,7 @@ static void free_profile(struct aa_profile *profile) aa_put_dfa(profile->xmatch); aa_put_dfa(profile->policy.dfa); - /* put the profile reference for replacedby, but not via - * put_profile(kref_put). - * replacedby can form a long chain that can result in cascading - * frees that blows the stack because kref_put makes a nested fn - * call (it looks like recursion, with free_profile calling - * free_profile) for each profile in the chain lp#1056078. - */ - for (p = profile->replacedby; p; ) { - if (atomic_dec_and_test(&p->base.count.refcount)) { - /* no more refs on p, grab its replacedby */ - struct aa_profile *next = p->replacedby; - /* break the chain */ - p->replacedby = NULL; - /* now free p, chain is broken */ - free_profile(p); - - /* follow up with next profile in the chain */ - p = next; - } else - break; - } + aa_put_profile(profile->replacedby); kzfree(profile); } diff --git a/trunk/security/device_cgroup.c b/trunk/security/device_cgroup.c index b08d20c66c2e..44dfc415a379 100644 --- a/trunk/security/device_cgroup.c +++ b/trunk/security/device_cgroup.c @@ -42,10 +42,7 @@ struct dev_exception_item { struct dev_cgroup { struct cgroup_subsys_state css; struct list_head exceptions; - enum { - DEVCG_DEFAULT_ALLOW, - DEVCG_DEFAULT_DENY, - } behavior; + bool deny_all; }; static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s) @@ -164,8 +161,8 @@ static void dev_exception_clean(struct dev_cgroup *dev_cgroup) struct dev_exception_item *ex, *tmp; list_for_each_entry_safe(ex, tmp, &dev_cgroup->exceptions, list) { - list_del_rcu(&ex->list); - kfree_rcu(ex, rcu); + list_del(&ex->list); + kfree(ex); } } @@ -185,13 +182,13 @@ static struct cgroup_subsys_state *devcgroup_create(struct cgroup *cgroup) parent_cgroup = cgroup->parent; if (parent_cgroup == NULL) - dev_cgroup->behavior = DEVCG_DEFAULT_ALLOW; + dev_cgroup->deny_all = false; else { parent_dev_cgroup = cgroup_to_devcgroup(parent_cgroup); mutex_lock(&devcgroup_mutex); ret = dev_exceptions_copy(&dev_cgroup->exceptions, &parent_dev_cgroup->exceptions); - dev_cgroup->behavior = parent_dev_cgroup->behavior; + dev_cgroup->deny_all = parent_dev_cgroup->deny_all; mutex_unlock(&devcgroup_mutex); if (ret) { kfree(dev_cgroup); @@ -263,7 +260,7 @@ static int devcgroup_seq_read(struct cgroup *cgroup, struct cftype *cft, * - List the exceptions in case the default policy is to deny * This way, the file remains as a "whitelist of devices" */ - if (devcgroup->behavior == DEVCG_DEFAULT_ALLOW) { + if (devcgroup->deny_all == false) { set_access(acc, ACC_MASK); set_majmin(maj, ~0); set_majmin(min, ~0); @@ -298,7 +295,7 @@ static int may_access(struct dev_cgroup *dev_cgroup, struct dev_exception_item *ex; bool match = false; - list_for_each_entry_rcu(ex, &dev_cgroup->exceptions, list) { + list_for_each_entry(ex, &dev_cgroup->exceptions, list) { if ((refex->type & DEV_BLOCK) && !(ex->type & DEV_BLOCK)) continue; if ((refex->type & DEV_CHAR) && !(ex->type & DEV_CHAR)) @@ -317,12 +314,12 @@ static int may_access(struct dev_cgroup *dev_cgroup, * In two cases we'll consider this new exception valid: * - the dev cgroup has its default policy to allow + exception list: * the new exception should *not* match any of the exceptions - * (behavior == DEVCG_DEFAULT_ALLOW, !match) + * (!deny_all, !match) * - the dev cgroup has its default policy to deny + exception list: * the new exception *should* match the exceptions - * (behavior == DEVCG_DEFAULT_DENY, match) + * (deny_all, match) */ - if ((dev_cgroup->behavior == DEVCG_DEFAULT_DENY) == match) + if (dev_cgroup->deny_all == match) return 1; return 0; } @@ -344,19 +341,6 @@ static int parent_has_perm(struct dev_cgroup *childcg, return may_access(parent, ex); } -/** - * may_allow_all - checks if it's possible to change the behavior to - * allow based on parent's rules. - * @parent: device cgroup's parent - * returns: != 0 in case it's allowed, 0 otherwise - */ -static inline int may_allow_all(struct dev_cgroup *parent) -{ - if (!parent) - return 1; - return parent->behavior == DEVCG_DEFAULT_ALLOW; -} - /* * Modify the exception list using allow/deny rules. * CAP_SYS_ADMIN is needed for this. It's at least separate from CAP_MKNOD @@ -374,18 +358,13 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, int filetype, const char *buffer) { const char *b; - char temp[12]; /* 11 + 1 characters needed for a u32 */ - int count, rc; + char *endp; + int count; struct dev_exception_item ex; - struct cgroup *p = devcgroup->css.cgroup; - struct dev_cgroup *parent = NULL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (p->parent) - parent = cgroup_to_devcgroup(p->parent); - memset(&ex, 0, sizeof(ex)); b = buffer; @@ -393,21 +372,14 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, case 'a': switch (filetype) { case DEVCG_ALLOW: - if (!may_allow_all(parent)) + if (!parent_has_perm(devcgroup, &ex)) return -EPERM; dev_exception_clean(devcgroup); - devcgroup->behavior = DEVCG_DEFAULT_ALLOW; - if (!parent) - break; - - rc = dev_exceptions_copy(&devcgroup->exceptions, - &parent->exceptions); - if (rc) - return rc; + devcgroup->deny_all = false; break; case DEVCG_DENY: dev_exception_clean(devcgroup); - devcgroup->behavior = DEVCG_DEFAULT_DENY; + devcgroup->deny_all = true; break; default: return -EINVAL; @@ -430,16 +402,8 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, ex.major = ~0; b++; } else if (isdigit(*b)) { - memset(temp, 0, sizeof(temp)); - for (count = 0; count < sizeof(temp) - 1; count++) { - temp[count] = *b; - b++; - if (!isdigit(*b)) - break; - } - rc = kstrtou32(temp, 10, &ex.major); - if (rc) - return -EINVAL; + ex.major = simple_strtoul(b, &endp, 10); + b = endp; } else { return -EINVAL; } @@ -452,16 +416,8 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, ex.minor = ~0; b++; } else if (isdigit(*b)) { - memset(temp, 0, sizeof(temp)); - for (count = 0; count < sizeof(temp) - 1; count++) { - temp[count] = *b; - b++; - if (!isdigit(*b)) - break; - } - rc = kstrtou32(temp, 10, &ex.minor); - if (rc) - return -EINVAL; + ex.minor = simple_strtoul(b, &endp, 10); + b = endp; } else { return -EINVAL; } @@ -496,7 +452,7 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, * an matching exception instead. And be silent about it: we * don't want to break compatibility */ - if (devcgroup->behavior == DEVCG_DEFAULT_ALLOW) { + if (devcgroup->deny_all == false) { dev_exception_rm(devcgroup, &ex); return 0; } @@ -507,7 +463,7 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, * an matching exception instead. And be silent about it: we * don't want to break compatibility */ - if (devcgroup->behavior == DEVCG_DEFAULT_DENY) { + if (devcgroup->deny_all == true) { dev_exception_rm(devcgroup, &ex); return 0; } @@ -577,10 +533,10 @@ struct cgroup_subsys devices_subsys = { * * returns 0 on success, -EPERM case the operation is not permitted */ -static int __devcgroup_check_permission(short type, u32 major, u32 minor, +static int __devcgroup_check_permission(struct dev_cgroup *dev_cgroup, + short type, u32 major, u32 minor, short access) { - struct dev_cgroup *dev_cgroup; struct dev_exception_item ex; int rc; @@ -591,7 +547,6 @@ static int __devcgroup_check_permission(short type, u32 major, u32 minor, ex.access = access; rcu_read_lock(); - dev_cgroup = task_devcgroup(current); rc = may_access(dev_cgroup, &ex); rcu_read_unlock(); @@ -603,6 +558,7 @@ static int __devcgroup_check_permission(short type, u32 major, u32 minor, int __devcgroup_inode_permission(struct inode *inode, int mask) { + struct dev_cgroup *dev_cgroup = task_devcgroup(current); short type, access = 0; if (S_ISBLK(inode->i_mode)) @@ -614,12 +570,13 @@ int __devcgroup_inode_permission(struct inode *inode, int mask) if (mask & MAY_READ) access |= ACC_READ; - return __devcgroup_check_permission(type, imajor(inode), iminor(inode), - access); + return __devcgroup_check_permission(dev_cgroup, type, imajor(inode), + iminor(inode), access); } int devcgroup_inode_mknod(int mode, dev_t dev) { + struct dev_cgroup *dev_cgroup = task_devcgroup(current); short type; if (!S_ISBLK(mode) && !S_ISCHR(mode)) @@ -630,7 +587,7 @@ int devcgroup_inode_mknod(int mode, dev_t dev) else type = DEV_CHAR; - return __devcgroup_check_permission(type, MAJOR(dev), MINOR(dev), - ACC_MKNOD); + return __devcgroup_check_permission(dev_cgroup, type, MAJOR(dev), + MINOR(dev), ACC_MKNOD); } diff --git a/trunk/security/selinux/netnode.c b/trunk/security/selinux/netnode.c index c5454c0477c3..28f911cdd7c7 100644 --- a/trunk/security/selinux/netnode.c +++ b/trunk/security/selinux/netnode.c @@ -174,8 +174,7 @@ static void sel_netnode_insert(struct sel_netnode *node) if (sel_netnode_hash[idx].size == SEL_NETNODE_HASH_BKT_LIMIT) { struct sel_netnode *tail; tail = list_entry( - rcu_dereference_protected(sel_netnode_hash[idx].list.prev, - lockdep_is_held(&sel_netnode_lock)), + rcu_dereference(sel_netnode_hash[idx].list.prev), struct sel_netnode, list); list_del_rcu(&tail->list); kfree_rcu(tail, rcu); diff --git a/trunk/sound/core/compress_offload.c b/trunk/sound/core/compress_offload.c index ad11dc994792..c40ae573346d 100644 --- a/trunk/sound/core/compress_offload.c +++ b/trunk/sound/core/compress_offload.c @@ -100,15 +100,12 @@ static int snd_compr_open(struct inode *inode, struct file *f) if (dirn != compr->direction) { pr_err("this device doesn't support this direction\n"); - snd_card_unref(compr->card); return -EINVAL; } data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) { - snd_card_unref(compr->card); + if (!data) return -ENOMEM; - } data->stream.ops = compr->ops; data->stream.direction = dirn; data->stream.private_data = compr->private_data; @@ -116,7 +113,6 @@ static int snd_compr_open(struct inode *inode, struct file *f) runtime = kzalloc(sizeof(*runtime), GFP_KERNEL); if (!runtime) { kfree(data); - snd_card_unref(compr->card); return -ENOMEM; } runtime->state = SNDRV_PCM_STATE_OPEN; @@ -130,8 +126,7 @@ static int snd_compr_open(struct inode *inode, struct file *f) kfree(runtime); kfree(data); } - snd_card_unref(compr->card); - return 0; + return ret; } static int snd_compr_free(struct inode *inode, struct file *f) diff --git a/trunk/sound/core/control.c b/trunk/sound/core/control.c index 8c7c2c9bba61..7e86a5b9f3b5 100644 --- a/trunk/sound/core/control.c +++ b/trunk/sound/core/control.c @@ -86,7 +86,6 @@ static int snd_ctl_open(struct inode *inode, struct file *file) write_lock_irqsave(&card->ctl_files_rwlock, flags); list_add_tail(&ctl->list, &card->ctl_files); write_unlock_irqrestore(&card->ctl_files_rwlock, flags); - snd_card_unref(card); return 0; __error: @@ -94,8 +93,6 @@ static int snd_ctl_open(struct inode *inode, struct file *file) __error2: snd_card_file_remove(card, file); __error1: - if (card) - snd_card_unref(card); return err; } @@ -1437,8 +1434,6 @@ static ssize_t snd_ctl_read(struct file *file, char __user *buffer, spin_unlock_irq(&ctl->read_lock); schedule(); remove_wait_queue(&ctl->change_sleep, &wait); - if (ctl->card->shutdown) - return -ENODEV; if (signal_pending(current)) return -ERESTARTSYS; spin_lock_irq(&ctl->read_lock); diff --git a/trunk/sound/core/hwdep.c b/trunk/sound/core/hwdep.c index 3f7f6628cf7b..75ea16f35b1a 100644 --- a/trunk/sound/core/hwdep.c +++ b/trunk/sound/core/hwdep.c @@ -100,10 +100,8 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) if (hw == NULL) return -ENODEV; - if (!try_module_get(hw->card->module)) { - snd_card_unref(hw->card); + if (!try_module_get(hw->card->module)) return -EFAULT; - } init_waitqueue_entry(&wait, current); add_wait_queue(&hw->open_wait, &wait); @@ -131,10 +129,6 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) mutex_unlock(&hw->open_mutex); schedule(); mutex_lock(&hw->open_mutex); - if (hw->card->shutdown) { - err = -ENODEV; - break; - } if (signal_pending(current)) { err = -ERESTARTSYS; break; @@ -154,7 +148,6 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) mutex_unlock(&hw->open_mutex); if (err < 0) module_put(hw->card->module); - snd_card_unref(hw->card); return err; } @@ -466,15 +459,12 @@ static int snd_hwdep_dev_disconnect(struct snd_device *device) mutex_unlock(®ister_mutex); return -EINVAL; } - mutex_lock(&hwdep->open_mutex); - wake_up(&hwdep->open_wait); #ifdef CONFIG_SND_OSSEMUL if (hwdep->ossreg) snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device); #endif snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device); list_del_init(&hwdep->list); - mutex_unlock(&hwdep->open_mutex); mutex_unlock(®ister_mutex); return 0; } diff --git a/trunk/sound/core/init.c b/trunk/sound/core/init.c index 7b012d15c2cf..d8ec849af128 100644 --- a/trunk/sound/core/init.c +++ b/trunk/sound/core/init.c @@ -213,7 +213,6 @@ int snd_card_create(int idx, const char *xid, spin_lock_init(&card->files_lock); INIT_LIST_HEAD(&card->files_list); init_waitqueue_head(&card->shutdown_sleep); - atomic_set(&card->refcount, 0); #ifdef CONFIG_PM mutex_init(&card->power_lock); init_waitqueue_head(&card->power_sleep); @@ -447,36 +446,21 @@ static int snd_card_do_free(struct snd_card *card) return 0; } -/** - * snd_card_unref - release the reference counter - * @card: the card instance - * - * Decrements the reference counter. When it reaches to zero, wake up - * the sleeper and call the destructor if needed. - */ -void snd_card_unref(struct snd_card *card) -{ - if (atomic_dec_and_test(&card->refcount)) { - wake_up(&card->shutdown_sleep); - if (card->free_on_last_close) - snd_card_do_free(card); - } -} -EXPORT_SYMBOL(snd_card_unref); - int snd_card_free_when_closed(struct snd_card *card) { - int ret; - - atomic_inc(&card->refcount); - ret = snd_card_disconnect(card); - if (ret) { - atomic_dec(&card->refcount); + int free_now = 0; + int ret = snd_card_disconnect(card); + if (ret) return ret; - } - card->free_on_last_close = 1; - if (atomic_dec_and_test(&card->refcount)) + spin_lock(&card->files_lock); + if (list_empty(&card->files_list)) + free_now = 1; + else + card->free_on_last_close = 1; + spin_unlock(&card->files_lock); + + if (free_now) snd_card_do_free(card); return 0; } @@ -490,7 +474,7 @@ int snd_card_free(struct snd_card *card) return ret; /* wait, until all devices are ready for the free operation */ - wait_event(card->shutdown_sleep, !atomic_read(&card->refcount)); + wait_event(card->shutdown_sleep, list_empty(&card->files_list)); snd_card_do_free(card); return 0; } @@ -902,7 +886,6 @@ int snd_card_file_add(struct snd_card *card, struct file *file) return -ENODEV; } list_add(&mfile->list, &card->files_list); - atomic_inc(&card->refcount); spin_unlock(&card->files_lock); return 0; } @@ -925,6 +908,7 @@ EXPORT_SYMBOL(snd_card_file_add); int snd_card_file_remove(struct snd_card *card, struct file *file) { struct snd_monitor_file *mfile, *found = NULL; + int last_close = 0; spin_lock(&card->files_lock); list_for_each_entry(mfile, &card->files_list, list) { @@ -939,13 +923,19 @@ int snd_card_file_remove(struct snd_card *card, struct file *file) break; } } + if (list_empty(&card->files_list)) + last_close = 1; spin_unlock(&card->files_lock); + if (last_close) { + wake_up(&card->shutdown_sleep); + if (card->free_on_last_close) + snd_card_do_free(card); + } if (!found) { snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file); return -ENOENT; } kfree(found); - snd_card_unref(card); return 0; } diff --git a/trunk/sound/core/oss/mixer_oss.c b/trunk/sound/core/oss/mixer_oss.c index e8a1d18774b2..29f6ded02555 100644 --- a/trunk/sound/core/oss/mixer_oss.c +++ b/trunk/sound/core/oss/mixer_oss.c @@ -52,19 +52,14 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file) SNDRV_OSS_DEVICE_TYPE_MIXER); if (card == NULL) return -ENODEV; - if (card->mixer_oss == NULL) { - snd_card_unref(card); + if (card->mixer_oss == NULL) return -ENODEV; - } err = snd_card_file_add(card, file); - if (err < 0) { - snd_card_unref(card); + if (err < 0) return err; - } fmixer = kzalloc(sizeof(*fmixer), GFP_KERNEL); if (fmixer == NULL) { snd_card_file_remove(card, file); - snd_card_unref(card); return -ENOMEM; } fmixer->card = card; @@ -73,10 +68,8 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file) if (!try_module_get(card->module)) { kfree(fmixer); snd_card_file_remove(card, file); - snd_card_unref(card); return -EFAULT; } - snd_card_unref(card); return 0; } diff --git a/trunk/sound/core/oss/pcm_oss.c b/trunk/sound/core/oss/pcm_oss.c index 4c1cc51772e6..08fde0060fd9 100644 --- a/trunk/sound/core/oss/pcm_oss.c +++ b/trunk/sound/core/oss/pcm_oss.c @@ -2441,10 +2441,6 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) mutex_unlock(&pcm->open_mutex); schedule(); mutex_lock(&pcm->open_mutex); - if (pcm->card->shutdown) { - err = -ENODEV; - break; - } if (signal_pending(current)) { err = -ERESTARTSYS; break; @@ -2454,7 +2450,6 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) mutex_unlock(&pcm->open_mutex); if (err < 0) goto __error; - snd_card_unref(pcm->card); return err; __error: @@ -2462,8 +2457,6 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) __error2: snd_card_file_remove(pcm->card, file); __error1: - if (pcm) - snd_card_unref(pcm->card); return err; } diff --git a/trunk/sound/core/pcm.c b/trunk/sound/core/pcm.c index 030102caeee9..f2991940b271 100644 --- a/trunk/sound/core/pcm.c +++ b/trunk/sound/core/pcm.c @@ -1086,19 +1086,11 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) if (list_empty(&pcm->list)) goto unlock; - mutex_lock(&pcm->open_mutex); - wake_up(&pcm->open_wait); list_del_init(&pcm->list); for (cidx = 0; cidx < 2; cidx++) - for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) { - snd_pcm_stream_lock_irq(substream); - if (substream->runtime) { + for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) + if (substream->runtime) substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED; - wake_up(&substream->runtime->sleep); - wake_up(&substream->runtime->tsleep); - } - snd_pcm_stream_unlock_irq(substream); - } list_for_each_entry(notify, &snd_pcm_notify_list, list) { notify->n_disconnect(pcm); } @@ -1118,7 +1110,6 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) pcm->streams[cidx].chmap_kctl = NULL; } } - mutex_unlock(&pcm->open_mutex); unlock: mutex_unlock(®ister_mutex); return 0; diff --git a/trunk/sound/core/pcm_native.c b/trunk/sound/core/pcm_native.c index f9ddecf2f4cd..5e12e5bacbba 100644 --- a/trunk/sound/core/pcm_native.c +++ b/trunk/sound/core/pcm_native.c @@ -369,14 +369,6 @@ static int period_to_usecs(struct snd_pcm_runtime *runtime) return usecs; } -static void snd_pcm_set_state(struct snd_pcm_substream *substream, int state) -{ - snd_pcm_stream_lock_irq(substream); - if (substream->runtime->status->state != SNDRV_PCM_STATE_DISCONNECTED) - substream->runtime->status->state = state; - snd_pcm_stream_unlock_irq(substream); -} - static int snd_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -460,7 +452,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, runtime->boundary *= 2; snd_pcm_timer_resolution_change(substream); - snd_pcm_set_state(substream, SNDRV_PCM_STATE_SETUP); + runtime->status->state = SNDRV_PCM_STATE_SETUP; if (pm_qos_request_active(&substream->latency_pm_qos_req)) pm_qos_remove_request(&substream->latency_pm_qos_req); @@ -472,7 +464,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, /* hardware might be unusable from this time, so we force application to retry to set the correct hardware parameter settings */ - snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN); + runtime->status->state = SNDRV_PCM_STATE_OPEN; if (substream->ops->hw_free != NULL) substream->ops->hw_free(substream); return err; @@ -520,7 +512,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream) return -EBADFD; if (substream->ops->hw_free) result = substream->ops->hw_free(substream); - snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN); + runtime->status->state = SNDRV_PCM_STATE_OPEN; pm_qos_remove_request(&substream->latency_pm_qos_req); return result; } @@ -1328,7 +1320,7 @@ static void snd_pcm_post_prepare(struct snd_pcm_substream *substream, int state) { struct snd_pcm_runtime *runtime = substream->runtime; runtime->control->appl_ptr = runtime->status->hw_ptr; - snd_pcm_set_state(substream, SNDRV_PCM_STATE_PREPARED); + runtime->status->state = SNDRV_PCM_STATE_PREPARED; } static struct action_ops snd_pcm_action_prepare = { @@ -1518,10 +1510,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream, down_read(&snd_pcm_link_rwsem); snd_pcm_stream_lock_irq(substream); remove_wait_queue(&to_check->sleep, &wait); - if (card->shutdown) { - result = -ENODEV; - break; - } if (tout == 0) { if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) result = -ESTRPIPE; @@ -1646,7 +1634,6 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) write_unlock_irq(&snd_pcm_link_rwlock); up_write(&snd_pcm_link_rwsem); _nolock: - snd_card_unref(substream1->pcm->card); fput_light(file, fput_needed); if (res < 0) kfree(group); @@ -2121,10 +2108,7 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file) return err; pcm = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_PCM_PLAYBACK); - err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); - if (pcm) - snd_card_unref(pcm->card); - return err; + return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); } static int snd_pcm_capture_open(struct inode *inode, struct file *file) @@ -2135,10 +2119,7 @@ static int snd_pcm_capture_open(struct inode *inode, struct file *file) return err; pcm = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_PCM_CAPTURE); - err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); - if (pcm) - snd_card_unref(pcm->card); - return err; + return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); } static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) @@ -2175,10 +2156,6 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) mutex_unlock(&pcm->open_mutex); schedule(); mutex_lock(&pcm->open_mutex); - if (pcm->card->shutdown) { - err = -ENODEV; - break; - } if (signal_pending(current)) { err = -ERESTARTSYS; break; diff --git a/trunk/sound/core/rawmidi.c b/trunk/sound/core/rawmidi.c index 1bb95aeea084..ebf6e49ad3d4 100644 --- a/trunk/sound/core/rawmidi.c +++ b/trunk/sound/core/rawmidi.c @@ -379,10 +379,8 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) if (rmidi == NULL) return -ENODEV; - if (!try_module_get(rmidi->card->module)) { - snd_card_unref(rmidi->card); + if (!try_module_get(rmidi->card->module)) return -ENXIO; - } mutex_lock(&rmidi->open_mutex); card = rmidi->card; @@ -424,10 +422,6 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) mutex_unlock(&rmidi->open_mutex); schedule(); mutex_lock(&rmidi->open_mutex); - if (rmidi->card->shutdown) { - err = -ENODEV; - break; - } if (signal_pending(current)) { err = -ERESTARTSYS; break; @@ -446,7 +440,6 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) #endif file->private_data = rawmidi_file; mutex_unlock(&rmidi->open_mutex); - snd_card_unref(rmidi->card); return 0; __error: @@ -454,7 +447,6 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) __error_card: mutex_unlock(&rmidi->open_mutex); module_put(rmidi->card->module); - snd_card_unref(rmidi->card); return err; } @@ -999,8 +991,6 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun spin_unlock_irq(&runtime->lock); schedule(); remove_wait_queue(&runtime->sleep, &wait); - if (rfile->rmidi->card->shutdown) - return -ENODEV; if (signal_pending(current)) return result > 0 ? result : -ERESTARTSYS; if (!runtime->avail) @@ -1244,8 +1234,6 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, spin_unlock_irq(&runtime->lock); timeout = schedule_timeout(30 * HZ); remove_wait_queue(&runtime->sleep, &wait); - if (rfile->rmidi->card->shutdown) - return -ENODEV; if (signal_pending(current)) return result > 0 ? result : -ERESTARTSYS; if (!runtime->avail && !timeout) @@ -1621,20 +1609,9 @@ static int snd_rawmidi_dev_register(struct snd_device *device) static int snd_rawmidi_dev_disconnect(struct snd_device *device) { struct snd_rawmidi *rmidi = device->device_data; - int dir; mutex_lock(®ister_mutex); - mutex_lock(&rmidi->open_mutex); - wake_up(&rmidi->open_wait); list_del_init(&rmidi->list); - for (dir = 0; dir < 2; dir++) { - struct snd_rawmidi_substream *s; - list_for_each_entry(s, &rmidi->streams[dir].substreams, list) { - if (s->runtime) - wake_up(&s->runtime->sleep); - } - } - #ifdef CONFIG_SND_OSSEMUL if (rmidi->ossreg) { if ((int)rmidi->device == midi_map[rmidi->card->number]) { @@ -1649,7 +1626,6 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device) } #endif /* CONFIG_SND_OSSEMUL */ snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); - mutex_unlock(&rmidi->open_mutex); mutex_unlock(®ister_mutex); return 0; } diff --git a/trunk/sound/core/sound.c b/trunk/sound/core/sound.c index 70ccdab74153..643976000ce8 100644 --- a/trunk/sound/core/sound.c +++ b/trunk/sound/core/sound.c @@ -98,10 +98,6 @@ static void snd_request_other(int minor) * * Checks that a minor device with the specified type is registered, and returns * its user data pointer. - * - * This function increments the reference counter of the card instance - * if an associated instance with the given minor number and type is found. - * The caller must call snd_card_unref() appropriately later. */ void *snd_lookup_minor_data(unsigned int minor, int type) { @@ -112,11 +108,9 @@ void *snd_lookup_minor_data(unsigned int minor, int type) return NULL; mutex_lock(&sound_mutex); mreg = snd_minors[minor]; - if (mreg && mreg->type == type) { + if (mreg && mreg->type == type) private_data = mreg->private_data; - if (private_data && mreg->card_ptr) - atomic_inc(&mreg->card_ptr->refcount); - } else + else private_data = NULL; mutex_unlock(&sound_mutex); return private_data; @@ -281,7 +275,6 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev, preg->device = dev; preg->f_ops = f_ops; preg->private_data = private_data; - preg->card_ptr = card; mutex_lock(&sound_mutex); #ifdef CONFIG_SND_DYNAMIC_MINORS minor = snd_find_free_minor(type); diff --git a/trunk/sound/core/sound_oss.c b/trunk/sound/core/sound_oss.c index 726a49ac9725..e9528333e36d 100644 --- a/trunk/sound/core/sound_oss.c +++ b/trunk/sound/core/sound_oss.c @@ -40,9 +40,6 @@ static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS]; static DEFINE_MUTEX(sound_oss_mutex); -/* NOTE: This function increments the refcount of the associated card like - * snd_lookup_minor_data(); the caller must call snd_card_unref() appropriately - */ void *snd_lookup_oss_minor_data(unsigned int minor, int type) { struct snd_minor *mreg; @@ -52,11 +49,9 @@ void *snd_lookup_oss_minor_data(unsigned int minor, int type) return NULL; mutex_lock(&sound_oss_mutex); mreg = snd_oss_minors[minor]; - if (mreg && mreg->type == type) { + if (mreg && mreg->type == type) private_data = mreg->private_data; - if (private_data && mreg->card_ptr) - atomic_inc(&mreg->card_ptr->refcount); - } else + else private_data = NULL; mutex_unlock(&sound_oss_mutex); return private_data; @@ -128,7 +123,6 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, preg->device = dev; preg->f_ops = f_ops; preg->private_data = private_data; - preg->card_ptr = card; mutex_lock(&sound_oss_mutex); snd_oss_minors[minor] = preg; minor_unit = SNDRV_MINOR_OSS_DEVICE(minor); diff --git a/trunk/sound/i2c/other/ak4113.c b/trunk/sound/i2c/other/ak4113.c index e04e750a77ed..ef68d710d08c 100644 --- a/trunk/sound/i2c/other/ak4113.c +++ b/trunk/sound/i2c/other/ak4113.c @@ -426,7 +426,7 @@ static struct snd_kcontrol_new snd_ak4113_iec958_controls[] = { }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "IEC958 Preamble Capture Default", + .name = "IEC958 Preample Capture Default", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = snd_ak4113_spdif_pinfo, diff --git a/trunk/sound/i2c/other/ak4114.c b/trunk/sound/i2c/other/ak4114.c index 5bf4fca19e48..816e7d225fb0 100644 --- a/trunk/sound/i2c/other/ak4114.c +++ b/trunk/sound/i2c/other/ak4114.c @@ -401,7 +401,7 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = { }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "IEC958 Preamble Capture Default", + .name = "IEC958 Preample Capture Default", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = snd_ak4114_spdif_pinfo, .get = snd_ak4114_spdif_pget, diff --git a/trunk/sound/i2c/other/ak4117.c b/trunk/sound/i2c/other/ak4117.c index 40e33c9f2b09..b4b2a51fc117 100644 --- a/trunk/sound/i2c/other/ak4117.c +++ b/trunk/sound/i2c/other/ak4117.c @@ -380,7 +380,7 @@ static struct snd_kcontrol_new snd_ak4117_iec958_controls[] = { }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "IEC958 Preamble Capture Default", + .name = "IEC958 Preample Capture Default", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = snd_ak4117_spdif_pinfo, .get = snd_ak4117_spdif_pget, diff --git a/trunk/sound/isa/opti9xx/miro.c b/trunk/sound/isa/opti9xx/miro.c index 4a7ff4e8985b..3d1afb612b35 100644 --- a/trunk/sound/isa/opti9xx/miro.c +++ b/trunk/sound/isa/opti9xx/miro.c @@ -1286,6 +1286,7 @@ static int __devinit snd_miro_probe(struct snd_card *card) error = snd_card_miro_aci_detect(card, miro); if (error < 0) { + snd_card_free(card); snd_printk(KERN_ERR "unable to detect aci chip\n"); return -ENODEV; } diff --git a/trunk/sound/pci/als300.c b/trunk/sound/pci/als300.c index 5af3cb6b0c18..00f157a2cf64 100644 --- a/trunk/sound/pci/als300.c +++ b/trunk/sound/pci/als300.c @@ -394,8 +394,6 @@ static int snd_als300_playback_open(struct snd_pcm_substream *substream) struct snd_als300_substream_data *data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; snd_als300_dbgcallenter(); chip->playback_substream = substream; runtime->hw = snd_als300_playback_hw; @@ -427,8 +425,6 @@ static int snd_als300_capture_open(struct snd_pcm_substream *substream) struct snd_als300_substream_data *data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; snd_als300_dbgcallenter(); chip->capture_substream = substream; runtime->hw = snd_als300_capture_hw; diff --git a/trunk/sound/pci/es1968.c b/trunk/sound/pci/es1968.c index 7266020c16cb..5d0e568fdea1 100644 --- a/trunk/sound/pci/es1968.c +++ b/trunk/sound/pci/es1968.c @@ -2581,14 +2581,9 @@ static u8 snd_es1968_tea575x_get_pins(struct snd_tea575x *tea) struct es1968 *chip = tea->private_data; unsigned long io = chip->io_port + GPIO_DATA; u16 val = inw(io); - u8 ret; - ret = 0; - if (val & STR_DATA) - ret |= TEA575X_DATA; - if (val & STR_MOST) - ret |= TEA575X_MOST; - return ret; + return (val & STR_DATA) ? TEA575X_DATA : 0 | + (val & STR_MOST) ? TEA575X_MOST : 0; } static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool output) @@ -2660,8 +2655,6 @@ static struct ess_device_list pm_whitelist[] __devinitdata = { { TYPE_MAESTRO2E, 0x1179 }, { TYPE_MAESTRO2E, 0x14c0 }, /* HP omnibook 4150 */ { TYPE_MAESTRO2E, 0x1558 }, - { TYPE_MAESTRO2E, 0x125d }, /* a PCI card, e.g. Terratec DMX */ - { TYPE_MAESTRO2, 0x125d }, /* a PCI card, e.g. SF64-PCE2 */ }; static struct ess_device_list mpu_blacklist[] __devinitdata = { diff --git a/trunk/sound/pci/fm801.c b/trunk/sound/pci/fm801.c index c5806f89be1e..cc2e91d15538 100644 --- a/trunk/sound/pci/fm801.c +++ b/trunk/sound/pci/fm801.c @@ -767,14 +767,9 @@ static u8 snd_fm801_tea575x_get_pins(struct snd_tea575x *tea) struct fm801 *chip = tea->private_data; unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip); - u8 ret; - - ret = 0; - if (reg & FM801_GPIO_GP(gpio.data)) - ret |= TEA575X_DATA; - if (reg & FM801_GPIO_GP(gpio.most)) - ret |= TEA575X_MOST; - return ret; + + return (reg & FM801_GPIO_GP(gpio.data)) ? TEA575X_DATA : 0 | + (reg & FM801_GPIO_GP(gpio.most)) ? TEA575X_MOST : 0; } static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output) diff --git a/trunk/sound/pci/hda/hda_codec.c b/trunk/sound/pci/hda/hda_codec.c index d010de12335e..70d4848b5cd0 100644 --- a/trunk/sound/pci/hda/hda_codec.c +++ b/trunk/sound/pci/hda/hda_codec.c @@ -95,7 +95,6 @@ int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset) EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset); #ifdef CONFIG_PM -#define codec_in_pm(codec) ((codec)->in_pm) static void hda_power_work(struct work_struct *work); static void hda_keep_power_on(struct hda_codec *codec); #define hda_codec_is_power_on(codec) ((codec)->power_on) @@ -105,7 +104,6 @@ static inline void hda_call_pm_notify(struct hda_bus *bus, bool power_up) bus->ops.pm_notify(bus, power_up); } #else -#define codec_in_pm(codec) 0 static inline void hda_keep_power_on(struct hda_codec *codec) {} #define hda_codec_is_power_on(codec) 1 #define hda_call_pm_notify(bus, state) {} @@ -230,7 +228,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, } mutex_unlock(&bus->cmd_mutex); snd_hda_power_down(codec); - if (!codec_in_pm(codec) && res && *res == -1 && bus->rirb_error) { + if (res && *res == -1 && bus->rirb_error) { if (bus->response_reset) { snd_printd("hda_codec: resetting BUS due to " "fatal communication error\n"); @@ -240,7 +238,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, goto again; } /* clear reset-flag when the communication gets recovered */ - if (!err || codec_in_pm(codec)) + if (!err) bus->response_reset = 0; return err; } @@ -3618,8 +3616,6 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq) { unsigned int state; - codec->in_pm = 1; - if (codec->patch_ops.suspend) codec->patch_ops.suspend(codec); hda_cleanup_all_streams(codec); @@ -3634,7 +3630,6 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq) codec->power_transition = 0; codec->power_jiffies = jiffies; spin_unlock(&codec->power_lock); - codec->in_pm = 0; return state; } @@ -3643,8 +3638,6 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq) */ static void hda_call_codec_resume(struct hda_codec *codec) { - codec->in_pm = 1; - /* set as if powered on for avoiding re-entering the resume * in the resume / power-save sequence */ @@ -3663,8 +3656,6 @@ static void hda_call_codec_resume(struct hda_codec *codec) snd_hda_codec_resume_cache(codec); } snd_hda_jack_report_sync(codec); - - codec->in_pm = 0; snd_hda_power_down(codec); /* flag down before returning */ } #endif /* CONFIG_PM */ diff --git a/trunk/sound/pci/hda/hda_codec.h b/trunk/sound/pci/hda/hda_codec.h index 4f4e545c0f4b..507fe8a917b6 100644 --- a/trunk/sound/pci/hda/hda_codec.h +++ b/trunk/sound/pci/hda/hda_codec.h @@ -869,7 +869,6 @@ struct hda_codec { unsigned int power_on :1; /* current (global) power-state */ unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */ unsigned int pm_down_notified:1; /* PM notified to controller */ - unsigned int in_pm:1; /* suspend/resume being performed */ int power_transition; /* power-state in transition */ int power_count; /* current (global) power refcount */ struct delayed_work power_work; /* delayed task for powerdown */ diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index f9d870e554d9..72b085ae7d46 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -556,12 +556,6 @@ enum { #define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ #define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ -#define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */ - -/* quirks for Intel PCH */ -#define AZX_DCAPS_INTEL_PCH \ - (AZX_DCAPS_SCH_SNOOP | AZX_DCAPS_BUFSIZE | \ - AZX_DCAPS_COUNT_LPIB_DELAY | AZX_DCAPS_PM_RUNTIME) /* quirks for ATI SB / AMD Hudson */ #define AZX_DCAPS_PRESET_ATI_SB \ @@ -2439,9 +2433,6 @@ static void azx_power_notify(struct hda_bus *bus, bool power_up) { struct azx *chip = bus->private_data; - if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) - return; - if (power_up) pm_runtime_get_sync(&chip->pci->dev); else @@ -2557,8 +2548,7 @@ static int azx_runtime_suspend(struct device *dev) struct snd_card *card = dev_get_drvdata(dev); struct azx *chip = card->private_data; - if (!power_save_controller || - !(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) + if (!power_save_controller) return -EAGAIN; azx_stop_chip(chip); @@ -3439,30 +3429,39 @@ static void __devexit azx_remove(struct pci_dev *pci) static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { /* CPT */ { PCI_DEVICE(0x8086, 0x1c20), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | + AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, /* PBG */ { PCI_DEVICE(0x8086, 0x1d20), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | + AZX_DCAPS_BUFSIZE}, /* Panther Point */ { PCI_DEVICE(0x8086, 0x1e20), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | + AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, /* Lynx Point */ { PCI_DEVICE(0x8086, 0x8c20), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | + AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, /* Lynx Point-LP */ { PCI_DEVICE(0x8086, 0x9c20), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | + AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, /* Lynx Point-LP */ { PCI_DEVICE(0x8086, 0x9c21), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | + AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, /* Haswell */ { PCI_DEVICE(0x8086, 0x0c0c), - .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | + AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, { PCI_DEVICE(0x8086, 0x0d0c), - .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | + AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, /* 5 Series/3400 */ { PCI_DEVICE(0x8086, 0x3b56), - .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | + AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, /* SCH */ { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | @@ -3564,8 +3563,6 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { /* Teradici */ { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT }, - { PCI_DEVICE(0x6549, 0x2200), - .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT }, /* Creative X-Fi (CA0110-IBG) */ /* CTHDA chips */ { PCI_DEVICE(0x1102, 0x0010), diff --git a/trunk/sound/pci/hda/patch_analog.c b/trunk/sound/pci/hda/patch_analog.c index 1eeba7386666..cdd43eadbc67 100644 --- a/trunk/sound/pci/hda/patch_analog.c +++ b/trunk/sound/pci/hda/patch_analog.c @@ -545,7 +545,6 @@ static int ad198x_build_pcms(struct hda_codec *codec) if (spec->multiout.dig_out_nid) { info++; codec->num_pcms++; - codec->spdif_status_reset = 1; info->name = "AD198x Digital"; info->pcm_type = HDA_PCM_TYPE_SPDIF; info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback; diff --git a/trunk/sound/pci/hda/patch_cirrus.c b/trunk/sound/pci/hda/patch_cirrus.c index 3bcb67172358..61a71131711c 100644 --- a/trunk/sound/pci/hda/patch_cirrus.c +++ b/trunk/sound/pci/hda/patch_cirrus.c @@ -101,8 +101,8 @@ enum { #define CS420X_VENDOR_NID 0x11 #define CS_DIG_OUT1_PIN_NID 0x10 #define CS_DIG_OUT2_PIN_NID 0x15 -#define CS_DMIC1_PIN_NID 0x0e -#define CS_DMIC2_PIN_NID 0x12 +#define CS_DMIC1_PIN_NID 0x12 +#define CS_DMIC2_PIN_NID 0x0e /* coef indices */ #define IDX_SPDIF_STAT 0x0000 @@ -466,7 +466,6 @@ static int parse_output(struct hda_codec *codec) memcpy(cfg->speaker_pins, cfg->line_out_pins, sizeof(cfg->speaker_pins)); cfg->line_outs = 0; - memset(cfg->line_out_pins, 0, sizeof(cfg->line_out_pins)); } return 0; @@ -1080,18 +1079,14 @@ static void init_input(struct hda_codec *codec) cs_automic(codec, NULL); coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */ - cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); - - coef = cs_vendor_coef_get(codec, IDX_BEEP_CFG); if (is_active_pin(codec, CS_DMIC2_PIN_NID)) - coef |= 1 << 4; /* DMIC2 2 chan on, GPIO1 off */ + coef |= 0x0500; /* DMIC2 2 chan on, GPIO1 off */ if (is_active_pin(codec, CS_DMIC1_PIN_NID)) - coef |= 1 << 3; /* DMIC1 2 chan on, GPIO0 off + coef |= 0x1800; /* DMIC1 2 chan on, GPIO0 off * No effect if SPDIF_OUT2 is * selected in IDX_SPDIF_CTL. */ - - cs_vendor_coef_set(codec, IDX_BEEP_CFG, coef); + cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); } else { if (spec->mic_detect) cs_automic(codec, NULL); @@ -1112,7 +1107,7 @@ static const struct hda_verb cs_coef_init_verbs[] = { | 0x0400 /* Disable Coefficient Auto increment */ )}, /* Beep */ - {0x11, AC_VERB_SET_COEF_INDEX, IDX_BEEP_CFG}, + {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG}, {0x11, AC_VERB_SET_PROC_COEF, 0x0007}, /* Enable Beep thru DAC1/2/3 */ {} /* terminator */ @@ -1733,7 +1728,8 @@ static int cs421x_mux_enum_put(struct snd_kcontrol *kcontrol, } -static const struct snd_kcontrol_new cs421x_capture_source = { +static struct snd_kcontrol_new cs421x_capture_source = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, @@ -1950,7 +1946,7 @@ static int cs421x_suspend(struct hda_codec *codec) } #endif -static const struct hda_codec_ops cs421x_patch_ops = { +static struct hda_codec_ops cs421x_patch_ops = { .build_controls = cs421x_build_controls, .build_pcms = cs_build_pcms, .init = cs421x_init, diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index ad68d223f8af..48d9d609f89b 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -5407,7 +5407,6 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO), - SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), @@ -5678,7 +5677,6 @@ static const struct hda_verb alc268_beep_init_verbs[] = { enum { ALC268_FIXUP_INV_DMIC, - ALC268_FIXUP_HP_EAPD, }; static const struct alc_fixup alc268_fixups[] = { @@ -5686,26 +5684,10 @@ static const struct alc_fixup alc268_fixups[] = { .type = ALC_FIXUP_FUNC, .v.func = alc_fixup_inv_dmic_0x12, }, - [ALC268_FIXUP_HP_EAPD] = { - .type = ALC_FIXUP_VERBS, - .v.verbs = (const struct hda_verb[]) { - {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0}, - {} - } - }, }; static const struct alc_model_fixup alc268_fixup_models[] = { {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"}, - {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"}, - {} -}; - -static const struct snd_pci_quirk alc268_fixup_tbl[] = { - /* below is codec SSID since multiple Toshiba laptops have the - * same PCI SSID 1179:ff00 - */ - SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD), {} }; @@ -5740,7 +5722,7 @@ static int patch_alc268(struct hda_codec *codec) spec = codec->spec; - alc_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups); + alc_pick_fixup(codec, alc268_fixup_models, NULL, alc268_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); /* automatic parse from the BIOS config */ @@ -5841,7 +5823,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) return alc_parse_auto_config(codec, alc269_ignore, ssids); } -static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) +static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) { int val = alc_read_coef_idx(codec, 0x04); if (power_up) @@ -5858,10 +5840,10 @@ static void alc269_shutup(struct hda_codec *codec) if (spec->codec_variant != ALC269_TYPE_ALC269VB) return; - if (spec->codec_variant == ALC269_TYPE_ALC269VB) - alc269vb_toggle_power_output(codec, 0); - if (spec->codec_variant == ALC269_TYPE_ALC269VB && - (alc_get_coef0(codec) & 0x00ff) == 0x018) { + if ((alc_get_coef0(codec) & 0x00ff) == 0x017) + alc269_toggle_power_output(codec, 0); + if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { + alc269_toggle_power_output(codec, 0); msleep(150); } } @@ -5871,22 +5853,24 @@ static int alc269_resume(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - if (spec->codec_variant == ALC269_TYPE_ALC269VB) - alc269vb_toggle_power_output(codec, 0); - if (spec->codec_variant == ALC269_TYPE_ALC269VB && + if (spec->codec_variant == ALC269_TYPE_ALC269VB || (alc_get_coef0(codec) & 0x00ff) == 0x018) { + alc269_toggle_power_output(codec, 0); msleep(150); } codec->patch_ops.init(codec); - if (spec->codec_variant == ALC269_TYPE_ALC269VB) - alc269vb_toggle_power_output(codec, 1); - if (spec->codec_variant == ALC269_TYPE_ALC269VB && + if (spec->codec_variant == ALC269_TYPE_ALC269VB || (alc_get_coef0(codec) & 0x00ff) == 0x017) { + alc269_toggle_power_output(codec, 1); msleep(200); } + if (spec->codec_variant == ALC269_TYPE_ALC269VB || + (alc_get_coef0(codec) & 0x00ff) == 0x018) + alc269_toggle_power_output(codec, 1); + snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); hda_call_check_power_status(codec, 0x01); @@ -6204,7 +6188,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), - SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), @@ -7065,7 +7048,6 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 }, { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, - { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", .patch = patch_alc861 }, { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, @@ -7079,7 +7061,6 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { .patch = patch_alc662 }, { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, - { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 }, { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, @@ -7097,7 +7078,6 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 }, - { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 }, {} /* terminator */ }; diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index 9ba8af056170..770013ff556f 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -1763,8 +1763,6 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { "HP", STAC_HP_ZEPHYR), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3660, "HP Mini", STAC_92HD83XXX_HP_LED), - SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x144E, - "HP Pavilion dv5", STAC_92HD83XXX_HP_INV_LED), {} /* terminator */ }; diff --git a/trunk/sound/pci/hda/patch_via.c b/trunk/sound/pci/hda/patch_via.c index 019e1a00414a..72a2f60b087c 100644 --- a/trunk/sound/pci/hda/patch_via.c +++ b/trunk/sound/pci/hda/patch_via.c @@ -1809,11 +1809,11 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec) { struct via_spec *spec = codec->spec; const struct auto_pin_cfg *cfg = &spec->autocfg; - int i; + int i, dac_num; hda_nid_t nid; - spec->multiout.num_dacs = 0; spec->multiout.dac_nids = spec->private_dac_nids; + dac_num = 0; for (i = 0; i < cfg->line_outs; i++) { hda_nid_t dac = 0; nid = cfg->line_out_pins[i]; @@ -1824,13 +1824,16 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec) if (!i && parse_output_path(codec, nid, dac, 1, &spec->out_mix_path)) dac = spec->out_mix_path.path[0]; - if (dac) - spec->private_dac_nids[spec->multiout.num_dacs++] = dac; + if (dac) { + spec->private_dac_nids[i] = dac; + dac_num++; + } } if (!spec->out_path[0].depth && spec->out_mix_path.depth) { spec->out_path[0] = spec->out_mix_path; spec->out_mix_path.depth = 0; } + spec->multiout.num_dacs = dac_num; return 0; } @@ -3625,7 +3628,6 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) */ enum { VIA_FIXUP_INTMIC_BOOST, - VIA_FIXUP_ASUS_G75, }; static void via_fixup_intmic_boost(struct hda_codec *codec, @@ -3640,35 +3642,13 @@ static const struct hda_fixup via_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = via_fixup_intmic_boost, }, - [VIA_FIXUP_ASUS_G75] = { - .type = HDA_FIXUP_PINS, - .v.pins = (const struct hda_pintbl[]) { - /* set 0x24 and 0x33 as speakers */ - { 0x24, 0x991301f0 }, - { 0x33, 0x991301f1 }, /* subwoofer */ - { } - } - }, }; static const struct snd_pci_quirk vt2002p_fixups[] = { - SND_PCI_QUIRK(0x1043, 0x1487, "Asus G75", VIA_FIXUP_ASUS_G75), SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST), {} }; -/* NIDs 0x24 and 0x33 on VT1802 have connections to non-existing NID 0x3e - * Replace this with mixer NID 0x1c - */ -static void fix_vt1802_connections(struct hda_codec *codec) -{ - static hda_nid_t conn_24[] = { 0x14, 0x1c }; - static hda_nid_t conn_33[] = { 0x1c }; - - snd_hda_override_conn_list(codec, 0x24, ARRAY_SIZE(conn_24), conn_24); - snd_hda_override_conn_list(codec, 0x33, ARRAY_SIZE(conn_33), conn_33); -} - /* patch for vt2002P */ static int patch_vt2002P(struct hda_codec *codec) { @@ -3683,8 +3663,6 @@ static int patch_vt2002P(struct hda_codec *codec) spec->aa_mix_nid = 0x21; override_mic_boost(codec, 0x2b, 0, 3, 40); override_mic_boost(codec, 0x29, 0, 3, 40); - if (spec->codec_type == VT1802) - fix_vt1802_connections(codec); add_secret_dac_path(codec); snd_hda_pick_fixup(codec, NULL, vt2002p_fixups, via_fixups); diff --git a/trunk/sound/pci/ice1712/ice1724.c b/trunk/sound/pci/ice1712/ice1724.c index 245d874891ba..3050a5279253 100644 --- a/trunk/sound/pci/ice1712/ice1724.c +++ b/trunk/sound/pci/ice1712/ice1724.c @@ -2859,12 +2859,7 @@ static int snd_vt1724_resume(struct device *dev) ice->set_spdif_clock(ice, 0); } else { /* internal on-card clock */ - int rate; - if (ice->cur_rate) - rate = ice->cur_rate; - else - rate = ice->pro_rate_default; - snd_vt1724_set_pro_rate(ice, rate, 1); + snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 1); } update_spdif_bits(ice, ice->pm_saved_spdif_ctrl); diff --git a/trunk/sound/pci/rme9652/hdspm.c b/trunk/sound/pci/rme9652/hdspm.c index 748e36c66603..b12308b5ba2a 100644 --- a/trunk/sound/pci/rme9652/hdspm.c +++ b/trunk/sound/pci/rme9652/hdspm.c @@ -971,7 +971,6 @@ static inline void snd_hdspm_initialize_midi_flush(struct hdspm *hdspm); static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm); static int hdspm_autosync_ref(struct hdspm *hdspm); static int snd_hdspm_set_defaults(struct hdspm *hdspm); -static int hdspm_system_clock_mode(struct hdspm *hdspm); static void hdspm_set_sgbuf(struct hdspm *hdspm, struct snd_pcm_substream *substream, unsigned int reg, int channels); @@ -1990,14 +1989,10 @@ static int hdspm_get_system_sample_rate(struct hdspm *hdspm) rate = hdspm_calc_dds_value(hdspm, period); if (rate > 207000) { - /* Unreasonable high sample rate as seen on PCI MADI cards. */ - if (0 == hdspm_system_clock_mode(hdspm)) { - /* master mode, return internal sample rate */ - rate = hdspm->system_sample_rate; - } else { - /* slave mode, return external sample rate */ - rate = hdspm_external_sample_rate(hdspm); - } + /* Unreasonable high sample rate as seen on PCI MADI cards. + * Use the cached value instead. + */ + rate = hdspm->system_sample_rate; } return rate; @@ -2005,14 +2000,12 @@ static int hdspm_get_system_sample_rate(struct hdspm *hdspm) #define HDSPM_SYSTEM_SAMPLE_RATE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\ - SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ - .info = snd_hdspm_info_system_sample_rate, \ - .put = snd_hdspm_put_system_sample_rate, \ - .get = snd_hdspm_get_system_sample_rate \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = xindex, \ + .access = SNDRV_CTL_ELEM_ACCESS_READ, \ + .info = snd_hdspm_info_system_sample_rate, \ + .get = snd_hdspm_get_system_sample_rate \ } static int snd_hdspm_info_system_sample_rate(struct snd_kcontrol *kcontrol, @@ -2037,16 +2030,6 @@ static int snd_hdspm_get_system_sample_rate(struct snd_kcontrol *kcontrol, return 0; } -static int snd_hdspm_put_system_sample_rate(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value * - ucontrol) -{ - struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); - - hdspm_set_dds_value(hdspm, ucontrol->value.enumerated.item[0]); - return 0; -} - /** * Returns the WordClock sample rate class for the given card. @@ -2180,7 +2163,6 @@ static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol, hdspm_get_s1_sample_rate(hdspm, kcontrol->private_value-1); } - break; case AIO: switch (kcontrol->private_value) { @@ -2201,7 +2183,6 @@ static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol, hdspm_get_s1_sample_rate(hdspm, ucontrol->id.index-1); } - break; case AES32: @@ -2223,23 +2204,8 @@ static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol, hdspm_get_s1_sample_rate(hdspm, kcontrol->private_value-1); break; - } - break; - case MADI: - case MADIface: - { - int rate = hdspm_external_sample_rate(hdspm); - int i, selected_rate = 0; - for (i = 1; i < 10; i++) - if (HDSPM_bit2freq(i) == rate) { - selected_rate = i; - break; - } - ucontrol->value.enumerated.item[0] = selected_rate; } - break; - default: break; } @@ -2464,7 +2430,7 @@ static int snd_hdspm_put_clock_source(struct snd_kcontrol *kcontrol, #define HDSPM_PREF_SYNC_REF(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ +{.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\ @@ -2800,12 +2766,12 @@ static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol, #define HDSPM_AUTOSYNC_REF(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .access = SNDRV_CTL_ELEM_ACCESS_READ, \ - .info = snd_hdspm_info_autosync_ref, \ - .get = snd_hdspm_get_autosync_ref, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = xindex, \ + .access = SNDRV_CTL_ELEM_ACCESS_READ, \ + .info = snd_hdspm_info_autosync_ref, \ + .get = snd_hdspm_get_autosync_ref, \ } static int hdspm_autosync_ref(struct hdspm *hdspm) @@ -2889,12 +2855,12 @@ static int snd_hdspm_get_autosync_ref(struct snd_kcontrol *kcontrol, #define HDSPM_LINE_OUT(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .info = snd_hdspm_info_line_out, \ - .get = snd_hdspm_get_line_out, \ - .put = snd_hdspm_put_line_out \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = xindex, \ + .info = snd_hdspm_info_line_out, \ + .get = snd_hdspm_get_line_out, \ + .put = snd_hdspm_put_line_out \ } static int hdspm_line_out(struct hdspm * hdspm) @@ -2946,12 +2912,12 @@ static int snd_hdspm_put_line_out(struct snd_kcontrol *kcontrol, #define HDSPM_TX_64(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .info = snd_hdspm_info_tx_64, \ - .get = snd_hdspm_get_tx_64, \ - .put = snd_hdspm_put_tx_64 \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = xindex, \ + .info = snd_hdspm_info_tx_64, \ + .get = snd_hdspm_get_tx_64, \ + .put = snd_hdspm_put_tx_64 \ } static int hdspm_tx_64(struct hdspm * hdspm) @@ -3002,12 +2968,12 @@ static int snd_hdspm_put_tx_64(struct snd_kcontrol *kcontrol, #define HDSPM_C_TMS(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .info = snd_hdspm_info_c_tms, \ - .get = snd_hdspm_get_c_tms, \ - .put = snd_hdspm_put_c_tms \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = xindex, \ + .info = snd_hdspm_info_c_tms, \ + .get = snd_hdspm_get_c_tms, \ + .put = snd_hdspm_put_c_tms \ } static int hdspm_c_tms(struct hdspm * hdspm) @@ -3058,12 +3024,12 @@ static int snd_hdspm_put_c_tms(struct snd_kcontrol *kcontrol, #define HDSPM_SAFE_MODE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .info = snd_hdspm_info_safe_mode, \ - .get = snd_hdspm_get_safe_mode, \ - .put = snd_hdspm_put_safe_mode \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = xindex, \ + .info = snd_hdspm_info_safe_mode, \ + .get = snd_hdspm_get_safe_mode, \ + .put = snd_hdspm_put_safe_mode \ } static int hdspm_safe_mode(struct hdspm * hdspm) @@ -3114,12 +3080,12 @@ static int snd_hdspm_put_safe_mode(struct snd_kcontrol *kcontrol, #define HDSPM_EMPHASIS(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .info = snd_hdspm_info_emphasis, \ - .get = snd_hdspm_get_emphasis, \ - .put = snd_hdspm_put_emphasis \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = xindex, \ + .info = snd_hdspm_info_emphasis, \ + .get = snd_hdspm_get_emphasis, \ + .put = snd_hdspm_put_emphasis \ } static int hdspm_emphasis(struct hdspm * hdspm) @@ -3170,12 +3136,12 @@ static int snd_hdspm_put_emphasis(struct snd_kcontrol *kcontrol, #define HDSPM_DOLBY(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .info = snd_hdspm_info_dolby, \ - .get = snd_hdspm_get_dolby, \ - .put = snd_hdspm_put_dolby \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = xindex, \ + .info = snd_hdspm_info_dolby, \ + .get = snd_hdspm_get_dolby, \ + .put = snd_hdspm_put_dolby \ } static int hdspm_dolby(struct hdspm * hdspm) @@ -3226,12 +3192,12 @@ static int snd_hdspm_put_dolby(struct snd_kcontrol *kcontrol, #define HDSPM_PROFESSIONAL(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .info = snd_hdspm_info_professional, \ - .get = snd_hdspm_get_professional, \ - .put = snd_hdspm_put_professional \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = xindex, \ + .info = snd_hdspm_info_professional, \ + .get = snd_hdspm_get_professional, \ + .put = snd_hdspm_put_professional \ } static int hdspm_professional(struct hdspm * hdspm) @@ -3281,12 +3247,12 @@ static int snd_hdspm_put_professional(struct snd_kcontrol *kcontrol, } #define HDSPM_INPUT_SELECT(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .info = snd_hdspm_info_input_select, \ - .get = snd_hdspm_get_input_select, \ - .put = snd_hdspm_put_input_select \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = xindex, \ + .info = snd_hdspm_info_input_select, \ + .get = snd_hdspm_get_input_select, \ + .put = snd_hdspm_put_input_select \ } static int hdspm_input_select(struct hdspm * hdspm) @@ -3353,12 +3319,12 @@ static int snd_hdspm_put_input_select(struct snd_kcontrol *kcontrol, #define HDSPM_DS_WIRE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .info = snd_hdspm_info_ds_wire, \ - .get = snd_hdspm_get_ds_wire, \ - .put = snd_hdspm_put_ds_wire \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = xindex, \ + .info = snd_hdspm_info_ds_wire, \ + .get = snd_hdspm_get_ds_wire, \ + .put = snd_hdspm_put_ds_wire \ } static int hdspm_ds_wire(struct hdspm * hdspm) @@ -3425,12 +3391,12 @@ static int snd_hdspm_put_ds_wire(struct snd_kcontrol *kcontrol, #define HDSPM_QS_WIRE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .info = snd_hdspm_info_qs_wire, \ - .get = snd_hdspm_get_qs_wire, \ - .put = snd_hdspm_put_qs_wire \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = xindex, \ + .info = snd_hdspm_info_qs_wire, \ + .get = snd_hdspm_get_qs_wire, \ + .put = snd_hdspm_put_qs_wire \ } static int hdspm_qs_wire(struct hdspm * hdspm) @@ -3597,15 +3563,15 @@ static int snd_hdspm_put_madi_speedmode(struct snd_kcontrol *kcontrol, } #define HDSPM_MIXER(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ - .name = xname, \ - .index = xindex, \ - .device = 0, \ - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ - SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ - .info = snd_hdspm_info_mixer, \ - .get = snd_hdspm_get_mixer, \ - .put = snd_hdspm_put_mixer \ +{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ + .name = xname, \ + .index = xindex, \ + .device = 0, \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ + SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ + .info = snd_hdspm_info_mixer, \ + .get = snd_hdspm_get_mixer, \ + .put = snd_hdspm_put_mixer \ } static int snd_hdspm_info_mixer(struct snd_kcontrol *kcontrol, @@ -3704,12 +3670,12 @@ static int snd_hdspm_put_mixer(struct snd_kcontrol *kcontrol, */ #define HDSPM_PLAYBACK_MIXER \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE | \ - SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ - .info = snd_hdspm_info_playback_mixer, \ - .get = snd_hdspm_get_playback_mixer, \ - .put = snd_hdspm_put_playback_mixer \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE | \ + SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ + .info = snd_hdspm_info_playback_mixer, \ + .get = snd_hdspm_get_playback_mixer, \ + .put = snd_hdspm_put_playback_mixer \ } static int snd_hdspm_info_playback_mixer(struct snd_kcontrol *kcontrol, @@ -3885,15 +3851,10 @@ static int hdspm_sync_in_sync_check(struct hdspm *hdspm) break; case MADI: - status = hdspm_read(hdspm, HDSPM_statusRegister); - lock = (status & HDSPM_syncInLock) ? 1 : 0; - sync = (status & HDSPM_syncInSync) ? 1 : 0; - break; - case AES32: status = hdspm_read(hdspm, HDSPM_statusRegister2); - lock = (status & 0x100000) ? 1 : 0; - sync = (status & 0x200000) ? 1 : 0; + lock = (status & HDSPM_syncInLock) ? 1 : 0; + sync = (status & HDSPM_syncInSync) ? 1 : 0; break; case MADIface: @@ -3979,10 +3940,8 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol, case 8: /* SYNC IN */ val = hdspm_sync_in_sync_check(hdspm); break; default: - val = hdspm_s1_sync_check(hdspm, - kcontrol->private_value-1); + val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1); } - break; case AIO: switch (kcontrol->private_value) { @@ -3995,7 +3954,6 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol, default: val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1); } - break; case MADI: switch (kcontrol->private_value) { @@ -4008,7 +3966,6 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol, case 3: /* SYNC_IN */ val = hdspm_sync_in_sync_check(hdspm); break; } - break; case MADIface: val = hdspm_madi_sync_check(hdspm); /* MADI */ @@ -4026,7 +3983,6 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol, val = hdspm_aes_sync_check(hdspm, kcontrol->private_value-1); } - break; } @@ -4471,10 +4427,9 @@ static struct snd_kcontrol_new snd_hdspm_controls_madi[] = { HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0), HDSPM_AUTOSYNC_REF("AutoSync Reference", 0), HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), - HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0), HDSPM_SYNC_CHECK("WC SyncCheck", 0), HDSPM_SYNC_CHECK("MADI SyncCheck", 1), - HDSPM_SYNC_CHECK("TCO SyncCheck", 2), + HDSPM_SYNC_CHECK("TCO SyncCHeck", 2), HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 3), HDSPM_LINE_OUT("Line Out", 0), HDSPM_TX_64("TX 64 channels mode", 0), @@ -4900,7 +4855,7 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry, insel = "Coaxial"; break; default: - insel = "Unknown"; + insel = "Unkown"; } snd_iprintf(buffer, diff --git a/trunk/sound/soc/codecs/arizona.c b/trunk/sound/soc/codecs/arizona.c index 054967d8bac2..c03b65af3059 100644 --- a/trunk/sound/soc/codecs/arizona.c +++ b/trunk/sound/soc/codecs/arizona.c @@ -268,7 +268,7 @@ EXPORT_SYMBOL_GPL(arizona_out_ev); static unsigned int arizona_sysclk_48k_rates[] = { 6144000, 12288000, - 24576000, + 22579200, 49152000, 73728000, 98304000, @@ -278,7 +278,7 @@ static unsigned int arizona_sysclk_48k_rates[] = { static unsigned int arizona_sysclk_44k1_rates[] = { 5644800, 11289600, - 22579200, + 24576000, 45158400, 67737600, 90316800, diff --git a/trunk/sound/soc/codecs/cs4271.c b/trunk/sound/soc/codecs/cs4271.c index e3f0a7f3131e..f994af34f552 100644 --- a/trunk/sound/soc/codecs/cs4271.c +++ b/trunk/sound/soc/codecs/cs4271.c @@ -485,7 +485,7 @@ static int cs4271_probe(struct snd_soc_codec *codec) gpio_nreset = cs4271plat->gpio_nreset; if (gpio_nreset >= 0) - if (devm_gpio_request(codec->dev, gpio_nreset, "CS4271 Reset")) + if (gpio_request(gpio_nreset, "CS4271 Reset")) gpio_nreset = -EINVAL; if (gpio_nreset >= 0) { /* Reset codec */ @@ -535,10 +535,15 @@ static int cs4271_probe(struct snd_soc_codec *codec) static int cs4271_remove(struct snd_soc_codec *codec) { struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); + int gpio_nreset; - if (gpio_is_valid(cs4271->gpio_nreset)) + gpio_nreset = cs4271->gpio_nreset; + + if (gpio_is_valid(gpio_nreset)) { /* Set codec to the reset state */ - gpio_set_value(cs4271->gpio_nreset, 0); + gpio_set_value(gpio_nreset, 0); + gpio_free(gpio_nreset); + } return 0; }; diff --git a/trunk/sound/soc/codecs/cs42l52.c b/trunk/sound/soc/codecs/cs42l52.c index 97a81051e88d..61599298fb26 100644 --- a/trunk/sound/soc/codecs/cs42l52.c +++ b/trunk/sound/soc/codecs/cs42l52.c @@ -763,7 +763,7 @@ static int cs42l52_set_sysclk(struct snd_soc_dai *codec_dai, if ((freq >= CS42L52_MIN_CLK) && (freq <= CS42L52_MAX_CLK)) { cs42l52->sysclk = freq; } else { - dev_err(codec->dev, "Invalid freq parameter\n"); + dev_err(codec->dev, "Invalid freq paramter\n"); return -EINVAL; } return 0; @@ -773,6 +773,7 @@ static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); + int ret = 0; u8 iface = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { @@ -821,7 +822,7 @@ static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) case SND_SOC_DAIFMT_NB_IF: break; default: - return -EINVAL; + ret = -EINVAL; } cs42l52->config.format = iface; snd_soc_write(codec, CS42L52_IFACE_CTL1, cs42l52->config.format); diff --git a/trunk/sound/soc/codecs/wm5102.c b/trunk/sound/soc/codecs/wm5102.c index 7394e73fa43c..1722b586bdba 100644 --- a/trunk/sound/soc/codecs/wm5102.c +++ b/trunk/sound/soc/codecs/wm5102.c @@ -42,556 +42,6 @@ static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0); -static const struct reg_default wm5102_sysclk_reva_patch[] = { - { 0x3000, 0x2225 }, - { 0x3001, 0x3a03 }, - { 0x3002, 0x0225 }, - { 0x3003, 0x0801 }, - { 0x3004, 0x6249 }, - { 0x3005, 0x0c04 }, - { 0x3006, 0x0225 }, - { 0x3007, 0x5901 }, - { 0x3008, 0xe249 }, - { 0x3009, 0x030d }, - { 0x300a, 0x0249 }, - { 0x300b, 0x2c01 }, - { 0x300c, 0xe249 }, - { 0x300d, 0x4342 }, - { 0x300e, 0xe249 }, - { 0x300f, 0x73c0 }, - { 0x3010, 0x4249 }, - { 0x3011, 0x0c00 }, - { 0x3012, 0x0225 }, - { 0x3013, 0x1f01 }, - { 0x3014, 0x0225 }, - { 0x3015, 0x1e01 }, - { 0x3016, 0x0225 }, - { 0x3017, 0xfa00 }, - { 0x3018, 0x0000 }, - { 0x3019, 0xf000 }, - { 0x301a, 0x0000 }, - { 0x301b, 0xf000 }, - { 0x301c, 0x0000 }, - { 0x301d, 0xf000 }, - { 0x301e, 0x0000 }, - { 0x301f, 0xf000 }, - { 0x3020, 0x0000 }, - { 0x3021, 0xf000 }, - { 0x3022, 0x0000 }, - { 0x3023, 0xf000 }, - { 0x3024, 0x0000 }, - { 0x3025, 0xf000 }, - { 0x3026, 0x0000 }, - { 0x3027, 0xf000 }, - { 0x3028, 0x0000 }, - { 0x3029, 0xf000 }, - { 0x302a, 0x0000 }, - { 0x302b, 0xf000 }, - { 0x302c, 0x0000 }, - { 0x302d, 0xf000 }, - { 0x302e, 0x0000 }, - { 0x302f, 0xf000 }, - { 0x3030, 0x0225 }, - { 0x3031, 0x1a01 }, - { 0x3032, 0x0225 }, - { 0x3033, 0x1e00 }, - { 0x3034, 0x0225 }, - { 0x3035, 0x1f00 }, - { 0x3036, 0x6225 }, - { 0x3037, 0xf800 }, - { 0x3038, 0x0000 }, - { 0x3039, 0xf000 }, - { 0x303a, 0x0000 }, - { 0x303b, 0xf000 }, - { 0x303c, 0x0000 }, - { 0x303d, 0xf000 }, - { 0x303e, 0x0000 }, - { 0x303f, 0xf000 }, - { 0x3040, 0x2226 }, - { 0x3041, 0x3a03 }, - { 0x3042, 0x0226 }, - { 0x3043, 0x0801 }, - { 0x3044, 0x6249 }, - { 0x3045, 0x0c06 }, - { 0x3046, 0x0226 }, - { 0x3047, 0x5901 }, - { 0x3048, 0xe249 }, - { 0x3049, 0x030d }, - { 0x304a, 0x0249 }, - { 0x304b, 0x2c01 }, - { 0x304c, 0xe249 }, - { 0x304d, 0x4342 }, - { 0x304e, 0xe249 }, - { 0x304f, 0x73c0 }, - { 0x3050, 0x4249 }, - { 0x3051, 0x0c00 }, - { 0x3052, 0x0226 }, - { 0x3053, 0x1f01 }, - { 0x3054, 0x0226 }, - { 0x3055, 0x1e01 }, - { 0x3056, 0x0226 }, - { 0x3057, 0xfa00 }, - { 0x3058, 0x0000 }, - { 0x3059, 0xf000 }, - { 0x305a, 0x0000 }, - { 0x305b, 0xf000 }, - { 0x305c, 0x0000 }, - { 0x305d, 0xf000 }, - { 0x305e, 0x0000 }, - { 0x305f, 0xf000 }, - { 0x3060, 0x0000 }, - { 0x3061, 0xf000 }, - { 0x3062, 0x0000 }, - { 0x3063, 0xf000 }, - { 0x3064, 0x0000 }, - { 0x3065, 0xf000 }, - { 0x3066, 0x0000 }, - { 0x3067, 0xf000 }, - { 0x3068, 0x0000 }, - { 0x3069, 0xf000 }, - { 0x306a, 0x0000 }, - { 0x306b, 0xf000 }, - { 0x306c, 0x0000 }, - { 0x306d, 0xf000 }, - { 0x306e, 0x0000 }, - { 0x306f, 0xf000 }, - { 0x3070, 0x0226 }, - { 0x3071, 0x1a01 }, - { 0x3072, 0x0226 }, - { 0x3073, 0x1e00 }, - { 0x3074, 0x0226 }, - { 0x3075, 0x1f00 }, - { 0x3076, 0x6226 }, - { 0x3077, 0xf800 }, - { 0x3078, 0x0000 }, - { 0x3079, 0xf000 }, - { 0x307a, 0x0000 }, - { 0x307b, 0xf000 }, - { 0x307c, 0x0000 }, - { 0x307d, 0xf000 }, - { 0x307e, 0x0000 }, - { 0x307f, 0xf000 }, - { 0x3080, 0x2227 }, - { 0x3081, 0x3a03 }, - { 0x3082, 0x0227 }, - { 0x3083, 0x0801 }, - { 0x3084, 0x6255 }, - { 0x3085, 0x0c04 }, - { 0x3086, 0x0227 }, - { 0x3087, 0x5901 }, - { 0x3088, 0xe255 }, - { 0x3089, 0x030d }, - { 0x308a, 0x0255 }, - { 0x308b, 0x2c01 }, - { 0x308c, 0xe255 }, - { 0x308d, 0x4342 }, - { 0x308e, 0xe255 }, - { 0x308f, 0x73c0 }, - { 0x3090, 0x4255 }, - { 0x3091, 0x0c00 }, - { 0x3092, 0x0227 }, - { 0x3093, 0x1f01 }, - { 0x3094, 0x0227 }, - { 0x3095, 0x1e01 }, - { 0x3096, 0x0227 }, - { 0x3097, 0xfa00 }, - { 0x3098, 0x0000 }, - { 0x3099, 0xf000 }, - { 0x309a, 0x0000 }, - { 0x309b, 0xf000 }, - { 0x309c, 0x0000 }, - { 0x309d, 0xf000 }, - { 0x309e, 0x0000 }, - { 0x309f, 0xf000 }, - { 0x30a0, 0x0000 }, - { 0x30a1, 0xf000 }, - { 0x30a2, 0x0000 }, - { 0x30a3, 0xf000 }, - { 0x30a4, 0x0000 }, - { 0x30a5, 0xf000 }, - { 0x30a6, 0x0000 }, - { 0x30a7, 0xf000 }, - { 0x30a8, 0x0000 }, - { 0x30a9, 0xf000 }, - { 0x30aa, 0x0000 }, - { 0x30ab, 0xf000 }, - { 0x30ac, 0x0000 }, - { 0x30ad, 0xf000 }, - { 0x30ae, 0x0000 }, - { 0x30af, 0xf000 }, - { 0x30b0, 0x0227 }, - { 0x30b1, 0x1a01 }, - { 0x30b2, 0x0227 }, - { 0x30b3, 0x1e00 }, - { 0x30b4, 0x0227 }, - { 0x30b5, 0x1f00 }, - { 0x30b6, 0x6227 }, - { 0x30b7, 0xf800 }, - { 0x30b8, 0x0000 }, - { 0x30b9, 0xf000 }, - { 0x30ba, 0x0000 }, - { 0x30bb, 0xf000 }, - { 0x30bc, 0x0000 }, - { 0x30bd, 0xf000 }, - { 0x30be, 0x0000 }, - { 0x30bf, 0xf000 }, - { 0x30c0, 0x2228 }, - { 0x30c1, 0x3a03 }, - { 0x30c2, 0x0228 }, - { 0x30c3, 0x0801 }, - { 0x30c4, 0x6255 }, - { 0x30c5, 0x0c06 }, - { 0x30c6, 0x0228 }, - { 0x30c7, 0x5901 }, - { 0x30c8, 0xe255 }, - { 0x30c9, 0x030d }, - { 0x30ca, 0x0255 }, - { 0x30cb, 0x2c01 }, - { 0x30cc, 0xe255 }, - { 0x30cd, 0x4342 }, - { 0x30ce, 0xe255 }, - { 0x30cf, 0x73c0 }, - { 0x30d0, 0x4255 }, - { 0x30d1, 0x0c00 }, - { 0x30d2, 0x0228 }, - { 0x30d3, 0x1f01 }, - { 0x30d4, 0x0228 }, - { 0x30d5, 0x1e01 }, - { 0x30d6, 0x0228 }, - { 0x30d7, 0xfa00 }, - { 0x30d8, 0x0000 }, - { 0x30d9, 0xf000 }, - { 0x30da, 0x0000 }, - { 0x30db, 0xf000 }, - { 0x30dc, 0x0000 }, - { 0x30dd, 0xf000 }, - { 0x30de, 0x0000 }, - { 0x30df, 0xf000 }, - { 0x30e0, 0x0000 }, - { 0x30e1, 0xf000 }, - { 0x30e2, 0x0000 }, - { 0x30e3, 0xf000 }, - { 0x30e4, 0x0000 }, - { 0x30e5, 0xf000 }, - { 0x30e6, 0x0000 }, - { 0x30e7, 0xf000 }, - { 0x30e8, 0x0000 }, - { 0x30e9, 0xf000 }, - { 0x30ea, 0x0000 }, - { 0x30eb, 0xf000 }, - { 0x30ec, 0x0000 }, - { 0x30ed, 0xf000 }, - { 0x30ee, 0x0000 }, - { 0x30ef, 0xf000 }, - { 0x30f0, 0x0228 }, - { 0x30f1, 0x1a01 }, - { 0x30f2, 0x0228 }, - { 0x30f3, 0x1e00 }, - { 0x30f4, 0x0228 }, - { 0x30f5, 0x1f00 }, - { 0x30f6, 0x6228 }, - { 0x30f7, 0xf800 }, - { 0x30f8, 0x0000 }, - { 0x30f9, 0xf000 }, - { 0x30fa, 0x0000 }, - { 0x30fb, 0xf000 }, - { 0x30fc, 0x0000 }, - { 0x30fd, 0xf000 }, - { 0x30fe, 0x0000 }, - { 0x30ff, 0xf000 }, - { 0x3100, 0x222b }, - { 0x3101, 0x3a03 }, - { 0x3102, 0x222b }, - { 0x3103, 0x5803 }, - { 0x3104, 0xe26f }, - { 0x3105, 0x030d }, - { 0x3106, 0x626f }, - { 0x3107, 0x2c01 }, - { 0x3108, 0xe26f }, - { 0x3109, 0x4342 }, - { 0x310a, 0xe26f }, - { 0x310b, 0x73c0 }, - { 0x310c, 0x026f }, - { 0x310d, 0x0c00 }, - { 0x310e, 0x022b }, - { 0x310f, 0x1f01 }, - { 0x3110, 0x022b }, - { 0x3111, 0x1e01 }, - { 0x3112, 0x022b }, - { 0x3113, 0xfa00 }, - { 0x3114, 0x0000 }, - { 0x3115, 0xf000 }, - { 0x3116, 0x0000 }, - { 0x3117, 0xf000 }, - { 0x3118, 0x0000 }, - { 0x3119, 0xf000 }, - { 0x311a, 0x0000 }, - { 0x311b, 0xf000 }, - { 0x311c, 0x0000 }, - { 0x311d, 0xf000 }, - { 0x311e, 0x0000 }, - { 0x311f, 0xf000 }, - { 0x3120, 0x022b }, - { 0x3121, 0x0a01 }, - { 0x3122, 0x022b }, - { 0x3123, 0x1e00 }, - { 0x3124, 0x022b }, - { 0x3125, 0x1f00 }, - { 0x3126, 0x622b }, - { 0x3127, 0xf800 }, - { 0x3128, 0x0000 }, - { 0x3129, 0xf000 }, - { 0x312a, 0x0000 }, - { 0x312b, 0xf000 }, - { 0x312c, 0x0000 }, - { 0x312d, 0xf000 }, - { 0x312e, 0x0000 }, - { 0x312f, 0xf000 }, - { 0x3130, 0x0000 }, - { 0x3131, 0xf000 }, - { 0x3132, 0x0000 }, - { 0x3133, 0xf000 }, - { 0x3134, 0x0000 }, - { 0x3135, 0xf000 }, - { 0x3136, 0x0000 }, - { 0x3137, 0xf000 }, - { 0x3138, 0x0000 }, - { 0x3139, 0xf000 }, - { 0x313a, 0x0000 }, - { 0x313b, 0xf000 }, - { 0x313c, 0x0000 }, - { 0x313d, 0xf000 }, - { 0x313e, 0x0000 }, - { 0x313f, 0xf000 }, - { 0x3140, 0x0000 }, - { 0x3141, 0xf000 }, - { 0x3142, 0x0000 }, - { 0x3143, 0xf000 }, - { 0x3144, 0x0000 }, - { 0x3145, 0xf000 }, - { 0x3146, 0x0000 }, - { 0x3147, 0xf000 }, - { 0x3148, 0x0000 }, - { 0x3149, 0xf000 }, - { 0x314a, 0x0000 }, - { 0x314b, 0xf000 }, - { 0x314c, 0x0000 }, - { 0x314d, 0xf000 }, - { 0x314e, 0x0000 }, - { 0x314f, 0xf000 }, - { 0x3150, 0x0000 }, - { 0x3151, 0xf000 }, - { 0x3152, 0x0000 }, - { 0x3153, 0xf000 }, - { 0x3154, 0x0000 }, - { 0x3155, 0xf000 }, - { 0x3156, 0x0000 }, - { 0x3157, 0xf000 }, - { 0x3158, 0x0000 }, - { 0x3159, 0xf000 }, - { 0x315a, 0x0000 }, - { 0x315b, 0xf000 }, - { 0x315c, 0x0000 }, - { 0x315d, 0xf000 }, - { 0x315e, 0x0000 }, - { 0x315f, 0xf000 }, - { 0x3160, 0x0000 }, - { 0x3161, 0xf000 }, - { 0x3162, 0x0000 }, - { 0x3163, 0xf000 }, - { 0x3164, 0x0000 }, - { 0x3165, 0xf000 }, - { 0x3166, 0x0000 }, - { 0x3167, 0xf000 }, - { 0x3168, 0x0000 }, - { 0x3169, 0xf000 }, - { 0x316a, 0x0000 }, - { 0x316b, 0xf000 }, - { 0x316c, 0x0000 }, - { 0x316d, 0xf000 }, - { 0x316e, 0x0000 }, - { 0x316f, 0xf000 }, - { 0x3170, 0x0000 }, - { 0x3171, 0xf000 }, - { 0x3172, 0x0000 }, - { 0x3173, 0xf000 }, - { 0x3174, 0x0000 }, - { 0x3175, 0xf000 }, - { 0x3176, 0x0000 }, - { 0x3177, 0xf000 }, - { 0x3178, 0x0000 }, - { 0x3179, 0xf000 }, - { 0x317a, 0x0000 }, - { 0x317b, 0xf000 }, - { 0x317c, 0x0000 }, - { 0x317d, 0xf000 }, - { 0x317e, 0x0000 }, - { 0x317f, 0xf000 }, - { 0x3180, 0x2001 }, - { 0x3181, 0xf101 }, - { 0x3182, 0x0000 }, - { 0x3183, 0xf000 }, - { 0x3184, 0x0000 }, - { 0x3185, 0xf000 }, - { 0x3186, 0x0000 }, - { 0x3187, 0xf000 }, - { 0x3188, 0x0000 }, - { 0x3189, 0xf000 }, - { 0x318a, 0x0000 }, - { 0x318b, 0xf000 }, - { 0x318c, 0x0000 }, - { 0x318d, 0xf000 }, - { 0x318e, 0x0000 }, - { 0x318f, 0xf000 }, - { 0x3190, 0x0000 }, - { 0x3191, 0xf000 }, - { 0x3192, 0x0000 }, - { 0x3193, 0xf000 }, - { 0x3194, 0x0000 }, - { 0x3195, 0xf000 }, - { 0x3196, 0x0000 }, - { 0x3197, 0xf000 }, - { 0x3198, 0x0000 }, - { 0x3199, 0xf000 }, - { 0x319a, 0x0000 }, - { 0x319b, 0xf000 }, - { 0x319c, 0x0000 }, - { 0x319d, 0xf000 }, - { 0x319e, 0x0000 }, - { 0x319f, 0xf000 }, - { 0x31a0, 0x0000 }, - { 0x31a1, 0xf000 }, - { 0x31a2, 0x0000 }, - { 0x31a3, 0xf000 }, - { 0x31a4, 0x0000 }, - { 0x31a5, 0xf000 }, - { 0x31a6, 0x0000 }, - { 0x31a7, 0xf000 }, - { 0x31a8, 0x0000 }, - { 0x31a9, 0xf000 }, - { 0x31aa, 0x0000 }, - { 0x31ab, 0xf000 }, - { 0x31ac, 0x0000 }, - { 0x31ad, 0xf000 }, - { 0x31ae, 0x0000 }, - { 0x31af, 0xf000 }, - { 0x31b0, 0x0000 }, - { 0x31b1, 0xf000 }, - { 0x31b2, 0x0000 }, - { 0x31b3, 0xf000 }, - { 0x31b4, 0x0000 }, - { 0x31b5, 0xf000 }, - { 0x31b6, 0x0000 }, - { 0x31b7, 0xf000 }, - { 0x31b8, 0x0000 }, - { 0x31b9, 0xf000 }, - { 0x31ba, 0x0000 }, - { 0x31bb, 0xf000 }, - { 0x31bc, 0x0000 }, - { 0x31bd, 0xf000 }, - { 0x31be, 0x0000 }, - { 0x31bf, 0xf000 }, - { 0x31c0, 0x0000 }, - { 0x31c1, 0xf000 }, - { 0x31c2, 0x0000 }, - { 0x31c3, 0xf000 }, - { 0x31c4, 0x0000 }, - { 0x31c5, 0xf000 }, - { 0x31c6, 0x0000 }, - { 0x31c7, 0xf000 }, - { 0x31c8, 0x0000 }, - { 0x31c9, 0xf000 }, - { 0x31ca, 0x0000 }, - { 0x31cb, 0xf000 }, - { 0x31cc, 0x0000 }, - { 0x31cd, 0xf000 }, - { 0x31ce, 0x0000 }, - { 0x31cf, 0xf000 }, - { 0x31d0, 0x0000 }, - { 0x31d1, 0xf000 }, - { 0x31d2, 0x0000 }, - { 0x31d3, 0xf000 }, - { 0x31d4, 0x0000 }, - { 0x31d5, 0xf000 }, - { 0x31d6, 0x0000 }, - { 0x31d7, 0xf000 }, - { 0x31d8, 0x0000 }, - { 0x31d9, 0xf000 }, - { 0x31da, 0x0000 }, - { 0x31db, 0xf000 }, - { 0x31dc, 0x0000 }, - { 0x31dd, 0xf000 }, - { 0x31de, 0x0000 }, - { 0x31df, 0xf000 }, - { 0x31e0, 0x0000 }, - { 0x31e1, 0xf000 }, - { 0x31e2, 0x0000 }, - { 0x31e3, 0xf000 }, - { 0x31e4, 0x0000 }, - { 0x31e5, 0xf000 }, - { 0x31e6, 0x0000 }, - { 0x31e7, 0xf000 }, - { 0x31e8, 0x0000 }, - { 0x31e9, 0xf000 }, - { 0x31ea, 0x0000 }, - { 0x31eb, 0xf000 }, - { 0x31ec, 0x0000 }, - { 0x31ed, 0xf000 }, - { 0x31ee, 0x0000 }, - { 0x31ef, 0xf000 }, - { 0x31f0, 0x0000 }, - { 0x31f1, 0xf000 }, - { 0x31f2, 0x0000 }, - { 0x31f3, 0xf000 }, - { 0x31f4, 0x0000 }, - { 0x31f5, 0xf000 }, - { 0x31f6, 0x0000 }, - { 0x31f7, 0xf000 }, - { 0x31f8, 0x0000 }, - { 0x31f9, 0xf000 }, - { 0x31fa, 0x0000 }, - { 0x31fb, 0xf000 }, - { 0x31fc, 0x0000 }, - { 0x31fd, 0xf000 }, - { 0x31fe, 0x0000 }, - { 0x31ff, 0xf000 }, - { 0x024d, 0xff50 }, - { 0x0252, 0xff50 }, - { 0x0259, 0x0112 }, - { 0x025e, 0x0112 }, -}; - -static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - struct arizona *arizona = dev_get_drvdata(codec->dev); - struct regmap *regmap = codec->control_data; - const struct reg_default *patch = NULL; - int i, patch_size; - - switch (arizona->rev) { - case 0: - patch = wm5102_sysclk_reva_patch; - patch_size = ARRAY_SIZE(wm5102_sysclk_reva_patch); - break; - } - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - if (patch) - for (i = 0; i < patch_size; i++) - regmap_write(regmap, patch[i].reg, - patch[i].def); - break; - - default: - break; - } - - return 0; -} - static const struct snd_kcontrol_new wm5102_snd_controls[] = { SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL, ARIZONA_IN1_OSR_SHIFT, 1, 0), @@ -847,7 +297,7 @@ static const struct snd_kcontrol_new wm5102_aec_loopback_mux = static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, - 0, wm5102_sysclk_ev, SND_SOC_DAPM_POST_PMU), + 0, NULL, 0), SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1, ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK, diff --git a/trunk/sound/soc/codecs/wm8978.c b/trunk/sound/soc/codecs/wm8978.c index 4c0a8e496131..5421fd9fbcb5 100644 --- a/trunk/sound/soc/codecs/wm8978.c +++ b/trunk/sound/soc/codecs/wm8978.c @@ -782,7 +782,7 @@ static int wm8978_hw_params(struct snd_pcm_substream *substream, wm8978->mclk_idx = -1; f_sel = wm8978->f_mclk; } else { - if (!wm8978->f_opclk) { + if (!wm8978->f_pllout) { /* We only enter here, if OPCLK is not used */ int ret = wm8978_configure_pll(codec); if (ret < 0) diff --git a/trunk/sound/soc/codecs/wm8994.c b/trunk/sound/soc/codecs/wm8994.c index b2b2b37131bd..2b2dadc54dac 100644 --- a/trunk/sound/soc/codecs/wm8994.c +++ b/trunk/sound/soc/codecs/wm8994.c @@ -1045,7 +1045,6 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; - struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994 *control = codec->control_data; int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA; int i; @@ -1064,10 +1063,6 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - /* Don't enable timeslot 2 if not in use */ - if (wm8994->channels[0] <= 2) - mask &= ~(WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA); - val = snd_soc_read(codec, WM8994_AIF1_CONTROL_1); if ((val & WM8994_AIF1ADCL_SRC) && (val & WM8994_AIF1ADCR_SRC)) @@ -2692,7 +2687,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - bclk_rate = params_rate(params); + bclk_rate = params_rate(params) * 4; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: bclk_rate *= 16; @@ -2713,17 +2708,6 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - wm8994->channels[id] = params_channels(params); - switch (params_channels(params)) { - case 1: - case 2: - bclk_rate *= 2; - break; - default: - bclk_rate *= 4; - break; - } - /* Try to find an appropriate sample rate; look for an exact match. */ for (i = 0; i < ARRAY_SIZE(srs); i++) if (srs[i].rate == params_rate(params)) @@ -3722,7 +3706,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) } while (count--); if (count == 0) - dev_warn(codec->dev, "No impedance range reported for jack\n"); + dev_warn(codec->dev, "No impedence range reported for jack\n"); #ifndef CONFIG_SND_SOC_WM8994_MODULE trace_snd_soc_jack_irq(dev_name(codec->dev)); diff --git a/trunk/sound/soc/codecs/wm8994.h b/trunk/sound/soc/codecs/wm8994.h index ccbce5791e95..f142ec198db3 100644 --- a/trunk/sound/soc/codecs/wm8994.h +++ b/trunk/sound/soc/codecs/wm8994.h @@ -77,7 +77,6 @@ struct wm8994_priv { int sysclk_rate[2]; int mclk[2]; int aifclk[2]; - int channels[2]; struct wm8994_fll_config fll[2], fll_suspend[2]; struct completion fll_locked[2]; bool fll_locked_irq; diff --git a/trunk/sound/soc/kirkwood/kirkwood-dma.c b/trunk/sound/soc/kirkwood/kirkwood-dma.c index 2ba08148655f..b9f16598324c 100644 --- a/trunk/sound/soc/kirkwood/kirkwood-dma.c +++ b/trunk/sound/soc/kirkwood/kirkwood-dma.c @@ -71,6 +71,7 @@ static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id) printk(KERN_WARNING "%s: got err interrupt 0x%lx\n", __func__, cause); writel(cause, priv->io + KIRKWOOD_ERR_CAUSE); + return IRQ_HANDLED; } /* we've enabled only bytes interrupts ... */ @@ -177,7 +178,7 @@ static int kirkwood_dma_open(struct snd_pcm_substream *substream) } dram = mv_mbus_dram_info(); - addr = substream->dma_buffer.addr; + addr = virt_to_phys(substream->dma_buffer.area); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { prdata->play_stream = substream; kirkwood_dma_conf_mbus_windows(priv->io, diff --git a/trunk/sound/soc/kirkwood/kirkwood-i2s.c b/trunk/sound/soc/kirkwood/kirkwood-i2s.c index 1d5db484d2df..542538d10ab7 100644 --- a/trunk/sound/soc/kirkwood/kirkwood-i2s.c +++ b/trunk/sound/soc/kirkwood/kirkwood-i2s.c @@ -95,7 +95,7 @@ static inline void kirkwood_set_dco(void __iomem *io, unsigned long rate) do { cpu_relax(); value = readl(io + KIRKWOOD_DCO_SPCR_STATUS); - value &= KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK; + value &= KIRKWOOD_DCO_SPCR_STATUS; } while (value == 0); } @@ -180,72 +180,67 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); - uint32_t ctl, value; - - ctl = readl(priv->io + KIRKWOOD_PLAYCTL); - if (ctl & KIRKWOOD_PLAYCTL_PAUSE) { - unsigned timeout = 5000; - /* - * The Armada510 spec says that if we enter pause mode, the - * busy bit must be read back as clear _twice_. Make sure - * we respect that otherwise we get DMA underruns. - */ - do { - value = ctl; - ctl = readl(priv->io + KIRKWOOD_PLAYCTL); - if (!((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY)) - break; - udelay(1); - } while (timeout--); - - if ((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY) - dev_notice(dai->dev, "timed out waiting for busy to deassert: %08x\n", - ctl); - } + unsigned long value; + + /* + * specs says KIRKWOOD_PLAYCTL must be read 2 times before + * changing it. So read 1 time here and 1 later. + */ + value = readl(priv->io + KIRKWOOD_PLAYCTL); switch (cmd) { case SNDRV_PCM_TRIGGER_START: + /* stop audio, enable interrupts */ + value = readl(priv->io + KIRKWOOD_PLAYCTL); + value |= KIRKWOOD_PLAYCTL_PAUSE; + writel(value, priv->io + KIRKWOOD_PLAYCTL); + value = readl(priv->io + KIRKWOOD_INT_MASK); value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES; writel(value, priv->io + KIRKWOOD_INT_MASK); /* configure audio & enable i2s playback */ - ctl &= ~KIRKWOOD_PLAYCTL_BURST_MASK; - ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE + value = readl(priv->io + KIRKWOOD_PLAYCTL); + value &= ~KIRKWOOD_PLAYCTL_BURST_MASK; + value &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE | KIRKWOOD_PLAYCTL_SPDIF_EN); if (priv->burst == 32) - ctl |= KIRKWOOD_PLAYCTL_BURST_32; + value |= KIRKWOOD_PLAYCTL_BURST_32; else - ctl |= KIRKWOOD_PLAYCTL_BURST_128; - ctl |= KIRKWOOD_PLAYCTL_I2S_EN; - writel(ctl, priv->io + KIRKWOOD_PLAYCTL); + value |= KIRKWOOD_PLAYCTL_BURST_128; + value |= KIRKWOOD_PLAYCTL_I2S_EN; + writel(value, priv->io + KIRKWOOD_PLAYCTL); break; case SNDRV_PCM_TRIGGER_STOP: /* stop audio, disable interrupts */ - ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; - writel(ctl, priv->io + KIRKWOOD_PLAYCTL); + value = readl(priv->io + KIRKWOOD_PLAYCTL); + value |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; + writel(value, priv->io + KIRKWOOD_PLAYCTL); value = readl(priv->io + KIRKWOOD_INT_MASK); value &= ~KIRKWOOD_INT_CAUSE_PLAY_BYTES; writel(value, priv->io + KIRKWOOD_INT_MASK); /* disable all playbacks */ - ctl &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN); - writel(ctl, priv->io + KIRKWOOD_PLAYCTL); + value = readl(priv->io + KIRKWOOD_PLAYCTL); + value &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN); + writel(value, priv->io + KIRKWOOD_PLAYCTL); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_SUSPEND: - ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; - writel(ctl, priv->io + KIRKWOOD_PLAYCTL); + value = readl(priv->io + KIRKWOOD_PLAYCTL); + value |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; + writel(value, priv->io + KIRKWOOD_PLAYCTL); break; case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE); - writel(ctl, priv->io + KIRKWOOD_PLAYCTL); + value = readl(priv->io + KIRKWOOD_PLAYCTL); + value &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE); + writel(value, priv->io + KIRKWOOD_PLAYCTL); break; default: @@ -265,6 +260,11 @@ static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream, switch (cmd) { case SNDRV_PCM_TRIGGER_START: + /* stop audio, enable interrupts */ + value = readl(priv->io + KIRKWOOD_RECCTL); + value |= KIRKWOOD_RECCTL_PAUSE; + writel(value, priv->io + KIRKWOOD_RECCTL); + value = readl(priv->io + KIRKWOOD_INT_MASK); value |= KIRKWOOD_INT_CAUSE_REC_BYTES; writel(value, priv->io + KIRKWOOD_INT_MASK); diff --git a/trunk/sound/soc/mxs/mxs-saif.c b/trunk/sound/soc/mxs/mxs-saif.c index c294fbb523fc..aa037b292f3d 100644 --- a/trunk/sound/soc/mxs/mxs-saif.c +++ b/trunk/sound/soc/mxs/mxs-saif.c @@ -523,24 +523,16 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { /* - * write data to saif data register to trigger - * the transfer. - * For 24-bit format the 32-bit FIFO register stores - * only one channel, so we need to write twice. - * This is also safe for the other non 24-bit formats. + * write a data to saif data register to trigger + * the transfer */ __raw_writel(0, saif->base + SAIF_DATA); - __raw_writel(0, saif->base + SAIF_DATA); } else { /* - * read data from saif data register to trigger - * the receive. - * For 24-bit format the 32-bit FIFO register stores - * only one channel, so we need to read twice. - * This is also safe for the other non 24-bit formats. + * read a data from saif data register to trigger + * the receive */ __raw_readl(saif->base + SAIF_DATA); - __raw_readl(saif->base + SAIF_DATA); } master_saif->ongoing = 1; @@ -820,4 +812,3 @@ module_platform_driver(mxs_saif_driver); MODULE_AUTHOR("Freescale Semiconductor, Inc."); MODULE_DESCRIPTION("MXS ASoC SAIF driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:mxs-saif"); diff --git a/trunk/sound/soc/omap/omap-dmic.c b/trunk/sound/soc/omap/omap-dmic.c index 5a6aeaf552a8..68f2cd1a9206 100644 --- a/trunk/sound/soc/omap/omap-dmic.c +++ b/trunk/sound/soc/omap/omap-dmic.c @@ -464,9 +464,9 @@ static __devinit int asoc_dmic_probe(struct platform_device *pdev) mutex_init(&dmic->mutex); - dmic->fclk = clk_get(dmic->dev, "fck"); + dmic->fclk = clk_get(dmic->dev, "dmic_fck"); if (IS_ERR(dmic->fclk)) { - dev_err(dmic->dev, "cant get fck\n"); + dev_err(dmic->dev, "cant get dmic_fck\n"); return -ENODEV; } diff --git a/trunk/sound/soc/omap/zoom2.c b/trunk/sound/soc/omap/zoom2.c index 1ff6bb9ade5c..677b567935f8 100644 --- a/trunk/sound/soc/omap/zoom2.c +++ b/trunk/sound/soc/omap/zoom2.c @@ -21,14 +21,15 @@ #include #include -#include #include #include #include #include +#include +#include +#include #include -#include /* Register descriptions for twl4030 codec part */ #include diff --git a/trunk/sound/soc/samsung/Kconfig b/trunk/sound/soc/samsung/Kconfig index 3c7c3a59ed39..e7b83179aca2 100644 --- a/trunk/sound/soc/samsung/Kconfig +++ b/trunk/sound/soc/samsung/Kconfig @@ -207,8 +207,6 @@ config SND_SOC_BELLS select SND_SOC_WM5102 select SND_SOC_WM5110 select SND_SOC_WM9081 - select SND_SOC_WM0010 - select SND_SOC_WM1250_EV1 config SND_SOC_LOWLAND tristate "Audio support for Wolfson Lowland" diff --git a/trunk/sound/soc/samsung/bells.c b/trunk/sound/soc/samsung/bells.c index a2ca1567b9e4..b0d46d63d55e 100644 --- a/trunk/sound/soc/samsung/bells.c +++ b/trunk/sound/soc/samsung/bells.c @@ -212,7 +212,7 @@ static struct snd_soc_dai_link bells_dai_wm5102[] = { { .name = "Sub", .stream_name = "Sub", - .cpu_dai_name = "wm5102-aif3", + .cpu_dai_name = "wm5110-aif3", .codec_dai_name = "wm9081-hifi", .codec_name = "wm9081.1-006c", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF diff --git a/trunk/sound/soc/soc-core.c b/trunk/sound/soc/soc-core.c index 10d21be383f6..d1198627fc40 100644 --- a/trunk/sound/soc/soc-core.c +++ b/trunk/sound/soc/soc-core.c @@ -2786,9 +2786,8 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, val = (ucontrol->value.integer.value[0] + min) & mask; val = val << shift; - err = snd_soc_update_bits_locked(codec, reg, val_mask, val); - if (err < 0) - return err; + if (snd_soc_update_bits_locked(codec, reg, val_mask, val)) + return err; if (snd_soc_volsw_is_stereo(mc)) { val_mask = mask << rshift; diff --git a/trunk/sound/soc/soc-dapm.c b/trunk/sound/soc/soc-dapm.c index 6e35bcae02df..d0a4be38dc0f 100644 --- a/trunk/sound/soc/soc-dapm.c +++ b/trunk/sound/soc/soc-dapm.c @@ -3745,7 +3745,7 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card) { struct snd_soc_codec *codec; - list_for_each_entry(codec, &card->codec_dev_list, card_list) { + list_for_each_entry(codec, &card->codec_dev_list, list) { soc_dapm_shutdown_codec(&codec->dapm); if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) snd_soc_dapm_set_bias_level(&codec->dapm, diff --git a/trunk/sound/soc/ux500/mop500.c b/trunk/sound/soc/ux500/mop500.c index 54f7e25b6f7d..356611d9654d 100644 --- a/trunk/sound/soc/ux500/mop500.c +++ b/trunk/sound/soc/ux500/mop500.c @@ -57,20 +57,6 @@ static struct snd_soc_card mop500_card = { .num_links = ARRAY_SIZE(mop500_dai_links), }; -static void mop500_of_node_put(void) -{ - int i; - - for (i = 0; i < 2; i++) { - if (mop500_dai_links[i].cpu_of_node) - of_node_put((struct device_node *) - mop500_dai_links[i].cpu_of_node); - if (mop500_dai_links[i].codec_of_node) - of_node_put((struct device_node *) - mop500_dai_links[i].codec_of_node); - } -} - static int __devinit mop500_of_probe(struct platform_device *pdev, struct device_node *np) { @@ -83,7 +69,6 @@ static int __devinit mop500_of_probe(struct platform_device *pdev, if (!(msp_np[0] && msp_np[1] && codec_np)) { dev_err(&pdev->dev, "Phandle missing or invalid\n"); - mop500_of_node_put(); return -EINVAL; } @@ -98,7 +83,6 @@ static int __devinit mop500_of_probe(struct platform_device *pdev, return 0; } - static int __devinit mop500_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -144,7 +128,6 @@ static int __devexit mop500_remove(struct platform_device *pdev) snd_soc_unregister_card(mop500_card); mop500_ab8500_remove(mop500_card); - mop500_of_node_put(); return 0; } diff --git a/trunk/sound/soc/ux500/ux500_msp_i2s.c b/trunk/sound/soc/ux500/ux500_msp_i2s.c index a26c6bf0a29b..b7c996e77570 100644 --- a/trunk/sound/soc/ux500/ux500_msp_i2s.c +++ b/trunk/sound/soc/ux500/ux500_msp_i2s.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -698,11 +697,14 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, platform_data = devm_kzalloc(&pdev->dev, sizeof(struct msp_i2s_platform_data), GFP_KERNEL); if (!platform_data) - return -ENOMEM; + ret = -ENOMEM; } } else if (!platform_data) - return -EINVAL; + ret = -EINVAL; + + if (ret) + goto err_res; dev_dbg(&pdev->dev, "%s: Enter (name: %s, id: %d).\n", __func__, pdev->name, platform_data->id); diff --git a/trunk/sound/usb/card.c b/trunk/sound/usb/card.c index dbf7999d18b4..561bb74fd364 100644 --- a/trunk/sound/usb/card.c +++ b/trunk/sound/usb/card.c @@ -339,7 +339,7 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx, } mutex_init(&chip->mutex); - init_rwsem(&chip->shutdown_rwsem); + mutex_init(&chip->shutdown_mutex); chip->index = idx; chip->dev = dev; chip->card = card; @@ -559,11 +559,9 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, return; card = chip->card; - down_write(&chip->shutdown_rwsem); - chip->shutdown = 1; - up_write(&chip->shutdown_rwsem); - mutex_lock(®ister_mutex); + mutex_lock(&chip->shutdown_mutex); + chip->shutdown = 1; chip->num_interfaces--; if (chip->num_interfaces <= 0) { snd_card_disconnect(card); @@ -584,9 +582,11 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, snd_usb_mixer_disconnect(p); } usb_chip[chip->index] = NULL; + mutex_unlock(&chip->shutdown_mutex); mutex_unlock(®ister_mutex); snd_card_free_when_closed(card); } else { + mutex_unlock(&chip->shutdown_mutex); mutex_unlock(®ister_mutex); } } @@ -618,20 +618,16 @@ int snd_usb_autoresume(struct snd_usb_audio *chip) { int err = -ENODEV; - down_read(&chip->shutdown_rwsem); if (!chip->shutdown && !chip->probing) err = usb_autopm_get_interface(chip->pm_intf); - up_read(&chip->shutdown_rwsem); return err; } void snd_usb_autosuspend(struct snd_usb_audio *chip) { - down_read(&chip->shutdown_rwsem); if (!chip->shutdown && !chip->probing) usb_autopm_put_interface(chip->pm_intf); - up_read(&chip->shutdown_rwsem); } static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) diff --git a/trunk/sound/usb/card.h b/trunk/sound/usb/card.h index 814cb357ff88..afa4f9e9b27a 100644 --- a/trunk/sound/usb/card.h +++ b/trunk/sound/usb/card.h @@ -126,7 +126,6 @@ struct snd_usb_substream { struct snd_usb_endpoint *sync_endpoint; unsigned long flags; bool need_setup_ep; /* (re)configure EP at prepare? */ - unsigned int speed; /* USB_SPEED_XXX */ u64 formats; /* format bitmasks (all or'ed) */ unsigned int num_formats; /* number of supported audio formats (list) */ diff --git a/trunk/sound/usb/endpoint.c b/trunk/sound/usb/endpoint.c index 34de6f2faf61..7f78c6d782b0 100644 --- a/trunk/sound/usb/endpoint.c +++ b/trunk/sound/usb/endpoint.c @@ -35,7 +35,6 @@ #define EP_FLAG_ACTIVATED 0 #define EP_FLAG_RUNNING 1 -#define EP_FLAG_STOPPING 2 /* * snd_usb_endpoint is a model that abstracts everything related to an @@ -503,20 +502,10 @@ static int wait_clear_urbs(struct snd_usb_endpoint *ep) if (alive) snd_printk(KERN_ERR "timeout: still %d active urbs on EP #%x\n", alive, ep->ep_num); - clear_bit(EP_FLAG_STOPPING, &ep->flags); return 0; } -/* sync the pending stop operation; - * this function itself doesn't trigger the stop operation - */ -void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep) -{ - if (ep && test_bit(EP_FLAG_STOPPING, &ep->flags)) - wait_clear_urbs(ep); -} - /* * unlink active urbs. */ @@ -929,8 +918,6 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, if (wait) wait_clear_urbs(ep); - else - set_bit(EP_FLAG_STOPPING, &ep->flags); } } diff --git a/trunk/sound/usb/endpoint.h b/trunk/sound/usb/endpoint.h index 3d4c9705041f..6376ccf10fd4 100644 --- a/trunk/sound/usb/endpoint.h +++ b/trunk/sound/usb/endpoint.h @@ -19,7 +19,6 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep); void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, int force, int can_sleep, int wait); -void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep); int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); void snd_usb_endpoint_free(struct list_head *head); diff --git a/trunk/sound/usb/midi.c b/trunk/sound/usb/midi.c index eeefbce3873c..c83f6143c0eb 100644 --- a/trunk/sound/usb/midi.c +++ b/trunk/sound/usb/midi.c @@ -148,7 +148,6 @@ struct snd_usb_midi_out_endpoint { struct snd_usb_midi_out_endpoint* ep; struct snd_rawmidi_substream *substream; int active; - bool autopm_reference; uint8_t cable; /* cable number << 4 */ uint8_t state; #define STATE_UNKNOWN 0 @@ -1077,8 +1076,7 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) return -ENXIO; } err = usb_autopm_get_interface(umidi->iface); - port->autopm_reference = err >= 0; - if (err < 0 && err != -EACCES) + if (err < 0) return -EIO; substream->runtime->private_data = port; port->state = STATE_UNKNOWN; @@ -1089,11 +1087,9 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) { struct snd_usb_midi* umidi = substream->rmidi->private_data; - struct usbmidi_out_port *port = substream->runtime->private_data; substream_open(substream, 0); - if (port->autopm_reference) - usb_autopm_put_interface(umidi->iface); + usb_autopm_put_interface(umidi->iface); return 0; } diff --git a/trunk/sound/usb/mixer.c b/trunk/sound/usb/mixer.c index 298070e8f2d4..fe56c9da38e9 100644 --- a/trunk/sound/usb/mixer.c +++ b/trunk/sound/usb/mixer.c @@ -287,32 +287,25 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v unsigned char buf[2]; int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; int timeout = 10; - int idx = 0, err; + int err; err = snd_usb_autoresume(cval->mixer->chip); if (err < 0) return -EIO; - down_read(&chip->shutdown_rwsem); while (timeout-- > 0) { - if (chip->shutdown) - break; - idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - validx, idx, buf, val_len) >= val_len) { + validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), + buf, val_len) >= val_len) { *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); - err = 0; - goto out; + snd_usb_autosuspend(cval->mixer->chip); + return 0; } } - snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", - request, validx, idx, cval->val_type); - err = -EINVAL; - - out: - up_read(&chip->shutdown_rwsem); snd_usb_autosuspend(cval->mixer->chip); - return err; + snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", + request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type); + return -EINVAL; } static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) @@ -320,7 +313,7 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v struct snd_usb_audio *chip = cval->mixer->chip; unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */ unsigned char *val; - int idx = 0, ret, size; + int ret, size; __u8 bRequest; if (request == UAC_GET_CUR) { @@ -337,22 +330,16 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v if (ret) goto error; - down_read(&chip->shutdown_rwsem); - if (chip->shutdown) - ret = -ENODEV; - else { - idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); - ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, + ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - validx, idx, buf, size); - } - up_read(&chip->shutdown_rwsem); + validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), + buf, size); snd_usb_autosuspend(chip); if (ret < 0) { error: snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", - request, validx, idx, cval->val_type); + request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type); return ret; } @@ -430,7 +417,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, { struct snd_usb_audio *chip = cval->mixer->chip; unsigned char buf[2]; - int idx = 0, val_len, err, timeout = 10; + int val_len, err, timeout = 10; if (cval->mixer->protocol == UAC_VERSION_1) { val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; @@ -453,27 +440,19 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, err = snd_usb_autoresume(chip); if (err < 0) return -EIO; - down_read(&chip->shutdown_rwsem); - while (timeout-- > 0) { - if (chip->shutdown) - break; - idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); + while (timeout-- > 0) if (snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), request, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, - validx, idx, buf, val_len) >= 0) { - err = 0; - goto out; + validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), + buf, val_len) >= 0) { + snd_usb_autosuspend(chip); + return 0; } - } - snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", - request, validx, idx, cval->val_type, buf[0], buf[1]); - err = -EINVAL; - - out: - up_read(&chip->shutdown_rwsem); snd_usb_autosuspend(chip); - return err; + snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", + request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type, buf[0], buf[1]); + return -EINVAL; } static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value) diff --git a/trunk/sound/usb/mixer_quirks.c b/trunk/sound/usb/mixer_quirks.c index ae2b71435220..690000db0ec0 100644 --- a/trunk/sound/usb/mixer_quirks.c +++ b/trunk/sound/usb/mixer_quirks.c @@ -283,11 +283,6 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e if (value > 1) return -EINVAL; changed = value != mixer->audigy2nx_leds[index]; - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) { - err = -ENODEV; - goto out; - } if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) err = snd_usb_ctl_msg(mixer->chip->dev, usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, @@ -304,8 +299,6 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, value, index + 2, NULL, 0); - out: - up_read(&mixer->chip->shutdown_rwsem); if (err < 0) return err; mixer->audigy2nx_leds[index] = value; @@ -399,16 +392,11 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry, for (i = 0; jacks[i].name; ++i) { snd_iprintf(buffer, "%s: ", jacks[i].name); - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) - err = 0; - else - err = snd_usb_ctl_msg(mixer->chip->dev, + err = snd_usb_ctl_msg(mixer->chip->dev, usb_rcvctrlpipe(mixer->chip->dev, 0), UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, jacks[i].unitid << 8, buf, 3); - up_read(&mixer->chip->shutdown_rwsem); if (err == 3 && (buf[0] == 3 || buf[0] == 6)) snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]); else @@ -438,15 +426,10 @@ static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol, else new_status = old_status & ~0x02; changed = new_status != old_status; - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) - err = -ENODEV; - else - err = snd_usb_ctl_msg(mixer->chip->dev, + err = snd_usb_ctl_msg(mixer->chip->dev, usb_sndctrlpipe(mixer->chip->dev, 0), 0x08, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, 50, 0, &new_status, 1); - up_read(&mixer->chip->shutdown_rwsem); if (err < 0) return err; mixer->xonar_u1_status = new_status; @@ -485,17 +468,11 @@ static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol, u8 bRequest = (kcontrol->private_value >> 16) & 0xff; u16 wIndex = kcontrol->private_value & 0xffff; u8 tmp; - int ret; - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) - ret = -ENODEV; - else - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest, + int ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0, cpu_to_le16(wIndex), &tmp, sizeof(tmp), 1000); - up_read(&mixer->chip->shutdown_rwsem); if (ret < 0) { snd_printk(KERN_ERR @@ -516,17 +493,11 @@ static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol, u8 bRequest = (kcontrol->private_value >> 16) & 0xff; u16 wIndex = kcontrol->private_value & 0xffff; u16 wValue = ucontrol->value.integer.value[0]; - int ret; - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) - ret = -ENODEV; - else - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest, + int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, cpu_to_le16(wValue), cpu_to_le16(wIndex), NULL, 0, 1000); - up_read(&mixer->chip->shutdown_rwsem); if (ret < 0) { snd_printk(KERN_ERR @@ -685,16 +656,11 @@ static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl, return -EINVAL; - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) - err = -ENODEV; - else - err = snd_usb_ctl_msg(chip->dev, + err = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), value, val_len); - up_read(&mixer->chip->shutdown_rwsem); if (err < 0) return err; @@ -737,16 +703,11 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl, if (!pval->is_cached) { /* Read current value */ - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) - err = -ENODEV; - else - err = snd_usb_ctl_msg(chip->dev, + err = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), value, val_len); - up_read(&mixer->chip->shutdown_rwsem); if (err < 0) return err; @@ -758,16 +719,11 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl, if (cur_val != new_val) { value[0] = new_val; value[1] = 0; - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) - err = -ENODEV; - else - err = snd_usb_ctl_msg(chip->dev, + err = snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), value, val_len); - up_read(&mixer->chip->shutdown_rwsem); if (err < 0) return err; diff --git a/trunk/sound/usb/pcm.c b/trunk/sound/usb/pcm.c index ef6fa24fc473..55e19e1b80ec 100644 --- a/trunk/sound/usb/pcm.c +++ b/trunk/sound/usb/pcm.c @@ -71,8 +71,6 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream unsigned int hwptr_done; subs = (struct snd_usb_substream *)substream->runtime->private_data; - if (subs->stream->chip->shutdown) - return SNDRV_PCM_POS_XRUN; spin_lock(&subs->lock); hwptr_done = subs->hwptr_done; substream->runtime->delay = snd_usb_pcm_delay(subs, @@ -446,6 +444,7 @@ static int configure_endpoint(struct snd_usb_substream *subs) { int ret; + mutex_lock(&subs->stream->chip->shutdown_mutex); /* format changed */ stop_endpoints(subs, 0, 0, 0); ret = snd_usb_endpoint_set_params(subs->data_endpoint, @@ -456,16 +455,19 @@ static int configure_endpoint(struct snd_usb_substream *subs) subs->cur_audiofmt, subs->sync_endpoint); if (ret < 0) - return ret; + goto unlock; if (subs->sync_endpoint) - ret = snd_usb_endpoint_set_params(subs->sync_endpoint, + ret = snd_usb_endpoint_set_params(subs->data_endpoint, subs->pcm_format, subs->channels, subs->period_bytes, subs->cur_rate, subs->cur_audiofmt, NULL); + +unlock: + mutex_unlock(&subs->stream->chip->shutdown_mutex); return ret; } @@ -503,13 +505,7 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - down_read(&subs->stream->chip->shutdown_rwsem); - if (subs->stream->chip->shutdown) - ret = -ENODEV; - else - ret = set_format(subs, fmt); - up_read(&subs->stream->chip->shutdown_rwsem); - if (ret < 0) + if ((ret = set_format(subs, fmt)) < 0) return ret; subs->interface = fmt->iface; @@ -531,12 +527,10 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream) subs->cur_audiofmt = NULL; subs->cur_rate = 0; subs->period_bytes = 0; - down_read(&subs->stream->chip->shutdown_rwsem); - if (!subs->stream->chip->shutdown) { - stop_endpoints(subs, 0, 1, 1); - deactivate_endpoints(subs); - } - up_read(&subs->stream->chip->shutdown_rwsem); + mutex_lock(&subs->stream->chip->shutdown_mutex); + stop_endpoints(subs, 0, 1, 1); + deactivate_endpoints(subs); + mutex_unlock(&subs->stream->chip->shutdown_mutex); return snd_pcm_lib_free_vmalloc_buffer(substream); } @@ -558,22 +552,12 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) return -ENXIO; } - down_read(&subs->stream->chip->shutdown_rwsem); - if (subs->stream->chip->shutdown) { - ret = -ENODEV; - goto unlock; - } - if (snd_BUG_ON(!subs->data_endpoint)) { - ret = -EIO; - goto unlock; - } - - snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint); - snd_usb_endpoint_sync_pending_stop(subs->data_endpoint); + if (snd_BUG_ON(!subs->data_endpoint)) + return -EIO; ret = set_format(subs, subs->cur_audiofmt); if (ret < 0) - goto unlock; + return ret; iface = usb_ifnum_to_if(subs->dev, subs->cur_audiofmt->iface); alts = &iface->altsetting[subs->cur_audiofmt->altset_idx]; @@ -583,12 +567,12 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) subs->cur_audiofmt, subs->cur_rate); if (ret < 0) - goto unlock; + return ret; if (subs->need_setup_ep) { ret = configure_endpoint(subs); if (ret < 0) - goto unlock; + return ret; subs->need_setup_ep = false; } @@ -608,11 +592,9 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) /* for playback, submit the URBs now; otherwise, the first hwptr_done * updates for all URBs would happen at the same time when starting */ if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) - ret = start_endpoints(subs, 1); + return start_endpoints(subs, 1); - unlock: - up_read(&subs->stream->chip->shutdown_rwsem); - return ret; + return 0; } static struct snd_pcm_hardware snd_usb_hardware = @@ -665,7 +647,7 @@ static int hw_check_valid_format(struct snd_usb_substream *subs, return 0; } /* check whether the period time is >= the data packet interval */ - if (subs->speed != USB_SPEED_FULL) { + if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) { ptime = 125 * (1 << fp->datainterval); if (ptime > pt->max || (ptime == pt->max && pt->openmax)) { hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max); @@ -943,7 +925,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre return err; param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME; - if (subs->speed == USB_SPEED_FULL) + if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) /* full speed devices have fixed data packet interval */ ptmin = 1000; if (ptmin == 1000) diff --git a/trunk/sound/usb/proc.c b/trunk/sound/usb/proc.c index d218f763501f..ebc1a5b5b3f1 100644 --- a/trunk/sound/usb/proc.c +++ b/trunk/sound/usb/proc.c @@ -108,7 +108,7 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s } snd_iprintf(buffer, "\n"); } - if (subs->speed != USB_SPEED_FULL) + if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) snd_iprintf(buffer, " Data packet interval: %d us\n", 125 * (1 << fp->datainterval)); // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize); @@ -124,7 +124,7 @@ static void proc_dump_ep_status(struct snd_usb_substream *subs, return; snd_iprintf(buffer, " Packet Size = %d\n", ep->curpacksize); snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n", - subs->speed == USB_SPEED_FULL + snd_usb_get_speed(subs->dev) == USB_SPEED_FULL ? get_full_speed_hz(ep->freqm) : get_high_speed_hz(ep->freqm), ep->freqm >> 16, ep->freqm & 0xffff); diff --git a/trunk/sound/usb/stream.c b/trunk/sound/usb/stream.c index 1de0c8c002a8..083ed81160e5 100644 --- a/trunk/sound/usb/stream.c +++ b/trunk/sound/usb/stream.c @@ -90,7 +90,6 @@ static void snd_usb_init_substream(struct snd_usb_stream *as, subs->direction = stream; subs->dev = as->chip->dev; subs->txfr_quirk = as->chip->txfr_quirk; - subs->speed = snd_usb_get_speed(subs->dev); snd_usb_set_pcm_ops(as->pcm, stream); diff --git a/trunk/sound/usb/usbaudio.h b/trunk/sound/usb/usbaudio.h index ef42797f56fb..b8233ebe250f 100644 --- a/trunk/sound/usb/usbaudio.h +++ b/trunk/sound/usb/usbaudio.h @@ -37,7 +37,7 @@ struct snd_usb_audio { struct usb_interface *pm_intf; u32 usb_id; struct mutex mutex; - struct rw_semaphore shutdown_rwsem; + struct mutex shutdown_mutex; unsigned int shutdown:1; unsigned int probing:1; unsigned int autosuspended:1; diff --git a/trunk/tools/Makefile b/trunk/tools/Makefile index 1f9a529fe544..3ae43947a171 100644 --- a/trunk/tools/Makefile +++ b/trunk/tools/Makefile @@ -31,44 +31,44 @@ help: @echo ' clean: a summary clean target to clean _all_ folders' cpupower: FORCE - $(call descend,power/$@) + $(QUIET_SUBDIR0)power/$@/ $(QUIET_SUBDIR1) firewire lguest perf usb virtio vm: FORCE - $(call descend,$@) + $(QUIET_SUBDIR0)$@/ $(QUIET_SUBDIR1) selftests: FORCE - $(call descend,testing/$@) + $(QUIET_SUBDIR0)testing/$@/ $(QUIET_SUBDIR1) turbostat x86_energy_perf_policy: FORCE - $(call descend,power/x86/$@) + $(QUIET_SUBDIR0)power/x86/$@/ $(QUIET_SUBDIR1) cpupower_install: - $(call descend,power/$(@:_install=),install) + $(QUIET_SUBDIR0)power/$(@:_install=)/ $(QUIET_SUBDIR1) install firewire_install lguest_install perf_install usb_install virtio_install vm_install: - $(call descend,$(@:_install=),install) + $(QUIET_SUBDIR0)$(@:_install=)/ $(QUIET_SUBDIR1) install selftests_install: - $(call descend,testing/$(@:_clean=),install) + $(QUIET_SUBDIR0)testing/$(@:_clean=)/ $(QUIET_SUBDIR1) install turbostat_install x86_energy_perf_policy_install: - $(call descend,power/x86/$(@:_install=),install) + $(QUIET_SUBDIR0)power/x86/$(@:_install=)/ $(QUIET_SUBDIR1) install install: cpupower_install firewire_install lguest_install perf_install \ selftests_install turbostat_install usb_install virtio_install \ vm_install x86_energy_perf_policy_install cpupower_clean: - $(call descend,power/cpupower,clean) + $(QUIET_SUBDIR0)power/cpupower/ $(QUIET_SUBDIR1) clean firewire_clean lguest_clean perf_clean usb_clean virtio_clean vm_clean: - $(call descend,$(@:_clean=),clean) + $(QUIET_SUBDIR0)$(@:_clean=)/ $(QUIET_SUBDIR1) clean selftests_clean: - $(call descend,testing/$(@:_clean=),clean) + $(QUIET_SUBDIR0)testing/$(@:_clean=)/ $(QUIET_SUBDIR1) clean turbostat_clean x86_energy_perf_policy_clean: - $(call descend,power/x86/$(@:_clean=),clean) + $(QUIET_SUBDIR0)power/x86/$(@:_clean=)/ $(QUIET_SUBDIR1) clean clean: cpupower_clean firewire_clean lguest_clean perf_clean selftests_clean \ turbostat_clean usb_clean virtio_clean vm_clean \ diff --git a/trunk/tools/perf/Makefile b/trunk/tools/perf/Makefile index 0a619af5be43..00deed4d6159 100644 --- a/trunk/tools/perf/Makefile +++ b/trunk/tools/perf/Makefile @@ -169,34 +169,7 @@ endif ### --- END CONFIGURATION SECTION --- -ifeq ($(srctree),) -srctree := $(patsubst %/,%,$(dir $(shell pwd))) -srctree := $(patsubst %/,%,$(dir $(srctree))) -#$(info Determined 'srctree' to be $(srctree)) -endif - -ifneq ($(objtree),) -#$(info Determined 'objtree' to be $(objtree)) -endif - -ifneq ($(OUTPUT),) -#$(info Determined 'OUTPUT' to be $(OUTPUT)) -endif - -BASIC_CFLAGS = \ - -Iutil/include \ - -Iarch/$(ARCH)/include \ - $(if $(objtree),-I$(objtree)/arch/$(ARCH)/include/generated/uapi) \ - -I$(srctree)/arch/$(ARCH)/include/uapi \ - -I$(srctree)/arch/$(ARCH)/include \ - $(if $(objtree),-I$(objtree)/include/generated/uapi) \ - -I$(srctree)/include/uapi \ - -I$(srctree)/include \ - -I$(OUTPUT)util \ - -Iutil \ - -I. \ - -I$(TRACE_EVENT_DIR) \ - -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE +BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE BASIC_LDFLAGS = # Guard against environment variables diff --git a/trunk/tools/perf/arch/x86/include/perf_regs.h b/trunk/tools/perf/arch/x86/include/perf_regs.h index 7fcdcdbee917..46fc9f15c6b3 100644 --- a/trunk/tools/perf/arch/x86/include/perf_regs.h +++ b/trunk/tools/perf/arch/x86/include/perf_regs.h @@ -3,7 +3,7 @@ #include #include "../../util/types.h" -#include +#include "../../../../../arch/x86/include/asm/perf_regs.h" #ifndef ARCH_X86_64 #define PERF_REGS_MASK ((1ULL << PERF_REG_X86_32_MAX) - 1) diff --git a/trunk/tools/perf/builtin-help.c b/trunk/tools/perf/builtin-help.c index 178b88ae3d2f..411ee5664e98 100644 --- a/trunk/tools/perf/builtin-help.c +++ b/trunk/tools/perf/builtin-help.c @@ -414,7 +414,7 @@ static int show_html_page(const char *perf_cmd) int cmd_help(int argc, const char **argv, const char *prefix __maybe_unused) { bool show_all = false; - enum help_format help_format = HELP_FORMAT_MAN; + enum help_format help_format = HELP_FORMAT_NONE; struct option builtin_help_options[] = { OPT_BOOLEAN('a', "all", &show_all, "print all available commands"), OPT_SET_UINT('m', "man", &help_format, "show man page", HELP_FORMAT_MAN), diff --git a/trunk/tools/perf/builtin-kvm.c b/trunk/tools/perf/builtin-kvm.c index 283b4397e397..260abc535b5b 100644 --- a/trunk/tools/perf/builtin-kvm.c +++ b/trunk/tools/perf/builtin-kvm.c @@ -22,10 +22,9 @@ #include #include -#if defined(__i386__) || defined(__x86_64__) -#include -#include -#include +#include "../../arch/x86/include/asm/svm.h" +#include "../../arch/x86/include/asm/vmx.h" +#include "../../arch/x86/include/asm/kvm.h" struct event_key { #define INVALID_KEY (~0ULL) @@ -59,7 +58,7 @@ struct kvm_event_key { }; -struct perf_kvm_stat; +struct perf_kvm; struct kvm_events_ops { bool (*is_begin_event)(struct perf_evsel *evsel, @@ -67,7 +66,7 @@ struct kvm_events_ops { struct event_key *key); bool (*is_end_event)(struct perf_evsel *evsel, struct perf_sample *sample, struct event_key *key); - void (*decode_key)(struct perf_kvm_stat *kvm, struct event_key *key, + void (*decode_key)(struct perf_kvm *kvm, struct event_key *key, char decode[20]); const char *name; }; @@ -80,7 +79,7 @@ struct exit_reasons_table { #define EVENTS_BITS 12 #define EVENTS_CACHE_SIZE (1UL << EVENTS_BITS) -struct perf_kvm_stat { +struct perf_kvm { struct perf_tool tool; struct perf_session *session; @@ -147,7 +146,7 @@ static struct exit_reasons_table svm_exit_reasons[] = { SVM_EXIT_REASONS }; -static const char *get_exit_reason(struct perf_kvm_stat *kvm, u64 exit_code) +static const char *get_exit_reason(struct perf_kvm *kvm, u64 exit_code) { int i = kvm->exit_reasons_size; struct exit_reasons_table *tbl = kvm->exit_reasons; @@ -163,7 +162,7 @@ static const char *get_exit_reason(struct perf_kvm_stat *kvm, u64 exit_code) return "UNKNOWN"; } -static void exit_event_decode_key(struct perf_kvm_stat *kvm, +static void exit_event_decode_key(struct perf_kvm *kvm, struct event_key *key, char decode[20]) { @@ -229,7 +228,7 @@ static bool mmio_event_end(struct perf_evsel *evsel, struct perf_sample *sample, return false; } -static void mmio_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused, +static void mmio_event_decode_key(struct perf_kvm *kvm __maybe_unused, struct event_key *key, char decode[20]) { @@ -272,7 +271,7 @@ static bool ioport_event_end(struct perf_evsel *evsel, return kvm_entry_event(evsel); } -static void ioport_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused, +static void ioport_event_decode_key(struct perf_kvm *kvm __maybe_unused, struct event_key *key, char decode[20]) { @@ -287,7 +286,7 @@ static struct kvm_events_ops ioport_events = { .name = "IO Port Access" }; -static bool register_kvm_events_ops(struct perf_kvm_stat *kvm) +static bool register_kvm_events_ops(struct perf_kvm *kvm) { bool ret = true; @@ -312,7 +311,7 @@ struct vcpu_event_record { }; -static void init_kvm_event_record(struct perf_kvm_stat *kvm) +static void init_kvm_event_record(struct perf_kvm *kvm) { int i; @@ -361,7 +360,7 @@ static struct kvm_event *kvm_alloc_init_event(struct event_key *key) return event; } -static struct kvm_event *find_create_kvm_event(struct perf_kvm_stat *kvm, +static struct kvm_event *find_create_kvm_event(struct perf_kvm *kvm, struct event_key *key) { struct kvm_event *event; @@ -382,7 +381,7 @@ static struct kvm_event *find_create_kvm_event(struct perf_kvm_stat *kvm, return event; } -static bool handle_begin_event(struct perf_kvm_stat *kvm, +static bool handle_begin_event(struct perf_kvm *kvm, struct vcpu_event_record *vcpu_record, struct event_key *key, u64 timestamp) { @@ -426,7 +425,7 @@ static bool update_kvm_event(struct kvm_event *event, int vcpu_id, return true; } -static bool handle_end_event(struct perf_kvm_stat *kvm, +static bool handle_end_event(struct perf_kvm *kvm, struct vcpu_event_record *vcpu_record, struct event_key *key, u64 timestamp) @@ -487,7 +486,7 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread, return thread->priv; } -static bool handle_kvm_event(struct perf_kvm_stat *kvm, +static bool handle_kvm_event(struct perf_kvm *kvm, struct thread *thread, struct perf_evsel *evsel, struct perf_sample *sample) @@ -542,7 +541,7 @@ static struct kvm_event_key keys[] = { { NULL, NULL } }; -static bool select_key(struct perf_kvm_stat *kvm) +static bool select_key(struct perf_kvm *kvm) { int i; @@ -578,8 +577,7 @@ static void insert_to_result(struct rb_root *result, struct kvm_event *event, rb_insert_color(&event->rb, result); } -static void -update_total_count(struct perf_kvm_stat *kvm, struct kvm_event *event) +static void update_total_count(struct perf_kvm *kvm, struct kvm_event *event) { int vcpu = kvm->trace_vcpu; @@ -592,7 +590,7 @@ static bool event_is_valid(struct kvm_event *event, int vcpu) return !!get_event_count(event, vcpu); } -static void sort_result(struct perf_kvm_stat *kvm) +static void sort_result(struct perf_kvm *kvm) { unsigned int i; int vcpu = kvm->trace_vcpu; @@ -629,7 +627,7 @@ static void print_vcpu_info(int vcpu) pr_info("VCPU %d:\n\n", vcpu); } -static void print_result(struct perf_kvm_stat *kvm) +static void print_result(struct perf_kvm *kvm) { char decode[20]; struct kvm_event *event; @@ -672,8 +670,7 @@ static int process_sample_event(struct perf_tool *tool, struct machine *machine) { struct thread *thread = machine__findnew_thread(machine, sample->tid); - struct perf_kvm_stat *kvm = container_of(tool, struct perf_kvm_stat, - tool); + struct perf_kvm *kvm = container_of(tool, struct perf_kvm, tool); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", @@ -704,7 +701,7 @@ static int get_cpu_isa(struct perf_session *session) return isa; } -static int read_events(struct perf_kvm_stat *kvm) +static int read_events(struct perf_kvm *kvm) { int ret; @@ -753,7 +750,7 @@ static bool verify_vcpu(int vcpu) return true; } -static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm) +static int kvm_events_report_vcpu(struct perf_kvm *kvm) { int ret = -EINVAL; int vcpu = kvm->trace_vcpu; @@ -801,8 +798,7 @@ static const char * const record_args[] = { _p; \ }) -static int -kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv) +static int kvm_events_record(struct perf_kvm *kvm, int argc, const char **argv) { unsigned int rec_argc, i, j; const char **rec_argv; @@ -825,8 +821,7 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv) return cmd_record(i, rec_argv, NULL); } -static int -kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv) +static int kvm_events_report(struct perf_kvm *kvm, int argc, const char **argv) { const struct option kvm_events_report_options[] = { OPT_STRING(0, "event", &kvm->report_event, "report event", @@ -869,37 +864,24 @@ static void print_kvm_stat_usage(void) printf("\nOtherwise, it is the alias of 'perf stat':\n"); } -static int kvm_cmd_stat(const char *file_name, int argc, const char **argv) +static int kvm_cmd_stat(struct perf_kvm *kvm, int argc, const char **argv) { - struct perf_kvm_stat kvm = { - .file_name = file_name, - - .trace_vcpu = -1, - .report_event = "vmexit", - .sort_key = "sample", - - .exit_reasons = svm_exit_reasons, - .exit_reasons_size = ARRAY_SIZE(svm_exit_reasons), - .exit_reasons_isa = "SVM", - }; - if (argc == 1) { print_kvm_stat_usage(); goto perf_stat; } if (!strncmp(argv[1], "rec", 3)) - return kvm_events_record(&kvm, argc - 1, argv + 1); + return kvm_events_record(kvm, argc - 1, argv + 1); if (!strncmp(argv[1], "rep", 3)) - return kvm_events_report(&kvm, argc - 1 , argv + 1); + return kvm_events_report(kvm, argc - 1 , argv + 1); perf_stat: return cmd_stat(argc, argv, NULL); } -#endif -static int __cmd_record(const char *file_name, int argc, const char **argv) +static int __cmd_record(struct perf_kvm *kvm, int argc, const char **argv) { int rec_argc, i = 0, j; const char **rec_argv; @@ -908,7 +890,7 @@ static int __cmd_record(const char *file_name, int argc, const char **argv) rec_argv = calloc(rec_argc + 1, sizeof(char *)); rec_argv[i++] = strdup("record"); rec_argv[i++] = strdup("-o"); - rec_argv[i++] = strdup(file_name); + rec_argv[i++] = strdup(kvm->file_name); for (j = 1; j < argc; j++, i++) rec_argv[i] = argv[j]; @@ -917,7 +899,7 @@ static int __cmd_record(const char *file_name, int argc, const char **argv) return cmd_record(i, rec_argv, NULL); } -static int __cmd_report(const char *file_name, int argc, const char **argv) +static int __cmd_report(struct perf_kvm *kvm, int argc, const char **argv) { int rec_argc, i = 0, j; const char **rec_argv; @@ -926,7 +908,7 @@ static int __cmd_report(const char *file_name, int argc, const char **argv) rec_argv = calloc(rec_argc + 1, sizeof(char *)); rec_argv[i++] = strdup("report"); rec_argv[i++] = strdup("-i"); - rec_argv[i++] = strdup(file_name); + rec_argv[i++] = strdup(kvm->file_name); for (j = 1; j < argc; j++, i++) rec_argv[i] = argv[j]; @@ -935,8 +917,7 @@ static int __cmd_report(const char *file_name, int argc, const char **argv) return cmd_report(i, rec_argv, NULL); } -static int -__cmd_buildid_list(const char *file_name, int argc, const char **argv) +static int __cmd_buildid_list(struct perf_kvm *kvm, int argc, const char **argv) { int rec_argc, i = 0, j; const char **rec_argv; @@ -945,7 +926,7 @@ __cmd_buildid_list(const char *file_name, int argc, const char **argv) rec_argv = calloc(rec_argc + 1, sizeof(char *)); rec_argv[i++] = strdup("buildid-list"); rec_argv[i++] = strdup("-i"); - rec_argv[i++] = strdup(file_name); + rec_argv[i++] = strdup(kvm->file_name); for (j = 1; j < argc; j++, i++) rec_argv[i] = argv[j]; @@ -956,12 +937,20 @@ __cmd_buildid_list(const char *file_name, int argc, const char **argv) int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused) { - const char *file_name; + struct perf_kvm kvm = { + .trace_vcpu = -1, + .report_event = "vmexit", + .sort_key = "sample", + + .exit_reasons = svm_exit_reasons, + .exit_reasons_size = ARRAY_SIZE(svm_exit_reasons), + .exit_reasons_isa = "SVM", + }; const struct option kvm_options[] = { - OPT_STRING('i', "input", &file_name, "file", + OPT_STRING('i', "input", &kvm.file_name, "file", "Input file name"), - OPT_STRING('o', "output", &file_name, "file", + OPT_STRING('o', "output", &kvm.file_name, "file", "Output file name"), OPT_BOOLEAN(0, "guest", &perf_guest, "Collect guest os data"), @@ -996,34 +985,32 @@ int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused) if (!perf_host) perf_guest = 1; - if (!file_name) { + if (!kvm.file_name) { if (perf_host && !perf_guest) - file_name = strdup("perf.data.host"); + kvm.file_name = strdup("perf.data.host"); else if (!perf_host && perf_guest) - file_name = strdup("perf.data.guest"); + kvm.file_name = strdup("perf.data.guest"); else - file_name = strdup("perf.data.kvm"); + kvm.file_name = strdup("perf.data.kvm"); - if (!file_name) { + if (!kvm.file_name) { pr_err("Failed to allocate memory for filename\n"); return -ENOMEM; } } if (!strncmp(argv[0], "rec", 3)) - return __cmd_record(file_name, argc, argv); + return __cmd_record(&kvm, argc, argv); else if (!strncmp(argv[0], "rep", 3)) - return __cmd_report(file_name, argc, argv); + return __cmd_report(&kvm, argc, argv); else if (!strncmp(argv[0], "diff", 4)) return cmd_diff(argc, argv, NULL); else if (!strncmp(argv[0], "top", 3)) return cmd_top(argc, argv, NULL); else if (!strncmp(argv[0], "buildid-list", 12)) - return __cmd_buildid_list(file_name, argc, argv); -#if defined(__i386__) || defined(__x86_64__) + return __cmd_buildid_list(&kvm, argc, argv); else if (!strncmp(argv[0], "stat", 4)) - return kvm_cmd_stat(file_name, argc, argv); -#endif + return kvm_cmd_stat(&kvm, argc, argv); else usage_with_options(kvm_usage, kvm_options); diff --git a/trunk/tools/perf/builtin-test.c b/trunk/tools/perf/builtin-test.c index 5acd6e8e658b..484f26cc0c00 100644 --- a/trunk/tools/perf/builtin-test.c +++ b/trunk/tools/perf/builtin-test.c @@ -15,7 +15,7 @@ #include "util/thread_map.h" #include "util/pmu.h" #include "event-parse.h" -#include +#include "../../include/linux/hw_breakpoint.h" #include diff --git a/trunk/tools/perf/builtin-trace.c b/trunk/tools/perf/builtin-trace.c index 7aaee39f6774..dec8ced61fb0 100644 --- a/trunk/tools/perf/builtin-trace.c +++ b/trunk/tools/perf/builtin-trace.c @@ -56,10 +56,6 @@ static int trace__read_syscall_info(struct trace *trace, int id) { char tp_name[128]; struct syscall *sc; - const char *name = audit_syscall_to_name(id, trace->audit_machine); - - if (name == NULL) - return -1; if (id > trace->syscalls.max) { struct syscall *nsyscalls = realloc(trace->syscalls.table, (id + 1) * sizeof(*sc)); @@ -79,8 +75,11 @@ static int trace__read_syscall_info(struct trace *trace, int id) } sc = trace->syscalls.table + id; - sc->name = name; - sc->fmt = syscall_fmt__find(sc->name); + sc->name = audit_syscall_to_name(id, trace->audit_machine); + if (sc->name == NULL) + return -1; + + sc->fmt = syscall_fmt__find(sc->name); snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->name); sc->tp_format = event_format__new("syscalls", tp_name); @@ -268,13 +267,6 @@ static int trace__run(struct trace *trace) if (evlist->threads->map[0] == -1 || evlist->threads->nr > 1) printf("%d ", sample.tid); - if (sample.raw_data == NULL) { - printf("%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n", - perf_evsel__name(evsel), sample.tid, - sample.cpu, sample.raw_size); - continue; - } - handler = evsel->handler.func; handler(trace, evsel, &sample); } diff --git a/trunk/tools/perf/perf.h b/trunk/tools/perf/perf.h index 238f923f2218..c50985eaec41 100644 --- a/trunk/tools/perf/perf.h +++ b/trunk/tools/perf/perf.h @@ -5,9 +5,8 @@ struct winsize; void get_term_dimensions(struct winsize *ws); -#include - #if defined(__i386__) +#include "../../arch/x86/include/asm/unistd.h" #define rmb() asm volatile("lock; addl $0,0(%%esp)" ::: "memory") #define cpu_relax() asm volatile("rep; nop" ::: "memory"); #define CPUINFO_PROC "model name" @@ -17,6 +16,7 @@ void get_term_dimensions(struct winsize *ws); #endif #if defined(__x86_64__) +#include "../../arch/x86/include/asm/unistd.h" #define rmb() asm volatile("lfence" ::: "memory") #define cpu_relax() asm volatile("rep; nop" ::: "memory"); #define CPUINFO_PROC "model name" @@ -26,17 +26,20 @@ void get_term_dimensions(struct winsize *ws); #endif #ifdef __powerpc__ +#include "../../arch/powerpc/include/asm/unistd.h" #define rmb() asm volatile ("sync" ::: "memory") #define cpu_relax() asm volatile ("" ::: "memory"); #define CPUINFO_PROC "cpu" #endif #ifdef __s390__ +#include "../../arch/s390/include/asm/unistd.h" #define rmb() asm volatile("bcr 15,0" ::: "memory") #define cpu_relax() asm volatile("" ::: "memory"); #endif #ifdef __sh__ +#include "../../arch/sh/include/asm/unistd.h" #if defined(__SH4A__) || defined(__SH5__) # define rmb() asm volatile("synco" ::: "memory") #else @@ -47,30 +50,35 @@ void get_term_dimensions(struct winsize *ws); #endif #ifdef __hppa__ +#include "../../arch/parisc/include/asm/unistd.h" #define rmb() asm volatile("" ::: "memory") #define cpu_relax() asm volatile("" ::: "memory"); #define CPUINFO_PROC "cpu" #endif #ifdef __sparc__ +#include "../../arch/sparc/include/uapi/asm/unistd.h" #define rmb() asm volatile("":::"memory") #define cpu_relax() asm volatile("":::"memory") #define CPUINFO_PROC "cpu" #endif #ifdef __alpha__ +#include "../../arch/alpha/include/asm/unistd.h" #define rmb() asm volatile("mb" ::: "memory") #define cpu_relax() asm volatile("" ::: "memory") #define CPUINFO_PROC "cpu model" #endif #ifdef __ia64__ +#include "../../arch/ia64/include/asm/unistd.h" #define rmb() asm volatile ("mf" ::: "memory") #define cpu_relax() asm volatile ("hint @pause" ::: "memory") #define CPUINFO_PROC "model name" #endif #ifdef __arm__ +#include "../../arch/arm/include/asm/unistd.h" /* * Use the __kuser_memory_barrier helper in the CPU helper page. See * arch/arm/kernel/entry-armv.S in the kernel source for details. @@ -81,11 +89,13 @@ void get_term_dimensions(struct winsize *ws); #endif #ifdef __aarch64__ +#include "../../arch/arm64/include/asm/unistd.h" #define rmb() asm volatile("dmb ld" ::: "memory") #define cpu_relax() asm volatile("yield" ::: "memory") #endif #ifdef __mips__ +#include "../../arch/mips/include/asm/unistd.h" #define rmb() asm volatile( \ ".set mips2\n\t" \ "sync\n\t" \ @@ -102,7 +112,7 @@ void get_term_dimensions(struct winsize *ws); #include #include -#include +#include "../../include/uapi/linux/perf_event.h" #include "util/types.h" #include diff --git a/trunk/tools/perf/util/evsel.c b/trunk/tools/perf/util/evsel.c index d144d464ce39..618d41140abd 100644 --- a/trunk/tools/perf/util/evsel.c +++ b/trunk/tools/perf/util/evsel.c @@ -18,8 +18,8 @@ #include "cpumap.h" #include "thread_map.h" #include "target.h" -#include -#include +#include "../../../include/linux/hw_breakpoint.h" +#include "../../../include/uapi/linux/perf_event.h" #include "perf_regs.h" #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) diff --git a/trunk/tools/perf/util/evsel.h b/trunk/tools/perf/util/evsel.h index d99b476ef37c..6f94d6dea00f 100644 --- a/trunk/tools/perf/util/evsel.h +++ b/trunk/tools/perf/util/evsel.h @@ -3,8 +3,7 @@ #include #include -#include -#include +#include "../../../include/uapi/linux/perf_event.h" #include "types.h" #include "xyarray.h" #include "cgroup.h" diff --git a/trunk/tools/perf/util/header.c b/trunk/tools/perf/util/header.c index 566b84c695c8..7daad237dea5 100644 --- a/trunk/tools/perf/util/header.c +++ b/trunk/tools/perf/util/header.c @@ -1378,8 +1378,6 @@ static void print_numa_topology(struct perf_header *ph, int fd __maybe_unused, str = tmp + 1; fprintf(fp, "# node%u cpu list : %s\n", c, str); - - str += strlen(str) + 1; } return; error: diff --git a/trunk/tools/perf/util/header.h b/trunk/tools/perf/util/header.h index 9bc00783f24f..879d215cdac9 100644 --- a/trunk/tools/perf/util/header.h +++ b/trunk/tools/perf/util/header.h @@ -1,7 +1,7 @@ #ifndef __PERF_HEADER_H #define __PERF_HEADER_H -#include +#include "../../../include/uapi/linux/perf_event.h" #include #include #include "types.h" diff --git a/trunk/tools/perf/util/parse-events-test.c b/trunk/tools/perf/util/parse-events-test.c index 6ef213b35ecd..28c18d1d52c3 100644 --- a/trunk/tools/perf/util/parse-events-test.c +++ b/trunk/tools/perf/util/parse-events-test.c @@ -3,7 +3,7 @@ #include "evsel.h" #include "evlist.h" #include "sysfs.h" -#include +#include "../../../include/linux/hw_breakpoint.h" #define TEST_ASSERT_VAL(text, cond) \ do { \ @@ -513,8 +513,7 @@ static int test__group1(struct perf_evlist *evlist) TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - /* use of precise requires exclude_guest */ - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); @@ -600,8 +599,7 @@ static int test__group3(struct perf_evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - /* use of precise requires exclude_guest */ - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 3); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); @@ -664,8 +662,7 @@ static int test__group4(struct perf_evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - /* use of precise requires exclude_guest */ - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 1); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); @@ -679,8 +676,7 @@ static int test__group4(struct perf_evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - /* use of precise requires exclude_guest */ - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); diff --git a/trunk/tools/perf/util/parse-events.c b/trunk/tools/perf/util/parse-events.c index 6b6d03e93c3d..75c7b0fca6d9 100644 --- a/trunk/tools/perf/util/parse-events.c +++ b/trunk/tools/perf/util/parse-events.c @@ -1,4 +1,4 @@ -#include +#include "../../../include/linux/hw_breakpoint.h" #include "util.h" #include "../perf.h" #include "evlist.h" diff --git a/trunk/tools/perf/util/parse-events.h b/trunk/tools/perf/util/parse-events.h index 2820c407adb2..839230ceb18b 100644 --- a/trunk/tools/perf/util/parse-events.h +++ b/trunk/tools/perf/util/parse-events.h @@ -7,7 +7,7 @@ #include #include #include "types.h" -#include +#include "../../../include/uapi/linux/perf_event.h" #include "types.h" struct list_head; diff --git a/trunk/tools/perf/util/pmu.h b/trunk/tools/perf/util/pmu.h index fdeb8ac7c5d2..39f3abac7744 100644 --- a/trunk/tools/perf/util/pmu.h +++ b/trunk/tools/perf/util/pmu.h @@ -2,7 +2,7 @@ #define __PMU_H #include -#include +#include "../../../include/uapi/linux/perf_event.h" enum { PERF_PMU_FORMAT_VALUE_CONFIG, diff --git a/trunk/tools/perf/util/session.h b/trunk/tools/perf/util/session.h index 0eae00ad5fe7..dd6426163ba6 100644 --- a/trunk/tools/perf/util/session.h +++ b/trunk/tools/perf/util/session.h @@ -7,7 +7,7 @@ #include "symbol.h" #include "thread.h" #include -#include +#include "../../../include/uapi/linux/perf_event.h" struct sample_queue; struct ip_callchain; diff --git a/trunk/tools/perf/util/strbuf.c b/trunk/tools/perf/util/strbuf.c index cfa906882e2c..2eeb51baf077 100644 --- a/trunk/tools/perf/util/strbuf.c +++ b/trunk/tools/perf/util/strbuf.c @@ -90,17 +90,17 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...) if (!strbuf_avail(sb)) strbuf_grow(sb, 64); va_start(ap, fmt); - len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); + len = vscnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); va_end(ap); if (len < 0) - die("your vsnprintf is broken"); + die("your vscnprintf is broken"); if (len > strbuf_avail(sb)) { strbuf_grow(sb, len); va_start(ap, fmt); - len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); + len = vscnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); va_end(ap); if (len > strbuf_avail(sb)) { - die("this should not happen, your vsnprintf is broken"); + die("this should not happen, your snprintf is broken"); } } strbuf_setlen(sb, sb->len + len); diff --git a/trunk/tools/perf/util/thread.c b/trunk/tools/perf/util/thread.c index 8b3e5939afb6..fb4b7ea6752f 100644 --- a/trunk/tools/perf/util/thread.c +++ b/trunk/tools/perf/util/thread.c @@ -39,6 +39,7 @@ int thread__set_comm(struct thread *self, const char *comm) err = self->comm == NULL ? -ENOMEM : 0; if (!err) { self->comm_set = true; + map_groups__flush(&self->mg); } return err; } diff --git a/trunk/tools/power/x86/turbostat/turbostat.c b/trunk/tools/power/x86/turbostat/turbostat.c index ea095abbe97e..2655ae9a3ad8 100644 --- a/trunk/tools/power/x86/turbostat/turbostat.c +++ b/trunk/tools/power/x86/turbostat/turbostat.c @@ -206,10 +206,8 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr) retval = pread(fd, msr, sizeof *msr, offset); close(fd); - if (retval != sizeof *msr) { - fprintf(stderr, "%s offset 0x%zx read failed\n", pathname, offset); + if (retval != sizeof *msr) return -1; - } return 0; } @@ -1103,9 +1101,7 @@ void turbostat_loop() restart: retval = for_all_cpus(get_counters, EVEN_COUNTERS); - if (retval < -1) { - exit(retval); - } else if (retval == -1) { + if (retval) { re_initialize(); goto restart; } @@ -1118,9 +1114,7 @@ void turbostat_loop() } sleep(interval_sec); retval = for_all_cpus(get_counters, ODD_COUNTERS); - if (retval < -1) { - exit(retval); - } else if (retval == -1) { + if (retval) { re_initialize(); goto restart; } @@ -1132,9 +1126,7 @@ void turbostat_loop() flush_stdout(); sleep(interval_sec); retval = for_all_cpus(get_counters, EVEN_COUNTERS); - if (retval < -1) { - exit(retval); - } else if (retval == -1) { + if (retval) { re_initialize(); goto restart; } @@ -1553,11 +1545,8 @@ void turbostat_init() int fork_it(char **argv) { pid_t child_pid; - int status; - status = for_all_cpus(get_counters, EVEN_COUNTERS); - if (status) - exit(status); + for_all_cpus(get_counters, EVEN_COUNTERS); /* clear affinity side-effect of get_counters() */ sched_setaffinity(0, cpu_present_setsize, cpu_present_set); gettimeofday(&tv_even, (struct timezone *)NULL); @@ -1567,6 +1556,7 @@ int fork_it(char **argv) /* child */ execvp(argv[0], argv); } else { + int status; /* parent */ if (child_pid == -1) { @@ -1578,7 +1568,7 @@ int fork_it(char **argv) signal(SIGQUIT, SIG_IGN); if (waitpid(child_pid, &status, 0) == -1) { perror("wait"); - exit(status); + exit(1); } } /* @@ -1595,7 +1585,7 @@ int fork_it(char **argv) fprintf(stderr, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0); - return status; + return 0; } void cmdline(int argc, char **argv) @@ -1604,7 +1594,7 @@ void cmdline(int argc, char **argv) progname = argv[0]; - while ((opt = getopt(argc, argv, "+pPSvi:sc:sC:m:M:")) != -1) { + while ((opt = getopt(argc, argv, "+pPSvisc:sC:m:M:")) != -1) { switch (opt) { case 'p': show_core_only++; diff --git a/trunk/tools/scripts/Makefile.include b/trunk/tools/scripts/Makefile.include index 2964b96aa55f..96ce80a3743b 100644 --- a/trunk/tools/scripts/Makefile.include +++ b/trunk/tools/scripts/Makefile.include @@ -1,11 +1,8 @@ -ifeq ($(origin O), command line) +ifeq ("$(origin O)", "command line") dummy := $(if $(shell test -d $(O) || echo $(O)),$(error O=$(O) does not exist),) ABSOLUTE_O := $(shell cd $(O) ; pwd) - OUTPUT := $(ABSOLUTE_O)/$(if $(subdir),$(subdir)/) + OUTPUT := $(ABSOLUTE_O)/ COMMAND_O := O=$(ABSOLUTE_O) -ifeq ($(objtree),) - objtree := $(O) -endif endif ifneq ($(OUTPUT),) @@ -44,16 +41,7 @@ else NO_SUBDIR = : endif -# -# Define a callable command for descending to a new directory -# -# Call by doing: $(call descend,directory[,target]) -# -descend = \ - +mkdir -p $(OUTPUT)$(1) && \ - $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2) - -QUIET_SUBDIR0 = +$(MAKE) $(COMMAND_O) -C # space to separate -C and subdir +QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir QUIET_SUBDIR1 = ifneq ($(findstring $(MAKEFLAGS),s),s) @@ -68,10 +56,5 @@ ifndef V $(MAKE) $(PRINT_DIR) -C $$subdir QUIET_FLEX = @echo ' ' FLEX $@; QUIET_BISON = @echo ' ' BISON $@; - - descend = \ - @echo ' ' DESCEND $(1); \ - mkdir -p $(OUTPUT)$(1) && \ - $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2) endif endif diff --git a/trunk/tools/testing/ktest/ktest.pl b/trunk/tools/testing/ktest/ktest.pl index c7ba7614061b..b51d787176d3 100755 --- a/trunk/tools/testing/ktest/ktest.pl +++ b/trunk/tools/testing/ktest/ktest.pl @@ -1740,10 +1740,8 @@ sub install { open(IN, "$output_config") or dodie("Can't read config file"); while () { if (/CONFIG_MODULES(=y)?/) { - if (defined($1)) { - $install_mods = 1; - last; - } + $install_mods = 1 if (defined($1)); + last; } } close(IN); diff --git a/trunk/tools/testing/selftests/Makefile b/trunk/tools/testing/selftests/Makefile index 85baf11e2acd..43480149119e 100644 --- a/trunk/tools/testing/selftests/Makefile +++ b/trunk/tools/testing/selftests/Makefile @@ -1,4 +1,4 @@ -TARGETS = breakpoints kcmp mqueue vm cpu-hotplug memory-hotplug +TARGETS = breakpoints kcmp mqueue vm cpu-hotplug memory-hotplug epoll all: for TARGET in $(TARGETS); do \ diff --git a/trunk/tools/testing/selftests/epoll/Makefile b/trunk/tools/testing/selftests/epoll/Makefile new file mode 100644 index 000000000000..19806ed62f50 --- /dev/null +++ b/trunk/tools/testing/selftests/epoll/Makefile @@ -0,0 +1,11 @@ +# Makefile for epoll selftests + +all: test_epoll +%: %.c + gcc -pthread -g -o $@ $^ + +run_tests: all + ./test_epoll + +clean: + $(RM) test_epoll diff --git a/trunk/tools/testing/selftests/epoll/test_epoll.c b/trunk/tools/testing/selftests/epoll/test_epoll.c new file mode 100644 index 000000000000..e0fcff1e8331 --- /dev/null +++ b/trunk/tools/testing/selftests/epoll/test_epoll.c @@ -0,0 +1,344 @@ +/* + * tools/testing/selftests/epoll/test_epoll.c + * + * Copyright 2012 Adobe Systems Incorporated + * + * 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. + * + * Paton J. Lewis + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * A pointer to an epoll_item_private structure will be stored in the epoll + * item's event structure so that we can get access to the epoll_item_private + * data after calling epoll_wait: + */ +struct epoll_item_private { + int index; /* Position of this struct within the epoll_items array. */ + int fd; + uint32_t events; + pthread_mutex_t mutex; /* Guards the following variables... */ + int stop; + int status; /* Stores any error encountered while handling item. */ + /* The following variable allows us to test whether we have encountered + a problem while attempting to cancel and delete the associated + event. When the test program exits, 'deleted' should be exactly + one. If it is greater than one, then the failed test reflects a real + world situation where we would have tried to access the epoll item's + private data after deleting it: */ + int deleted; +}; + +struct epoll_item_private *epoll_items; + +/* + * Delete the specified item from the epoll set. In a real-world secneario this + * is where we would free the associated data structure, but in this testing + * environment we retain the structure so that we can test for double-deletion: + */ +void delete_item(int index) +{ + __sync_fetch_and_add(&epoll_items[index].deleted, 1); +} + +/* + * A pointer to a read_thread_data structure will be passed as the argument to + * each read thread: + */ +struct read_thread_data { + int stop; + int status; /* Indicates any error encountered by the read thread. */ + int epoll_set; +}; + +/* + * The function executed by the read threads: + */ +void *read_thread_function(void *function_data) +{ + struct read_thread_data *thread_data = + (struct read_thread_data *)function_data; + struct epoll_event event_data; + struct epoll_item_private *item_data; + char socket_data; + + /* Handle events until we encounter an error or this thread's 'stop' + condition is set: */ + while (1) { + int result = epoll_wait(thread_data->epoll_set, + &event_data, + 1, /* Number of desired events */ + 1000); /* Timeout in ms */ + if (result < 0) { + /* Breakpoints signal all threads. Ignore that while + debugging: */ + if (errno == EINTR) + continue; + thread_data->status = errno; + return 0; + } else if (thread_data->stop) + return 0; + else if (result == 0) /* Timeout */ + continue; + + /* We need the mutex here because checking for the stop + condition and re-enabling the epoll item need to be done + together as one atomic operation when EPOLL_CTL_DISABLE is + available: */ + item_data = (struct epoll_item_private *)event_data.data.ptr; + pthread_mutex_lock(&item_data->mutex); + + /* Remove the item from the epoll set if we want to stop + handling that event: */ + if (item_data->stop) + delete_item(item_data->index); + else { + /* Clear the data that was written to the other end of + our non-blocking socket: */ + do { + if (read(item_data->fd, &socket_data, 1) < 1) { + if ((errno == EAGAIN) || + (errno == EWOULDBLOCK)) + break; + else + goto error_unlock; + } + } while (item_data->events & EPOLLET); + + /* The item was one-shot, so re-enable it: */ + event_data.events = item_data->events; + if (epoll_ctl(thread_data->epoll_set, + EPOLL_CTL_MOD, + item_data->fd, + &event_data) < 0) + goto error_unlock; + } + + pthread_mutex_unlock(&item_data->mutex); + } + +error_unlock: + thread_data->status = item_data->status = errno; + pthread_mutex_unlock(&item_data->mutex); + return 0; +} + +/* + * A pointer to a write_thread_data structure will be passed as the argument to + * the write thread: + */ +struct write_thread_data { + int stop; + int status; /* Indicates any error encountered by the write thread. */ + int n_fds; + int *fds; +}; + +/* + * The function executed by the write thread. It writes a single byte to each + * socket in turn until the stop condition for this thread is set. If writing to + * a socket would block (i.e. errno was EAGAIN), we leave that socket alone for + * the moment and just move on to the next socket in the list. We don't care + * about the order in which we deliver events to the epoll set. In fact we don't + * care about the data we're writing to the pipes at all; we just want to + * trigger epoll events: + */ +void *write_thread_function(void *function_data) +{ + const char data = 'X'; + int index; + struct write_thread_data *thread_data = + (struct write_thread_data *)function_data; + while (!write_thread_data->stop) + for (index = 0; + !thread_data->stop && (index < thread_data->n_fds); + ++index) + if ((write(thread_data->fds[index], &data, 1) < 1) && + (errno != EAGAIN) && + (errno != EWOULDBLOCK)) { + write_thread_data->status = errno; + return; + } +} + +/* + * Arguments are currently ignored: + */ +int main(int argc, char **argv) +{ + const int n_read_threads = 100; + const int n_epoll_items = 500; + int index; + int epoll_set = epoll_create1(0); + struct write_thread_data write_thread_data = { + 0, 0, n_epoll_items, malloc(n_epoll_items * sizeof(int)) + }; + struct read_thread_data *read_thread_data = + malloc(n_read_threads * sizeof(struct read_thread_data)); + pthread_t *read_threads = malloc(n_read_threads * sizeof(pthread_t)); + pthread_t write_thread; + + printf("-----------------\n"); + printf("Runing test_epoll\n"); + printf("-----------------\n"); + + epoll_items = malloc(n_epoll_items * sizeof(struct epoll_item_private)); + + if (epoll_set < 0 || epoll_items == 0 || write_thread_data.fds == 0 || + read_thread_data == 0 || read_threads == 0) + goto error; + + if (sysconf(_SC_NPROCESSORS_ONLN) < 2) { + printf("Error: please run this test on a multi-core system.\n"); + goto error; + } + + /* Create the socket pairs and epoll items: */ + for (index = 0; index < n_epoll_items; ++index) { + int socket_pair[2]; + struct epoll_event event_data; + if (socketpair(AF_UNIX, + SOCK_STREAM | SOCK_NONBLOCK, + 0, + socket_pair) < 0) + goto error; + write_thread_data.fds[index] = socket_pair[0]; + epoll_items[index].index = index; + epoll_items[index].fd = socket_pair[1]; + if (pthread_mutex_init(&epoll_items[index].mutex, NULL) != 0) + goto error; + /* We always use EPOLLONESHOT because this test is currently + structured to demonstrate the need for EPOLL_CTL_DISABLE, + which only produces useful information in the EPOLLONESHOT + case (without EPOLLONESHOT, calling epoll_ctl with + EPOLL_CTL_DISABLE will never return EBUSY). If support for + testing events without EPOLLONESHOT is desired, it should + probably be implemented in a separate unit test. */ + epoll_items[index].events = EPOLLIN | EPOLLONESHOT; + if (index < n_epoll_items / 2) + epoll_items[index].events |= EPOLLET; + epoll_items[index].stop = 0; + epoll_items[index].status = 0; + epoll_items[index].deleted = 0; + event_data.events = epoll_items[index].events; + event_data.data.ptr = &epoll_items[index]; + if (epoll_ctl(epoll_set, + EPOLL_CTL_ADD, + epoll_items[index].fd, + &event_data) < 0) + goto error; + } + + /* Create and start the read threads: */ + for (index = 0; index < n_read_threads; ++index) { + read_thread_data[index].stop = 0; + read_thread_data[index].status = 0; + read_thread_data[index].epoll_set = epoll_set; + if (pthread_create(&read_threads[index], + NULL, + read_thread_function, + &read_thread_data[index]) != 0) + goto error; + } + + if (pthread_create(&write_thread, + NULL, + write_thread_function, + &write_thread_data) != 0) + goto error; + + /* Cancel all event pollers: */ +#ifdef EPOLL_CTL_DISABLE + for (index = 0; index < n_epoll_items; ++index) { + pthread_mutex_lock(&epoll_items[index].mutex); + ++epoll_items[index].stop; + if (epoll_ctl(epoll_set, + EPOLL_CTL_DISABLE, + epoll_items[index].fd, + NULL) == 0) + delete_item(index); + else if (errno != EBUSY) { + pthread_mutex_unlock(&epoll_items[index].mutex); + goto error; + } + /* EBUSY means events were being handled; allow the other thread + to delete the item. */ + pthread_mutex_unlock(&epoll_items[index].mutex); + } +#else + for (index = 0; index < n_epoll_items; ++index) { + pthread_mutex_lock(&epoll_items[index].mutex); + ++epoll_items[index].stop; + pthread_mutex_unlock(&epoll_items[index].mutex); + /* Wait in case a thread running read_thread_function is + currently executing code between epoll_wait and + pthread_mutex_lock with this item. Note that a longer delay + would make double-deletion less likely (at the expense of + performance), but there is no guarantee that any delay would + ever be sufficient. Note also that we delete all event + pollers at once for testing purposes, but in a real-world + environment we are likely to want to be able to cancel event + pollers at arbitrary times. Therefore we can't improve this + situation by just splitting this loop into two loops + (i.e. signal 'stop' for all items, sleep, and then delete all + items). We also can't fix the problem via EPOLL_CTL_DEL + because that command can't prevent the case where some other + thread is executing read_thread_function within the region + mentioned above: */ + usleep(1); + pthread_mutex_lock(&epoll_items[index].mutex); + if (!epoll_items[index].deleted) + delete_item(index); + pthread_mutex_unlock(&epoll_items[index].mutex); + } +#endif + + /* Shut down the read threads: */ + for (index = 0; index < n_read_threads; ++index) + __sync_fetch_and_add(&read_thread_data[index].stop, 1); + for (index = 0; index < n_read_threads; ++index) { + if (pthread_join(read_threads[index], NULL) != 0) + goto error; + if (read_thread_data[index].status) + goto error; + } + + /* Shut down the write thread: */ + __sync_fetch_and_add(&write_thread_data.stop, 1); + if ((pthread_join(write_thread, NULL) != 0) || write_thread_data.status) + goto error; + + /* Check for final error conditions: */ + for (index = 0; index < n_epoll_items; ++index) { + if (epoll_items[index].status != 0) + goto error; + if (pthread_mutex_destroy(&epoll_items[index].mutex) < 0) + goto error; + } + for (index = 0; index < n_epoll_items; ++index) + if (epoll_items[index].deleted != 1) { + printf("Error: item data deleted %1d times.\n", + epoll_items[index].deleted); + goto error; + } + + printf("[PASS]\n"); + return 0; + + error: + printf("[FAIL]\n"); + return errno; +} diff --git a/trunk/tools/vm/page-types.c b/trunk/tools/vm/page-types.c index b76edf2f8333..cd1b03e80899 100644 --- a/trunk/tools/vm/page-types.c +++ b/trunk/tools/vm/page-types.c @@ -35,7 +35,7 @@ #include #include #include "../../include/uapi/linux/magic.h" -#include "../../include/uapi/linux/kernel-page-flags.h" +#include "../../include/linux/kernel-page-flags.h" #ifndef MAX_PATH diff --git a/trunk/usr/gen_init_cpio.c b/trunk/usr/gen_init_cpio.c index aca6edcbbc6f..af0f22fb1ef7 100644 --- a/trunk/usr/gen_init_cpio.c +++ b/trunk/usr/gen_init_cpio.c @@ -303,7 +303,7 @@ static int cpio_mkfile(const char *name, const char *location, int retval; int rc = -1; int namesize; - unsigned int i; + int i; mode |= S_IFREG; @@ -381,28 +381,25 @@ static int cpio_mkfile(const char *name, const char *location, static char *cpio_replace_env(char *new_location) { - char expanded[PATH_MAX + 1]; - char env_var[PATH_MAX + 1]; - char *start; - char *end; - - for (start = NULL; (start = strstr(new_location, "${")); ) { - end = strchr(start, '}'); - if (start < end) { - *env_var = *expanded = '\0'; - strncat(env_var, start + 2, end - start - 2); - strncat(expanded, new_location, start - new_location); - strncat(expanded, getenv(env_var), - PATH_MAX - strlen(expanded)); - strncat(expanded, end + 1, - PATH_MAX - strlen(expanded)); - strncpy(new_location, expanded, PATH_MAX); - new_location[PATH_MAX] = 0; - } else - break; - } - - return new_location; + char expanded[PATH_MAX + 1]; + char env_var[PATH_MAX + 1]; + char *start; + char *end; + + for (start = NULL; (start = strstr(new_location, "${")); ) { + end = strchr(start, '}'); + if (start < end) { + *env_var = *expanded = '\0'; + strncat(env_var, start + 2, end - start - 2); + strncat(expanded, new_location, start - new_location); + strncat(expanded, getenv(env_var), PATH_MAX); + strncat(expanded, end + 1, PATH_MAX); + strncpy(new_location, expanded, PATH_MAX); + } else + break; + } + + return new_location; } diff --git a/trunk/virt/kvm/kvm_main.c b/trunk/virt/kvm/kvm_main.c index be70035fd42a..e59bb63cb089 100644 --- a/trunk/virt/kvm/kvm_main.c +++ b/trunk/virt/kvm/kvm_main.c @@ -1322,7 +1322,9 @@ EXPORT_SYMBOL_GPL(kvm_release_page_clean); void kvm_release_pfn_clean(pfn_t pfn) { - if (!is_error_pfn(pfn) && !kvm_is_mmio_pfn(pfn)) + WARN_ON(is_error_pfn(pfn)); + + if (!kvm_is_mmio_pfn(pfn)) put_page(pfn_to_page(pfn)); } EXPORT_SYMBOL_GPL(kvm_release_pfn_clean);