diff options
68 files changed, 2016 insertions, 613 deletions
diff --git a/Documentation/powerpc/dts-bindings/fsl/mpic.txt b/Documentation/powerpc/dts-bindings/fsl/mpic.txt new file mode 100644 index 000000000000..71e39cf3215b --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/mpic.txt | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | * OpenPIC and its interrupt numbers on Freescale's e500/e600 cores | ||
| 2 | |||
| 3 | The OpenPIC specification does not specify which interrupt source has to | ||
| 4 | become which interrupt number. This is up to the software implementation | ||
| 5 | of the interrupt controller. The only requirement is that every | ||
| 6 | interrupt source has to have an unique interrupt number / vector number. | ||
| 7 | To accomplish this the current implementation assigns the number zero to | ||
| 8 | the first source, the number one to the second source and so on until | ||
| 9 | all interrupt sources have their unique number. | ||
| 10 | Usually the assigned vector number equals the interrupt number mentioned | ||
| 11 | in the documentation for a given core / CPU. This is however not true | ||
| 12 | for the e500 cores (MPC85XX CPUs) where the documentation distinguishes | ||
| 13 | between internal and external interrupt sources and starts counting at | ||
| 14 | zero for both of them. | ||
| 15 | |||
| 16 | So what to write for external interrupt source X or internal interrupt | ||
| 17 | source Y into the device tree? Here is an example: | ||
| 18 | |||
| 19 | The memory map for the interrupt controller in the MPC8544[0] shows, | ||
| 20 | that the first interrupt source starts at 0x5_0000 (PIC Register Address | ||
| 21 | Map-Interrupt Source Configuration Registers). This source becomes the | ||
| 22 | number zero therefore: | ||
| 23 | External interrupt 0 = interrupt number 0 | ||
| 24 | External interrupt 1 = interrupt number 1 | ||
| 25 | External interrupt 2 = interrupt number 2 | ||
| 26 | ... | ||
| 27 | Every interrupt number allocates 0x20 bytes register space. So to get | ||
| 28 | its number it is sufficient to shift the lower 16bits to right by five. | ||
| 29 | So for the external interrupt 10 we have: | ||
| 30 | 0x0140 >> 5 = 10 | ||
| 31 | |||
| 32 | After the external sources, the internal sources follow. The in core I2C | ||
| 33 | controller on the MPC8544 for instance has the internal source number | ||
| 34 | 27. Oo obtain its interrupt number we take the lower 16bits of its memory | ||
| 35 | address (0x5_0560) and shift it right: | ||
| 36 | 0x0560 >> 5 = 43 | ||
| 37 | |||
| 38 | Therefore the I2C device node for the MPC8544 CPU has to have the | ||
| 39 | interrupt number 43 specified in the device tree. | ||
| 40 | |||
| 41 | [0] MPC8544E PowerQUICCTM III, Integrated Host Processor Family Reference Manual | ||
| 42 | MPC8544ERM Rev. 1 10/2007 | ||
diff --git a/Documentation/trace/events-kmem.txt b/Documentation/trace/events-kmem.txt index 6ef2a8652e17..aa82ee4a5a87 100644 --- a/Documentation/trace/events-kmem.txt +++ b/Documentation/trace/events-kmem.txt | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | Subsystem Trace Points: kmem | 1 | Subsystem Trace Points: kmem |
| 2 | 2 | ||
| 3 | The tracing system kmem captures events related to object and page allocation | 3 | The kmem tracing system captures events related to object and page allocation |
| 4 | within the kernel. Broadly speaking there are four major subheadings. | 4 | within the kernel. Broadly speaking there are five major subheadings. |
| 5 | 5 | ||
| 6 | o Slab allocation of small objects of unknown type (kmalloc) | 6 | o Slab allocation of small objects of unknown type (kmalloc) |
| 7 | o Slab allocation of small objects of known type | 7 | o Slab allocation of small objects of known type |
| @@ -9,7 +9,7 @@ within the kernel. Broadly speaking there are four major subheadings. | |||
| 9 | o Per-CPU Allocator Activity | 9 | o Per-CPU Allocator Activity |
| 10 | o External Fragmentation | 10 | o External Fragmentation |
| 11 | 11 | ||
| 12 | This document will describe what each of the tracepoints are and why they | 12 | This document describes what each of the tracepoints is and why they |
| 13 | might be useful. | 13 | might be useful. |
| 14 | 14 | ||
| 15 | 1. Slab allocation of small objects of unknown type | 15 | 1. Slab allocation of small objects of unknown type |
| @@ -34,7 +34,7 @@ kmem_cache_free call_site=%lx ptr=%p | |||
| 34 | These events are similar in usage to the kmalloc-related events except that | 34 | These events are similar in usage to the kmalloc-related events except that |
| 35 | it is likely easier to pin the event down to a specific cache. At the time | 35 | it is likely easier to pin the event down to a specific cache. At the time |
| 36 | of writing, no information is available on what slab is being allocated from, | 36 | of writing, no information is available on what slab is being allocated from, |
| 37 | but the call_site can usually be used to extrapolate that information | 37 | but the call_site can usually be used to extrapolate that information. |
| 38 | 38 | ||
| 39 | 3. Page allocation | 39 | 3. Page allocation |
| 40 | ================== | 40 | ================== |
| @@ -80,9 +80,9 @@ event indicating whether it is for a percpu_refill or not. | |||
| 80 | When the per-CPU list is too full, a number of pages are freed, each one | 80 | When the per-CPU list is too full, a number of pages are freed, each one |
| 81 | which triggers a mm_page_pcpu_drain event. | 81 | which triggers a mm_page_pcpu_drain event. |
| 82 | 82 | ||
| 83 | The individual nature of the events are so that pages can be tracked | 83 | The individual nature of the events is so that pages can be tracked |
| 84 | between allocation and freeing. A number of drain or refill pages that occur | 84 | between allocation and freeing. A number of drain or refill pages that occur |
| 85 | consecutively imply the zone->lock being taken once. Large amounts of PCP | 85 | consecutively imply the zone->lock being taken once. Large amounts of per-CPU |
| 86 | refills and drains could imply an imbalance between CPUs where too much work | 86 | refills and drains could imply an imbalance between CPUs where too much work |
| 87 | is being concentrated in one place. It could also indicate that the per-CPU | 87 | is being concentrated in one place. It could also indicate that the per-CPU |
| 88 | lists should be a larger size. Finally, large amounts of refills on one CPU | 88 | lists should be a larger size. Finally, large amounts of refills on one CPU |
| @@ -102,6 +102,6 @@ is important. | |||
| 102 | 102 | ||
| 103 | Large numbers of this event implies that memory is fragmenting and | 103 | Large numbers of this event implies that memory is fragmenting and |
| 104 | high-order allocations will start failing at some time in the future. One | 104 | high-order allocations will start failing at some time in the future. One |
| 105 | means of reducing the occurange of this event is to increase the size of | 105 | means of reducing the occurrence of this event is to increase the size of |
| 106 | min_free_kbytes in increments of 3*pageblock_size*nr_online_nodes where | 106 | min_free_kbytes in increments of 3*pageblock_size*nr_online_nodes where |
| 107 | pageblock_size is usually the size of the default hugepage size. | 107 | pageblock_size is usually the size of the default hugepage size. |
diff --git a/arch/powerpc/boot/dts/katmai.dts b/arch/powerpc/boot/dts/katmai.dts index 51eb6ed5da2d..8f345de960cd 100644 --- a/arch/powerpc/boot/dts/katmai.dts +++ b/arch/powerpc/boot/dts/katmai.dts | |||
| @@ -108,12 +108,19 @@ | |||
| 108 | dcr-reg = <0x00c 0x002>; | 108 | dcr-reg = <0x00c 0x002>; |
| 109 | }; | 109 | }; |
| 110 | 110 | ||
| 111 | MQ0: mq { | ||
| 112 | compatible = "ibm,mq-440spe"; | ||
| 113 | dcr-reg = <0x040 0x020>; | ||
| 114 | }; | ||
| 115 | |||
| 111 | plb { | 116 | plb { |
| 112 | compatible = "ibm,plb-440spe", "ibm,plb-440gp", "ibm,plb4"; | 117 | compatible = "ibm,plb-440spe", "ibm,plb-440gp", "ibm,plb4"; |
| 113 | #address-cells = <2>; | 118 | #address-cells = <2>; |
| 114 | #size-cells = <1>; | 119 | #size-cells = <1>; |
| 115 | /* addr-child addr-parent size */ | 120 | /* addr-child addr-parent size */ |
| 116 | ranges = <0x4 0xe0000000 0x4 0xe0000000 0x20000000 | 121 | ranges = <0x4 0x00100000 0x4 0x00100000 0x00001000 |
| 122 | 0x4 0x00200000 0x4 0x00200000 0x00000400 | ||
| 123 | 0x4 0xe0000000 0x4 0xe0000000 0x20000000 | ||
| 117 | 0xc 0x00000000 0xc 0x00000000 0x20000000 | 124 | 0xc 0x00000000 0xc 0x00000000 0x20000000 |
| 118 | 0xd 0x00000000 0xd 0x00000000 0x80000000 | 125 | 0xd 0x00000000 0xd 0x00000000 0x80000000 |
| 119 | 0xd 0x80000000 0xd 0x80000000 0x80000000 | 126 | 0xd 0x80000000 0xd 0x80000000 0x80000000 |
| @@ -400,6 +407,49 @@ | |||
| 400 | 0x0 0x0 0x0 0x3 &UIC3 0xa 0x4 /* swizzled int C */ | 407 | 0x0 0x0 0x0 0x3 &UIC3 0xa 0x4 /* swizzled int C */ |
| 401 | 0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /* swizzled int D */>; | 408 | 0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /* swizzled int D */>; |
| 402 | }; | 409 | }; |
| 410 | |||
| 411 | I2O: i2o@400100000 { | ||
| 412 | compatible = "ibm,i2o-440spe"; | ||
| 413 | reg = <0x00000004 0x00100000 0x100>; | ||
| 414 | dcr-reg = <0x060 0x020>; | ||
| 415 | }; | ||
| 416 | |||
| 417 | DMA0: dma0@400100100 { | ||
| 418 | compatible = "ibm,dma-440spe"; | ||
| 419 | cell-index = <0>; | ||
| 420 | reg = <0x00000004 0x00100100 0x100>; | ||
| 421 | dcr-reg = <0x060 0x020>; | ||
| 422 | interrupt-parent = <&DMA0>; | ||
| 423 | interrupts = <0 1>; | ||
| 424 | #interrupt-cells = <1>; | ||
| 425 | #address-cells = <0>; | ||
| 426 | #size-cells = <0>; | ||
| 427 | interrupt-map = < | ||
| 428 | 0 &UIC0 0x14 4 | ||
| 429 | 1 &UIC1 0x16 4>; | ||
| 430 | }; | ||
| 431 | |||
| 432 | DMA1: dma1@400100200 { | ||
| 433 | compatible = "ibm,dma-440spe"; | ||
| 434 | cell-index = <1>; | ||
| 435 | reg = <0x00000004 0x00100200 0x100>; | ||
| 436 | dcr-reg = <0x060 0x020>; | ||
| 437 | interrupt-parent = <&DMA1>; | ||
| 438 | interrupts = <0 1>; | ||
| 439 | #interrupt-cells = <1>; | ||
| 440 | #address-cells = <0>; | ||
| 441 | #size-cells = <0>; | ||
| 442 | interrupt-map = < | ||
| 443 | 0 &UIC0 0x16 4 | ||
| 444 | 1 &UIC1 0x16 4>; | ||
| 445 | }; | ||
| 446 | |||
| 447 | xor-accel@400200000 { | ||
| 448 | compatible = "amcc,xor-accelerator"; | ||
| 449 | reg = <0x00000004 0x00200000 0x400>; | ||
| 450 | interrupt-parent = <&UIC1>; | ||
| 451 | interrupts = <0x1f 4>; | ||
| 452 | }; | ||
| 403 | }; | 453 | }; |
| 404 | 454 | ||
| 405 | chosen { | 455 | chosen { |
diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts index 32e10f588c1d..8a3a4f3ef831 100644 --- a/arch/powerpc/boot/dts/mpc8315erdb.dts +++ b/arch/powerpc/boot/dts/mpc8315erdb.dts | |||
| @@ -204,6 +204,7 @@ | |||
| 204 | interrupt-parent = <&ipic>; | 204 | interrupt-parent = <&ipic>; |
| 205 | tbi-handle = <&tbi0>; | 205 | tbi-handle = <&tbi0>; |
| 206 | phy-handle = < &phy0 >; | 206 | phy-handle = < &phy0 >; |
| 207 | fsl,magic-packet; | ||
| 207 | 208 | ||
| 208 | mdio@520 { | 209 | mdio@520 { |
| 209 | #address-cells = <1>; | 210 | #address-cells = <1>; |
| @@ -246,6 +247,7 @@ | |||
| 246 | interrupt-parent = <&ipic>; | 247 | interrupt-parent = <&ipic>; |
| 247 | tbi-handle = <&tbi1>; | 248 | tbi-handle = <&tbi1>; |
| 248 | phy-handle = < &phy1 >; | 249 | phy-handle = < &phy1 >; |
| 250 | fsl,magic-packet; | ||
| 249 | 251 | ||
| 250 | mdio@520 { | 252 | mdio@520 { |
| 251 | #address-cells = <1>; | 253 | #address-cells = <1>; |
| @@ -309,6 +311,22 @@ | |||
| 309 | interrupt-parent = <&ipic>; | 311 | interrupt-parent = <&ipic>; |
| 310 | }; | 312 | }; |
| 311 | 313 | ||
| 314 | gtm1: timer@500 { | ||
| 315 | compatible = "fsl,mpc8315-gtm", "fsl,gtm"; | ||
| 316 | reg = <0x500 0x100>; | ||
| 317 | interrupts = <90 8 78 8 84 8 72 8>; | ||
| 318 | interrupt-parent = <&ipic>; | ||
| 319 | clock-frequency = <133333333>; | ||
| 320 | }; | ||
| 321 | |||
| 322 | timer@600 { | ||
| 323 | compatible = "fsl,mpc8315-gtm", "fsl,gtm"; | ||
| 324 | reg = <0x600 0x100>; | ||
| 325 | interrupts = <91 8 79 8 85 8 73 8>; | ||
| 326 | interrupt-parent = <&ipic>; | ||
| 327 | clock-frequency = <133333333>; | ||
| 328 | }; | ||
| 329 | |||
| 312 | /* IPIC | 330 | /* IPIC |
| 313 | * interrupts cell = <intr #, sense> | 331 | * interrupts cell = <intr #, sense> |
| 314 | * sense values match linux IORESOURCE_IRQ_* defines: | 332 | * sense values match linux IORESOURCE_IRQ_* defines: |
| @@ -337,6 +355,15 @@ | |||
| 337 | 0x59 0x8>; | 355 | 0x59 0x8>; |
| 338 | interrupt-parent = < &ipic >; | 356 | interrupt-parent = < &ipic >; |
| 339 | }; | 357 | }; |
| 358 | |||
| 359 | pmc: power@b00 { | ||
| 360 | compatible = "fsl,mpc8315-pmc", "fsl,mpc8313-pmc", | ||
| 361 | "fsl,mpc8349-pmc"; | ||
| 362 | reg = <0xb00 0x100 0xa00 0x100>; | ||
| 363 | interrupts = <80 8>; | ||
| 364 | interrupt-parent = <&ipic>; | ||
| 365 | fsl,mpc8313-wakeup-timer = <>m1>; | ||
| 366 | }; | ||
| 340 | }; | 367 | }; |
| 341 | 368 | ||
| 342 | pci0: pci@e0008500 { | 369 | pci0: pci@e0008500 { |
diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index feeeb7f9d609..b53d1df11e2d 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts | |||
| @@ -63,6 +63,24 @@ | |||
| 63 | reg = <0x200 0x100>; | 63 | reg = <0x200 0x100>; |
| 64 | }; | 64 | }; |
| 65 | 65 | ||
| 66 | gpio1: gpio-controller@c00 { | ||
| 67 | #gpio-cells = <2>; | ||
| 68 | compatible = "fsl,mpc8349-gpio"; | ||
| 69 | reg = <0xc00 0x100>; | ||
| 70 | interrupts = <74 0x8>; | ||
| 71 | interrupt-parent = <&ipic>; | ||
| 72 | gpio-controller; | ||
| 73 | }; | ||
| 74 | |||
| 75 | gpio2: gpio-controller@d00 { | ||
| 76 | #gpio-cells = <2>; | ||
| 77 | compatible = "fsl,mpc8349-gpio"; | ||
| 78 | reg = <0xd00 0x100>; | ||
| 79 | interrupts = <75 0x8>; | ||
| 80 | interrupt-parent = <&ipic>; | ||
| 81 | gpio-controller; | ||
| 82 | }; | ||
| 83 | |||
| 66 | i2c@3000 { | 84 | i2c@3000 { |
| 67 | #address-cells = <1>; | 85 | #address-cells = <1>; |
| 68 | #size-cells = <0>; | 86 | #size-cells = <0>; |
| @@ -72,6 +90,12 @@ | |||
| 72 | interrupts = <14 0x8>; | 90 | interrupts = <14 0x8>; |
| 73 | interrupt-parent = <&ipic>; | 91 | interrupt-parent = <&ipic>; |
| 74 | dfsrr; | 92 | dfsrr; |
| 93 | |||
| 94 | eeprom: at24@50 { | ||
| 95 | compatible = "st-micro,24c256"; | ||
| 96 | reg = <0x50>; | ||
| 97 | }; | ||
| 98 | |||
| 75 | }; | 99 | }; |
| 76 | 100 | ||
| 77 | i2c@3100 { | 101 | i2c@3100 { |
| @@ -91,6 +115,25 @@ | |||
| 91 | interrupt-parent = <&ipic>; | 115 | interrupt-parent = <&ipic>; |
| 92 | }; | 116 | }; |
| 93 | 117 | ||
| 118 | pcf1: iexp@38 { | ||
| 119 | #gpio-cells = <2>; | ||
| 120 | compatible = "ti,pcf8574a"; | ||
| 121 | reg = <0x38>; | ||
| 122 | gpio-controller; | ||
| 123 | }; | ||
| 124 | |||
| 125 | pcf2: iexp@39 { | ||
| 126 | #gpio-cells = <2>; | ||
| 127 | compatible = "ti,pcf8574a"; | ||
| 128 | reg = <0x39>; | ||
| 129 | gpio-controller; | ||
| 130 | }; | ||
| 131 | |||
| 132 | spd: at24@51 { | ||
| 133 | compatible = "at24,spd"; | ||
| 134 | reg = <0x51>; | ||
| 135 | }; | ||
| 136 | |||
| 94 | mcu_pio: mcu@a { | 137 | mcu_pio: mcu@a { |
| 95 | #gpio-cells = <2>; | 138 | #gpio-cells = <2>; |
| 96 | compatible = "fsl,mc9s08qg8-mpc8349emitx", | 139 | compatible = "fsl,mc9s08qg8-mpc8349emitx", |
| @@ -275,6 +318,24 @@ | |||
| 275 | reg = <0x700 0x100>; | 318 | reg = <0x700 0x100>; |
| 276 | device_type = "ipic"; | 319 | device_type = "ipic"; |
| 277 | }; | 320 | }; |
| 321 | |||
| 322 | gpio-leds { | ||
| 323 | compatible = "gpio-leds"; | ||
| 324 | |||
| 325 | green { | ||
| 326 | label = "Green"; | ||
| 327 | gpios = <&pcf1 0 1>; | ||
| 328 | linux,default-trigger = "heartbeat"; | ||
| 329 | }; | ||
| 330 | |||
| 331 | yellow { | ||
| 332 | label = "Yellow"; | ||
| 333 | gpios = <&pcf1 1 1>; | ||
| 334 | /* linux,default-trigger = "heartbeat"; */ | ||
| 335 | default-state = "on"; | ||
| 336 | }; | ||
| 337 | }; | ||
| 338 | |||
| 278 | }; | 339 | }; |
| 279 | 340 | ||
| 280 | pci0: pci@e0008500 { | 341 | pci0: pci@e0008500 { |
| @@ -331,7 +392,26 @@ | |||
| 331 | compatible = "fsl,mpc8349e-localbus", | 392 | compatible = "fsl,mpc8349e-localbus", |
| 332 | "fsl,pq2pro-localbus"; | 393 | "fsl,pq2pro-localbus"; |
| 333 | reg = <0xe0005000 0xd8>; | 394 | reg = <0xe0005000 0xd8>; |
| 334 | ranges = <0x3 0x0 0xf0000000 0x210>; | 395 | ranges = <0x0 0x0 0xfe000000 0x1000000 /* flash */ |
| 396 | 0x1 0x0 0xf8000000 0x20000 /* VSC 7385 */ | ||
| 397 | 0x2 0x0 0xf9000000 0x200000 /* exp slot */ | ||
| 398 | 0x3 0x0 0xf0000000 0x210>; /* CF slot */ | ||
| 399 | |||
| 400 | flash@0,0 { | ||
| 401 | compatible = "cfi-flash"; | ||
| 402 | reg = <0x0 0x0 0x800000>; | ||
| 403 | bank-width = <2>; | ||
| 404 | device-width = <1>; | ||
| 405 | }; | ||
| 406 | |||
| 407 | flash@0,800000 { | ||
| 408 | #address-cells = <1>; | ||
| 409 | #size-cells = <1>; | ||
| 410 | compatible = "cfi-flash"; | ||
| 411 | reg = <0x0 0x800000 0x800000>; | ||
| 412 | bank-width = <2>; | ||
| 413 | device-width = <1>; | ||
| 414 | }; | ||
| 335 | 415 | ||
| 336 | pata@3,0 { | 416 | pata@3,0 { |
| 337 | compatible = "fsl,mpc8349emitx-pata", "ata-generic"; | 417 | compatible = "fsl,mpc8349emitx-pata", "ata-generic"; |
diff --git a/arch/powerpc/boot/dts/warp.dts b/arch/powerpc/boot/dts/warp.dts index 31605ee4afb6..e576ee85c42f 100644 --- a/arch/powerpc/boot/dts/warp.dts +++ b/arch/powerpc/boot/dts/warp.dts | |||
| @@ -146,7 +146,7 @@ | |||
| 146 | 146 | ||
| 147 | fpga@2,4000 { | 147 | fpga@2,4000 { |
| 148 | compatible = "pika,fpga-sd"; | 148 | compatible = "pika,fpga-sd"; |
| 149 | reg = <0x00000002 0x00004000 0x00000A00>; | 149 | reg = <0x00000002 0x00004000 0x00004000>; |
| 150 | }; | 150 | }; |
| 151 | 151 | ||
| 152 | nor@0,0 { | 152 | nor@0,0 { |
diff --git a/arch/powerpc/boot/ugecon.c b/arch/powerpc/boot/ugecon.c index 50609ea6ddf8..8f2a6b311534 100644 --- a/arch/powerpc/boot/ugecon.c +++ b/arch/powerpc/boot/ugecon.c | |||
| @@ -86,7 +86,7 @@ static void ug_putc(char ch) | |||
| 86 | 86 | ||
| 87 | while (!ug_is_txfifo_ready() && count--) | 87 | while (!ug_is_txfifo_ready() && count--) |
| 88 | barrier(); | 88 | barrier(); |
| 89 | if (count) | 89 | if (count >= 0) |
| 90 | ug_raw_putc(ch); | 90 | ug_raw_putc(ch); |
| 91 | } | 91 | } |
| 92 | 92 | ||
diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig index fc905924c022..826a65d3f002 100644 --- a/arch/powerpc/configs/g5_defconfig +++ b/arch/powerpc/configs/g5_defconfig | |||
| @@ -757,7 +757,7 @@ CONFIG_SUNGEM=y | |||
| 757 | # CONFIG_B44 is not set | 757 | # CONFIG_B44 is not set |
| 758 | # CONFIG_ATL2 is not set | 758 | # CONFIG_ATL2 is not set |
| 759 | CONFIG_NETDEV_1000=y | 759 | CONFIG_NETDEV_1000=y |
| 760 | CONFIG_ACENIC=y | 760 | CONFIG_ACENIC=m |
| 761 | CONFIG_ACENIC_OMIT_TIGON_I=y | 761 | CONFIG_ACENIC_OMIT_TIGON_I=y |
| 762 | # CONFIG_DL2K is not set | 762 | # CONFIG_DL2K is not set |
| 763 | CONFIG_E1000=y | 763 | CONFIG_E1000=y |
| @@ -794,8 +794,8 @@ CONFIG_NETDEV_10000=y | |||
| 794 | # CONFIG_BNX2X is not set | 794 | # CONFIG_BNX2X is not set |
| 795 | # CONFIG_QLGE is not set | 795 | # CONFIG_QLGE is not set |
| 796 | # CONFIG_SFC is not set | 796 | # CONFIG_SFC is not set |
| 797 | CONFIG_TR=y | 797 | # CONFIG_TR is not set |
| 798 | CONFIG_IBMOL=y | 798 | # CONFIG_IBMOL is not set |
| 799 | # CONFIG_3C359 is not set | 799 | # CONFIG_3C359 is not set |
| 800 | # CONFIG_TMS380TR is not set | 800 | # CONFIG_TMS380TR is not set |
| 801 | 801 | ||
diff --git a/arch/powerpc/configs/iseries_defconfig b/arch/powerpc/configs/iseries_defconfig index f925c555508e..76982c51a4c7 100644 --- a/arch/powerpc/configs/iseries_defconfig +++ b/arch/powerpc/configs/iseries_defconfig | |||
| @@ -714,8 +714,8 @@ CONFIG_NETDEV_10000=y | |||
| 714 | # CONFIG_BNX2X is not set | 714 | # CONFIG_BNX2X is not set |
| 715 | # CONFIG_QLGE is not set | 715 | # CONFIG_QLGE is not set |
| 716 | # CONFIG_SFC is not set | 716 | # CONFIG_SFC is not set |
| 717 | CONFIG_TR=y | 717 | # CONFIG_TR is not set |
| 718 | CONFIG_IBMOL=y | 718 | # CONFIG_IBMOL is not set |
| 719 | # CONFIG_3C359 is not set | 719 | # CONFIG_3C359 is not set |
| 720 | # CONFIG_TMS380TR is not set | 720 | # CONFIG_TMS380TR is not set |
| 721 | 721 | ||
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index 252401824575..7b3804a6e363 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig | |||
| @@ -304,11 +304,11 @@ CONFIG_TICK_ONESHOT=y | |||
| 304 | CONFIG_NO_HZ=y | 304 | CONFIG_NO_HZ=y |
| 305 | CONFIG_HIGH_RES_TIMERS=y | 305 | CONFIG_HIGH_RES_TIMERS=y |
| 306 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y | 306 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y |
| 307 | # CONFIG_HZ_100 is not set | 307 | CONFIG_HZ_100=y |
| 308 | CONFIG_HZ_250=y | 308 | # CONFIG_HZ_250 is not set |
| 309 | # CONFIG_HZ_300 is not set | 309 | # CONFIG_HZ_300 is not set |
| 310 | # CONFIG_HZ_1000 is not set | 310 | # CONFIG_HZ_1000 is not set |
| 311 | CONFIG_HZ=250 | 311 | CONFIG_HZ=100 |
| 312 | CONFIG_SCHED_HRTICK=y | 312 | CONFIG_SCHED_HRTICK=y |
| 313 | CONFIG_PREEMPT_NONE=y | 313 | CONFIG_PREEMPT_NONE=y |
| 314 | # CONFIG_PREEMPT_VOLUNTARY is not set | 314 | # CONFIG_PREEMPT_VOLUNTARY is not set |
| @@ -980,7 +980,7 @@ CONFIG_E100=y | |||
| 980 | # CONFIG_SC92031 is not set | 980 | # CONFIG_SC92031 is not set |
| 981 | # CONFIG_ATL2 is not set | 981 | # CONFIG_ATL2 is not set |
| 982 | CONFIG_NETDEV_1000=y | 982 | CONFIG_NETDEV_1000=y |
| 983 | CONFIG_ACENIC=y | 983 | CONFIG_ACENIC=m |
| 984 | CONFIG_ACENIC_OMIT_TIGON_I=y | 984 | CONFIG_ACENIC_OMIT_TIGON_I=y |
| 985 | # CONFIG_DL2K is not set | 985 | # CONFIG_DL2K is not set |
| 986 | CONFIG_E1000=y | 986 | CONFIG_E1000=y |
| @@ -1023,8 +1023,8 @@ CONFIG_PASEMI_MAC=y | |||
| 1023 | # CONFIG_BNX2X is not set | 1023 | # CONFIG_BNX2X is not set |
| 1024 | # CONFIG_QLGE is not set | 1024 | # CONFIG_QLGE is not set |
| 1025 | # CONFIG_SFC is not set | 1025 | # CONFIG_SFC is not set |
| 1026 | CONFIG_TR=y | 1026 | # CONFIG_TR is not set |
| 1027 | CONFIG_IBMOL=y | 1027 | # CONFIG_IBMOL is not set |
| 1028 | # CONFIG_3C359 is not set | 1028 | # CONFIG_3C359 is not set |
| 1029 | # CONFIG_TMS380TR is not set | 1029 | # CONFIG_TMS380TR is not set |
| 1030 | 1030 | ||
| @@ -1863,7 +1863,7 @@ CONFIG_HFSPLUS_FS=m | |||
| 1863 | # CONFIG_BEFS_FS is not set | 1863 | # CONFIG_BEFS_FS is not set |
| 1864 | # CONFIG_BFS_FS is not set | 1864 | # CONFIG_BFS_FS is not set |
| 1865 | # CONFIG_EFS_FS is not set | 1865 | # CONFIG_EFS_FS is not set |
| 1866 | CONFIG_CRAMFS=y | 1866 | CONFIG_CRAMFS=m |
| 1867 | # CONFIG_VXFS_FS is not set | 1867 | # CONFIG_VXFS_FS is not set |
| 1868 | # CONFIG_MINIX_FS is not set | 1868 | # CONFIG_MINIX_FS is not set |
| 1869 | # CONFIG_OMFS_FS is not set | 1869 | # CONFIG_OMFS_FS is not set |
diff --git a/arch/powerpc/configs/ppc64e_defconfig b/arch/powerpc/configs/ppc64e_defconfig index 18af46036258..8195f1650cbf 100644 --- a/arch/powerpc/configs/ppc64e_defconfig +++ b/arch/powerpc/configs/ppc64e_defconfig | |||
| @@ -1008,8 +1008,8 @@ CONFIG_IXGB=m | |||
| 1008 | # CONFIG_QLGE is not set | 1008 | # CONFIG_QLGE is not set |
| 1009 | # CONFIG_SFC is not set | 1009 | # CONFIG_SFC is not set |
| 1010 | # CONFIG_BE2NET is not set | 1010 | # CONFIG_BE2NET is not set |
| 1011 | CONFIG_TR=y | 1011 | # CONFIG_TR is not set |
| 1012 | CONFIG_IBMOL=y | 1012 | # CONFIG_IBMOL is not set |
| 1013 | # CONFIG_3C359 is not set | 1013 | # CONFIG_3C359 is not set |
| 1014 | # CONFIG_TMS380TR is not set | 1014 | # CONFIG_TMS380TR is not set |
| 1015 | CONFIG_WLAN=y | 1015 | CONFIG_WLAN=y |
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index c568329723b8..ca9ff9aad74a 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig | |||
| @@ -230,11 +230,11 @@ CONFIG_TICK_ONESHOT=y | |||
| 230 | CONFIG_NO_HZ=y | 230 | CONFIG_NO_HZ=y |
| 231 | CONFIG_HIGH_RES_TIMERS=y | 231 | CONFIG_HIGH_RES_TIMERS=y |
| 232 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y | 232 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y |
| 233 | # CONFIG_HZ_100 is not set | 233 | CONFIG_HZ_100=y |
| 234 | CONFIG_HZ_250=y | 234 | # CONFIG_HZ_250 is not set |
| 235 | # CONFIG_HZ_300 is not set | 235 | # CONFIG_HZ_300 is not set |
| 236 | # CONFIG_HZ_1000 is not set | 236 | # CONFIG_HZ_1000 is not set |
| 237 | CONFIG_HZ=250 | 237 | CONFIG_HZ=100 |
| 238 | CONFIG_SCHED_HRTICK=y | 238 | CONFIG_SCHED_HRTICK=y |
| 239 | CONFIG_PREEMPT_NONE=y | 239 | CONFIG_PREEMPT_NONE=y |
| 240 | # CONFIG_PREEMPT_VOLUNTARY is not set | 240 | # CONFIG_PREEMPT_VOLUNTARY is not set |
| @@ -796,7 +796,7 @@ CONFIG_E100=y | |||
| 796 | # CONFIG_NET_POCKET is not set | 796 | # CONFIG_NET_POCKET is not set |
| 797 | # CONFIG_ATL2 is not set | 797 | # CONFIG_ATL2 is not set |
| 798 | CONFIG_NETDEV_1000=y | 798 | CONFIG_NETDEV_1000=y |
| 799 | CONFIG_ACENIC=y | 799 | CONFIG_ACENIC=m |
| 800 | CONFIG_ACENIC_OMIT_TIGON_I=y | 800 | CONFIG_ACENIC_OMIT_TIGON_I=y |
| 801 | # CONFIG_DL2K is not set | 801 | # CONFIG_DL2K is not set |
| 802 | CONFIG_E1000=y | 802 | CONFIG_E1000=y |
| @@ -834,8 +834,8 @@ CONFIG_S2IO=m | |||
| 834 | # CONFIG_BNX2X is not set | 834 | # CONFIG_BNX2X is not set |
| 835 | # CONFIG_QLGE is not set | 835 | # CONFIG_QLGE is not set |
| 836 | # CONFIG_SFC is not set | 836 | # CONFIG_SFC is not set |
| 837 | CONFIG_TR=y | 837 | # CONFIG_TR is not set |
| 838 | CONFIG_IBMOL=y | 838 | # CONFIG_IBMOL is not set |
| 839 | # CONFIG_3C359 is not set | 839 | # CONFIG_3C359 is not set |
| 840 | # CONFIG_TMS380TR is not set | 840 | # CONFIG_TMS380TR is not set |
| 841 | 841 | ||
| @@ -1494,7 +1494,7 @@ CONFIG_CONFIGFS_FS=m | |||
| 1494 | # CONFIG_BEFS_FS is not set | 1494 | # CONFIG_BEFS_FS is not set |
| 1495 | # CONFIG_BFS_FS is not set | 1495 | # CONFIG_BFS_FS is not set |
| 1496 | # CONFIG_EFS_FS is not set | 1496 | # CONFIG_EFS_FS is not set |
| 1497 | CONFIG_CRAMFS=y | 1497 | CONFIG_CRAMFS=m |
| 1498 | # CONFIG_VXFS_FS is not set | 1498 | # CONFIG_VXFS_FS is not set |
| 1499 | # CONFIG_MINIX_FS is not set | 1499 | # CONFIG_MINIX_FS is not set |
| 1500 | # CONFIG_OMFS_FS is not set | 1500 | # CONFIG_OMFS_FS is not set |
diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h index 64e1fdca233e..2c15212e1700 100644 --- a/arch/powerpc/include/asm/bug.h +++ b/arch/powerpc/include/asm/bug.h | |||
| @@ -68,7 +68,7 @@ | |||
| 68 | _EMIT_BUG_ENTRY \ | 68 | _EMIT_BUG_ENTRY \ |
| 69 | : : "i" (__FILE__), "i" (__LINE__), \ | 69 | : : "i" (__FILE__), "i" (__LINE__), \ |
| 70 | "i" (0), "i" (sizeof(struct bug_entry))); \ | 70 | "i" (0), "i" (sizeof(struct bug_entry))); \ |
| 71 | for(;;) ; \ | 71 | unreachable(); \ |
| 72 | } while (0) | 72 | } while (0) |
| 73 | 73 | ||
| 74 | #define BUG_ON(x) do { \ | 74 | #define BUG_ON(x) do { \ |
diff --git a/arch/powerpc/include/asm/gpio.h b/arch/powerpc/include/asm/gpio.h index ea04632399d8..38762edb5e58 100644 --- a/arch/powerpc/include/asm/gpio.h +++ b/arch/powerpc/include/asm/gpio.h | |||
| @@ -38,12 +38,9 @@ static inline int gpio_cansleep(unsigned int gpio) | |||
| 38 | return __gpio_cansleep(gpio); | 38 | return __gpio_cansleep(gpio); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | /* | ||
| 42 | * Not implemented, yet. | ||
| 43 | */ | ||
| 44 | static inline int gpio_to_irq(unsigned int gpio) | 41 | static inline int gpio_to_irq(unsigned int gpio) |
| 45 | { | 42 | { |
| 46 | return -ENOSYS; | 43 | return __gpio_to_irq(gpio); |
| 47 | } | 44 | } |
| 48 | 45 | ||
| 49 | static inline int irq_to_gpio(unsigned int irq) | 46 | static inline int irq_to_gpio(unsigned int irq) |
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index 3839839f83c7..b876e989220b 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c | |||
| @@ -642,10 +642,14 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg, | |||
| 642 | */ | 642 | */ |
| 643 | static int emulate_vsx(unsigned char __user *addr, unsigned int reg, | 643 | static int emulate_vsx(unsigned char __user *addr, unsigned int reg, |
| 644 | unsigned int areg, struct pt_regs *regs, | 644 | unsigned int areg, struct pt_regs *regs, |
| 645 | unsigned int flags, unsigned int length) | 645 | unsigned int flags, unsigned int length, |
| 646 | unsigned int elsize) | ||
| 646 | { | 647 | { |
| 647 | char *ptr; | 648 | char *ptr; |
| 649 | unsigned long *lptr; | ||
| 648 | int ret = 0; | 650 | int ret = 0; |
| 651 | int sw = 0; | ||
| 652 | int i, j; | ||
| 649 | 653 | ||
| 650 | flush_vsx_to_thread(current); | 654 | flush_vsx_to_thread(current); |
| 651 | 655 | ||
| @@ -654,19 +658,35 @@ static int emulate_vsx(unsigned char __user *addr, unsigned int reg, | |||
| 654 | else | 658 | else |
| 655 | ptr = (char *) ¤t->thread.vr[reg - 32]; | 659 | ptr = (char *) ¤t->thread.vr[reg - 32]; |
| 656 | 660 | ||
| 657 | if (flags & ST) | 661 | lptr = (unsigned long *) ptr; |
| 658 | ret = __copy_to_user(addr, ptr, length); | 662 | |
| 659 | else { | 663 | if (flags & SW) |
| 660 | if (flags & SPLT){ | 664 | sw = elsize-1; |
| 661 | ret = __copy_from_user(ptr, addr, length); | 665 | |
| 662 | ptr += length; | 666 | for (j = 0; j < length; j += elsize) { |
| 667 | for (i = 0; i < elsize; ++i) { | ||
| 668 | if (flags & ST) | ||
| 669 | ret |= __put_user(ptr[i^sw], addr + i); | ||
| 670 | else | ||
| 671 | ret |= __get_user(ptr[i^sw], addr + i); | ||
| 663 | } | 672 | } |
| 664 | ret |= __copy_from_user(ptr, addr, length); | 673 | ptr += elsize; |
| 674 | addr += elsize; | ||
| 665 | } | 675 | } |
| 666 | if (flags & U) | 676 | |
| 667 | regs->gpr[areg] = regs->dar; | 677 | if (!ret) { |
| 668 | if (ret) | 678 | if (flags & U) |
| 679 | regs->gpr[areg] = regs->dar; | ||
| 680 | |||
| 681 | /* Splat load copies the same data to top and bottom 8 bytes */ | ||
| 682 | if (flags & SPLT) | ||
| 683 | lptr[1] = lptr[0]; | ||
| 684 | /* For 8 byte loads, zero the top 8 bytes */ | ||
| 685 | else if (!(flags & ST) && (8 == length)) | ||
| 686 | lptr[1] = 0; | ||
| 687 | } else | ||
| 669 | return -EFAULT; | 688 | return -EFAULT; |
| 689 | |||
| 670 | return 1; | 690 | return 1; |
| 671 | } | 691 | } |
| 672 | #endif | 692 | #endif |
| @@ -767,16 +787,25 @@ int fix_alignment(struct pt_regs *regs) | |||
| 767 | 787 | ||
| 768 | #ifdef CONFIG_VSX | 788 | #ifdef CONFIG_VSX |
| 769 | if ((instruction & 0xfc00003e) == 0x7c000018) { | 789 | if ((instruction & 0xfc00003e) == 0x7c000018) { |
| 770 | /* Additional register addressing bit (64 VSX vs 32 FPR/GPR */ | 790 | unsigned int elsize; |
| 791 | |||
| 792 | /* Additional register addressing bit (64 VSX vs 32 FPR/GPR) */ | ||
| 771 | reg |= (instruction & 0x1) << 5; | 793 | reg |= (instruction & 0x1) << 5; |
| 772 | /* Simple inline decoder instead of a table */ | 794 | /* Simple inline decoder instead of a table */ |
| 795 | /* VSX has only 8 and 16 byte memory accesses */ | ||
| 796 | nb = 8; | ||
| 773 | if (instruction & 0x200) | 797 | if (instruction & 0x200) |
| 774 | nb = 16; | 798 | nb = 16; |
| 775 | else if (instruction & 0x080) | 799 | |
| 776 | nb = 8; | 800 | /* Vector stores in little-endian mode swap individual |
| 777 | else | 801 | elements, so process them separately */ |
| 778 | nb = 4; | 802 | elsize = 4; |
| 803 | if (instruction & 0x80) | ||
| 804 | elsize = 8; | ||
| 805 | |||
| 779 | flags = 0; | 806 | flags = 0; |
| 807 | if (regs->msr & MSR_LE) | ||
| 808 | flags |= SW; | ||
| 780 | if (instruction & 0x100) | 809 | if (instruction & 0x100) |
| 781 | flags |= ST; | 810 | flags |= ST; |
| 782 | if (instruction & 0x040) | 811 | if (instruction & 0x040) |
| @@ -787,7 +816,7 @@ int fix_alignment(struct pt_regs *regs) | |||
| 787 | nb = 8; | 816 | nb = 8; |
| 788 | } | 817 | } |
| 789 | PPC_WARN_ALIGNMENT(vsx, regs); | 818 | PPC_WARN_ALIGNMENT(vsx, regs); |
| 790 | return emulate_vsx(addr, reg, areg, regs, flags, nb); | 819 | return emulate_vsx(addr, reg, areg, regs, flags, nb, elsize); |
| 791 | } | 820 | } |
| 792 | #endif | 821 | #endif |
| 793 | /* A size of 0 indicates an instruction we don't support, with | 822 | /* A size of 0 indicates an instruction we don't support, with |
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 50f867d657df..3ecdcec0a39e 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
| @@ -340,7 +340,7 @@ static int __init htab_dt_scan_page_sizes(unsigned long node, | |||
| 340 | else | 340 | else |
| 341 | def->tlbiel = 0; | 341 | def->tlbiel = 0; |
| 342 | 342 | ||
| 343 | DBG(" %d: shift=%02x, sllp=%04x, avpnm=%08x, " | 343 | DBG(" %d: shift=%02x, sllp=%04lx, avpnm=%08lx, " |
| 344 | "tlbiel=%d, penc=%d\n", | 344 | "tlbiel=%d, penc=%d\n", |
| 345 | idx, shift, def->sllp, def->avpnm, def->tlbiel, | 345 | idx, shift, def->sllp, def->avpnm, def->tlbiel, |
| 346 | def->penc); | 346 | def->penc); |
| @@ -663,7 +663,7 @@ static void __init htab_initialize(void) | |||
| 663 | base = (unsigned long)__va(lmb.memory.region[i].base); | 663 | base = (unsigned long)__va(lmb.memory.region[i].base); |
| 664 | size = lmb.memory.region[i].size; | 664 | size = lmb.memory.region[i].size; |
| 665 | 665 | ||
| 666 | DBG("creating mapping for region: %lx..%lx (prot: %x)\n", | 666 | DBG("creating mapping for region: %lx..%lx (prot: %lx)\n", |
| 667 | base, size, prot); | 667 | base, size, prot); |
| 668 | 668 | ||
| 669 | #ifdef CONFIG_U3_DART | 669 | #ifdef CONFIG_U3_DART |
| @@ -879,7 +879,7 @@ static inline int subpage_protection(struct mm_struct *mm, unsigned long ea) | |||
| 879 | */ | 879 | */ |
| 880 | int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | 880 | int hash_page(unsigned long ea, unsigned long access, unsigned long trap) |
| 881 | { | 881 | { |
| 882 | void *pgdir; | 882 | pgd_t *pgdir; |
| 883 | unsigned long vsid; | 883 | unsigned long vsid; |
| 884 | struct mm_struct *mm; | 884 | struct mm_struct *mm; |
| 885 | pte_t *ptep; | 885 | pte_t *ptep; |
| @@ -1025,7 +1025,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
| 1025 | else | 1025 | else |
| 1026 | #endif /* CONFIG_PPC_HAS_HASH_64K */ | 1026 | #endif /* CONFIG_PPC_HAS_HASH_64K */ |
| 1027 | { | 1027 | { |
| 1028 | int spp = subpage_protection(pgdir, ea); | 1028 | int spp = subpage_protection(mm, ea); |
| 1029 | if (access & spp) | 1029 | if (access & spp) |
| 1030 | rc = -2; | 1030 | rc = -2; |
| 1031 | else | 1031 | else |
| @@ -1115,7 +1115,7 @@ void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int ssize, | |||
| 1115 | { | 1115 | { |
| 1116 | unsigned long hash, index, shift, hidx, slot; | 1116 | unsigned long hash, index, shift, hidx, slot; |
| 1117 | 1117 | ||
| 1118 | DBG_LOW("flush_hash_page(va=%016x)\n", va); | 1118 | DBG_LOW("flush_hash_page(va=%016lx)\n", va); |
| 1119 | pte_iterate_hashed_subpages(pte, psize, va, index, shift) { | 1119 | pte_iterate_hashed_subpages(pte, psize, va, index, shift) { |
| 1120 | hash = hpt_hash(va, shift, ssize); | 1120 | hash = hpt_hash(va, shift, ssize); |
| 1121 | hidx = __rpte_to_hidx(pte, index); | 1121 | hidx = __rpte_to_hidx(pte, index); |
| @@ -1123,7 +1123,7 @@ void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int ssize, | |||
| 1123 | hash = ~hash; | 1123 | hash = ~hash; |
| 1124 | slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; | 1124 | slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; |
| 1125 | slot += hidx & _PTEIDX_GROUP_IX; | 1125 | slot += hidx & _PTEIDX_GROUP_IX; |
| 1126 | DBG_LOW(" sub %d: hash=%x, hidx=%x\n", index, slot, hidx); | 1126 | DBG_LOW(" sub %ld: hash=%lx, hidx=%lx\n", index, slot, hidx); |
| 1127 | ppc_md.hpte_invalidate(slot, va, psize, ssize, local); | 1127 | ppc_md.hpte_invalidate(slot, va, psize, ssize, local); |
| 1128 | } pte_iterate_hashed_end(); | 1128 | } pte_iterate_hashed_end(); |
| 1129 | } | 1129 | } |
diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c index be4f34c30a0b..1044a634b6d0 100644 --- a/arch/powerpc/mm/mmu_context_nohash.c +++ b/arch/powerpc/mm/mmu_context_nohash.c | |||
| @@ -353,7 +353,7 @@ static int __cpuinit mmu_context_cpu_notify(struct notifier_block *self, | |||
| 353 | read_lock(&tasklist_lock); | 353 | read_lock(&tasklist_lock); |
| 354 | for_each_process(p) { | 354 | for_each_process(p) { |
| 355 | if (p->mm) | 355 | if (p->mm) |
| 356 | cpu_mask_clear_cpu(cpu, mm_cpumask(p->mm)); | 356 | cpumask_clear_cpu(cpu, mm_cpumask(p->mm)); |
| 357 | } | 357 | } |
| 358 | read_unlock(&tasklist_lock); | 358 | read_unlock(&tasklist_lock); |
| 359 | break; | 359 | break; |
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 177e4038b43c..573b3bd1c45b 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c | |||
| @@ -382,7 +382,7 @@ static int __change_page_attr(struct page *page, pgprot_t prot) | |||
| 382 | return 0; | 382 | return 0; |
| 383 | if (!get_pteptr(&init_mm, address, &kpte, &kpmd)) | 383 | if (!get_pteptr(&init_mm, address, &kpte, &kpmd)) |
| 384 | return -EINVAL; | 384 | return -EINVAL; |
| 385 | set_pte_at(&init_mm, address, kpte, mk_pte(page, prot)); | 385 | __set_pte_at(&init_mm, address, kpte, mk_pte(page, prot), 0); |
| 386 | wmb(); | 386 | wmb(); |
| 387 | #ifdef CONFIG_PPC_STD_MMU | 387 | #ifdef CONFIG_PPC_STD_MMU |
| 388 | flush_hash_pages(0, address, pmd_val(*kpmd), 1); | 388 | flush_hash_pages(0, address, pmd_val(*kpmd), 1); |
diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index d306f07b9aa1..43805348b81e 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #define PMCCR1_NEXT_STATE 0x0C /* Next state for power management */ | 32 | #define PMCCR1_NEXT_STATE 0x0C /* Next state for power management */ |
| 33 | #define PMCCR1_NEXT_STATE_SHIFT 2 | 33 | #define PMCCR1_NEXT_STATE_SHIFT 2 |
| 34 | #define PMCCR1_CURR_STATE 0x03 /* Current state for power management*/ | 34 | #define PMCCR1_CURR_STATE 0x03 /* Current state for power management*/ |
| 35 | #define IMMR_SYSCR_OFFSET 0x100 | ||
| 35 | #define IMMR_RCW_OFFSET 0x900 | 36 | #define IMMR_RCW_OFFSET 0x900 |
| 36 | #define RCW_PCI_HOST 0x80000000 | 37 | #define RCW_PCI_HOST 0x80000000 |
| 37 | 38 | ||
| @@ -78,6 +79,22 @@ struct mpc83xx_clock { | |||
| 78 | u32 sccr; | 79 | u32 sccr; |
| 79 | }; | 80 | }; |
| 80 | 81 | ||
| 82 | struct mpc83xx_syscr { | ||
| 83 | __be32 sgprl; | ||
| 84 | __be32 sgprh; | ||
| 85 | __be32 spridr; | ||
| 86 | __be32 :32; | ||
| 87 | __be32 spcr; | ||
| 88 | __be32 sicrl; | ||
| 89 | __be32 sicrh; | ||
| 90 | }; | ||
| 91 | |||
| 92 | struct mpc83xx_saved { | ||
| 93 | u32 sicrl; | ||
| 94 | u32 sicrh; | ||
| 95 | u32 sccr; | ||
| 96 | }; | ||
| 97 | |||
| 81 | struct pmc_type { | 98 | struct pmc_type { |
| 82 | int has_deep_sleep; | 99 | int has_deep_sleep; |
| 83 | }; | 100 | }; |
| @@ -87,6 +104,8 @@ static int has_deep_sleep, deep_sleeping; | |||
| 87 | static int pmc_irq; | 104 | static int pmc_irq; |
| 88 | static struct mpc83xx_pmc __iomem *pmc_regs; | 105 | static struct mpc83xx_pmc __iomem *pmc_regs; |
| 89 | static struct mpc83xx_clock __iomem *clock_regs; | 106 | static struct mpc83xx_clock __iomem *clock_regs; |
| 107 | static struct mpc83xx_syscr __iomem *syscr_regs; | ||
| 108 | static struct mpc83xx_saved saved_regs; | ||
| 90 | static int is_pci_agent, wake_from_pci; | 109 | static int is_pci_agent, wake_from_pci; |
| 91 | static phys_addr_t immrbase; | 110 | static phys_addr_t immrbase; |
| 92 | static int pci_pm_state; | 111 | static int pci_pm_state; |
| @@ -137,6 +156,20 @@ static irqreturn_t pmc_irq_handler(int irq, void *dev_id) | |||
| 137 | return ret; | 156 | return ret; |
| 138 | } | 157 | } |
| 139 | 158 | ||
| 159 | static void mpc83xx_suspend_restore_regs(void) | ||
| 160 | { | ||
| 161 | out_be32(&syscr_regs->sicrl, saved_regs.sicrl); | ||
| 162 | out_be32(&syscr_regs->sicrh, saved_regs.sicrh); | ||
| 163 | out_be32(&clock_regs->sccr, saved_regs.sccr); | ||
| 164 | } | ||
| 165 | |||
| 166 | static void mpc83xx_suspend_save_regs(void) | ||
| 167 | { | ||
| 168 | saved_regs.sicrl = in_be32(&syscr_regs->sicrl); | ||
| 169 | saved_regs.sicrh = in_be32(&syscr_regs->sicrh); | ||
| 170 | saved_regs.sccr = in_be32(&clock_regs->sccr); | ||
| 171 | } | ||
| 172 | |||
| 140 | static int mpc83xx_suspend_enter(suspend_state_t state) | 173 | static int mpc83xx_suspend_enter(suspend_state_t state) |
| 141 | { | 174 | { |
| 142 | int ret = -EAGAIN; | 175 | int ret = -EAGAIN; |
| @@ -166,6 +199,8 @@ static int mpc83xx_suspend_enter(suspend_state_t state) | |||
| 166 | */ | 199 | */ |
| 167 | 200 | ||
| 168 | if (deep_sleeping) { | 201 | if (deep_sleeping) { |
| 202 | mpc83xx_suspend_save_regs(); | ||
| 203 | |||
| 169 | out_be32(&pmc_regs->mask, PMCER_ALL); | 204 | out_be32(&pmc_regs->mask, PMCER_ALL); |
| 170 | 205 | ||
| 171 | out_be32(&pmc_regs->config1, | 206 | out_be32(&pmc_regs->config1, |
| @@ -179,6 +214,8 @@ static int mpc83xx_suspend_enter(suspend_state_t state) | |||
| 179 | in_be32(&pmc_regs->config1) & ~PMCCR1_POWER_OFF); | 214 | in_be32(&pmc_regs->config1) & ~PMCCR1_POWER_OFF); |
| 180 | 215 | ||
| 181 | out_be32(&pmc_regs->mask, PMCER_PMCI); | 216 | out_be32(&pmc_regs->mask, PMCER_PMCI); |
| 217 | |||
| 218 | mpc83xx_suspend_restore_regs(); | ||
| 182 | } else { | 219 | } else { |
| 183 | out_be32(&pmc_regs->mask, PMCER_PMCI); | 220 | out_be32(&pmc_regs->mask, PMCER_PMCI); |
| 184 | 221 | ||
| @@ -194,7 +231,7 @@ out: | |||
| 194 | return ret; | 231 | return ret; |
| 195 | } | 232 | } |
| 196 | 233 | ||
| 197 | static void mpc83xx_suspend_finish(void) | 234 | static void mpc83xx_suspend_end(void) |
| 198 | { | 235 | { |
| 199 | deep_sleeping = 0; | 236 | deep_sleeping = 0; |
| 200 | } | 237 | } |
| @@ -278,7 +315,7 @@ static struct platform_suspend_ops mpc83xx_suspend_ops = { | |||
| 278 | .valid = mpc83xx_suspend_valid, | 315 | .valid = mpc83xx_suspend_valid, |
| 279 | .begin = mpc83xx_suspend_begin, | 316 | .begin = mpc83xx_suspend_begin, |
| 280 | .enter = mpc83xx_suspend_enter, | 317 | .enter = mpc83xx_suspend_enter, |
| 281 | .finish = mpc83xx_suspend_finish, | 318 | .end = mpc83xx_suspend_end, |
| 282 | }; | 319 | }; |
| 283 | 320 | ||
| 284 | static int pmc_probe(struct of_device *ofdev, | 321 | static int pmc_probe(struct of_device *ofdev, |
| @@ -333,12 +370,23 @@ static int pmc_probe(struct of_device *ofdev, | |||
| 333 | goto out_pmc; | 370 | goto out_pmc; |
| 334 | } | 371 | } |
| 335 | 372 | ||
| 373 | if (has_deep_sleep) { | ||
| 374 | syscr_regs = ioremap(immrbase + IMMR_SYSCR_OFFSET, | ||
| 375 | sizeof(*syscr_regs)); | ||
| 376 | if (!syscr_regs) { | ||
| 377 | ret = -ENOMEM; | ||
| 378 | goto out_syscr; | ||
| 379 | } | ||
| 380 | } | ||
| 381 | |||
| 336 | if (is_pci_agent) | 382 | if (is_pci_agent) |
| 337 | mpc83xx_set_agent(); | 383 | mpc83xx_set_agent(); |
| 338 | 384 | ||
| 339 | suspend_set_ops(&mpc83xx_suspend_ops); | 385 | suspend_set_ops(&mpc83xx_suspend_ops); |
| 340 | return 0; | 386 | return 0; |
| 341 | 387 | ||
| 388 | out_syscr: | ||
| 389 | iounmap(clock_regs); | ||
| 342 | out_pmc: | 390 | out_pmc: |
| 343 | iounmap(pmc_regs); | 391 | iounmap(pmc_regs); |
| 344 | out: | 392 | out: |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index c5028a2e5a58..21f61b8c445b 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c | |||
| @@ -86,7 +86,7 @@ static int mpc8568_fixup_125_clock(struct phy_device *phydev) | |||
| 86 | scr = phy_read(phydev, MV88E1111_SCR); | 86 | scr = phy_read(phydev, MV88E1111_SCR); |
| 87 | 87 | ||
| 88 | if (scr < 0) | 88 | if (scr < 0) |
| 89 | return err; | 89 | return scr; |
| 90 | 90 | ||
| 91 | err = phy_write(phydev, MV88E1111_SCR, scr | 0x0008); | 91 | err = phy_write(phydev, MV88E1111_SCR, scr | 0x0008); |
| 92 | 92 | ||
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c index d5963285e3be..c278bd3a8fec 100644 --- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c +++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c | |||
| @@ -102,7 +102,7 @@ static int flipper_pic_map(struct irq_host *h, unsigned int virq, | |||
| 102 | irq_hw_number_t hwirq) | 102 | irq_hw_number_t hwirq) |
| 103 | { | 103 | { |
| 104 | set_irq_chip_data(virq, h->host_data); | 104 | set_irq_chip_data(virq, h->host_data); |
| 105 | get_irq_desc(virq)->status |= IRQ_LEVEL; | 105 | irq_to_desc(virq)->status |= IRQ_LEVEL; |
| 106 | set_irq_chip_and_handler(virq, &flipper_pic, handle_level_irq); | 106 | set_irq_chip_and_handler(virq, &flipper_pic, handle_level_irq); |
| 107 | return 0; | 107 | return 0; |
| 108 | } | 108 | } |
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c index dd20bff33207..a771f91e215b 100644 --- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c +++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c | |||
| @@ -95,7 +95,7 @@ static int hlwd_pic_map(struct irq_host *h, unsigned int virq, | |||
| 95 | irq_hw_number_t hwirq) | 95 | irq_hw_number_t hwirq) |
| 96 | { | 96 | { |
| 97 | set_irq_chip_data(virq, h->host_data); | 97 | set_irq_chip_data(virq, h->host_data); |
| 98 | get_irq_desc(virq)->status |= IRQ_LEVEL; | 98 | irq_to_desc(virq)->status |= IRQ_LEVEL; |
| 99 | set_irq_chip_and_handler(virq, &hlwd_pic, handle_level_irq); | 99 | set_irq_chip_and_handler(virq, &hlwd_pic, handle_level_irq); |
| 100 | return 0; | 100 | return 0; |
| 101 | } | 101 | } |
| @@ -132,9 +132,9 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq, | |||
| 132 | struct irq_host *irq_host = get_irq_data(cascade_virq); | 132 | struct irq_host *irq_host = get_irq_data(cascade_virq); |
| 133 | unsigned int virq; | 133 | unsigned int virq; |
| 134 | 134 | ||
| 135 | spin_lock(&desc->lock); | 135 | raw_spin_lock(&desc->lock); |
| 136 | desc->chip->mask(cascade_virq); /* IRQ_LEVEL */ | 136 | desc->chip->mask(cascade_virq); /* IRQ_LEVEL */ |
| 137 | spin_unlock(&desc->lock); | 137 | raw_spin_unlock(&desc->lock); |
| 138 | 138 | ||
| 139 | virq = __hlwd_pic_get_irq(irq_host); | 139 | virq = __hlwd_pic_get_irq(irq_host); |
| 140 | if (virq != NO_IRQ) | 140 | if (virq != NO_IRQ) |
| @@ -142,11 +142,11 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq, | |||
| 142 | else | 142 | else |
| 143 | pr_err("spurious interrupt!\n"); | 143 | pr_err("spurious interrupt!\n"); |
| 144 | 144 | ||
| 145 | spin_lock(&desc->lock); | 145 | raw_spin_lock(&desc->lock); |
| 146 | desc->chip->ack(cascade_virq); /* IRQ_LEVEL */ | 146 | desc->chip->ack(cascade_virq); /* IRQ_LEVEL */ |
| 147 | if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) | 147 | if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) |
| 148 | desc->chip->unmask(cascade_virq); | 148 | desc->chip->unmask(cascade_virq); |
| 149 | spin_unlock(&desc->lock); | 149 | raw_spin_unlock(&desc->lock); |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | /* | 152 | /* |
diff --git a/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c index edc956cc8b13..20a8ed91962e 100644 --- a/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c +++ b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c | |||
| @@ -120,7 +120,7 @@ static void ug_putc(char ch) | |||
| 120 | 120 | ||
| 121 | while (!ug_is_txfifo_ready() && count--) | 121 | while (!ug_is_txfifo_ready() && count--) |
| 122 | barrier(); | 122 | barrier(); |
| 123 | if (count) | 123 | if (count >= 0) |
| 124 | ug_raw_putc(ch); | 124 | ug_raw_putc(ch); |
| 125 | } | 125 | } |
| 126 | 126 | ||
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index 0d9343df35bc..6617915bcb1a 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c | |||
| @@ -855,59 +855,58 @@ static int mf_get_boot_rtc(struct rtc_time *tm) | |||
| 855 | } | 855 | } |
| 856 | 856 | ||
| 857 | #ifdef CONFIG_PROC_FS | 857 | #ifdef CONFIG_PROC_FS |
| 858 | 858 | static int mf_cmdline_proc_show(struct seq_file *m, void *v) | |
| 859 | static int proc_mf_dump_cmdline(char *page, char **start, off_t off, | ||
| 860 | int count, int *eof, void *data) | ||
| 861 | { | 859 | { |
| 862 | int len; | 860 | char *page, *p; |
| 863 | char *p; | ||
| 864 | struct vsp_cmd_data vsp_cmd; | 861 | struct vsp_cmd_data vsp_cmd; |
| 865 | int rc; | 862 | int rc; |
| 866 | dma_addr_t dma_addr; | 863 | dma_addr_t dma_addr; |
| 867 | 864 | ||
| 868 | /* The HV appears to return no more than 256 bytes of command line */ | 865 | /* The HV appears to return no more than 256 bytes of command line */ |
| 869 | if (off >= 256) | 866 | page = kmalloc(256, GFP_KERNEL); |
| 870 | return 0; | 867 | if (!page) |
| 871 | if ((off + count) > 256) | 868 | return -ENOMEM; |
| 872 | count = 256 - off; | ||
| 873 | 869 | ||
| 874 | dma_addr = iseries_hv_map(page, off + count, DMA_FROM_DEVICE); | 870 | dma_addr = iseries_hv_map(page, 256, DMA_FROM_DEVICE); |
| 875 | if (dma_addr == DMA_ERROR_CODE) | 871 | if (dma_addr == DMA_ERROR_CODE) { |
| 872 | kfree(page); | ||
| 876 | return -ENOMEM; | 873 | return -ENOMEM; |
| 877 | memset(page, 0, off + count); | 874 | } |
| 875 | memset(page, 0, 256); | ||
| 878 | memset(&vsp_cmd, 0, sizeof(vsp_cmd)); | 876 | memset(&vsp_cmd, 0, sizeof(vsp_cmd)); |
| 879 | vsp_cmd.cmd = 33; | 877 | vsp_cmd.cmd = 33; |
| 880 | vsp_cmd.sub_data.kern.token = dma_addr; | 878 | vsp_cmd.sub_data.kern.token = dma_addr; |
| 881 | vsp_cmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex; | 879 | vsp_cmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex; |
| 882 | vsp_cmd.sub_data.kern.side = (u64)data; | 880 | vsp_cmd.sub_data.kern.side = (u64)m->private; |
| 883 | vsp_cmd.sub_data.kern.length = off + count; | 881 | vsp_cmd.sub_data.kern.length = 256; |
| 884 | mb(); | 882 | mb(); |
| 885 | rc = signal_vsp_instruction(&vsp_cmd); | 883 | rc = signal_vsp_instruction(&vsp_cmd); |
| 886 | iseries_hv_unmap(dma_addr, off + count, DMA_FROM_DEVICE); | 884 | iseries_hv_unmap(dma_addr, 256, DMA_FROM_DEVICE); |
| 887 | if (rc) | 885 | if (rc) { |
| 886 | kfree(page); | ||
| 888 | return rc; | 887 | return rc; |
| 889 | if (vsp_cmd.result_code != 0) | 888 | } |
| 889 | if (vsp_cmd.result_code != 0) { | ||
| 890 | kfree(page); | ||
| 890 | return -ENOMEM; | 891 | return -ENOMEM; |
| 892 | } | ||
| 891 | p = page; | 893 | p = page; |
| 892 | len = 0; | 894 | while (p - page < 256) { |
| 893 | while (len < (off + count)) { | 895 | if (*p == '\0' || *p == '\n') { |
| 894 | if ((*p == '\0') || (*p == '\n')) { | 896 | *p = '\n'; |
| 895 | if (*p == '\0') | ||
| 896 | *p = '\n'; | ||
| 897 | p++; | ||
| 898 | len++; | ||
| 899 | *eof = 1; | ||
| 900 | break; | 897 | break; |
| 901 | } | 898 | } |
| 902 | p++; | 899 | p++; |
| 903 | len++; | ||
| 904 | } | ||
| 905 | 900 | ||
| 906 | if (len < off) { | ||
| 907 | *eof = 1; | ||
| 908 | len = 0; | ||
| 909 | } | 901 | } |
| 910 | return len; | 902 | seq_write(m, page, p - page); |
| 903 | kfree(page); | ||
| 904 | return 0; | ||
| 905 | } | ||
| 906 | |||
| 907 | static int mf_cmdline_proc_open(struct inode *inode, struct file *file) | ||
| 908 | { | ||
| 909 | return single_open(file, mf_cmdline_proc_show, PDE(inode)->data); | ||
| 911 | } | 910 | } |
| 912 | 911 | ||
| 913 | #if 0 | 912 | #if 0 |
| @@ -962,10 +961,8 @@ static int proc_mf_dump_vmlinux(char *page, char **start, off_t off, | |||
| 962 | } | 961 | } |
| 963 | #endif | 962 | #endif |
| 964 | 963 | ||
| 965 | static int proc_mf_dump_side(char *page, char **start, off_t off, | 964 | static int mf_side_proc_show(struct seq_file *m, void *v) |
| 966 | int count, int *eof, void *data) | ||
| 967 | { | 965 | { |
| 968 | int len; | ||
| 969 | char mf_current_side = ' '; | 966 | char mf_current_side = ' '; |
| 970 | struct vsp_cmd_data vsp_cmd; | 967 | struct vsp_cmd_data vsp_cmd; |
| 971 | 968 | ||
| @@ -989,21 +986,17 @@ static int proc_mf_dump_side(char *page, char **start, off_t off, | |||
| 989 | } | 986 | } |
| 990 | } | 987 | } |
| 991 | 988 | ||
| 992 | len = sprintf(page, "%c\n", mf_current_side); | 989 | seq_printf(m, "%c\n", mf_current_side); |
| 990 | return 0; | ||
| 991 | } | ||
| 993 | 992 | ||
| 994 | if (len <= (off + count)) | 993 | static int mf_side_proc_open(struct inode *inode, struct file *file) |
| 995 | *eof = 1; | 994 | { |
| 996 | *start = page + off; | 995 | return single_open(file, mf_side_proc_show, NULL); |
| 997 | len -= off; | ||
| 998 | if (len > count) | ||
| 999 | len = count; | ||
| 1000 | if (len < 0) | ||
| 1001 | len = 0; | ||
| 1002 | return len; | ||
| 1003 | } | 996 | } |
| 1004 | 997 | ||
| 1005 | static int proc_mf_change_side(struct file *file, const char __user *buffer, | 998 | static ssize_t mf_side_proc_write(struct file *file, const char __user *buffer, |
| 1006 | unsigned long count, void *data) | 999 | size_t count, loff_t *pos) |
| 1007 | { | 1000 | { |
| 1008 | char side; | 1001 | char side; |
| 1009 | u64 newSide; | 1002 | u64 newSide; |
| @@ -1041,6 +1034,15 @@ static int proc_mf_change_side(struct file *file, const char __user *buffer, | |||
| 1041 | return count; | 1034 | return count; |
| 1042 | } | 1035 | } |
| 1043 | 1036 | ||
| 1037 | static const struct file_operations mf_side_proc_fops = { | ||
| 1038 | .owner = THIS_MODULE, | ||
| 1039 | .open = mf_side_proc_open, | ||
| 1040 | .read = seq_read, | ||
| 1041 | .llseek = seq_lseek, | ||
| 1042 | .release = single_release, | ||
| 1043 | .write = mf_side_proc_write, | ||
| 1044 | }; | ||
| 1045 | |||
| 1044 | #if 0 | 1046 | #if 0 |
| 1045 | static void mf_getSrcHistory(char *buffer, int size) | 1047 | static void mf_getSrcHistory(char *buffer, int size) |
| 1046 | { | 1048 | { |
| @@ -1087,8 +1089,7 @@ static void mf_getSrcHistory(char *buffer, int size) | |||
| 1087 | } | 1089 | } |
| 1088 | #endif | 1090 | #endif |
| 1089 | 1091 | ||
| 1090 | static int proc_mf_dump_src(char *page, char **start, off_t off, | 1092 | static int mf_src_proc_show(struct seq_file *m, void *v) |
| 1091 | int count, int *eof, void *data) | ||
| 1092 | { | 1093 | { |
| 1093 | #if 0 | 1094 | #if 0 |
| 1094 | int len; | 1095 | int len; |
| @@ -1109,8 +1110,13 @@ static int proc_mf_dump_src(char *page, char **start, off_t off, | |||
| 1109 | #endif | 1110 | #endif |
| 1110 | } | 1111 | } |
| 1111 | 1112 | ||
| 1112 | static int proc_mf_change_src(struct file *file, const char __user *buffer, | 1113 | static int mf_src_proc_open(struct inode *inode, struct file *file) |
| 1113 | unsigned long count, void *data) | 1114 | { |
| 1115 | return single_open(file, mf_src_proc_show, NULL); | ||
| 1116 | } | ||
| 1117 | |||
| 1118 | static ssize_t mf_src_proc_write(struct file *file, const char __user *buffer, | ||
| 1119 | size_t count, loff_t *pos) | ||
| 1114 | { | 1120 | { |
| 1115 | char stkbuf[10]; | 1121 | char stkbuf[10]; |
| 1116 | 1122 | ||
| @@ -1135,9 +1141,19 @@ static int proc_mf_change_src(struct file *file, const char __user *buffer, | |||
| 1135 | return count; | 1141 | return count; |
| 1136 | } | 1142 | } |
| 1137 | 1143 | ||
| 1138 | static int proc_mf_change_cmdline(struct file *file, const char __user *buffer, | 1144 | static const struct file_operations mf_src_proc_fops = { |
| 1139 | unsigned long count, void *data) | 1145 | .owner = THIS_MODULE, |
| 1146 | .open = mf_src_proc_open, | ||
| 1147 | .read = seq_read, | ||
| 1148 | .llseek = seq_lseek, | ||
| 1149 | .release = single_release, | ||
| 1150 | .write = mf_src_proc_write, | ||
| 1151 | }; | ||
| 1152 | |||
| 1153 | static ssize_t mf_cmdline_proc_write(struct file *file, const char __user *buffer, | ||
| 1154 | size_t count, loff_t *pos) | ||
| 1140 | { | 1155 | { |
| 1156 | void *data = PDE(file->f_path.dentry->d_inode)->data; | ||
| 1141 | struct vsp_cmd_data vsp_cmd; | 1157 | struct vsp_cmd_data vsp_cmd; |
| 1142 | dma_addr_t dma_addr; | 1158 | dma_addr_t dma_addr; |
| 1143 | char *page; | 1159 | char *page; |
| @@ -1172,6 +1188,15 @@ out: | |||
| 1172 | return ret; | 1188 | return ret; |
| 1173 | } | 1189 | } |
| 1174 | 1190 | ||
| 1191 | static const struct file_operations mf_cmdline_proc_fops = { | ||
| 1192 | .owner = THIS_MODULE, | ||
| 1193 | .open = mf_cmdline_proc_open, | ||
| 1194 | .read = seq_read, | ||
| 1195 | .llseek = seq_lseek, | ||
| 1196 | .release = single_release, | ||
| 1197 | .write = mf_cmdline_proc_write, | ||
| 1198 | }; | ||
| 1199 | |||
| 1175 | static ssize_t proc_mf_change_vmlinux(struct file *file, | 1200 | static ssize_t proc_mf_change_vmlinux(struct file *file, |
| 1176 | const char __user *buf, | 1201 | const char __user *buf, |
| 1177 | size_t count, loff_t *ppos) | 1202 | size_t count, loff_t *ppos) |
| @@ -1246,12 +1271,10 @@ static int __init mf_proc_init(void) | |||
| 1246 | if (!mf) | 1271 | if (!mf) |
| 1247 | return 1; | 1272 | return 1; |
| 1248 | 1273 | ||
| 1249 | ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf); | 1274 | ent = proc_create_data("cmdline", S_IRUSR|S_IWUSR, mf, |
| 1275 | &mf_cmdline_proc_fops, (void *)(long)i); | ||
| 1250 | if (!ent) | 1276 | if (!ent) |
| 1251 | return 1; | 1277 | return 1; |
| 1252 | ent->data = (void *)(long)i; | ||
| 1253 | ent->read_proc = proc_mf_dump_cmdline; | ||
| 1254 | ent->write_proc = proc_mf_change_cmdline; | ||
| 1255 | 1278 | ||
| 1256 | if (i == 3) /* no vmlinux entry for 'D' */ | 1279 | if (i == 3) /* no vmlinux entry for 'D' */ |
| 1257 | continue; | 1280 | continue; |
| @@ -1263,19 +1286,15 @@ static int __init mf_proc_init(void) | |||
| 1263 | return 1; | 1286 | return 1; |
| 1264 | } | 1287 | } |
| 1265 | 1288 | ||
| 1266 | ent = create_proc_entry("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root); | 1289 | ent = proc_create("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root, |
| 1290 | &mf_side_proc_fops); | ||
| 1267 | if (!ent) | 1291 | if (!ent) |
| 1268 | return 1; | 1292 | return 1; |
| 1269 | ent->data = (void *)0; | ||
| 1270 | ent->read_proc = proc_mf_dump_side; | ||
| 1271 | ent->write_proc = proc_mf_change_side; | ||
| 1272 | 1293 | ||
| 1273 | ent = create_proc_entry("src", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root); | 1294 | ent = proc_create("src", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root, |
| 1295 | &mf_src_proc_fops); | ||
| 1274 | if (!ent) | 1296 | if (!ent) |
| 1275 | return 1; | 1297 | return 1; |
| 1276 | ent->data = (void *)0; | ||
| 1277 | ent->read_proc = proc_mf_dump_src; | ||
| 1278 | ent->write_proc = proc_mf_change_src; | ||
| 1279 | 1298 | ||
| 1280 | return 0; | 1299 | return 0; |
| 1281 | } | 1300 | } |
diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c index 49ff4dc422b7..5aea94f30836 100644 --- a/arch/powerpc/platforms/iseries/viopath.c +++ b/arch/powerpc/platforms/iseries/viopath.c | |||
| @@ -116,7 +116,7 @@ static int proc_viopath_show(struct seq_file *m, void *v) | |||
| 116 | u16 vlanMap; | 116 | u16 vlanMap; |
| 117 | dma_addr_t handle; | 117 | dma_addr_t handle; |
| 118 | HvLpEvent_Rc hvrc; | 118 | HvLpEvent_Rc hvrc; |
| 119 | DECLARE_COMPLETION(done); | 119 | DECLARE_COMPLETION_ONSTACK(done); |
| 120 | struct device_node *node; | 120 | struct device_node *node; |
| 121 | const char *sysid; | 121 | const char *sysid; |
| 122 | 122 | ||
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index 27554c807fd5..c667f0f02c34 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig | |||
| @@ -2,6 +2,8 @@ config PPC_PSERIES | |||
| 2 | depends on PPC64 && PPC_BOOK3S | 2 | depends on PPC64 && PPC_BOOK3S |
| 3 | bool "IBM pSeries & new (POWER5-based) iSeries" | 3 | bool "IBM pSeries & new (POWER5-based) iSeries" |
| 4 | select MPIC | 4 | select MPIC |
| 5 | select PCI_MSI | ||
| 6 | select XICS | ||
| 5 | select PPC_I8259 | 7 | select PPC_I8259 |
| 6 | select PPC_RTAS | 8 | select PPC_RTAS |
| 7 | select PPC_RTAS_DAEMON | 9 | select PPC_RTAS_DAEMON |
diff --git a/arch/powerpc/platforms/pseries/cmm.c b/arch/powerpc/platforms/pseries/cmm.c index bcdcf0ccc8d7..a277f2e28dbc 100644 --- a/arch/powerpc/platforms/pseries/cmm.c +++ b/arch/powerpc/platforms/pseries/cmm.c | |||
| @@ -38,19 +38,28 @@ | |||
| 38 | #include <asm/mmu.h> | 38 | #include <asm/mmu.h> |
| 39 | #include <asm/pgalloc.h> | 39 | #include <asm/pgalloc.h> |
| 40 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
| 41 | #include <linux/memory.h> | ||
| 41 | 42 | ||
| 42 | #include "plpar_wrappers.h" | 43 | #include "plpar_wrappers.h" |
| 43 | 44 | ||
| 44 | #define CMM_DRIVER_VERSION "1.0.0" | 45 | #define CMM_DRIVER_VERSION "1.0.0" |
| 45 | #define CMM_DEFAULT_DELAY 1 | 46 | #define CMM_DEFAULT_DELAY 1 |
| 47 | #define CMM_HOTPLUG_DELAY 5 | ||
| 46 | #define CMM_DEBUG 0 | 48 | #define CMM_DEBUG 0 |
| 47 | #define CMM_DISABLE 0 | 49 | #define CMM_DISABLE 0 |
| 48 | #define CMM_OOM_KB 1024 | 50 | #define CMM_OOM_KB 1024 |
| 49 | #define CMM_MIN_MEM_MB 256 | 51 | #define CMM_MIN_MEM_MB 256 |
| 50 | #define KB2PAGES(_p) ((_p)>>(PAGE_SHIFT-10)) | 52 | #define KB2PAGES(_p) ((_p)>>(PAGE_SHIFT-10)) |
| 51 | #define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10)) | 53 | #define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10)) |
| 54 | /* | ||
| 55 | * The priority level tries to ensure that this notifier is called as | ||
| 56 | * late as possible to reduce thrashing in the shared memory pool. | ||
| 57 | */ | ||
| 58 | #define CMM_MEM_HOTPLUG_PRI 1 | ||
| 59 | #define CMM_MEM_ISOLATE_PRI 15 | ||
| 52 | 60 | ||
| 53 | static unsigned int delay = CMM_DEFAULT_DELAY; | 61 | static unsigned int delay = CMM_DEFAULT_DELAY; |
| 62 | static unsigned int hotplug_delay = CMM_HOTPLUG_DELAY; | ||
| 54 | static unsigned int oom_kb = CMM_OOM_KB; | 63 | static unsigned int oom_kb = CMM_OOM_KB; |
| 55 | static unsigned int cmm_debug = CMM_DEBUG; | 64 | static unsigned int cmm_debug = CMM_DEBUG; |
| 56 | static unsigned int cmm_disabled = CMM_DISABLE; | 65 | static unsigned int cmm_disabled = CMM_DISABLE; |
| @@ -65,6 +74,10 @@ MODULE_VERSION(CMM_DRIVER_VERSION); | |||
| 65 | module_param_named(delay, delay, uint, S_IRUGO | S_IWUSR); | 74 | module_param_named(delay, delay, uint, S_IRUGO | S_IWUSR); |
| 66 | MODULE_PARM_DESC(delay, "Delay (in seconds) between polls to query hypervisor paging requests. " | 75 | MODULE_PARM_DESC(delay, "Delay (in seconds) between polls to query hypervisor paging requests. " |
| 67 | "[Default=" __stringify(CMM_DEFAULT_DELAY) "]"); | 76 | "[Default=" __stringify(CMM_DEFAULT_DELAY) "]"); |
| 77 | module_param_named(hotplug_delay, hotplug_delay, uint, S_IRUGO | S_IWUSR); | ||
| 78 | MODULE_PARM_DESC(delay, "Delay (in seconds) after memory hotplug remove " | ||
| 79 | "before loaning resumes. " | ||
| 80 | "[Default=" __stringify(CMM_HOTPLUG_DELAY) "]"); | ||
| 68 | module_param_named(oom_kb, oom_kb, uint, S_IRUGO | S_IWUSR); | 81 | module_param_named(oom_kb, oom_kb, uint, S_IRUGO | S_IWUSR); |
| 69 | MODULE_PARM_DESC(oom_kb, "Amount of memory in kb to free on OOM. " | 82 | MODULE_PARM_DESC(oom_kb, "Amount of memory in kb to free on OOM. " |
| 70 | "[Default=" __stringify(CMM_OOM_KB) "]"); | 83 | "[Default=" __stringify(CMM_OOM_KB) "]"); |
| @@ -92,6 +105,9 @@ static unsigned long oom_freed_pages; | |||
| 92 | static struct cmm_page_array *cmm_page_list; | 105 | static struct cmm_page_array *cmm_page_list; |
| 93 | static DEFINE_SPINLOCK(cmm_lock); | 106 | static DEFINE_SPINLOCK(cmm_lock); |
| 94 | 107 | ||
| 108 | static DEFINE_MUTEX(hotplug_mutex); | ||
| 109 | static int hotplug_occurred; /* protected by the hotplug mutex */ | ||
| 110 | |||
| 95 | static struct task_struct *cmm_thread_ptr; | 111 | static struct task_struct *cmm_thread_ptr; |
| 96 | 112 | ||
| 97 | /** | 113 | /** |
| @@ -110,6 +126,17 @@ static long cmm_alloc_pages(long nr) | |||
| 110 | cmm_dbg("Begin request for %ld pages\n", nr); | 126 | cmm_dbg("Begin request for %ld pages\n", nr); |
| 111 | 127 | ||
| 112 | while (nr) { | 128 | while (nr) { |
| 129 | /* Exit if a hotplug operation is in progress or occurred */ | ||
| 130 | if (mutex_trylock(&hotplug_mutex)) { | ||
| 131 | if (hotplug_occurred) { | ||
| 132 | mutex_unlock(&hotplug_mutex); | ||
| 133 | break; | ||
| 134 | } | ||
| 135 | mutex_unlock(&hotplug_mutex); | ||
| 136 | } else { | ||
| 137 | break; | ||
| 138 | } | ||
| 139 | |||
| 113 | addr = __get_free_page(GFP_NOIO | __GFP_NOWARN | | 140 | addr = __get_free_page(GFP_NOIO | __GFP_NOWARN | |
| 114 | __GFP_NORETRY | __GFP_NOMEMALLOC); | 141 | __GFP_NORETRY | __GFP_NOMEMALLOC); |
| 115 | if (!addr) | 142 | if (!addr) |
| @@ -119,8 +146,9 @@ static long cmm_alloc_pages(long nr) | |||
| 119 | if (!pa || pa->index >= CMM_NR_PAGES) { | 146 | if (!pa || pa->index >= CMM_NR_PAGES) { |
| 120 | /* Need a new page for the page list. */ | 147 | /* Need a new page for the page list. */ |
| 121 | spin_unlock(&cmm_lock); | 148 | spin_unlock(&cmm_lock); |
| 122 | npa = (struct cmm_page_array *)__get_free_page(GFP_NOIO | __GFP_NOWARN | | 149 | npa = (struct cmm_page_array *)__get_free_page( |
| 123 | __GFP_NORETRY | __GFP_NOMEMALLOC); | 150 | GFP_NOIO | __GFP_NOWARN | |
| 151 | __GFP_NORETRY | __GFP_NOMEMALLOC); | ||
| 124 | if (!npa) { | 152 | if (!npa) { |
| 125 | pr_info("%s: Can not allocate new page list\n", __func__); | 153 | pr_info("%s: Can not allocate new page list\n", __func__); |
| 126 | free_page(addr); | 154 | free_page(addr); |
| @@ -282,9 +310,28 @@ static int cmm_thread(void *dummy) | |||
| 282 | while (1) { | 310 | while (1) { |
| 283 | timeleft = msleep_interruptible(delay * 1000); | 311 | timeleft = msleep_interruptible(delay * 1000); |
| 284 | 312 | ||
| 285 | if (kthread_should_stop() || timeleft) { | 313 | if (kthread_should_stop() || timeleft) |
| 286 | loaned_pages_target = loaned_pages; | ||
| 287 | break; | 314 | break; |
| 315 | |||
| 316 | if (mutex_trylock(&hotplug_mutex)) { | ||
| 317 | if (hotplug_occurred) { | ||
| 318 | hotplug_occurred = 0; | ||
| 319 | mutex_unlock(&hotplug_mutex); | ||
| 320 | cmm_dbg("Hotplug operation has occurred, " | ||
| 321 | "loaning activity suspended " | ||
| 322 | "for %d seconds.\n", | ||
| 323 | hotplug_delay); | ||
| 324 | timeleft = msleep_interruptible(hotplug_delay * | ||
| 325 | 1000); | ||
| 326 | if (kthread_should_stop() || timeleft) | ||
| 327 | break; | ||
| 328 | continue; | ||
| 329 | } | ||
| 330 | mutex_unlock(&hotplug_mutex); | ||
| 331 | } else { | ||
| 332 | cmm_dbg("Hotplug operation in progress, activity " | ||
| 333 | "suspended\n"); | ||
| 334 | continue; | ||
| 288 | } | 335 | } |
| 289 | 336 | ||
| 290 | cmm_get_mpp(); | 337 | cmm_get_mpp(); |
| @@ -414,6 +461,193 @@ static struct notifier_block cmm_reboot_nb = { | |||
| 414 | }; | 461 | }; |
| 415 | 462 | ||
| 416 | /** | 463 | /** |
| 464 | * cmm_count_pages - Count the number of pages loaned in a particular range. | ||
| 465 | * | ||
| 466 | * @arg: memory_isolate_notify structure with address range and count | ||
| 467 | * | ||
| 468 | * Return value: | ||
| 469 | * 0 on success | ||
| 470 | **/ | ||
| 471 | static unsigned long cmm_count_pages(void *arg) | ||
| 472 | { | ||
| 473 | struct memory_isolate_notify *marg = arg; | ||
| 474 | struct cmm_page_array *pa; | ||
| 475 | unsigned long start = (unsigned long)pfn_to_kaddr(marg->start_pfn); | ||
| 476 | unsigned long end = start + (marg->nr_pages << PAGE_SHIFT); | ||
| 477 | unsigned long idx; | ||
| 478 | |||
| 479 | spin_lock(&cmm_lock); | ||
| 480 | pa = cmm_page_list; | ||
| 481 | while (pa) { | ||
| 482 | if ((unsigned long)pa >= start && (unsigned long)pa < end) | ||
| 483 | marg->pages_found++; | ||
| 484 | for (idx = 0; idx < pa->index; idx++) | ||
| 485 | if (pa->page[idx] >= start && pa->page[idx] < end) | ||
| 486 | marg->pages_found++; | ||
| 487 | pa = pa->next; | ||
| 488 | } | ||
| 489 | spin_unlock(&cmm_lock); | ||
| 490 | return 0; | ||
| 491 | } | ||
| 492 | |||
| 493 | /** | ||
| 494 | * cmm_memory_isolate_cb - Handle memory isolation notifier calls | ||
| 495 | * @self: notifier block struct | ||
| 496 | * @action: action to take | ||
| 497 | * @arg: struct memory_isolate_notify data for handler | ||
| 498 | * | ||
| 499 | * Return value: | ||
| 500 | * NOTIFY_OK or notifier error based on subfunction return value | ||
| 501 | **/ | ||
| 502 | static int cmm_memory_isolate_cb(struct notifier_block *self, | ||
| 503 | unsigned long action, void *arg) | ||
| 504 | { | ||
| 505 | int ret = 0; | ||
| 506 | |||
| 507 | if (action == MEM_ISOLATE_COUNT) | ||
| 508 | ret = cmm_count_pages(arg); | ||
| 509 | |||
| 510 | if (ret) | ||
| 511 | ret = notifier_from_errno(ret); | ||
| 512 | else | ||
| 513 | ret = NOTIFY_OK; | ||
| 514 | |||
| 515 | return ret; | ||
| 516 | } | ||
| 517 | |||
| 518 | static struct notifier_block cmm_mem_isolate_nb = { | ||
| 519 | .notifier_call = cmm_memory_isolate_cb, | ||
| 520 | .priority = CMM_MEM_ISOLATE_PRI | ||
| 521 | }; | ||
| 522 | |||
| 523 | /** | ||
| 524 | * cmm_mem_going_offline - Unloan pages where memory is to be removed | ||
| 525 | * @arg: memory_notify structure with page range to be offlined | ||
| 526 | * | ||
| 527 | * Return value: | ||
| 528 | * 0 on success | ||
| 529 | **/ | ||
| 530 | static int cmm_mem_going_offline(void *arg) | ||
| 531 | { | ||
| 532 | struct memory_notify *marg = arg; | ||
| 533 | unsigned long start_page = (unsigned long)pfn_to_kaddr(marg->start_pfn); | ||
| 534 | unsigned long end_page = start_page + (marg->nr_pages << PAGE_SHIFT); | ||
| 535 | struct cmm_page_array *pa_curr, *pa_last, *npa; | ||
| 536 | unsigned long idx; | ||
| 537 | unsigned long freed = 0; | ||
| 538 | |||
| 539 | cmm_dbg("Memory going offline, searching 0x%lx (%ld pages).\n", | ||
| 540 | start_page, marg->nr_pages); | ||
| 541 | spin_lock(&cmm_lock); | ||
| 542 | |||
| 543 | /* Search the page list for pages in the range to be offlined */ | ||
| 544 | pa_last = pa_curr = cmm_page_list; | ||
| 545 | while (pa_curr) { | ||
| 546 | for (idx = (pa_curr->index - 1); (idx + 1) > 0; idx--) { | ||
| 547 | if ((pa_curr->page[idx] < start_page) || | ||
| 548 | (pa_curr->page[idx] >= end_page)) | ||
| 549 | continue; | ||
| 550 | |||
| 551 | plpar_page_set_active(__pa(pa_curr->page[idx])); | ||
| 552 | free_page(pa_curr->page[idx]); | ||
| 553 | freed++; | ||
| 554 | loaned_pages--; | ||
| 555 | totalram_pages++; | ||
| 556 | pa_curr->page[idx] = pa_last->page[--pa_last->index]; | ||
| 557 | if (pa_last->index == 0) { | ||
| 558 | if (pa_curr == pa_last) | ||
| 559 | pa_curr = pa_last->next; | ||
| 560 | pa_last = pa_last->next; | ||
| 561 | free_page((unsigned long)cmm_page_list); | ||
| 562 | cmm_page_list = pa_last; | ||
| 563 | continue; | ||
| 564 | } | ||
| 565 | } | ||
| 566 | pa_curr = pa_curr->next; | ||
| 567 | } | ||
| 568 | |||
| 569 | /* Search for page list structures in the range to be offlined */ | ||
| 570 | pa_last = NULL; | ||
| 571 | pa_curr = cmm_page_list; | ||
| 572 | while (pa_curr) { | ||
| 573 | if (((unsigned long)pa_curr >= start_page) && | ||
| 574 | ((unsigned long)pa_curr < end_page)) { | ||
| 575 | npa = (struct cmm_page_array *)__get_free_page( | ||
| 576 | GFP_NOIO | __GFP_NOWARN | | ||
| 577 | __GFP_NORETRY | __GFP_NOMEMALLOC); | ||
| 578 | if (!npa) { | ||
| 579 | spin_unlock(&cmm_lock); | ||
| 580 | cmm_dbg("Failed to allocate memory for list " | ||
| 581 | "management. Memory hotplug " | ||
| 582 | "failed.\n"); | ||
| 583 | return ENOMEM; | ||
| 584 | } | ||
| 585 | memcpy(npa, pa_curr, PAGE_SIZE); | ||
| 586 | if (pa_curr == cmm_page_list) | ||
| 587 | cmm_page_list = npa; | ||
| 588 | if (pa_last) | ||
| 589 | pa_last->next = npa; | ||
| 590 | free_page((unsigned long) pa_curr); | ||
| 591 | freed++; | ||
| 592 | pa_curr = npa; | ||
| 593 | } | ||
| 594 | |||
| 595 | pa_last = pa_curr; | ||
| 596 | pa_curr = pa_curr->next; | ||
| 597 | } | ||
| 598 | |||
| 599 | spin_unlock(&cmm_lock); | ||
| 600 | cmm_dbg("Released %ld pages in the search range.\n", freed); | ||
| 601 | |||
| 602 | return 0; | ||
| 603 | } | ||
| 604 | |||
| 605 | /** | ||
| 606 | * cmm_memory_cb - Handle memory hotplug notifier calls | ||
| 607 | * @self: notifier block struct | ||
| 608 | * @action: action to take | ||
| 609 | * @arg: struct memory_notify data for handler | ||
| 610 | * | ||
| 611 | * Return value: | ||
| 612 | * NOTIFY_OK or notifier error based on subfunction return value | ||
| 613 | * | ||
| 614 | **/ | ||
| 615 | static int cmm_memory_cb(struct notifier_block *self, | ||
| 616 | unsigned long action, void *arg) | ||
| 617 | { | ||
| 618 | int ret = 0; | ||
| 619 | |||
| 620 | switch (action) { | ||
| 621 | case MEM_GOING_OFFLINE: | ||
| 622 | mutex_lock(&hotplug_mutex); | ||
| 623 | hotplug_occurred = 1; | ||
| 624 | ret = cmm_mem_going_offline(arg); | ||
| 625 | break; | ||
| 626 | case MEM_OFFLINE: | ||
| 627 | case MEM_CANCEL_OFFLINE: | ||
| 628 | mutex_unlock(&hotplug_mutex); | ||
| 629 | cmm_dbg("Memory offline operation complete.\n"); | ||
| 630 | break; | ||
| 631 | case MEM_GOING_ONLINE: | ||
| 632 | case MEM_ONLINE: | ||
| 633 | case MEM_CANCEL_ONLINE: | ||
| 634 | break; | ||
| 635 | } | ||
| 636 | |||
| 637 | if (ret) | ||
| 638 | ret = notifier_from_errno(ret); | ||
| 639 | else | ||
| 640 | ret = NOTIFY_OK; | ||
| 641 | |||
| 642 | return ret; | ||
| 643 | } | ||
| 644 | |||
| 645 | static struct notifier_block cmm_mem_nb = { | ||
| 646 | .notifier_call = cmm_memory_cb, | ||
| 647 | .priority = CMM_MEM_HOTPLUG_PRI | ||
| 648 | }; | ||
| 649 | |||
| 650 | /** | ||
| 417 | * cmm_init - Module initialization | 651 | * cmm_init - Module initialization |
| 418 | * | 652 | * |
| 419 | * Return value: | 653 | * Return value: |
| @@ -435,18 +669,24 @@ static int cmm_init(void) | |||
| 435 | if ((rc = cmm_sysfs_register(&cmm_sysdev))) | 669 | if ((rc = cmm_sysfs_register(&cmm_sysdev))) |
| 436 | goto out_reboot_notifier; | 670 | goto out_reboot_notifier; |
| 437 | 671 | ||
| 672 | if (register_memory_notifier(&cmm_mem_nb) || | ||
| 673 | register_memory_isolate_notifier(&cmm_mem_isolate_nb)) | ||
| 674 | goto out_unregister_notifier; | ||
| 675 | |||
| 438 | if (cmm_disabled) | 676 | if (cmm_disabled) |
| 439 | return rc; | 677 | return rc; |
| 440 | 678 | ||
| 441 | cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread"); | 679 | cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread"); |
| 442 | if (IS_ERR(cmm_thread_ptr)) { | 680 | if (IS_ERR(cmm_thread_ptr)) { |
| 443 | rc = PTR_ERR(cmm_thread_ptr); | 681 | rc = PTR_ERR(cmm_thread_ptr); |
| 444 | goto out_unregister_sysfs; | 682 | goto out_unregister_notifier; |
| 445 | } | 683 | } |
| 446 | 684 | ||
| 447 | return rc; | 685 | return rc; |
| 448 | 686 | ||
| 449 | out_unregister_sysfs: | 687 | out_unregister_notifier: |
| 688 | unregister_memory_notifier(&cmm_mem_nb); | ||
| 689 | unregister_memory_isolate_notifier(&cmm_mem_isolate_nb); | ||
| 450 | cmm_unregister_sysfs(&cmm_sysdev); | 690 | cmm_unregister_sysfs(&cmm_sysdev); |
| 451 | out_reboot_notifier: | 691 | out_reboot_notifier: |
| 452 | unregister_reboot_notifier(&cmm_reboot_nb); | 692 | unregister_reboot_notifier(&cmm_reboot_nb); |
| @@ -467,6 +707,8 @@ static void cmm_exit(void) | |||
| 467 | kthread_stop(cmm_thread_ptr); | 707 | kthread_stop(cmm_thread_ptr); |
| 468 | unregister_oom_notifier(&cmm_oom_nb); | 708 | unregister_oom_notifier(&cmm_oom_nb); |
| 469 | unregister_reboot_notifier(&cmm_reboot_nb); | 709 | unregister_reboot_notifier(&cmm_reboot_nb); |
| 710 | unregister_memory_notifier(&cmm_mem_nb); | ||
| 711 | unregister_memory_isolate_notifier(&cmm_mem_isolate_nb); | ||
| 470 | cmm_free_pages(loaned_pages); | 712 | cmm_free_pages(loaned_pages); |
| 471 | cmm_unregister_sysfs(&cmm_sysdev); | 713 | cmm_unregister_sysfs(&cmm_sysdev); |
| 472 | } | 714 | } |
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 12df9e8812a9..67b7a10f9fce 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c | |||
| @@ -346,12 +346,14 @@ int dlpar_release_drc(u32 drc_index) | |||
| 346 | 346 | ||
| 347 | static DEFINE_MUTEX(pseries_cpu_hotplug_mutex); | 347 | static DEFINE_MUTEX(pseries_cpu_hotplug_mutex); |
| 348 | 348 | ||
| 349 | void cpu_hotplug_driver_lock() | 349 | void cpu_hotplug_driver_lock(void) |
| 350 | __acquires(pseries_cpu_hotplug_mutex) | ||
| 350 | { | 351 | { |
| 351 | mutex_lock(&pseries_cpu_hotplug_mutex); | 352 | mutex_lock(&pseries_cpu_hotplug_mutex); |
| 352 | } | 353 | } |
| 353 | 354 | ||
| 354 | void cpu_hotplug_driver_unlock() | 355 | void cpu_hotplug_driver_unlock(void) |
| 356 | __releases(pseries_cpu_hotplug_mutex) | ||
| 355 | { | 357 | { |
| 356 | mutex_unlock(&pseries_cpu_hotplug_mutex); | 358 | mutex_unlock(&pseries_cpu_hotplug_mutex); |
| 357 | } | 359 | } |
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 8868c012268a..b4886635972c 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c | |||
| @@ -144,8 +144,8 @@ static void __devinit smp_pSeries_kick_cpu(int nr) | |||
| 144 | hcpuid = get_hard_smp_processor_id(nr); | 144 | hcpuid = get_hard_smp_processor_id(nr); |
| 145 | rc = plpar_hcall_norets(H_PROD, hcpuid); | 145 | rc = plpar_hcall_norets(H_PROD, hcpuid); |
| 146 | if (rc != H_SUCCESS) | 146 | if (rc != H_SUCCESS) |
| 147 | panic("Error: Prod to wake up processor %d Ret= %ld\n", | 147 | printk(KERN_ERR "Error: Prod to wake up processor %d\ |
| 148 | nr, rc); | 148 | Ret= %ld\n", nr, rc); |
| 149 | } | 149 | } |
| 150 | } | 150 | } |
| 151 | 151 | ||
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c index 971483f0dfac..1709ac5aac7c 100644 --- a/arch/powerpc/sysdev/cpm2_pic.c +++ b/arch/powerpc/sysdev/cpm2_pic.c | |||
| @@ -143,13 +143,23 @@ static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type) | |||
| 143 | struct irq_desc *desc = irq_to_desc(virq); | 143 | struct irq_desc *desc = irq_to_desc(virq); |
| 144 | unsigned int vold, vnew, edibit; | 144 | unsigned int vold, vnew, edibit; |
| 145 | 145 | ||
| 146 | if (flow_type == IRQ_TYPE_NONE) | 146 | /* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or |
| 147 | flow_type = IRQ_TYPE_LEVEL_LOW; | 147 | * IRQ_TYPE_EDGE_BOTH (default). All others are IRQ_TYPE_EDGE_FALLING |
| 148 | 148 | * or IRQ_TYPE_LEVEL_LOW (default) | |
| 149 | if (flow_type & IRQ_TYPE_EDGE_RISING) { | 149 | */ |
| 150 | printk(KERN_ERR "CPM2 PIC: sense type 0x%x not supported\n", | 150 | if (src >= CPM2_IRQ_PORTC15 && src <= CPM2_IRQ_PORTC0) { |
| 151 | flow_type); | 151 | if (flow_type == IRQ_TYPE_NONE) |
| 152 | return -EINVAL; | 152 | flow_type = IRQ_TYPE_EDGE_BOTH; |
| 153 | |||
| 154 | if (flow_type != IRQ_TYPE_EDGE_BOTH && | ||
| 155 | flow_type != IRQ_TYPE_EDGE_FALLING) | ||
| 156 | goto err_sense; | ||
| 157 | } else { | ||
| 158 | if (flow_type == IRQ_TYPE_NONE) | ||
| 159 | flow_type = IRQ_TYPE_LEVEL_LOW; | ||
| 160 | |||
| 161 | if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH)) | ||
| 162 | goto err_sense; | ||
| 153 | } | 163 | } |
| 154 | 164 | ||
| 155 | desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); | 165 | desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); |
| @@ -181,6 +191,10 @@ static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type) | |||
| 181 | if (vold != vnew) | 191 | if (vold != vnew) |
| 182 | out_be32(&cpm2_intctl->ic_siexr, vnew); | 192 | out_be32(&cpm2_intctl->ic_siexr, vnew); |
| 183 | return 0; | 193 | return 0; |
| 194 | |||
| 195 | err_sense: | ||
| 196 | pr_err("CPM2 PIC: sense type 0x%x not supported\n", flow_type); | ||
| 197 | return -EINVAL; | ||
| 184 | } | 198 | } |
| 185 | 199 | ||
| 186 | static struct irq_chip cpm2_pic = { | 200 | static struct irq_chip cpm2_pic = { |
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 4e3a3e345ab3..e1a028c1f18d 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c | |||
| @@ -464,8 +464,7 @@ static void __iomem *mpc83xx_pcie_remap_cfg(struct pci_bus *bus, | |||
| 464 | { | 464 | { |
| 465 | struct pci_controller *hose = pci_bus_to_host(bus); | 465 | struct pci_controller *hose = pci_bus_to_host(bus); |
| 466 | struct mpc83xx_pcie_priv *pcie = hose->dn->data; | 466 | struct mpc83xx_pcie_priv *pcie = hose->dn->data; |
| 467 | u8 bus_no = bus->number - hose->first_busno; | 467 | u32 dev_base = bus->number << 24 | devfn << 16; |
| 468 | u32 dev_base = bus_no << 24 | devfn << 16; | ||
| 469 | int ret; | 468 | int ret; |
| 470 | 469 | ||
| 471 | ret = mpc83xx_pcie_exclude_device(bus, devfn); | 470 | ret = mpc83xx_pcie_exclude_device(bus, devfn); |
| @@ -515,12 +514,17 @@ static int mpc83xx_pcie_read_config(struct pci_bus *bus, unsigned int devfn, | |||
| 515 | static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn, | 514 | static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn, |
| 516 | int offset, int len, u32 val) | 515 | int offset, int len, u32 val) |
| 517 | { | 516 | { |
| 517 | struct pci_controller *hose = pci_bus_to_host(bus); | ||
| 518 | void __iomem *cfg_addr; | 518 | void __iomem *cfg_addr; |
| 519 | 519 | ||
| 520 | cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset); | 520 | cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset); |
| 521 | if (!cfg_addr) | 521 | if (!cfg_addr) |
| 522 | return PCIBIOS_DEVICE_NOT_FOUND; | 522 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 523 | 523 | ||
| 524 | /* PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS */ | ||
| 525 | if (offset == PCI_PRIMARY_BUS && bus->number == hose->first_busno) | ||
| 526 | val &= 0xffffff00; | ||
| 527 | |||
| 524 | switch (len) { | 528 | switch (len) { |
| 525 | case 1: | 529 | case 1: |
| 526 | out_8(cfg_addr, val); | 530 | out_8(cfg_addr, val); |
diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c index 103eace36194..ee1c0e1cf4a7 100644 --- a/arch/powerpc/sysdev/mpc8xxx_gpio.c +++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c | |||
| @@ -54,6 +54,22 @@ static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm) | |||
| 54 | mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT); | 54 | mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | /* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs | ||
| 58 | * defined as output cannot be determined by reading GPDAT register, | ||
| 59 | * so we use shadow data register instead. The status of input pins | ||
| 60 | * is determined by reading GPDAT register. | ||
| 61 | */ | ||
| 62 | static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio) | ||
| 63 | { | ||
| 64 | u32 val; | ||
| 65 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
| 66 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
| 67 | |||
| 68 | val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR); | ||
| 69 | |||
| 70 | return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio); | ||
| 71 | } | ||
| 72 | |||
| 57 | static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio) | 73 | static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio) |
| 58 | { | 74 | { |
| 59 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | 75 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); |
| @@ -136,7 +152,10 @@ static void __init mpc8xxx_add_controller(struct device_node *np) | |||
| 136 | gc->ngpio = MPC8XXX_GPIO_PINS; | 152 | gc->ngpio = MPC8XXX_GPIO_PINS; |
| 137 | gc->direction_input = mpc8xxx_gpio_dir_in; | 153 | gc->direction_input = mpc8xxx_gpio_dir_in; |
| 138 | gc->direction_output = mpc8xxx_gpio_dir_out; | 154 | gc->direction_output = mpc8xxx_gpio_dir_out; |
| 139 | gc->get = mpc8xxx_gpio_get; | 155 | if (of_device_is_compatible(np, "fsl,mpc8572-gpio")) |
| 156 | gc->get = mpc8572_gpio_get; | ||
| 157 | else | ||
| 158 | gc->get = mpc8xxx_gpio_get; | ||
| 140 | gc->set = mpc8xxx_gpio_set; | 159 | gc->set = mpc8xxx_gpio_set; |
| 141 | 160 | ||
| 142 | ret = of_mm_gpiochip_add(np, mm_gc); | 161 | ret = of_mm_gpiochip_add(np, mm_gc); |
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index aa9d06e5925b..470dc6c11d57 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
| @@ -567,13 +567,11 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic) | |||
| 567 | #endif /* CONFIG_MPIC_U3_HT_IRQS */ | 567 | #endif /* CONFIG_MPIC_U3_HT_IRQS */ |
| 568 | 568 | ||
| 569 | #ifdef CONFIG_SMP | 569 | #ifdef CONFIG_SMP |
| 570 | static int irq_choose_cpu(unsigned int virt_irq) | 570 | static int irq_choose_cpu(const cpumask_t *mask) |
| 571 | { | 571 | { |
| 572 | cpumask_t mask; | ||
| 573 | int cpuid; | 572 | int cpuid; |
| 574 | 573 | ||
| 575 | cpumask_copy(&mask, irq_to_desc(virt_irq)->affinity); | 574 | if (cpumask_equal(mask, cpu_all_mask)) { |
| 576 | if (cpus_equal(mask, CPU_MASK_ALL)) { | ||
| 577 | static int irq_rover; | 575 | static int irq_rover; |
| 578 | static DEFINE_SPINLOCK(irq_rover_lock); | 576 | static DEFINE_SPINLOCK(irq_rover_lock); |
| 579 | unsigned long flags; | 577 | unsigned long flags; |
| @@ -594,20 +592,15 @@ static int irq_choose_cpu(unsigned int virt_irq) | |||
| 594 | 592 | ||
| 595 | spin_unlock_irqrestore(&irq_rover_lock, flags); | 593 | spin_unlock_irqrestore(&irq_rover_lock, flags); |
| 596 | } else { | 594 | } else { |
| 597 | cpumask_t tmp; | 595 | cpuid = cpumask_first_and(mask, cpu_online_mask); |
| 598 | 596 | if (cpuid >= nr_cpu_ids) | |
| 599 | cpus_and(tmp, cpu_online_map, mask); | ||
| 600 | |||
| 601 | if (cpus_empty(tmp)) | ||
| 602 | goto do_round_robin; | 597 | goto do_round_robin; |
| 603 | |||
| 604 | cpuid = first_cpu(tmp); | ||
| 605 | } | 598 | } |
| 606 | 599 | ||
| 607 | return get_hard_smp_processor_id(cpuid); | 600 | return get_hard_smp_processor_id(cpuid); |
| 608 | } | 601 | } |
| 609 | #else | 602 | #else |
| 610 | static int irq_choose_cpu(unsigned int virt_irq) | 603 | static int irq_choose_cpu(const cpumask_t *mask) |
| 611 | { | 604 | { |
| 612 | return hard_smp_processor_id(); | 605 | return hard_smp_processor_id(); |
| 613 | } | 606 | } |
| @@ -816,7 +809,7 @@ int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask) | |||
| 816 | unsigned int src = mpic_irq_to_hw(irq); | 809 | unsigned int src = mpic_irq_to_hw(irq); |
| 817 | 810 | ||
| 818 | if (mpic->flags & MPIC_SINGLE_DEST_CPU) { | 811 | if (mpic->flags & MPIC_SINGLE_DEST_CPU) { |
| 819 | int cpuid = irq_choose_cpu(irq); | 812 | int cpuid = irq_choose_cpu(cpumask); |
| 820 | 813 | ||
| 821 | mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid); | 814 | mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid); |
| 822 | } else { | 815 | } else { |
diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c index 1d44eee80fa1..0f67cd79d481 100644 --- a/arch/powerpc/sysdev/mpic_msi.c +++ b/arch/powerpc/sysdev/mpic_msi.c | |||
| @@ -39,7 +39,12 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic) | |||
| 39 | 39 | ||
| 40 | pr_debug("mpic: found U3, guessing msi allocator setup\n"); | 40 | pr_debug("mpic: found U3, guessing msi allocator setup\n"); |
| 41 | 41 | ||
| 42 | /* Reserve source numbers we know are reserved in the HW */ | 42 | /* Reserve source numbers we know are reserved in the HW. |
| 43 | * | ||
| 44 | * This is a bit of a mix of U3 and U4 reserves but that's going | ||
| 45 | * to work fine, we have plenty enugh numbers left so let's just | ||
| 46 | * mark anything we don't like reserved. | ||
| 47 | */ | ||
| 43 | for (i = 0; i < 8; i++) | 48 | for (i = 0; i < 8; i++) |
| 44 | msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i); | 49 | msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i); |
| 45 | 50 | ||
| @@ -49,6 +54,10 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic) | |||
| 49 | for (i = 100; i < 105; i++) | 54 | for (i = 100; i < 105; i++) |
| 50 | msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i); | 55 | msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i); |
| 51 | 56 | ||
| 57 | for (i = 124; i < mpic->irq_count; i++) | ||
| 58 | msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i); | ||
| 59 | |||
| 60 | |||
| 52 | np = NULL; | 61 | np = NULL; |
| 53 | while ((np = of_find_all_nodes(np))) { | 62 | while ((np = of_find_all_nodes(np))) { |
| 54 | pr_debug("mpic: mapping hwirqs for %s\n", np->full_name); | 63 | pr_debug("mpic: mapping hwirqs for %s\n", np->full_name); |
diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c index d3caf23e6312..bcbfe79c704b 100644 --- a/arch/powerpc/sysdev/mpic_u3msi.c +++ b/arch/powerpc/sysdev/mpic_u3msi.c | |||
| @@ -64,12 +64,12 @@ static u64 read_ht_magic_addr(struct pci_dev *pdev, unsigned int pos) | |||
| 64 | return addr; | 64 | return addr; |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | static u64 find_ht_magic_addr(struct pci_dev *pdev) | 67 | static u64 find_ht_magic_addr(struct pci_dev *pdev, unsigned int hwirq) |
| 68 | { | 68 | { |
| 69 | struct pci_bus *bus; | 69 | struct pci_bus *bus; |
| 70 | unsigned int pos; | 70 | unsigned int pos; |
| 71 | 71 | ||
| 72 | for (bus = pdev->bus; bus; bus = bus->parent) { | 72 | for (bus = pdev->bus; bus && bus->self; bus = bus->parent) { |
| 73 | pos = pci_find_ht_capability(bus->self, HT_CAPTYPE_MSI_MAPPING); | 73 | pos = pci_find_ht_capability(bus->self, HT_CAPTYPE_MSI_MAPPING); |
| 74 | if (pos) | 74 | if (pos) |
| 75 | return read_ht_magic_addr(bus->self, pos); | 75 | return read_ht_magic_addr(bus->self, pos); |
| @@ -78,13 +78,41 @@ static u64 find_ht_magic_addr(struct pci_dev *pdev) | |||
| 78 | return 0; | 78 | return 0; |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | static u64 find_u4_magic_addr(struct pci_dev *pdev, unsigned int hwirq) | ||
| 82 | { | ||
| 83 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); | ||
| 84 | |||
| 85 | /* U4 PCIe MSIs need to write to the special register in | ||
| 86 | * the bridge that generates interrupts. There should be | ||
| 87 | * theorically a register at 0xf8005000 where you just write | ||
| 88 | * the MSI number and that triggers the right interrupt, but | ||
| 89 | * unfortunately, this is busted in HW, the bridge endian swaps | ||
| 90 | * the value and hits the wrong nibble in the register. | ||
| 91 | * | ||
| 92 | * So instead we use another register set which is used normally | ||
| 93 | * for converting HT interrupts to MPIC interrupts, which decodes | ||
| 94 | * the interrupt number as part of the low address bits | ||
| 95 | * | ||
| 96 | * This will not work if we ever use more than one legacy MSI in | ||
| 97 | * a block but we never do. For one MSI or multiple MSI-X where | ||
| 98 | * each interrupt address can be specified separately, it works | ||
| 99 | * just fine. | ||
| 100 | */ | ||
| 101 | if (of_device_is_compatible(hose->dn, "u4-pcie") || | ||
| 102 | of_device_is_compatible(hose->dn, "U4-pcie")) | ||
| 103 | return 0xf8004000 | (hwirq << 4); | ||
| 104 | |||
| 105 | return 0; | ||
| 106 | } | ||
| 107 | |||
| 81 | static int u3msi_msi_check_device(struct pci_dev *pdev, int nvec, int type) | 108 | static int u3msi_msi_check_device(struct pci_dev *pdev, int nvec, int type) |
| 82 | { | 109 | { |
| 83 | if (type == PCI_CAP_ID_MSIX) | 110 | if (type == PCI_CAP_ID_MSIX) |
| 84 | pr_debug("u3msi: MSI-X untested, trying anyway.\n"); | 111 | pr_debug("u3msi: MSI-X untested, trying anyway.\n"); |
| 85 | 112 | ||
| 86 | /* If we can't find a magic address then MSI ain't gonna work */ | 113 | /* If we can't find a magic address then MSI ain't gonna work */ |
| 87 | if (find_ht_magic_addr(pdev) == 0) { | 114 | if (find_ht_magic_addr(pdev, 0) == 0 && |
| 115 | find_u4_magic_addr(pdev, 0) == 0) { | ||
| 88 | pr_debug("u3msi: no magic address found for %s\n", | 116 | pr_debug("u3msi: no magic address found for %s\n", |
| 89 | pci_name(pdev)); | 117 | pci_name(pdev)); |
| 90 | return -ENXIO; | 118 | return -ENXIO; |
| @@ -118,10 +146,6 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
| 118 | u64 addr; | 146 | u64 addr; |
| 119 | int hwirq; | 147 | int hwirq; |
| 120 | 148 | ||
| 121 | addr = find_ht_magic_addr(pdev); | ||
| 122 | msg.address_lo = addr & 0xFFFFFFFF; | ||
| 123 | msg.address_hi = addr >> 32; | ||
| 124 | |||
| 125 | list_for_each_entry(entry, &pdev->msi_list, list) { | 149 | list_for_each_entry(entry, &pdev->msi_list, list) { |
| 126 | hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap, 1); | 150 | hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap, 1); |
| 127 | if (hwirq < 0) { | 151 | if (hwirq < 0) { |
| @@ -129,6 +153,12 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
| 129 | return hwirq; | 153 | return hwirq; |
| 130 | } | 154 | } |
| 131 | 155 | ||
| 156 | addr = find_ht_magic_addr(pdev, hwirq); | ||
| 157 | if (addr == 0) | ||
| 158 | addr = find_u4_magic_addr(pdev, hwirq); | ||
| 159 | msg.address_lo = addr & 0xFFFFFFFF; | ||
| 160 | msg.address_hi = addr >> 32; | ||
| 161 | |||
| 132 | virq = irq_create_mapping(msi_mpic->irqhost, hwirq); | 162 | virq = irq_create_mapping(msi_mpic->irqhost, hwirq); |
| 133 | if (virq == NO_IRQ) { | 163 | if (virq == NO_IRQ) { |
| 134 | pr_debug("u3msi: failed mapping hwirq 0x%x\n", hwirq); | 164 | pr_debug("u3msi: failed mapping hwirq 0x%x\n", hwirq); |
| @@ -143,6 +173,8 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
| 143 | pr_debug("u3msi: allocated virq 0x%x (hw 0x%x) addr 0x%lx\n", | 173 | pr_debug("u3msi: allocated virq 0x%x (hw 0x%x) addr 0x%lx\n", |
| 144 | virq, hwirq, (unsigned long)addr); | 174 | virq, hwirq, (unsigned long)addr); |
| 145 | 175 | ||
| 176 | printk("u3msi: allocated virq 0x%x (hw 0x%x) addr 0x%lx\n", | ||
| 177 | virq, hwirq, (unsigned long)addr); | ||
| 146 | msg.data = hwirq; | 178 | msg.data = hwirq; |
| 147 | write_msi_msg(virq, &msg); | 179 | write_msi_msg(virq, &msg); |
| 148 | 180 | ||
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index c4c8f2e1dd15..d7d77d4a402c 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
| @@ -63,6 +63,20 @@ void unregister_memory_notifier(struct notifier_block *nb) | |||
| 63 | } | 63 | } |
| 64 | EXPORT_SYMBOL(unregister_memory_notifier); | 64 | EXPORT_SYMBOL(unregister_memory_notifier); |
| 65 | 65 | ||
| 66 | static ATOMIC_NOTIFIER_HEAD(memory_isolate_chain); | ||
| 67 | |||
| 68 | int register_memory_isolate_notifier(struct notifier_block *nb) | ||
| 69 | { | ||
| 70 | return atomic_notifier_chain_register(&memory_isolate_chain, nb); | ||
| 71 | } | ||
| 72 | EXPORT_SYMBOL(register_memory_isolate_notifier); | ||
| 73 | |||
| 74 | void unregister_memory_isolate_notifier(struct notifier_block *nb) | ||
| 75 | { | ||
| 76 | atomic_notifier_chain_unregister(&memory_isolate_chain, nb); | ||
| 77 | } | ||
| 78 | EXPORT_SYMBOL(unregister_memory_isolate_notifier); | ||
| 79 | |||
| 66 | /* | 80 | /* |
| 67 | * register_memory - Setup a sysfs device for a memory block | 81 | * register_memory - Setup a sysfs device for a memory block |
| 68 | */ | 82 | */ |
| @@ -157,6 +171,11 @@ int memory_notify(unsigned long val, void *v) | |||
| 157 | return blocking_notifier_call_chain(&memory_chain, val, v); | 171 | return blocking_notifier_call_chain(&memory_chain, val, v); |
| 158 | } | 172 | } |
| 159 | 173 | ||
| 174 | int memory_isolate_notify(unsigned long val, void *v) | ||
| 175 | { | ||
| 176 | return atomic_notifier_call_chain(&memory_isolate_chain, val, v); | ||
| 177 | } | ||
| 178 | |||
| 160 | /* | 179 | /* |
| 161 | * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is | 180 | * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is |
| 162 | * OK to have direct references to sparsemem variables in here. | 181 | * OK to have direct references to sparsemem variables in here. |
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index d3400b20444f..7d73cd430340 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c | |||
| @@ -358,7 +358,7 @@ struct port { | |||
| 358 | u8 update_flow_control; | 358 | u8 update_flow_control; |
| 359 | struct ctrl_ul ctrl_ul; | 359 | struct ctrl_ul ctrl_ul; |
| 360 | struct ctrl_dl ctrl_dl; | 360 | struct ctrl_dl ctrl_dl; |
| 361 | struct kfifo *fifo_ul; | 361 | struct kfifo fifo_ul; |
| 362 | void __iomem *dl_addr[2]; | 362 | void __iomem *dl_addr[2]; |
| 363 | u32 dl_size[2]; | 363 | u32 dl_size[2]; |
| 364 | u8 toggle_dl; | 364 | u8 toggle_dl; |
| @@ -685,8 +685,6 @@ static int nozomi_read_config_table(struct nozomi *dc) | |||
| 685 | dump_table(dc); | 685 | dump_table(dc); |
| 686 | 686 | ||
| 687 | for (i = PORT_MDM; i < MAX_PORT; i++) { | 687 | for (i = PORT_MDM; i < MAX_PORT; i++) { |
| 688 | dc->port[i].fifo_ul = | ||
| 689 | kfifo_alloc(FIFO_BUFFER_SIZE_UL, GFP_ATOMIC, NULL); | ||
| 690 | memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl)); | 688 | memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl)); |
| 691 | memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul)); | 689 | memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul)); |
| 692 | } | 690 | } |
| @@ -798,7 +796,7 @@ static int send_data(enum port_type index, struct nozomi *dc) | |||
| 798 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 796 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
| 799 | 797 | ||
| 800 | /* Get data from tty and place in buf for now */ | 798 | /* Get data from tty and place in buf for now */ |
| 801 | size = __kfifo_get(port->fifo_ul, dc->send_buf, | 799 | size = kfifo_out(&port->fifo_ul, dc->send_buf, |
| 802 | ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX); | 800 | ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX); |
| 803 | 801 | ||
| 804 | if (size == 0) { | 802 | if (size == 0) { |
| @@ -988,11 +986,11 @@ static int receive_flow_control(struct nozomi *dc) | |||
| 988 | 986 | ||
| 989 | } else if (old_ctrl.CTS == 0 && ctrl_dl.CTS == 1) { | 987 | } else if (old_ctrl.CTS == 0 && ctrl_dl.CTS == 1) { |
| 990 | 988 | ||
| 991 | if (__kfifo_len(dc->port[port].fifo_ul)) { | 989 | if (kfifo_len(&dc->port[port].fifo_ul)) { |
| 992 | DBG1("Enable interrupt (0x%04X) on port: %d", | 990 | DBG1("Enable interrupt (0x%04X) on port: %d", |
| 993 | enable_ier, port); | 991 | enable_ier, port); |
| 994 | DBG1("Data in buffer [%d], enable transmit! ", | 992 | DBG1("Data in buffer [%d], enable transmit! ", |
| 995 | __kfifo_len(dc->port[port].fifo_ul)); | 993 | kfifo_len(&dc->port[port].fifo_ul)); |
| 996 | enable_transmit_ul(port, dc); | 994 | enable_transmit_ul(port, dc); |
| 997 | } else { | 995 | } else { |
| 998 | DBG1("No data in buffer..."); | 996 | DBG1("No data in buffer..."); |
| @@ -1433,6 +1431,16 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
| 1433 | goto err_free_sbuf; | 1431 | goto err_free_sbuf; |
| 1434 | } | 1432 | } |
| 1435 | 1433 | ||
| 1434 | for (i = PORT_MDM; i < MAX_PORT; i++) { | ||
| 1435 | if (kfifo_alloc(&dc->port[i].fifo_ul, | ||
| 1436 | FIFO_BUFFER_SIZE_UL, GFP_ATOMIC)) { | ||
| 1437 | dev_err(&pdev->dev, | ||
| 1438 | "Could not allocate kfifo buffer\n"); | ||
| 1439 | ret = -ENOMEM; | ||
| 1440 | goto err_free_kfifo; | ||
| 1441 | } | ||
| 1442 | } | ||
| 1443 | |||
| 1436 | spin_lock_init(&dc->spin_mutex); | 1444 | spin_lock_init(&dc->spin_mutex); |
| 1437 | 1445 | ||
| 1438 | nozomi_setup_private_data(dc); | 1446 | nozomi_setup_private_data(dc); |
| @@ -1445,7 +1453,7 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
| 1445 | NOZOMI_NAME, dc); | 1453 | NOZOMI_NAME, dc); |
| 1446 | if (unlikely(ret)) { | 1454 | if (unlikely(ret)) { |
| 1447 | dev_err(&pdev->dev, "can't request irq %d\n", pdev->irq); | 1455 | dev_err(&pdev->dev, "can't request irq %d\n", pdev->irq); |
| 1448 | goto err_free_sbuf; | 1456 | goto err_free_kfifo; |
| 1449 | } | 1457 | } |
| 1450 | 1458 | ||
| 1451 | DBG1("base_addr: %p", dc->base_addr); | 1459 | DBG1("base_addr: %p", dc->base_addr); |
| @@ -1464,13 +1472,28 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
| 1464 | dc->state = NOZOMI_STATE_ENABLED; | 1472 | dc->state = NOZOMI_STATE_ENABLED; |
| 1465 | 1473 | ||
| 1466 | for (i = 0; i < MAX_PORT; i++) { | 1474 | for (i = 0; i < MAX_PORT; i++) { |
| 1475 | struct device *tty_dev; | ||
| 1476 | |||
| 1467 | mutex_init(&dc->port[i].tty_sem); | 1477 | mutex_init(&dc->port[i].tty_sem); |
| 1468 | tty_port_init(&dc->port[i].port); | 1478 | tty_port_init(&dc->port[i].port); |
| 1469 | tty_register_device(ntty_driver, dc->index_start + i, | 1479 | tty_dev = tty_register_device(ntty_driver, dc->index_start + i, |
| 1470 | &pdev->dev); | 1480 | &pdev->dev); |
| 1481 | |||
| 1482 | if (IS_ERR(tty_dev)) { | ||
| 1483 | ret = PTR_ERR(tty_dev); | ||
| 1484 | dev_err(&pdev->dev, "Could not allocate tty?\n"); | ||
| 1485 | goto err_free_tty; | ||
| 1486 | } | ||
| 1471 | } | 1487 | } |
| 1488 | |||
| 1472 | return 0; | 1489 | return 0; |
| 1473 | 1490 | ||
| 1491 | err_free_tty: | ||
| 1492 | for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i) | ||
| 1493 | tty_unregister_device(ntty_driver, i); | ||
| 1494 | err_free_kfifo: | ||
| 1495 | for (i = 0; i < MAX_PORT; i++) | ||
| 1496 | kfifo_free(&dc->port[i].fifo_ul); | ||
| 1474 | err_free_sbuf: | 1497 | err_free_sbuf: |
| 1475 | kfree(dc->send_buf); | 1498 | kfree(dc->send_buf); |
| 1476 | iounmap(dc->base_addr); | 1499 | iounmap(dc->base_addr); |
| @@ -1536,8 +1559,7 @@ static void __devexit nozomi_card_exit(struct pci_dev *pdev) | |||
| 1536 | free_irq(pdev->irq, dc); | 1559 | free_irq(pdev->irq, dc); |
| 1537 | 1560 | ||
| 1538 | for (i = 0; i < MAX_PORT; i++) | 1561 | for (i = 0; i < MAX_PORT; i++) |
| 1539 | if (dc->port[i].fifo_ul) | 1562 | kfifo_free(&dc->port[i].fifo_ul); |
| 1540 | kfifo_free(dc->port[i].fifo_ul); | ||
| 1541 | 1563 | ||
| 1542 | kfree(dc->send_buf); | 1564 | kfree(dc->send_buf); |
| 1543 | 1565 | ||
| @@ -1673,7 +1695,7 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, | |||
| 1673 | goto exit; | 1695 | goto exit; |
| 1674 | } | 1696 | } |
| 1675 | 1697 | ||
| 1676 | rval = __kfifo_put(port->fifo_ul, (unsigned char *)buffer, count); | 1698 | rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count); |
| 1677 | 1699 | ||
| 1678 | /* notify card */ | 1700 | /* notify card */ |
| 1679 | if (unlikely(dc == NULL)) { | 1701 | if (unlikely(dc == NULL)) { |
| @@ -1721,7 +1743,7 @@ static int ntty_write_room(struct tty_struct *tty) | |||
| 1721 | if (!port->port.count) | 1743 | if (!port->port.count) |
| 1722 | goto exit; | 1744 | goto exit; |
| 1723 | 1745 | ||
| 1724 | room = port->fifo_ul->size - __kfifo_len(port->fifo_ul); | 1746 | room = port->fifo_ul.size - kfifo_len(&port->fifo_ul); |
| 1725 | 1747 | ||
| 1726 | exit: | 1748 | exit: |
| 1727 | mutex_unlock(&port->tty_sem); | 1749 | mutex_unlock(&port->tty_sem); |
| @@ -1878,7 +1900,7 @@ static s32 ntty_chars_in_buffer(struct tty_struct *tty) | |||
| 1878 | goto exit_in_buffer; | 1900 | goto exit_in_buffer; |
| 1879 | } | 1901 | } |
| 1880 | 1902 | ||
| 1881 | rval = __kfifo_len(port->fifo_ul); | 1903 | rval = kfifo_len(&port->fifo_ul); |
| 1882 | 1904 | ||
| 1883 | exit_in_buffer: | 1905 | exit_in_buffer: |
| 1884 | return rval; | 1906 | return rval; |
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 8c262aaf7c26..0798754a607c 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c | |||
| @@ -487,7 +487,7 @@ static struct sonypi_device { | |||
| 487 | int camera_power; | 487 | int camera_power; |
| 488 | int bluetooth_power; | 488 | int bluetooth_power; |
| 489 | struct mutex lock; | 489 | struct mutex lock; |
| 490 | struct kfifo *fifo; | 490 | struct kfifo fifo; |
| 491 | spinlock_t fifo_lock; | 491 | spinlock_t fifo_lock; |
| 492 | wait_queue_head_t fifo_proc_list; | 492 | wait_queue_head_t fifo_proc_list; |
| 493 | struct fasync_struct *fifo_async; | 493 | struct fasync_struct *fifo_async; |
| @@ -496,7 +496,7 @@ static struct sonypi_device { | |||
| 496 | struct input_dev *input_jog_dev; | 496 | struct input_dev *input_jog_dev; |
| 497 | struct input_dev *input_key_dev; | 497 | struct input_dev *input_key_dev; |
| 498 | struct work_struct input_work; | 498 | struct work_struct input_work; |
| 499 | struct kfifo *input_fifo; | 499 | struct kfifo input_fifo; |
| 500 | spinlock_t input_fifo_lock; | 500 | spinlock_t input_fifo_lock; |
| 501 | } sonypi_device; | 501 | } sonypi_device; |
| 502 | 502 | ||
| @@ -777,8 +777,9 @@ static void input_keyrelease(struct work_struct *work) | |||
| 777 | { | 777 | { |
| 778 | struct sonypi_keypress kp; | 778 | struct sonypi_keypress kp; |
| 779 | 779 | ||
| 780 | while (kfifo_get(sonypi_device.input_fifo, (unsigned char *)&kp, | 780 | while (kfifo_out_locked(&sonypi_device.input_fifo, (unsigned char *)&kp, |
| 781 | sizeof(kp)) == sizeof(kp)) { | 781 | sizeof(kp), &sonypi_device.input_fifo_lock) |
| 782 | == sizeof(kp)) { | ||
| 782 | msleep(10); | 783 | msleep(10); |
| 783 | input_report_key(kp.dev, kp.key, 0); | 784 | input_report_key(kp.dev, kp.key, 0); |
| 784 | input_sync(kp.dev); | 785 | input_sync(kp.dev); |
| @@ -827,8 +828,9 @@ static void sonypi_report_input_event(u8 event) | |||
| 827 | if (kp.dev) { | 828 | if (kp.dev) { |
| 828 | input_report_key(kp.dev, kp.key, 1); | 829 | input_report_key(kp.dev, kp.key, 1); |
| 829 | input_sync(kp.dev); | 830 | input_sync(kp.dev); |
| 830 | kfifo_put(sonypi_device.input_fifo, | 831 | kfifo_in_locked(&sonypi_device.input_fifo, |
| 831 | (unsigned char *)&kp, sizeof(kp)); | 832 | (unsigned char *)&kp, sizeof(kp), |
| 833 | &sonypi_device.input_fifo_lock); | ||
| 832 | schedule_work(&sonypi_device.input_work); | 834 | schedule_work(&sonypi_device.input_work); |
| 833 | } | 835 | } |
| 834 | } | 836 | } |
| @@ -880,7 +882,8 @@ found: | |||
| 880 | acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event); | 882 | acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event); |
| 881 | #endif | 883 | #endif |
| 882 | 884 | ||
| 883 | kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event)); | 885 | kfifo_in_locked(&sonypi_device.fifo, (unsigned char *)&event, |
| 886 | sizeof(event), &sonypi_device.fifo_lock); | ||
| 884 | kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); | 887 | kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); |
| 885 | wake_up_interruptible(&sonypi_device.fifo_proc_list); | 888 | wake_up_interruptible(&sonypi_device.fifo_proc_list); |
| 886 | 889 | ||
| @@ -906,7 +909,7 @@ static int sonypi_misc_open(struct inode *inode, struct file *file) | |||
| 906 | mutex_lock(&sonypi_device.lock); | 909 | mutex_lock(&sonypi_device.lock); |
| 907 | /* Flush input queue on first open */ | 910 | /* Flush input queue on first open */ |
| 908 | if (!sonypi_device.open_count) | 911 | if (!sonypi_device.open_count) |
| 909 | kfifo_reset(sonypi_device.fifo); | 912 | kfifo_reset(&sonypi_device.fifo); |
| 910 | sonypi_device.open_count++; | 913 | sonypi_device.open_count++; |
| 911 | mutex_unlock(&sonypi_device.lock); | 914 | mutex_unlock(&sonypi_device.lock); |
| 912 | unlock_kernel(); | 915 | unlock_kernel(); |
| @@ -919,17 +922,18 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf, | |||
| 919 | ssize_t ret; | 922 | ssize_t ret; |
| 920 | unsigned char c; | 923 | unsigned char c; |
| 921 | 924 | ||
| 922 | if ((kfifo_len(sonypi_device.fifo) == 0) && | 925 | if ((kfifo_len(&sonypi_device.fifo) == 0) && |
| 923 | (file->f_flags & O_NONBLOCK)) | 926 | (file->f_flags & O_NONBLOCK)) |
| 924 | return -EAGAIN; | 927 | return -EAGAIN; |
| 925 | 928 | ||
| 926 | ret = wait_event_interruptible(sonypi_device.fifo_proc_list, | 929 | ret = wait_event_interruptible(sonypi_device.fifo_proc_list, |
| 927 | kfifo_len(sonypi_device.fifo) != 0); | 930 | kfifo_len(&sonypi_device.fifo) != 0); |
| 928 | if (ret) | 931 | if (ret) |
| 929 | return ret; | 932 | return ret; |
| 930 | 933 | ||
| 931 | while (ret < count && | 934 | while (ret < count && |
| 932 | (kfifo_get(sonypi_device.fifo, &c, sizeof(c)) == sizeof(c))) { | 935 | (kfifo_out_locked(&sonypi_device.fifo, &c, sizeof(c), |
| 936 | &sonypi_device.fifo_lock) == sizeof(c))) { | ||
| 933 | if (put_user(c, buf++)) | 937 | if (put_user(c, buf++)) |
| 934 | return -EFAULT; | 938 | return -EFAULT; |
| 935 | ret++; | 939 | ret++; |
| @@ -946,7 +950,7 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf, | |||
| 946 | static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait) | 950 | static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait) |
| 947 | { | 951 | { |
| 948 | poll_wait(file, &sonypi_device.fifo_proc_list, wait); | 952 | poll_wait(file, &sonypi_device.fifo_proc_list, wait); |
| 949 | if (kfifo_len(sonypi_device.fifo)) | 953 | if (kfifo_len(&sonypi_device.fifo)) |
| 950 | return POLLIN | POLLRDNORM; | 954 | return POLLIN | POLLRDNORM; |
| 951 | return 0; | 955 | return 0; |
| 952 | } | 956 | } |
| @@ -1313,11 +1317,10 @@ static int __devinit sonypi_probe(struct platform_device *dev) | |||
| 1313 | "http://www.linux.it/~malattia/wiki/index.php/Sony_drivers\n"); | 1317 | "http://www.linux.it/~malattia/wiki/index.php/Sony_drivers\n"); |
| 1314 | 1318 | ||
| 1315 | spin_lock_init(&sonypi_device.fifo_lock); | 1319 | spin_lock_init(&sonypi_device.fifo_lock); |
| 1316 | sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL, | 1320 | error = kfifo_alloc(&sonypi_device.fifo, SONYPI_BUF_SIZE, GFP_KERNEL); |
| 1317 | &sonypi_device.fifo_lock); | 1321 | if (error) { |
| 1318 | if (IS_ERR(sonypi_device.fifo)) { | ||
| 1319 | printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); | 1322 | printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); |
| 1320 | return PTR_ERR(sonypi_device.fifo); | 1323 | return error; |
| 1321 | } | 1324 | } |
| 1322 | 1325 | ||
| 1323 | init_waitqueue_head(&sonypi_device.fifo_proc_list); | 1326 | init_waitqueue_head(&sonypi_device.fifo_proc_list); |
| @@ -1393,12 +1396,10 @@ static int __devinit sonypi_probe(struct platform_device *dev) | |||
| 1393 | } | 1396 | } |
| 1394 | 1397 | ||
| 1395 | spin_lock_init(&sonypi_device.input_fifo_lock); | 1398 | spin_lock_init(&sonypi_device.input_fifo_lock); |
| 1396 | sonypi_device.input_fifo = | 1399 | error = kfifo_alloc(&sonypi_device.input_fifo, SONYPI_BUF_SIZE, |
| 1397 | kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL, | 1400 | GFP_KERNEL); |
| 1398 | &sonypi_device.input_fifo_lock); | 1401 | if (error) { |
| 1399 | if (IS_ERR(sonypi_device.input_fifo)) { | ||
| 1400 | printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); | 1402 | printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); |
| 1401 | error = PTR_ERR(sonypi_device.input_fifo); | ||
| 1402 | goto err_inpdev_unregister; | 1403 | goto err_inpdev_unregister; |
| 1403 | } | 1404 | } |
| 1404 | 1405 | ||
| @@ -1423,7 +1424,7 @@ static int __devinit sonypi_probe(struct platform_device *dev) | |||
| 1423 | pci_disable_device(pcidev); | 1424 | pci_disable_device(pcidev); |
| 1424 | err_put_pcidev: | 1425 | err_put_pcidev: |
| 1425 | pci_dev_put(pcidev); | 1426 | pci_dev_put(pcidev); |
| 1426 | kfifo_free(sonypi_device.fifo); | 1427 | kfifo_free(&sonypi_device.fifo); |
| 1427 | 1428 | ||
| 1428 | return error; | 1429 | return error; |
| 1429 | } | 1430 | } |
| @@ -1438,7 +1439,7 @@ static int __devexit sonypi_remove(struct platform_device *dev) | |||
| 1438 | if (useinput) { | 1439 | if (useinput) { |
| 1439 | input_unregister_device(sonypi_device.input_key_dev); | 1440 | input_unregister_device(sonypi_device.input_key_dev); |
| 1440 | input_unregister_device(sonypi_device.input_jog_dev); | 1441 | input_unregister_device(sonypi_device.input_jog_dev); |
| 1441 | kfifo_free(sonypi_device.input_fifo); | 1442 | kfifo_free(&sonypi_device.input_fifo); |
| 1442 | } | 1443 | } |
| 1443 | 1444 | ||
| 1444 | misc_deregister(&sonypi_misc_device); | 1445 | misc_deregister(&sonypi_misc_device); |
| @@ -1451,7 +1452,7 @@ static int __devexit sonypi_remove(struct platform_device *dev) | |||
| 1451 | pci_dev_put(sonypi_device.dev); | 1452 | pci_dev_put(sonypi_device.dev); |
| 1452 | } | 1453 | } |
| 1453 | 1454 | ||
| 1454 | kfifo_free(sonypi_device.fifo); | 1455 | kfifo_free(&sonypi_device.fifo); |
| 1455 | 1456 | ||
| 1456 | return 0; | 1457 | return 0; |
| 1457 | } | 1458 | } |
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h index bfd03bf8be54..f3d440cc68f2 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.h +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | #include <linux/list.h> | 35 | #include <linux/list.h> |
| 36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
| 37 | #include <linux/kfifo.h> | ||
| 37 | 38 | ||
| 38 | #include "t3_cpl.h" | 39 | #include "t3_cpl.h" |
| 39 | #include "t3cdev.h" | 40 | #include "t3cdev.h" |
| @@ -75,13 +76,13 @@ struct cxio_hal_ctrl_qp { | |||
| 75 | }; | 76 | }; |
| 76 | 77 | ||
| 77 | struct cxio_hal_resource { | 78 | struct cxio_hal_resource { |
| 78 | struct kfifo *tpt_fifo; | 79 | struct kfifo tpt_fifo; |
| 79 | spinlock_t tpt_fifo_lock; | 80 | spinlock_t tpt_fifo_lock; |
| 80 | struct kfifo *qpid_fifo; | 81 | struct kfifo qpid_fifo; |
| 81 | spinlock_t qpid_fifo_lock; | 82 | spinlock_t qpid_fifo_lock; |
| 82 | struct kfifo *cqid_fifo; | 83 | struct kfifo cqid_fifo; |
| 83 | spinlock_t cqid_fifo_lock; | 84 | spinlock_t cqid_fifo_lock; |
| 84 | struct kfifo *pdid_fifo; | 85 | struct kfifo pdid_fifo; |
| 85 | spinlock_t pdid_fifo_lock; | 86 | spinlock_t pdid_fifo_lock; |
| 86 | }; | 87 | }; |
| 87 | 88 | ||
diff --git a/drivers/infiniband/hw/cxgb3/cxio_resource.c b/drivers/infiniband/hw/cxgb3/cxio_resource.c index bd233c087653..31f9201b2980 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_resource.c +++ b/drivers/infiniband/hw/cxgb3/cxio_resource.c | |||
| @@ -39,12 +39,12 @@ | |||
| 39 | #include "cxio_resource.h" | 39 | #include "cxio_resource.h" |
| 40 | #include "cxio_hal.h" | 40 | #include "cxio_hal.h" |
| 41 | 41 | ||
| 42 | static struct kfifo *rhdl_fifo; | 42 | static struct kfifo rhdl_fifo; |
| 43 | static spinlock_t rhdl_fifo_lock; | 43 | static spinlock_t rhdl_fifo_lock; |
| 44 | 44 | ||
| 45 | #define RANDOM_SIZE 16 | 45 | #define RANDOM_SIZE 16 |
| 46 | 46 | ||
| 47 | static int __cxio_init_resource_fifo(struct kfifo **fifo, | 47 | static int __cxio_init_resource_fifo(struct kfifo *fifo, |
| 48 | spinlock_t *fifo_lock, | 48 | spinlock_t *fifo_lock, |
| 49 | u32 nr, u32 skip_low, | 49 | u32 nr, u32 skip_low, |
| 50 | u32 skip_high, | 50 | u32 skip_high, |
| @@ -55,12 +55,11 @@ static int __cxio_init_resource_fifo(struct kfifo **fifo, | |||
| 55 | u32 rarray[16]; | 55 | u32 rarray[16]; |
| 56 | spin_lock_init(fifo_lock); | 56 | spin_lock_init(fifo_lock); |
| 57 | 57 | ||
| 58 | *fifo = kfifo_alloc(nr * sizeof(u32), GFP_KERNEL, fifo_lock); | 58 | if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL)) |
| 59 | if (IS_ERR(*fifo)) | ||
| 60 | return -ENOMEM; | 59 | return -ENOMEM; |
| 61 | 60 | ||
| 62 | for (i = 0; i < skip_low + skip_high; i++) | 61 | for (i = 0; i < skip_low + skip_high; i++) |
| 63 | __kfifo_put(*fifo, (unsigned char *) &entry, sizeof(u32)); | 62 | kfifo_in(fifo, (unsigned char *) &entry, sizeof(u32)); |
| 64 | if (random) { | 63 | if (random) { |
| 65 | j = 0; | 64 | j = 0; |
| 66 | random_bytes = random32(); | 65 | random_bytes = random32(); |
| @@ -72,33 +71,35 @@ static int __cxio_init_resource_fifo(struct kfifo **fifo, | |||
| 72 | random_bytes = random32(); | 71 | random_bytes = random32(); |
| 73 | } | 72 | } |
| 74 | idx = (random_bytes >> (j * 2)) & 0xF; | 73 | idx = (random_bytes >> (j * 2)) & 0xF; |
| 75 | __kfifo_put(*fifo, | 74 | kfifo_in(fifo, |
| 76 | (unsigned char *) &rarray[idx], | 75 | (unsigned char *) &rarray[idx], |
| 77 | sizeof(u32)); | 76 | sizeof(u32)); |
| 78 | rarray[idx] = i; | 77 | rarray[idx] = i; |
| 79 | j++; | 78 | j++; |
| 80 | } | 79 | } |
| 81 | for (i = 0; i < RANDOM_SIZE; i++) | 80 | for (i = 0; i < RANDOM_SIZE; i++) |
| 82 | __kfifo_put(*fifo, | 81 | kfifo_in(fifo, |
| 83 | (unsigned char *) &rarray[i], | 82 | (unsigned char *) &rarray[i], |
| 84 | sizeof(u32)); | 83 | sizeof(u32)); |
| 85 | } else | 84 | } else |
| 86 | for (i = skip_low; i < nr - skip_high; i++) | 85 | for (i = skip_low; i < nr - skip_high; i++) |
| 87 | __kfifo_put(*fifo, (unsigned char *) &i, sizeof(u32)); | 86 | kfifo_in(fifo, (unsigned char *) &i, sizeof(u32)); |
| 88 | 87 | ||
| 89 | for (i = 0; i < skip_low + skip_high; i++) | 88 | for (i = 0; i < skip_low + skip_high; i++) |
| 90 | kfifo_get(*fifo, (unsigned char *) &entry, sizeof(u32)); | 89 | if (kfifo_out_locked(fifo, (unsigned char *) &entry, |
| 90 | sizeof(u32), fifo_lock) != sizeof(u32)) | ||
| 91 | break; | ||
| 91 | return 0; | 92 | return 0; |
| 92 | } | 93 | } |
| 93 | 94 | ||
| 94 | static int cxio_init_resource_fifo(struct kfifo **fifo, spinlock_t * fifo_lock, | 95 | static int cxio_init_resource_fifo(struct kfifo *fifo, spinlock_t * fifo_lock, |
| 95 | u32 nr, u32 skip_low, u32 skip_high) | 96 | u32 nr, u32 skip_low, u32 skip_high) |
| 96 | { | 97 | { |
| 97 | return (__cxio_init_resource_fifo(fifo, fifo_lock, nr, skip_low, | 98 | return (__cxio_init_resource_fifo(fifo, fifo_lock, nr, skip_low, |
| 98 | skip_high, 0)); | 99 | skip_high, 0)); |
| 99 | } | 100 | } |
| 100 | 101 | ||
| 101 | static int cxio_init_resource_fifo_random(struct kfifo **fifo, | 102 | static int cxio_init_resource_fifo_random(struct kfifo *fifo, |
| 102 | spinlock_t * fifo_lock, | 103 | spinlock_t * fifo_lock, |
| 103 | u32 nr, u32 skip_low, u32 skip_high) | 104 | u32 nr, u32 skip_low, u32 skip_high) |
| 104 | { | 105 | { |
| @@ -113,15 +114,13 @@ static int cxio_init_qpid_fifo(struct cxio_rdev *rdev_p) | |||
| 113 | 114 | ||
| 114 | spin_lock_init(&rdev_p->rscp->qpid_fifo_lock); | 115 | spin_lock_init(&rdev_p->rscp->qpid_fifo_lock); |
| 115 | 116 | ||
| 116 | rdev_p->rscp->qpid_fifo = kfifo_alloc(T3_MAX_NUM_QP * sizeof(u32), | 117 | if (kfifo_alloc(&rdev_p->rscp->qpid_fifo, T3_MAX_NUM_QP * sizeof(u32), |
| 117 | GFP_KERNEL, | 118 | GFP_KERNEL)) |
| 118 | &rdev_p->rscp->qpid_fifo_lock); | ||
| 119 | if (IS_ERR(rdev_p->rscp->qpid_fifo)) | ||
| 120 | return -ENOMEM; | 119 | return -ENOMEM; |
| 121 | 120 | ||
| 122 | for (i = 16; i < T3_MAX_NUM_QP; i++) | 121 | for (i = 16; i < T3_MAX_NUM_QP; i++) |
| 123 | if (!(i & rdev_p->qpmask)) | 122 | if (!(i & rdev_p->qpmask)) |
| 124 | __kfifo_put(rdev_p->rscp->qpid_fifo, | 123 | kfifo_in(&rdev_p->rscp->qpid_fifo, |
| 125 | (unsigned char *) &i, sizeof(u32)); | 124 | (unsigned char *) &i, sizeof(u32)); |
| 126 | return 0; | 125 | return 0; |
| 127 | } | 126 | } |
| @@ -134,7 +133,7 @@ int cxio_hal_init_rhdl_resource(u32 nr_rhdl) | |||
| 134 | 133 | ||
| 135 | void cxio_hal_destroy_rhdl_resource(void) | 134 | void cxio_hal_destroy_rhdl_resource(void) |
| 136 | { | 135 | { |
| 137 | kfifo_free(rhdl_fifo); | 136 | kfifo_free(&rhdl_fifo); |
| 138 | } | 137 | } |
| 139 | 138 | ||
| 140 | /* nr_* must be power of 2 */ | 139 | /* nr_* must be power of 2 */ |
| @@ -167,11 +166,11 @@ int cxio_hal_init_resource(struct cxio_rdev *rdev_p, | |||
| 167 | goto pdid_err; | 166 | goto pdid_err; |
| 168 | return 0; | 167 | return 0; |
| 169 | pdid_err: | 168 | pdid_err: |
| 170 | kfifo_free(rscp->cqid_fifo); | 169 | kfifo_free(&rscp->cqid_fifo); |
| 171 | cqid_err: | 170 | cqid_err: |
| 172 | kfifo_free(rscp->qpid_fifo); | 171 | kfifo_free(&rscp->qpid_fifo); |
| 173 | qpid_err: | 172 | qpid_err: |
| 174 | kfifo_free(rscp->tpt_fifo); | 173 | kfifo_free(&rscp->tpt_fifo); |
| 175 | tpt_err: | 174 | tpt_err: |
| 176 | return -ENOMEM; | 175 | return -ENOMEM; |
| 177 | } | 176 | } |
| @@ -179,33 +178,37 @@ tpt_err: | |||
| 179 | /* | 178 | /* |
| 180 | * returns 0 if no resource available | 179 | * returns 0 if no resource available |
| 181 | */ | 180 | */ |
| 182 | static u32 cxio_hal_get_resource(struct kfifo *fifo) | 181 | static u32 cxio_hal_get_resource(struct kfifo *fifo, spinlock_t * lock) |
| 183 | { | 182 | { |
| 184 | u32 entry; | 183 | u32 entry; |
| 185 | if (kfifo_get(fifo, (unsigned char *) &entry, sizeof(u32))) | 184 | if (kfifo_out_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock)) |
| 186 | return entry; | 185 | return entry; |
| 187 | else | 186 | else |
| 188 | return 0; /* fifo emptry */ | 187 | return 0; /* fifo emptry */ |
| 189 | } | 188 | } |
| 190 | 189 | ||
| 191 | static void cxio_hal_put_resource(struct kfifo *fifo, u32 entry) | 190 | static void cxio_hal_put_resource(struct kfifo *fifo, spinlock_t * lock, |
| 191 | u32 entry) | ||
| 192 | { | 192 | { |
| 193 | BUG_ON(kfifo_put(fifo, (unsigned char *) &entry, sizeof(u32)) == 0); | 193 | BUG_ON( |
| 194 | kfifo_in_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock) | ||
| 195 | == 0); | ||
| 194 | } | 196 | } |
| 195 | 197 | ||
| 196 | u32 cxio_hal_get_stag(struct cxio_hal_resource *rscp) | 198 | u32 cxio_hal_get_stag(struct cxio_hal_resource *rscp) |
| 197 | { | 199 | { |
| 198 | return cxio_hal_get_resource(rscp->tpt_fifo); | 200 | return cxio_hal_get_resource(&rscp->tpt_fifo, &rscp->tpt_fifo_lock); |
| 199 | } | 201 | } |
| 200 | 202 | ||
| 201 | void cxio_hal_put_stag(struct cxio_hal_resource *rscp, u32 stag) | 203 | void cxio_hal_put_stag(struct cxio_hal_resource *rscp, u32 stag) |
| 202 | { | 204 | { |
| 203 | cxio_hal_put_resource(rscp->tpt_fifo, stag); | 205 | cxio_hal_put_resource(&rscp->tpt_fifo, &rscp->tpt_fifo_lock, stag); |
| 204 | } | 206 | } |
| 205 | 207 | ||
| 206 | u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp) | 208 | u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp) |
| 207 | { | 209 | { |
| 208 | u32 qpid = cxio_hal_get_resource(rscp->qpid_fifo); | 210 | u32 qpid = cxio_hal_get_resource(&rscp->qpid_fifo, |
| 211 | &rscp->qpid_fifo_lock); | ||
| 209 | PDBG("%s qpid 0x%x\n", __func__, qpid); | 212 | PDBG("%s qpid 0x%x\n", __func__, qpid); |
| 210 | return qpid; | 213 | return qpid; |
| 211 | } | 214 | } |
| @@ -213,35 +216,35 @@ u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp) | |||
| 213 | void cxio_hal_put_qpid(struct cxio_hal_resource *rscp, u32 qpid) | 216 | void cxio_hal_put_qpid(struct cxio_hal_resource *rscp, u32 qpid) |
| 214 | { | 217 | { |
| 215 | PDBG("%s qpid 0x%x\n", __func__, qpid); | 218 | PDBG("%s qpid 0x%x\n", __func__, qpid); |
| 216 | cxio_hal_put_resource(rscp->qpid_fifo, qpid); | 219 | cxio_hal_put_resource(&rscp->qpid_fifo, &rscp->qpid_fifo_lock, qpid); |
| 217 | } | 220 | } |
| 218 | 221 | ||
| 219 | u32 cxio_hal_get_cqid(struct cxio_hal_resource *rscp) | 222 | u32 cxio_hal_get_cqid(struct cxio_hal_resource *rscp) |
| 220 | { | 223 | { |
| 221 | return cxio_hal_get_resource(rscp->cqid_fifo); | 224 | return cxio_hal_get_resource(&rscp->cqid_fifo, &rscp->cqid_fifo_lock); |
| 222 | } | 225 | } |
| 223 | 226 | ||
| 224 | void cxio_hal_put_cqid(struct cxio_hal_resource *rscp, u32 cqid) | 227 | void cxio_hal_put_cqid(struct cxio_hal_resource *rscp, u32 cqid) |
| 225 | { | 228 | { |
| 226 | cxio_hal_put_resource(rscp->cqid_fifo, cqid); | 229 | cxio_hal_put_resource(&rscp->cqid_fifo, &rscp->cqid_fifo_lock, cqid); |
| 227 | } | 230 | } |
| 228 | 231 | ||
| 229 | u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp) | 232 | u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp) |
| 230 | { | 233 | { |
| 231 | return cxio_hal_get_resource(rscp->pdid_fifo); | 234 | return cxio_hal_get_resource(&rscp->pdid_fifo, &rscp->pdid_fifo_lock); |
| 232 | } | 235 | } |
| 233 | 236 | ||
| 234 | void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid) | 237 | void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid) |
| 235 | { | 238 | { |
| 236 | cxio_hal_put_resource(rscp->pdid_fifo, pdid); | 239 | cxio_hal_put_resource(&rscp->pdid_fifo, &rscp->pdid_fifo_lock, pdid); |
| 237 | } | 240 | } |
| 238 | 241 | ||
| 239 | void cxio_hal_destroy_resource(struct cxio_hal_resource *rscp) | 242 | void cxio_hal_destroy_resource(struct cxio_hal_resource *rscp) |
| 240 | { | 243 | { |
| 241 | kfifo_free(rscp->tpt_fifo); | 244 | kfifo_free(&rscp->tpt_fifo); |
| 242 | kfifo_free(rscp->cqid_fifo); | 245 | kfifo_free(&rscp->cqid_fifo); |
| 243 | kfifo_free(rscp->qpid_fifo); | 246 | kfifo_free(&rscp->qpid_fifo); |
| 244 | kfifo_free(rscp->pdid_fifo); | 247 | kfifo_free(&rscp->pdid_fifo); |
| 245 | kfree(rscp); | 248 | kfree(rscp); |
| 246 | } | 249 | } |
| 247 | 250 | ||
diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c index 3ccc8afeccf3..2bf57a4527d3 100644 --- a/drivers/media/video/cx23885/cx23888-ir.c +++ b/drivers/media/video/cx23885/cx23888-ir.c | |||
| @@ -124,15 +124,12 @@ struct cx23888_ir_state { | |||
| 124 | atomic_t rxclk_divider; | 124 | atomic_t rxclk_divider; |
| 125 | atomic_t rx_invert; | 125 | atomic_t rx_invert; |
| 126 | 126 | ||
| 127 | struct kfifo *rx_kfifo; | 127 | struct kfifo rx_kfifo; |
| 128 | spinlock_t rx_kfifo_lock; | 128 | spinlock_t rx_kfifo_lock; |
| 129 | 129 | ||
| 130 | struct v4l2_subdev_ir_parameters tx_params; | 130 | struct v4l2_subdev_ir_parameters tx_params; |
| 131 | struct mutex tx_params_lock; | 131 | struct mutex tx_params_lock; |
| 132 | atomic_t txclk_divider; | 132 | atomic_t txclk_divider; |
| 133 | |||
| 134 | struct kfifo *tx_kfifo; | ||
| 135 | spinlock_t tx_kfifo_lock; | ||
| 136 | }; | 133 | }; |
| 137 | 134 | ||
| 138 | static inline struct cx23888_ir_state *to_state(struct v4l2_subdev *sd) | 135 | static inline struct cx23888_ir_state *to_state(struct v4l2_subdev *sd) |
| @@ -522,6 +519,7 @@ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status, | |||
| 522 | { | 519 | { |
| 523 | struct cx23888_ir_state *state = to_state(sd); | 520 | struct cx23888_ir_state *state = to_state(sd); |
| 524 | struct cx23885_dev *dev = state->dev; | 521 | struct cx23885_dev *dev = state->dev; |
| 522 | unsigned long flags; | ||
| 525 | 523 | ||
| 526 | u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG); | 524 | u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG); |
| 527 | u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG); | 525 | u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG); |
| @@ -594,8 +592,9 @@ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status, | |||
| 594 | if (i == 0) | 592 | if (i == 0) |
| 595 | break; | 593 | break; |
| 596 | j = i * sizeof(u32); | 594 | j = i * sizeof(u32); |
| 597 | k = kfifo_put(state->rx_kfifo, | 595 | k = kfifo_in_locked(&state->rx_kfifo, |
| 598 | (unsigned char *) rx_data, j); | 596 | (unsigned char *) rx_data, j, |
| 597 | &state->rx_kfifo_lock); | ||
| 599 | if (k != j) | 598 | if (k != j) |
| 600 | kror++; /* rx_kfifo over run */ | 599 | kror++; /* rx_kfifo over run */ |
| 601 | } | 600 | } |
| @@ -631,8 +630,11 @@ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status, | |||
| 631 | cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl); | 630 | cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl); |
| 632 | *handled = true; | 631 | *handled = true; |
| 633 | } | 632 | } |
| 634 | if (kfifo_len(state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2) | 633 | |
| 634 | spin_lock_irqsave(&state->rx_kfifo_lock, flags); | ||
| 635 | if (kfifo_len(&state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2) | ||
| 635 | events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ; | 636 | events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ; |
| 637 | spin_unlock_irqrestore(&state->rx_kfifo_lock, flags); | ||
| 636 | 638 | ||
| 637 | if (events) | 639 | if (events) |
| 638 | v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_RX_NOTIFY, &events); | 640 | v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_RX_NOTIFY, &events); |
| @@ -657,7 +659,7 @@ static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count, | |||
| 657 | return 0; | 659 | return 0; |
| 658 | } | 660 | } |
| 659 | 661 | ||
| 660 | n = kfifo_get(state->rx_kfifo, buf, n); | 662 | n = kfifo_out_locked(&state->rx_kfifo, buf, n, &state->rx_kfifo_lock); |
| 661 | 663 | ||
| 662 | n /= sizeof(u32); | 664 | n /= sizeof(u32); |
| 663 | *num = n * sizeof(u32); | 665 | *num = n * sizeof(u32); |
| @@ -785,7 +787,12 @@ static int cx23888_ir_rx_s_parameters(struct v4l2_subdev *sd, | |||
| 785 | o->interrupt_enable = p->interrupt_enable; | 787 | o->interrupt_enable = p->interrupt_enable; |
| 786 | o->enable = p->enable; | 788 | o->enable = p->enable; |
| 787 | if (p->enable) { | 789 | if (p->enable) { |
| 788 | kfifo_reset(state->rx_kfifo); | 790 | unsigned long flags; |
| 791 | |||
| 792 | spin_lock_irqsave(&state->rx_kfifo_lock, flags); | ||
| 793 | kfifo_reset(&state->rx_kfifo); | ||
| 794 | /* reset tx_fifo too if there is one... */ | ||
| 795 | spin_unlock_irqrestore(&state->rx_kfifo_lock, flags); | ||
| 789 | if (p->interrupt_enable) | 796 | if (p->interrupt_enable) |
| 790 | irqenable_rx(dev, IRQEN_RSE | IRQEN_RTE | IRQEN_ROE); | 797 | irqenable_rx(dev, IRQEN_RSE | IRQEN_RTE | IRQEN_ROE); |
| 791 | control_rx_enable(dev, p->enable); | 798 | control_rx_enable(dev, p->enable); |
| @@ -892,7 +899,6 @@ static int cx23888_ir_tx_s_parameters(struct v4l2_subdev *sd, | |||
| 892 | o->interrupt_enable = p->interrupt_enable; | 899 | o->interrupt_enable = p->interrupt_enable; |
| 893 | o->enable = p->enable; | 900 | o->enable = p->enable; |
| 894 | if (p->enable) { | 901 | if (p->enable) { |
| 895 | kfifo_reset(state->tx_kfifo); | ||
| 896 | if (p->interrupt_enable) | 902 | if (p->interrupt_enable) |
| 897 | irqenable_tx(dev, IRQEN_TSE); | 903 | irqenable_tx(dev, IRQEN_TSE); |
| 898 | control_tx_enable(dev, p->enable); | 904 | control_tx_enable(dev, p->enable); |
| @@ -1168,18 +1174,8 @@ int cx23888_ir_probe(struct cx23885_dev *dev) | |||
| 1168 | return -ENOMEM; | 1174 | return -ENOMEM; |
| 1169 | 1175 | ||
| 1170 | spin_lock_init(&state->rx_kfifo_lock); | 1176 | spin_lock_init(&state->rx_kfifo_lock); |
| 1171 | state->rx_kfifo = kfifo_alloc(CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL, | 1177 | if (kfifo_alloc(&state->rx_kfifo, CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL)) |
| 1172 | &state->rx_kfifo_lock); | ||
| 1173 | if (state->rx_kfifo == NULL) | ||
| 1174 | return -ENOMEM; | ||
| 1175 | |||
| 1176 | spin_lock_init(&state->tx_kfifo_lock); | ||
| 1177 | state->tx_kfifo = kfifo_alloc(CX23888_IR_TX_KFIFO_SIZE, GFP_KERNEL, | ||
| 1178 | &state->tx_kfifo_lock); | ||
| 1179 | if (state->tx_kfifo == NULL) { | ||
| 1180 | kfifo_free(state->rx_kfifo); | ||
| 1181 | return -ENOMEM; | 1178 | return -ENOMEM; |
| 1182 | } | ||
| 1183 | 1179 | ||
| 1184 | state->dev = dev; | 1180 | state->dev = dev; |
| 1185 | state->id = V4L2_IDENT_CX23888_IR; | 1181 | state->id = V4L2_IDENT_CX23888_IR; |
| @@ -1211,8 +1207,7 @@ int cx23888_ir_probe(struct cx23885_dev *dev) | |||
| 1211 | sizeof(struct v4l2_subdev_ir_parameters)); | 1207 | sizeof(struct v4l2_subdev_ir_parameters)); |
| 1212 | v4l2_subdev_call(sd, ir, tx_s_parameters, &default_params); | 1208 | v4l2_subdev_call(sd, ir, tx_s_parameters, &default_params); |
| 1213 | } else { | 1209 | } else { |
| 1214 | kfifo_free(state->rx_kfifo); | 1210 | kfifo_free(&state->rx_kfifo); |
| 1215 | kfifo_free(state->tx_kfifo); | ||
| 1216 | } | 1211 | } |
| 1217 | return ret; | 1212 | return ret; |
| 1218 | } | 1213 | } |
| @@ -1231,8 +1226,7 @@ int cx23888_ir_remove(struct cx23885_dev *dev) | |||
| 1231 | 1226 | ||
| 1232 | state = to_state(sd); | 1227 | state = to_state(sd); |
| 1233 | v4l2_device_unregister_subdev(sd); | 1228 | v4l2_device_unregister_subdev(sd); |
| 1234 | kfifo_free(state->rx_kfifo); | 1229 | kfifo_free(&state->rx_kfifo); |
| 1235 | kfifo_free(state->tx_kfifo); | ||
| 1236 | kfree(state); | 1230 | kfree(state); |
| 1237 | /* Nothing more to free() as state held the actual v4l2_subdev object */ | 1231 | /* Nothing more to free() as state held the actual v4l2_subdev object */ |
| 1238 | return 0; | 1232 | return 0; |
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 6ffa64cd1c6d..b421858ccf90 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c | |||
| @@ -800,8 +800,8 @@ again: | |||
| 800 | return IRQ_HANDLED; | 800 | return IRQ_HANDLED; |
| 801 | 801 | ||
| 802 | if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) { | 802 | if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) { |
| 803 | if (kfifo_get(meye.grabq, (unsigned char *)&reqnr, | 803 | if (kfifo_out_locked(&meye.grabq, (unsigned char *)&reqnr, |
| 804 | sizeof(int)) != sizeof(int)) { | 804 | sizeof(int), &meye.grabq_lock) != sizeof(int)) { |
| 805 | mchip_free_frame(); | 805 | mchip_free_frame(); |
| 806 | return IRQ_HANDLED; | 806 | return IRQ_HANDLED; |
| 807 | } | 807 | } |
| @@ -811,7 +811,8 @@ again: | |||
| 811 | meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; | 811 | meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; |
| 812 | do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); | 812 | do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); |
| 813 | meye.grab_buffer[reqnr].sequence = sequence++; | 813 | meye.grab_buffer[reqnr].sequence = sequence++; |
| 814 | kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int)); | 814 | kfifo_in_locked(&meye.doneq, (unsigned char *)&reqnr, |
| 815 | sizeof(int), &meye.doneq_lock); | ||
| 815 | wake_up_interruptible(&meye.proc_list); | 816 | wake_up_interruptible(&meye.proc_list); |
| 816 | } else { | 817 | } else { |
| 817 | int size; | 818 | int size; |
| @@ -820,8 +821,8 @@ again: | |||
| 820 | mchip_free_frame(); | 821 | mchip_free_frame(); |
| 821 | goto again; | 822 | goto again; |
| 822 | } | 823 | } |
| 823 | if (kfifo_get(meye.grabq, (unsigned char *)&reqnr, | 824 | if (kfifo_out_locked(&meye.grabq, (unsigned char *)&reqnr, |
| 824 | sizeof(int)) != sizeof(int)) { | 825 | sizeof(int), &meye.grabq_lock) != sizeof(int)) { |
| 825 | mchip_free_frame(); | 826 | mchip_free_frame(); |
| 826 | goto again; | 827 | goto again; |
| 827 | } | 828 | } |
| @@ -831,7 +832,8 @@ again: | |||
| 831 | meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; | 832 | meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; |
| 832 | do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); | 833 | do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); |
| 833 | meye.grab_buffer[reqnr].sequence = sequence++; | 834 | meye.grab_buffer[reqnr].sequence = sequence++; |
| 834 | kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int)); | 835 | kfifo_in_locked(&meye.doneq, (unsigned char *)&reqnr, |
| 836 | sizeof(int), &meye.doneq_lock); | ||
| 835 | wake_up_interruptible(&meye.proc_list); | 837 | wake_up_interruptible(&meye.proc_list); |
| 836 | } | 838 | } |
| 837 | mchip_free_frame(); | 839 | mchip_free_frame(); |
| @@ -859,8 +861,8 @@ static int meye_open(struct file *file) | |||
| 859 | 861 | ||
| 860 | for (i = 0; i < MEYE_MAX_BUFNBRS; i++) | 862 | for (i = 0; i < MEYE_MAX_BUFNBRS; i++) |
| 861 | meye.grab_buffer[i].state = MEYE_BUF_UNUSED; | 863 | meye.grab_buffer[i].state = MEYE_BUF_UNUSED; |
| 862 | kfifo_reset(meye.grabq); | 864 | kfifo_reset(&meye.grabq); |
| 863 | kfifo_reset(meye.doneq); | 865 | kfifo_reset(&meye.doneq); |
| 864 | return 0; | 866 | return 0; |
| 865 | } | 867 | } |
| 866 | 868 | ||
| @@ -933,7 +935,8 @@ static int meyeioc_qbuf_capt(int *nb) | |||
| 933 | mchip_cont_compression_start(); | 935 | mchip_cont_compression_start(); |
| 934 | 936 | ||
| 935 | meye.grab_buffer[*nb].state = MEYE_BUF_USING; | 937 | meye.grab_buffer[*nb].state = MEYE_BUF_USING; |
| 936 | kfifo_put(meye.grabq, (unsigned char *)nb, sizeof(int)); | 938 | kfifo_in_locked(&meye.grabq, (unsigned char *)nb, sizeof(int), |
| 939 | &meye.grabq_lock); | ||
| 937 | mutex_unlock(&meye.lock); | 940 | mutex_unlock(&meye.lock); |
| 938 | 941 | ||
| 939 | return 0; | 942 | return 0; |
| @@ -965,7 +968,9 @@ static int meyeioc_sync(struct file *file, void *fh, int *i) | |||
| 965 | /* fall through */ | 968 | /* fall through */ |
| 966 | case MEYE_BUF_DONE: | 969 | case MEYE_BUF_DONE: |
| 967 | meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; | 970 | meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; |
| 968 | kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int)); | 971 | if (kfifo_out_locked(&meye.doneq, (unsigned char *)&unused, |
| 972 | sizeof(int), &meye.doneq_lock) != sizeof(int)) | ||
| 973 | break; | ||
| 969 | } | 974 | } |
| 970 | *i = meye.grab_buffer[*i].size; | 975 | *i = meye.grab_buffer[*i].size; |
| 971 | mutex_unlock(&meye.lock); | 976 | mutex_unlock(&meye.lock); |
| @@ -1452,7 +1457,8 @@ static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) | |||
| 1452 | buf->flags |= V4L2_BUF_FLAG_QUEUED; | 1457 | buf->flags |= V4L2_BUF_FLAG_QUEUED; |
| 1453 | buf->flags &= ~V4L2_BUF_FLAG_DONE; | 1458 | buf->flags &= ~V4L2_BUF_FLAG_DONE; |
| 1454 | meye.grab_buffer[buf->index].state = MEYE_BUF_USING; | 1459 | meye.grab_buffer[buf->index].state = MEYE_BUF_USING; |
| 1455 | kfifo_put(meye.grabq, (unsigned char *)&buf->index, sizeof(int)); | 1460 | kfifo_in_locked(&meye.grabq, (unsigned char *)&buf->index, |
| 1461 | sizeof(int), &meye.grabq_lock); | ||
| 1456 | mutex_unlock(&meye.lock); | 1462 | mutex_unlock(&meye.lock); |
| 1457 | 1463 | ||
| 1458 | return 0; | 1464 | return 0; |
| @@ -1467,19 +1473,19 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) | |||
| 1467 | 1473 | ||
| 1468 | mutex_lock(&meye.lock); | 1474 | mutex_lock(&meye.lock); |
| 1469 | 1475 | ||
| 1470 | if (kfifo_len(meye.doneq) == 0 && file->f_flags & O_NONBLOCK) { | 1476 | if (kfifo_len(&meye.doneq) == 0 && file->f_flags & O_NONBLOCK) { |
| 1471 | mutex_unlock(&meye.lock); | 1477 | mutex_unlock(&meye.lock); |
| 1472 | return -EAGAIN; | 1478 | return -EAGAIN; |
| 1473 | } | 1479 | } |
| 1474 | 1480 | ||
| 1475 | if (wait_event_interruptible(meye.proc_list, | 1481 | if (wait_event_interruptible(meye.proc_list, |
| 1476 | kfifo_len(meye.doneq) != 0) < 0) { | 1482 | kfifo_len(&meye.doneq) != 0) < 0) { |
| 1477 | mutex_unlock(&meye.lock); | 1483 | mutex_unlock(&meye.lock); |
| 1478 | return -EINTR; | 1484 | return -EINTR; |
| 1479 | } | 1485 | } |
| 1480 | 1486 | ||
| 1481 | if (!kfifo_get(meye.doneq, (unsigned char *)&reqnr, | 1487 | if (!kfifo_out_locked(&meye.doneq, (unsigned char *)&reqnr, |
| 1482 | sizeof(int))) { | 1488 | sizeof(int), &meye.doneq_lock)) { |
| 1483 | mutex_unlock(&meye.lock); | 1489 | mutex_unlock(&meye.lock); |
| 1484 | return -EBUSY; | 1490 | return -EBUSY; |
| 1485 | } | 1491 | } |
| @@ -1529,8 +1535,8 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) | |||
| 1529 | { | 1535 | { |
| 1530 | mutex_lock(&meye.lock); | 1536 | mutex_lock(&meye.lock); |
| 1531 | mchip_hic_stop(); | 1537 | mchip_hic_stop(); |
| 1532 | kfifo_reset(meye.grabq); | 1538 | kfifo_reset(&meye.grabq); |
| 1533 | kfifo_reset(meye.doneq); | 1539 | kfifo_reset(&meye.doneq); |
| 1534 | 1540 | ||
| 1535 | for (i = 0; i < MEYE_MAX_BUFNBRS; i++) | 1541 | for (i = 0; i < MEYE_MAX_BUFNBRS; i++) |
| 1536 | meye.grab_buffer[i].state = MEYE_BUF_UNUSED; | 1542 | meye.grab_buffer[i].state = MEYE_BUF_UNUSED; |
| @@ -1572,7 +1578,7 @@ static unsigned int meye_poll(struct file *file, poll_table *wait) | |||
| 1572 | 1578 | ||
| 1573 | mutex_lock(&meye.lock); | 1579 | mutex_lock(&meye.lock); |
| 1574 | poll_wait(file, &meye.proc_list, wait); | 1580 | poll_wait(file, &meye.proc_list, wait); |
| 1575 | if (kfifo_len(meye.doneq)) | 1581 | if (kfifo_len(&meye.doneq)) |
| 1576 | res = POLLIN | POLLRDNORM; | 1582 | res = POLLIN | POLLRDNORM; |
| 1577 | mutex_unlock(&meye.lock); | 1583 | mutex_unlock(&meye.lock); |
| 1578 | return res; | 1584 | return res; |
| @@ -1745,16 +1751,14 @@ static int __devinit meye_probe(struct pci_dev *pcidev, | |||
| 1745 | } | 1751 | } |
| 1746 | 1752 | ||
| 1747 | spin_lock_init(&meye.grabq_lock); | 1753 | spin_lock_init(&meye.grabq_lock); |
| 1748 | meye.grabq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL, | 1754 | if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS, |
| 1749 | &meye.grabq_lock); | 1755 | GFP_KERNEL)) { |
| 1750 | if (IS_ERR(meye.grabq)) { | ||
| 1751 | printk(KERN_ERR "meye: fifo allocation failed\n"); | 1756 | printk(KERN_ERR "meye: fifo allocation failed\n"); |
| 1752 | goto outkfifoalloc1; | 1757 | goto outkfifoalloc1; |
| 1753 | } | 1758 | } |
| 1754 | spin_lock_init(&meye.doneq_lock); | 1759 | spin_lock_init(&meye.doneq_lock); |
| 1755 | meye.doneq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL, | 1760 | if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS, |
| 1756 | &meye.doneq_lock); | 1761 | GFP_KERNEL)) { |
| 1757 | if (IS_ERR(meye.doneq)) { | ||
| 1758 | printk(KERN_ERR "meye: fifo allocation failed\n"); | 1762 | printk(KERN_ERR "meye: fifo allocation failed\n"); |
| 1759 | goto outkfifoalloc2; | 1763 | goto outkfifoalloc2; |
| 1760 | } | 1764 | } |
| @@ -1868,9 +1872,9 @@ outregions: | |||
| 1868 | outenabledev: | 1872 | outenabledev: |
| 1869 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0); | 1873 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0); |
| 1870 | outsonypienable: | 1874 | outsonypienable: |
| 1871 | kfifo_free(meye.doneq); | 1875 | kfifo_free(&meye.doneq); |
| 1872 | outkfifoalloc2: | 1876 | outkfifoalloc2: |
| 1873 | kfifo_free(meye.grabq); | 1877 | kfifo_free(&meye.grabq); |
| 1874 | outkfifoalloc1: | 1878 | outkfifoalloc1: |
| 1875 | vfree(meye.grab_temp); | 1879 | vfree(meye.grab_temp); |
| 1876 | outvmalloc: | 1880 | outvmalloc: |
| @@ -1901,8 +1905,8 @@ static void __devexit meye_remove(struct pci_dev *pcidev) | |||
| 1901 | 1905 | ||
| 1902 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0); | 1906 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0); |
| 1903 | 1907 | ||
| 1904 | kfifo_free(meye.doneq); | 1908 | kfifo_free(&meye.doneq); |
| 1905 | kfifo_free(meye.grabq); | 1909 | kfifo_free(&meye.grabq); |
| 1906 | 1910 | ||
| 1907 | vfree(meye.grab_temp); | 1911 | vfree(meye.grab_temp); |
| 1908 | 1912 | ||
diff --git a/drivers/media/video/meye.h b/drivers/media/video/meye.h index 5f70a106ba2b..1321ad5d6597 100644 --- a/drivers/media/video/meye.h +++ b/drivers/media/video/meye.h | |||
| @@ -303,9 +303,9 @@ struct meye { | |||
| 303 | struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS]; | 303 | struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS]; |
| 304 | int vma_use_count[MEYE_MAX_BUFNBRS]; /* mmap count */ | 304 | int vma_use_count[MEYE_MAX_BUFNBRS]; /* mmap count */ |
| 305 | struct mutex lock; /* mutex for open/mmap... */ | 305 | struct mutex lock; /* mutex for open/mmap... */ |
| 306 | struct kfifo *grabq; /* queue for buffers to be grabbed */ | 306 | struct kfifo grabq; /* queue for buffers to be grabbed */ |
| 307 | spinlock_t grabq_lock; /* lock protecting the queue */ | 307 | spinlock_t grabq_lock; /* lock protecting the queue */ |
| 308 | struct kfifo *doneq; /* queue for grabbed buffers */ | 308 | struct kfifo doneq; /* queue for grabbed buffers */ |
| 309 | spinlock_t doneq_lock; /* lock protecting the queue */ | 309 | spinlock_t doneq_lock; /* lock protecting the queue */ |
| 310 | wait_queue_head_t proc_list; /* wait queue */ | 310 | wait_queue_head_t proc_list; /* wait queue */ |
| 311 | struct video_device *video_dev; /* video device parameters */ | 311 | struct video_device *video_dev; /* video device parameters */ |
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index b9b371bfa30f..42611bea76a3 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
| @@ -1365,7 +1365,7 @@ static void lbs_send_confirmsleep(struct lbs_private *priv) | |||
| 1365 | priv->dnld_sent = DNLD_RES_RECEIVED; | 1365 | priv->dnld_sent = DNLD_RES_RECEIVED; |
| 1366 | 1366 | ||
| 1367 | /* If nothing to do, go back to sleep (?) */ | 1367 | /* If nothing to do, go back to sleep (?) */ |
| 1368 | if (!__kfifo_len(priv->event_fifo) && !priv->resp_len[priv->resp_idx]) | 1368 | if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx]) |
| 1369 | priv->psstate = PS_STATE_SLEEP; | 1369 | priv->psstate = PS_STATE_SLEEP; |
| 1370 | 1370 | ||
| 1371 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 1371 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
| @@ -1439,7 +1439,7 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv) | |||
| 1439 | } | 1439 | } |
| 1440 | 1440 | ||
| 1441 | /* Pending events or command responses? */ | 1441 | /* Pending events or command responses? */ |
| 1442 | if (__kfifo_len(priv->event_fifo) || priv->resp_len[priv->resp_idx]) { | 1442 | if (kfifo_len(&priv->event_fifo) || priv->resp_len[priv->resp_idx]) { |
| 1443 | allowed = 0; | 1443 | allowed = 0; |
| 1444 | lbs_deb_host("pending events or command responses\n"); | 1444 | lbs_deb_host("pending events or command responses\n"); |
| 1445 | } | 1445 | } |
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 6a8d2b291d8c..05bb298dfae9 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | #include "scan.h" | 10 | #include "scan.h" |
| 11 | #include "assoc.h" | 11 | #include "assoc.h" |
| 12 | 12 | ||
| 13 | 13 | #include <linux/kfifo.h> | |
| 14 | 14 | ||
| 15 | /** sleep_params */ | 15 | /** sleep_params */ |
| 16 | struct sleep_params { | 16 | struct sleep_params { |
| @@ -120,7 +120,7 @@ struct lbs_private { | |||
| 120 | u32 resp_len[2]; | 120 | u32 resp_len[2]; |
| 121 | 121 | ||
| 122 | /* Events sent from hardware to driver */ | 122 | /* Events sent from hardware to driver */ |
| 123 | struct kfifo *event_fifo; | 123 | struct kfifo event_fifo; |
| 124 | 124 | ||
| 125 | /** thread to service interrupts */ | 125 | /** thread to service interrupts */ |
| 126 | struct task_struct *main_thread; | 126 | struct task_struct *main_thread; |
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index db38a5a719fa..c2975c8e2f21 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
| @@ -459,7 +459,7 @@ static int lbs_thread(void *data) | |||
| 459 | else if (!list_empty(&priv->cmdpendingq) && | 459 | else if (!list_empty(&priv->cmdpendingq) && |
| 460 | !(priv->wakeup_dev_required)) | 460 | !(priv->wakeup_dev_required)) |
| 461 | shouldsleep = 0; /* We have a command to send */ | 461 | shouldsleep = 0; /* We have a command to send */ |
| 462 | else if (__kfifo_len(priv->event_fifo)) | 462 | else if (kfifo_len(&priv->event_fifo)) |
| 463 | shouldsleep = 0; /* We have an event to process */ | 463 | shouldsleep = 0; /* We have an event to process */ |
| 464 | else | 464 | else |
| 465 | shouldsleep = 1; /* No command */ | 465 | shouldsleep = 1; /* No command */ |
| @@ -511,10 +511,13 @@ static int lbs_thread(void *data) | |||
| 511 | 511 | ||
| 512 | /* Process hardware events, e.g. card removed, link lost */ | 512 | /* Process hardware events, e.g. card removed, link lost */ |
| 513 | spin_lock_irq(&priv->driver_lock); | 513 | spin_lock_irq(&priv->driver_lock); |
| 514 | while (__kfifo_len(priv->event_fifo)) { | 514 | while (kfifo_len(&priv->event_fifo)) { |
| 515 | u32 event; | 515 | u32 event; |
| 516 | __kfifo_get(priv->event_fifo, (unsigned char *) &event, | 516 | |
| 517 | sizeof(event)); | 517 | if (kfifo_out(&priv->event_fifo, |
| 518 | (unsigned char *) &event, sizeof(event)) != | ||
| 519 | sizeof(event)) | ||
| 520 | break; | ||
| 518 | spin_unlock_irq(&priv->driver_lock); | 521 | spin_unlock_irq(&priv->driver_lock); |
| 519 | lbs_process_event(priv, event); | 522 | lbs_process_event(priv, event); |
| 520 | spin_lock_irq(&priv->driver_lock); | 523 | spin_lock_irq(&priv->driver_lock); |
| @@ -883,10 +886,9 @@ static int lbs_init_adapter(struct lbs_private *priv) | |||
| 883 | priv->resp_len[0] = priv->resp_len[1] = 0; | 886 | priv->resp_len[0] = priv->resp_len[1] = 0; |
| 884 | 887 | ||
| 885 | /* Create the event FIFO */ | 888 | /* Create the event FIFO */ |
| 886 | priv->event_fifo = kfifo_alloc(sizeof(u32) * 16, GFP_KERNEL, NULL); | 889 | ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL); |
| 887 | if (IS_ERR(priv->event_fifo)) { | 890 | if (ret) { |
| 888 | lbs_pr_err("Out of memory allocating event FIFO buffer\n"); | 891 | lbs_pr_err("Out of memory allocating event FIFO buffer\n"); |
| 889 | ret = -ENOMEM; | ||
| 890 | goto out; | 892 | goto out; |
| 891 | } | 893 | } |
| 892 | 894 | ||
| @@ -901,8 +903,7 @@ static void lbs_free_adapter(struct lbs_private *priv) | |||
| 901 | lbs_deb_enter(LBS_DEB_MAIN); | 903 | lbs_deb_enter(LBS_DEB_MAIN); |
| 902 | 904 | ||
| 903 | lbs_free_cmd_buffer(priv); | 905 | lbs_free_cmd_buffer(priv); |
| 904 | if (priv->event_fifo) | 906 | kfifo_free(&priv->event_fifo); |
| 905 | kfifo_free(priv->event_fifo); | ||
| 906 | del_timer(&priv->command_timer); | 907 | del_timer(&priv->command_timer); |
| 907 | del_timer(&priv->auto_deepsleep_timer); | 908 | del_timer(&priv->auto_deepsleep_timer); |
| 908 | kfree(priv->networks); | 909 | kfree(priv->networks); |
| @@ -1177,7 +1178,7 @@ void lbs_queue_event(struct lbs_private *priv, u32 event) | |||
| 1177 | if (priv->psstate == PS_STATE_SLEEP) | 1178 | if (priv->psstate == PS_STATE_SLEEP) |
| 1178 | priv->psstate = PS_STATE_AWAKE; | 1179 | priv->psstate = PS_STATE_AWAKE; |
| 1179 | 1180 | ||
| 1180 | __kfifo_put(priv->event_fifo, (unsigned char *) &event, sizeof(u32)); | 1181 | kfifo_in(&priv->event_fifo, (unsigned char *) &event, sizeof(u32)); |
| 1181 | 1182 | ||
| 1182 | wake_up_interruptible(&priv->waitq); | 1183 | wake_up_interruptible(&priv->waitq); |
| 1183 | 1184 | ||
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index bcd4ba8be7db..b66029bd75d0 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c | |||
| @@ -164,7 +164,7 @@ struct fujitsu_hotkey_t { | |||
| 164 | struct input_dev *input; | 164 | struct input_dev *input; |
| 165 | char phys[32]; | 165 | char phys[32]; |
| 166 | struct platform_device *pf_device; | 166 | struct platform_device *pf_device; |
| 167 | struct kfifo *fifo; | 167 | struct kfifo fifo; |
| 168 | spinlock_t fifo_lock; | 168 | spinlock_t fifo_lock; |
| 169 | int rfkill_supported; | 169 | int rfkill_supported; |
| 170 | int rfkill_state; | 170 | int rfkill_state; |
| @@ -824,12 +824,10 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
| 824 | 824 | ||
| 825 | /* kfifo */ | 825 | /* kfifo */ |
| 826 | spin_lock_init(&fujitsu_hotkey->fifo_lock); | 826 | spin_lock_init(&fujitsu_hotkey->fifo_lock); |
| 827 | fujitsu_hotkey->fifo = | 827 | error = kfifo_alloc(&fujitsu_hotkey->fifo, RINGBUFFERSIZE * sizeof(int), |
| 828 | kfifo_alloc(RINGBUFFERSIZE * sizeof(int), GFP_KERNEL, | 828 | GFP_KERNEL); |
| 829 | &fujitsu_hotkey->fifo_lock); | 829 | if (error) { |
| 830 | if (IS_ERR(fujitsu_hotkey->fifo)) { | ||
| 831 | printk(KERN_ERR "kfifo_alloc failed\n"); | 830 | printk(KERN_ERR "kfifo_alloc failed\n"); |
| 832 | error = PTR_ERR(fujitsu_hotkey->fifo); | ||
| 833 | goto err_stop; | 831 | goto err_stop; |
| 834 | } | 832 | } |
| 835 | 833 | ||
| @@ -934,7 +932,7 @@ err_unregister_input_dev: | |||
| 934 | err_free_input_dev: | 932 | err_free_input_dev: |
| 935 | input_free_device(input); | 933 | input_free_device(input); |
| 936 | err_free_fifo: | 934 | err_free_fifo: |
| 937 | kfifo_free(fujitsu_hotkey->fifo); | 935 | kfifo_free(&fujitsu_hotkey->fifo); |
| 938 | err_stop: | 936 | err_stop: |
| 939 | return result; | 937 | return result; |
| 940 | } | 938 | } |
| @@ -956,7 +954,7 @@ static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type) | |||
| 956 | 954 | ||
| 957 | input_free_device(input); | 955 | input_free_device(input); |
| 958 | 956 | ||
| 959 | kfifo_free(fujitsu_hotkey->fifo); | 957 | kfifo_free(&fujitsu_hotkey->fifo); |
| 960 | 958 | ||
| 961 | fujitsu_hotkey->acpi_handle = NULL; | 959 | fujitsu_hotkey->acpi_handle = NULL; |
| 962 | 960 | ||
| @@ -1008,9 +1006,10 @@ static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event) | |||
| 1008 | vdbg_printk(FUJLAPTOP_DBG_TRACE, | 1006 | vdbg_printk(FUJLAPTOP_DBG_TRACE, |
| 1009 | "Push keycode into ringbuffer [%d]\n", | 1007 | "Push keycode into ringbuffer [%d]\n", |
| 1010 | keycode); | 1008 | keycode); |
| 1011 | status = kfifo_put(fujitsu_hotkey->fifo, | 1009 | status = kfifo_in_locked(&fujitsu_hotkey->fifo, |
| 1012 | (unsigned char *)&keycode, | 1010 | (unsigned char *)&keycode, |
| 1013 | sizeof(keycode)); | 1011 | sizeof(keycode), |
| 1012 | &fujitsu_hotkey->fifo_lock); | ||
| 1014 | if (status != sizeof(keycode)) { | 1013 | if (status != sizeof(keycode)) { |
| 1015 | vdbg_printk(FUJLAPTOP_DBG_WARN, | 1014 | vdbg_printk(FUJLAPTOP_DBG_WARN, |
| 1016 | "Could not push keycode [0x%x]\n", | 1015 | "Could not push keycode [0x%x]\n", |
| @@ -1021,11 +1020,12 @@ static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event) | |||
| 1021 | } | 1020 | } |
| 1022 | } else if (keycode == 0) { | 1021 | } else if (keycode == 0) { |
| 1023 | while ((status = | 1022 | while ((status = |
| 1024 | kfifo_get | 1023 | kfifo_out_locked( |
| 1025 | (fujitsu_hotkey->fifo, (unsigned char *) | 1024 | &fujitsu_hotkey->fifo, |
| 1026 | &keycode_r, | 1025 | (unsigned char *) &keycode_r, |
| 1027 | sizeof | 1026 | sizeof(keycode_r), |
| 1028 | (keycode_r))) == sizeof(keycode_r)) { | 1027 | &fujitsu_hotkey->fifo_lock)) |
| 1028 | == sizeof(keycode_r)) { | ||
| 1029 | input_report_key(input, keycode_r, 0); | 1029 | input_report_key(input, keycode_r, 0); |
| 1030 | input_sync(input); | 1030 | input_sync(input); |
| 1031 | vdbg_printk(FUJLAPTOP_DBG_TRACE, | 1031 | vdbg_printk(FUJLAPTOP_DBG_TRACE, |
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 7a2cc8a5c975..2896ca4cd9ab 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
| @@ -142,7 +142,7 @@ struct sony_laptop_input_s { | |||
| 142 | atomic_t users; | 142 | atomic_t users; |
| 143 | struct input_dev *jog_dev; | 143 | struct input_dev *jog_dev; |
| 144 | struct input_dev *key_dev; | 144 | struct input_dev *key_dev; |
| 145 | struct kfifo *fifo; | 145 | struct kfifo fifo; |
| 146 | spinlock_t fifo_lock; | 146 | spinlock_t fifo_lock; |
| 147 | struct workqueue_struct *wq; | 147 | struct workqueue_struct *wq; |
| 148 | }; | 148 | }; |
| @@ -300,8 +300,9 @@ static void do_sony_laptop_release_key(struct work_struct *work) | |||
| 300 | { | 300 | { |
| 301 | struct sony_laptop_keypress kp; | 301 | struct sony_laptop_keypress kp; |
| 302 | 302 | ||
| 303 | while (kfifo_get(sony_laptop_input.fifo, (unsigned char *)&kp, | 303 | while (kfifo_out_locked(&sony_laptop_input.fifo, (unsigned char *)&kp, |
| 304 | sizeof(kp)) == sizeof(kp)) { | 304 | sizeof(kp), &sony_laptop_input.fifo_lock) |
| 305 | == sizeof(kp)) { | ||
| 305 | msleep(10); | 306 | msleep(10); |
| 306 | input_report_key(kp.dev, kp.key, 0); | 307 | input_report_key(kp.dev, kp.key, 0); |
| 307 | input_sync(kp.dev); | 308 | input_sync(kp.dev); |
| @@ -362,8 +363,9 @@ static void sony_laptop_report_input_event(u8 event) | |||
| 362 | /* we emit the scancode so we can always remap the key */ | 363 | /* we emit the scancode so we can always remap the key */ |
| 363 | input_event(kp.dev, EV_MSC, MSC_SCAN, event); | 364 | input_event(kp.dev, EV_MSC, MSC_SCAN, event); |
| 364 | input_sync(kp.dev); | 365 | input_sync(kp.dev); |
| 365 | kfifo_put(sony_laptop_input.fifo, | 366 | kfifo_in_locked(&sony_laptop_input.fifo, |
| 366 | (unsigned char *)&kp, sizeof(kp)); | 367 | (unsigned char *)&kp, sizeof(kp), |
| 368 | &sony_laptop_input.fifo_lock); | ||
| 367 | 369 | ||
| 368 | if (!work_pending(&sony_laptop_release_key_work)) | 370 | if (!work_pending(&sony_laptop_release_key_work)) |
| 369 | queue_work(sony_laptop_input.wq, | 371 | queue_work(sony_laptop_input.wq, |
| @@ -385,12 +387,10 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device) | |||
| 385 | 387 | ||
| 386 | /* kfifo */ | 388 | /* kfifo */ |
| 387 | spin_lock_init(&sony_laptop_input.fifo_lock); | 389 | spin_lock_init(&sony_laptop_input.fifo_lock); |
| 388 | sony_laptop_input.fifo = | 390 | error = |
| 389 | kfifo_alloc(SONY_LAPTOP_BUF_SIZE, GFP_KERNEL, | 391 | kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); |
| 390 | &sony_laptop_input.fifo_lock); | 392 | if (error) { |
| 391 | if (IS_ERR(sony_laptop_input.fifo)) { | ||
| 392 | printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); | 393 | printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); |
| 393 | error = PTR_ERR(sony_laptop_input.fifo); | ||
| 394 | goto err_dec_users; | 394 | goto err_dec_users; |
| 395 | } | 395 | } |
| 396 | 396 | ||
| @@ -474,7 +474,7 @@ err_destroy_wq: | |||
| 474 | destroy_workqueue(sony_laptop_input.wq); | 474 | destroy_workqueue(sony_laptop_input.wq); |
| 475 | 475 | ||
| 476 | err_free_kfifo: | 476 | err_free_kfifo: |
| 477 | kfifo_free(sony_laptop_input.fifo); | 477 | kfifo_free(&sony_laptop_input.fifo); |
| 478 | 478 | ||
| 479 | err_dec_users: | 479 | err_dec_users: |
| 480 | atomic_dec(&sony_laptop_input.users); | 480 | atomic_dec(&sony_laptop_input.users); |
| @@ -500,7 +500,7 @@ static void sony_laptop_remove_input(void) | |||
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | destroy_workqueue(sony_laptop_input.wq); | 502 | destroy_workqueue(sony_laptop_input.wq); |
| 503 | kfifo_free(sony_laptop_input.fifo); | 503 | kfifo_free(&sony_laptop_input.fifo); |
| 504 | } | 504 | } |
| 505 | 505 | ||
| 506 | /*********** Platform Device ***********/ | 506 | /*********** Platform Device ***********/ |
| @@ -2079,7 +2079,7 @@ static struct attribute_group spic_attribute_group = { | |||
| 2079 | 2079 | ||
| 2080 | struct sonypi_compat_s { | 2080 | struct sonypi_compat_s { |
| 2081 | struct fasync_struct *fifo_async; | 2081 | struct fasync_struct *fifo_async; |
| 2082 | struct kfifo *fifo; | 2082 | struct kfifo fifo; |
| 2083 | spinlock_t fifo_lock; | 2083 | spinlock_t fifo_lock; |
| 2084 | wait_queue_head_t fifo_proc_list; | 2084 | wait_queue_head_t fifo_proc_list; |
| 2085 | atomic_t open_count; | 2085 | atomic_t open_count; |
| @@ -2104,12 +2104,12 @@ static int sonypi_misc_open(struct inode *inode, struct file *file) | |||
| 2104 | /* Flush input queue on first open */ | 2104 | /* Flush input queue on first open */ |
| 2105 | unsigned long flags; | 2105 | unsigned long flags; |
| 2106 | 2106 | ||
| 2107 | spin_lock_irqsave(sonypi_compat.fifo->lock, flags); | 2107 | spin_lock_irqsave(&sonypi_compat.fifo_lock, flags); |
| 2108 | 2108 | ||
| 2109 | if (atomic_inc_return(&sonypi_compat.open_count) == 1) | 2109 | if (atomic_inc_return(&sonypi_compat.open_count) == 1) |
| 2110 | __kfifo_reset(sonypi_compat.fifo); | 2110 | kfifo_reset(&sonypi_compat.fifo); |
| 2111 | 2111 | ||
| 2112 | spin_unlock_irqrestore(sonypi_compat.fifo->lock, flags); | 2112 | spin_unlock_irqrestore(&sonypi_compat.fifo_lock, flags); |
| 2113 | 2113 | ||
| 2114 | return 0; | 2114 | return 0; |
| 2115 | } | 2115 | } |
| @@ -2120,17 +2120,18 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf, | |||
| 2120 | ssize_t ret; | 2120 | ssize_t ret; |
| 2121 | unsigned char c; | 2121 | unsigned char c; |
| 2122 | 2122 | ||
| 2123 | if ((kfifo_len(sonypi_compat.fifo) == 0) && | 2123 | if ((kfifo_len(&sonypi_compat.fifo) == 0) && |
| 2124 | (file->f_flags & O_NONBLOCK)) | 2124 | (file->f_flags & O_NONBLOCK)) |
| 2125 | return -EAGAIN; | 2125 | return -EAGAIN; |
| 2126 | 2126 | ||
| 2127 | ret = wait_event_interruptible(sonypi_compat.fifo_proc_list, | 2127 | ret = wait_event_interruptible(sonypi_compat.fifo_proc_list, |
| 2128 | kfifo_len(sonypi_compat.fifo) != 0); | 2128 | kfifo_len(&sonypi_compat.fifo) != 0); |
| 2129 | if (ret) | 2129 | if (ret) |
| 2130 | return ret; | 2130 | return ret; |
| 2131 | 2131 | ||
| 2132 | while (ret < count && | 2132 | while (ret < count && |
| 2133 | (kfifo_get(sonypi_compat.fifo, &c, sizeof(c)) == sizeof(c))) { | 2133 | (kfifo_out_locked(&sonypi_compat.fifo, &c, sizeof(c), |
| 2134 | &sonypi_compat.fifo_lock) == sizeof(c))) { | ||
| 2134 | if (put_user(c, buf++)) | 2135 | if (put_user(c, buf++)) |
| 2135 | return -EFAULT; | 2136 | return -EFAULT; |
| 2136 | ret++; | 2137 | ret++; |
| @@ -2147,7 +2148,7 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf, | |||
| 2147 | static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait) | 2148 | static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait) |
| 2148 | { | 2149 | { |
| 2149 | poll_wait(file, &sonypi_compat.fifo_proc_list, wait); | 2150 | poll_wait(file, &sonypi_compat.fifo_proc_list, wait); |
| 2150 | if (kfifo_len(sonypi_compat.fifo)) | 2151 | if (kfifo_len(&sonypi_compat.fifo)) |
| 2151 | return POLLIN | POLLRDNORM; | 2152 | return POLLIN | POLLRDNORM; |
| 2152 | return 0; | 2153 | return 0; |
| 2153 | } | 2154 | } |
| @@ -2309,7 +2310,8 @@ static struct miscdevice sonypi_misc_device = { | |||
| 2309 | 2310 | ||
| 2310 | static void sonypi_compat_report_event(u8 event) | 2311 | static void sonypi_compat_report_event(u8 event) |
| 2311 | { | 2312 | { |
| 2312 | kfifo_put(sonypi_compat.fifo, (unsigned char *)&event, sizeof(event)); | 2313 | kfifo_in_locked(&sonypi_compat.fifo, (unsigned char *)&event, |
| 2314 | sizeof(event), &sonypi_compat.fifo_lock); | ||
| 2313 | kill_fasync(&sonypi_compat.fifo_async, SIGIO, POLL_IN); | 2315 | kill_fasync(&sonypi_compat.fifo_async, SIGIO, POLL_IN); |
| 2314 | wake_up_interruptible(&sonypi_compat.fifo_proc_list); | 2316 | wake_up_interruptible(&sonypi_compat.fifo_proc_list); |
| 2315 | } | 2317 | } |
| @@ -2319,11 +2321,11 @@ static int sonypi_compat_init(void) | |||
| 2319 | int error; | 2321 | int error; |
| 2320 | 2322 | ||
| 2321 | spin_lock_init(&sonypi_compat.fifo_lock); | 2323 | spin_lock_init(&sonypi_compat.fifo_lock); |
| 2322 | sonypi_compat.fifo = kfifo_alloc(SONY_LAPTOP_BUF_SIZE, GFP_KERNEL, | 2324 | error = |
| 2323 | &sonypi_compat.fifo_lock); | 2325 | kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); |
| 2324 | if (IS_ERR(sonypi_compat.fifo)) { | 2326 | if (error) { |
| 2325 | printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); | 2327 | printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); |
| 2326 | return PTR_ERR(sonypi_compat.fifo); | 2328 | return error; |
| 2327 | } | 2329 | } |
| 2328 | 2330 | ||
| 2329 | init_waitqueue_head(&sonypi_compat.fifo_proc_list); | 2331 | init_waitqueue_head(&sonypi_compat.fifo_proc_list); |
| @@ -2342,14 +2344,14 @@ static int sonypi_compat_init(void) | |||
| 2342 | return 0; | 2344 | return 0; |
| 2343 | 2345 | ||
| 2344 | err_free_kfifo: | 2346 | err_free_kfifo: |
| 2345 | kfifo_free(sonypi_compat.fifo); | 2347 | kfifo_free(&sonypi_compat.fifo); |
| 2346 | return error; | 2348 | return error; |
| 2347 | } | 2349 | } |
| 2348 | 2350 | ||
| 2349 | static void sonypi_compat_exit(void) | 2351 | static void sonypi_compat_exit(void) |
| 2350 | { | 2352 | { |
| 2351 | misc_deregister(&sonypi_misc_device); | 2353 | misc_deregister(&sonypi_misc_device); |
| 2352 | kfifo_free(sonypi_compat.fifo); | 2354 | kfifo_free(&sonypi_compat.fifo); |
| 2353 | } | 2355 | } |
| 2354 | #else | 2356 | #else |
| 2355 | static int sonypi_compat_init(void) { return 0; } | 2357 | static int sonypi_compat_init(void) { return 0; } |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index b7689f3d05f5..c28a712fd4db 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
| @@ -517,7 +517,7 @@ static void iscsi_free_task(struct iscsi_task *task) | |||
| 517 | if (conn->login_task == task) | 517 | if (conn->login_task == task) |
| 518 | return; | 518 | return; |
| 519 | 519 | ||
| 520 | __kfifo_put(session->cmdpool.queue, (void*)&task, sizeof(void*)); | 520 | kfifo_in(&session->cmdpool.queue, (void*)&task, sizeof(void*)); |
| 521 | 521 | ||
| 522 | if (sc) { | 522 | if (sc) { |
| 523 | task->sc = NULL; | 523 | task->sc = NULL; |
| @@ -737,7 +737,7 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
| 737 | BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); | 737 | BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); |
| 738 | BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); | 738 | BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); |
| 739 | 739 | ||
| 740 | if (!__kfifo_get(session->cmdpool.queue, | 740 | if (!kfifo_out(&session->cmdpool.queue, |
| 741 | (void*)&task, sizeof(void*))) | 741 | (void*)&task, sizeof(void*))) |
| 742 | return NULL; | 742 | return NULL; |
| 743 | } | 743 | } |
| @@ -1567,7 +1567,7 @@ static inline struct iscsi_task *iscsi_alloc_task(struct iscsi_conn *conn, | |||
| 1567 | { | 1567 | { |
| 1568 | struct iscsi_task *task; | 1568 | struct iscsi_task *task; |
| 1569 | 1569 | ||
| 1570 | if (!__kfifo_get(conn->session->cmdpool.queue, | 1570 | if (!kfifo_out(&conn->session->cmdpool.queue, |
| 1571 | (void *) &task, sizeof(void *))) | 1571 | (void *) &task, sizeof(void *))) |
| 1572 | return NULL; | 1572 | return NULL; |
| 1573 | 1573 | ||
| @@ -2461,12 +2461,7 @@ iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size) | |||
| 2461 | if (q->pool == NULL) | 2461 | if (q->pool == NULL) |
| 2462 | return -ENOMEM; | 2462 | return -ENOMEM; |
| 2463 | 2463 | ||
| 2464 | q->queue = kfifo_init((void*)q->pool, max * sizeof(void*), | 2464 | kfifo_init(&q->queue, (void*)q->pool, max * sizeof(void*)); |
| 2465 | GFP_KERNEL, NULL); | ||
| 2466 | if (IS_ERR(q->queue)) { | ||
| 2467 | q->queue = NULL; | ||
| 2468 | goto enomem; | ||
| 2469 | } | ||
| 2470 | 2465 | ||
| 2471 | for (i = 0; i < max; i++) { | 2466 | for (i = 0; i < max; i++) { |
| 2472 | q->pool[i] = kzalloc(item_size, GFP_KERNEL); | 2467 | q->pool[i] = kzalloc(item_size, GFP_KERNEL); |
| @@ -2474,7 +2469,7 @@ iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size) | |||
| 2474 | q->max = i; | 2469 | q->max = i; |
| 2475 | goto enomem; | 2470 | goto enomem; |
| 2476 | } | 2471 | } |
| 2477 | __kfifo_put(q->queue, (void*)&q->pool[i], sizeof(void*)); | 2472 | kfifo_in(&q->queue, (void*)&q->pool[i], sizeof(void*)); |
| 2478 | } | 2473 | } |
| 2479 | 2474 | ||
| 2480 | if (items) { | 2475 | if (items) { |
| @@ -2497,7 +2492,6 @@ void iscsi_pool_free(struct iscsi_pool *q) | |||
| 2497 | for (i = 0; i < q->max; i++) | 2492 | for (i = 0; i < q->max; i++) |
| 2498 | kfree(q->pool[i]); | 2493 | kfree(q->pool[i]); |
| 2499 | kfree(q->pool); | 2494 | kfree(q->pool); |
| 2500 | kfree(q->queue); | ||
| 2501 | } | 2495 | } |
| 2502 | EXPORT_SYMBOL_GPL(iscsi_pool_free); | 2496 | EXPORT_SYMBOL_GPL(iscsi_pool_free); |
| 2503 | 2497 | ||
| @@ -2825,7 +2819,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, | |||
| 2825 | 2819 | ||
| 2826 | /* allocate login_task used for the login/text sequences */ | 2820 | /* allocate login_task used for the login/text sequences */ |
| 2827 | spin_lock_bh(&session->lock); | 2821 | spin_lock_bh(&session->lock); |
| 2828 | if (!__kfifo_get(session->cmdpool.queue, | 2822 | if (!kfifo_out(&session->cmdpool.queue, |
| 2829 | (void*)&conn->login_task, | 2823 | (void*)&conn->login_task, |
| 2830 | sizeof(void*))) { | 2824 | sizeof(void*))) { |
| 2831 | spin_unlock_bh(&session->lock); | 2825 | spin_unlock_bh(&session->lock); |
| @@ -2845,7 +2839,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, | |||
| 2845 | return cls_conn; | 2839 | return cls_conn; |
| 2846 | 2840 | ||
| 2847 | login_task_data_alloc_fail: | 2841 | login_task_data_alloc_fail: |
| 2848 | __kfifo_put(session->cmdpool.queue, (void*)&conn->login_task, | 2842 | kfifo_in(&session->cmdpool.queue, (void*)&conn->login_task, |
| 2849 | sizeof(void*)); | 2843 | sizeof(void*)); |
| 2850 | login_task_alloc_fail: | 2844 | login_task_alloc_fail: |
| 2851 | iscsi_destroy_conn(cls_conn); | 2845 | iscsi_destroy_conn(cls_conn); |
| @@ -2908,7 +2902,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) | |||
| 2908 | free_pages((unsigned long) conn->data, | 2902 | free_pages((unsigned long) conn->data, |
| 2909 | get_order(ISCSI_DEF_MAX_RECV_SEG_LEN)); | 2903 | get_order(ISCSI_DEF_MAX_RECV_SEG_LEN)); |
| 2910 | kfree(conn->persistent_address); | 2904 | kfree(conn->persistent_address); |
| 2911 | __kfifo_put(session->cmdpool.queue, (void*)&conn->login_task, | 2905 | kfifo_in(&session->cmdpool.queue, (void*)&conn->login_task, |
| 2912 | sizeof(void*)); | 2906 | sizeof(void*)); |
| 2913 | if (session->leadconn == conn) | 2907 | if (session->leadconn == conn) |
| 2914 | session->leadconn = NULL; | 2908 | session->leadconn = NULL; |
diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index ca25ee5190b0..db6856c138fc 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c | |||
| @@ -445,15 +445,15 @@ void iscsi_tcp_cleanup_task(struct iscsi_task *task) | |||
| 445 | return; | 445 | return; |
| 446 | 446 | ||
| 447 | /* flush task's r2t queues */ | 447 | /* flush task's r2t queues */ |
| 448 | while (__kfifo_get(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) { | 448 | while (kfifo_out(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) { |
| 449 | __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t, | 449 | kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t, |
| 450 | sizeof(void*)); | 450 | sizeof(void*)); |
| 451 | ISCSI_DBG_TCP(task->conn, "pending r2t dropped\n"); | 451 | ISCSI_DBG_TCP(task->conn, "pending r2t dropped\n"); |
| 452 | } | 452 | } |
| 453 | 453 | ||
| 454 | r2t = tcp_task->r2t; | 454 | r2t = tcp_task->r2t; |
| 455 | if (r2t != NULL) { | 455 | if (r2t != NULL) { |
| 456 | __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t, | 456 | kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t, |
| 457 | sizeof(void*)); | 457 | sizeof(void*)); |
| 458 | tcp_task->r2t = NULL; | 458 | tcp_task->r2t = NULL; |
| 459 | } | 459 | } |
| @@ -541,7 +541,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) | |||
| 541 | return 0; | 541 | return 0; |
| 542 | } | 542 | } |
| 543 | 543 | ||
| 544 | rc = __kfifo_get(tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); | 544 | rc = kfifo_out(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); |
| 545 | if (!rc) { | 545 | if (!rc) { |
| 546 | iscsi_conn_printk(KERN_ERR, conn, "Could not allocate R2T. " | 546 | iscsi_conn_printk(KERN_ERR, conn, "Could not allocate R2T. " |
| 547 | "Target has sent more R2Ts than it " | 547 | "Target has sent more R2Ts than it " |
| @@ -554,7 +554,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) | |||
| 554 | if (r2t->data_length == 0) { | 554 | if (r2t->data_length == 0) { |
| 555 | iscsi_conn_printk(KERN_ERR, conn, | 555 | iscsi_conn_printk(KERN_ERR, conn, |
| 556 | "invalid R2T with zero data len\n"); | 556 | "invalid R2T with zero data len\n"); |
| 557 | __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t, | 557 | kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t, |
| 558 | sizeof(void*)); | 558 | sizeof(void*)); |
| 559 | return ISCSI_ERR_DATALEN; | 559 | return ISCSI_ERR_DATALEN; |
| 560 | } | 560 | } |
| @@ -570,7 +570,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) | |||
| 570 | "invalid R2T with data len %u at offset %u " | 570 | "invalid R2T with data len %u at offset %u " |
| 571 | "and total length %d\n", r2t->data_length, | 571 | "and total length %d\n", r2t->data_length, |
| 572 | r2t->data_offset, scsi_out(task->sc)->length); | 572 | r2t->data_offset, scsi_out(task->sc)->length); |
| 573 | __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t, | 573 | kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t, |
| 574 | sizeof(void*)); | 574 | sizeof(void*)); |
| 575 | return ISCSI_ERR_DATALEN; | 575 | return ISCSI_ERR_DATALEN; |
| 576 | } | 576 | } |
| @@ -580,7 +580,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) | |||
| 580 | r2t->sent = 0; | 580 | r2t->sent = 0; |
| 581 | 581 | ||
| 582 | tcp_task->exp_datasn = r2tsn + 1; | 582 | tcp_task->exp_datasn = r2tsn + 1; |
| 583 | __kfifo_put(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*)); | 583 | kfifo_in(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*)); |
| 584 | conn->r2t_pdus_cnt++; | 584 | conn->r2t_pdus_cnt++; |
| 585 | 585 | ||
| 586 | iscsi_requeue_task(task); | 586 | iscsi_requeue_task(task); |
| @@ -951,7 +951,7 @@ int iscsi_tcp_task_init(struct iscsi_task *task) | |||
| 951 | return conn->session->tt->init_pdu(task, 0, task->data_count); | 951 | return conn->session->tt->init_pdu(task, 0, task->data_count); |
| 952 | } | 952 | } |
| 953 | 953 | ||
| 954 | BUG_ON(__kfifo_len(tcp_task->r2tqueue)); | 954 | BUG_ON(kfifo_len(&tcp_task->r2tqueue)); |
| 955 | tcp_task->exp_datasn = 0; | 955 | tcp_task->exp_datasn = 0; |
| 956 | 956 | ||
| 957 | /* Prepare PDU, optionally w/ immediate data */ | 957 | /* Prepare PDU, optionally w/ immediate data */ |
| @@ -982,7 +982,7 @@ static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task) | |||
| 982 | if (r2t->data_length <= r2t->sent) { | 982 | if (r2t->data_length <= r2t->sent) { |
| 983 | ISCSI_DBG_TCP(task->conn, | 983 | ISCSI_DBG_TCP(task->conn, |
| 984 | " done with r2t %p\n", r2t); | 984 | " done with r2t %p\n", r2t); |
| 985 | __kfifo_put(tcp_task->r2tpool.queue, | 985 | kfifo_in(&tcp_task->r2tpool.queue, |
| 986 | (void *)&tcp_task->r2t, | 986 | (void *)&tcp_task->r2t, |
| 987 | sizeof(void *)); | 987 | sizeof(void *)); |
| 988 | tcp_task->r2t = r2t = NULL; | 988 | tcp_task->r2t = r2t = NULL; |
| @@ -990,8 +990,13 @@ static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task) | |||
| 990 | } | 990 | } |
| 991 | 991 | ||
| 992 | if (r2t == NULL) { | 992 | if (r2t == NULL) { |
| 993 | __kfifo_get(tcp_task->r2tqueue, | 993 | if (kfifo_out(&tcp_task->r2tqueue, |
| 994 | (void *)&tcp_task->r2t, sizeof(void *)); | 994 | (void *)&tcp_task->r2t, sizeof(void *)) != |
| 995 | sizeof(void *)) { | ||
| 996 | WARN_ONCE(1, "unexpected fifo state"); | ||
| 997 | r2t = NULL; | ||
| 998 | } | ||
| 999 | |||
| 995 | r2t = tcp_task->r2t; | 1000 | r2t = tcp_task->r2t; |
| 996 | } | 1001 | } |
| 997 | spin_unlock_bh(&session->lock); | 1002 | spin_unlock_bh(&session->lock); |
| @@ -1127,9 +1132,8 @@ int iscsi_tcp_r2tpool_alloc(struct iscsi_session *session) | |||
| 1127 | } | 1132 | } |
| 1128 | 1133 | ||
| 1129 | /* R2T xmit queue */ | 1134 | /* R2T xmit queue */ |
| 1130 | tcp_task->r2tqueue = kfifo_alloc( | 1135 | if (kfifo_alloc(&tcp_task->r2tqueue, |
| 1131 | session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL); | 1136 | session->max_r2t * 4 * sizeof(void*), GFP_KERNEL)) { |
| 1132 | if (tcp_task->r2tqueue == ERR_PTR(-ENOMEM)) { | ||
| 1133 | iscsi_pool_free(&tcp_task->r2tpool); | 1137 | iscsi_pool_free(&tcp_task->r2tpool); |
| 1134 | goto r2t_alloc_fail; | 1138 | goto r2t_alloc_fail; |
| 1135 | } | 1139 | } |
| @@ -1142,7 +1146,7 @@ r2t_alloc_fail: | |||
| 1142 | struct iscsi_task *task = session->cmds[i]; | 1146 | struct iscsi_task *task = session->cmds[i]; |
| 1143 | struct iscsi_tcp_task *tcp_task = task->dd_data; | 1147 | struct iscsi_tcp_task *tcp_task = task->dd_data; |
| 1144 | 1148 | ||
| 1145 | kfifo_free(tcp_task->r2tqueue); | 1149 | kfifo_free(&tcp_task->r2tqueue); |
| 1146 | iscsi_pool_free(&tcp_task->r2tpool); | 1150 | iscsi_pool_free(&tcp_task->r2tpool); |
| 1147 | } | 1151 | } |
| 1148 | return -ENOMEM; | 1152 | return -ENOMEM; |
| @@ -1157,7 +1161,7 @@ void iscsi_tcp_r2tpool_free(struct iscsi_session *session) | |||
| 1157 | struct iscsi_task *task = session->cmds[i]; | 1161 | struct iscsi_task *task = session->cmds[i]; |
| 1158 | struct iscsi_tcp_task *tcp_task = task->dd_data; | 1162 | struct iscsi_tcp_task *tcp_task = task->dd_data; |
| 1159 | 1163 | ||
| 1160 | kfifo_free(tcp_task->r2tqueue); | 1164 | kfifo_free(&tcp_task->r2tqueue); |
| 1161 | iscsi_pool_free(&tcp_task->r2tpool); | 1165 | iscsi_pool_free(&tcp_task->r2tpool); |
| 1162 | } | 1166 | } |
| 1163 | } | 1167 | } |
diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c index 9ad38e81e343..ab19b3b4be52 100644 --- a/drivers/scsi/libsrp.c +++ b/drivers/scsi/libsrp.c | |||
| @@ -58,19 +58,15 @@ static int srp_iu_pool_alloc(struct srp_queue *q, size_t max, | |||
| 58 | goto free_pool; | 58 | goto free_pool; |
| 59 | 59 | ||
| 60 | spin_lock_init(&q->lock); | 60 | spin_lock_init(&q->lock); |
| 61 | q->queue = kfifo_init((void *) q->pool, max * sizeof(void *), | 61 | kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *)); |
| 62 | GFP_KERNEL, &q->lock); | ||
| 63 | if (IS_ERR(q->queue)) | ||
| 64 | goto free_item; | ||
| 65 | 62 | ||
| 66 | for (i = 0, iue = q->items; i < max; i++) { | 63 | for (i = 0, iue = q->items; i < max; i++) { |
| 67 | __kfifo_put(q->queue, (void *) &iue, sizeof(void *)); | 64 | kfifo_in(&q->queue, (void *) &iue, sizeof(void *)); |
| 68 | iue->sbuf = ring[i]; | 65 | iue->sbuf = ring[i]; |
| 69 | iue++; | 66 | iue++; |
| 70 | } | 67 | } |
| 71 | return 0; | 68 | return 0; |
| 72 | 69 | ||
| 73 | free_item: | ||
| 74 | kfree(q->items); | 70 | kfree(q->items); |
| 75 | free_pool: | 71 | free_pool: |
| 76 | kfree(q->pool); | 72 | kfree(q->pool); |
| @@ -167,7 +163,11 @@ struct iu_entry *srp_iu_get(struct srp_target *target) | |||
| 167 | { | 163 | { |
| 168 | struct iu_entry *iue = NULL; | 164 | struct iu_entry *iue = NULL; |
| 169 | 165 | ||
| 170 | kfifo_get(target->iu_queue.queue, (void *) &iue, sizeof(void *)); | 166 | if (kfifo_out_locked(&target->iu_queue.queue, (void *) &iue, |
| 167 | sizeof(void *), &target->iu_queue.lock) != sizeof(void *)) { | ||
| 168 | WARN_ONCE(1, "unexpected fifo state"); | ||
| 169 | return NULL; | ||
| 170 | } | ||
| 171 | if (!iue) | 171 | if (!iue) |
| 172 | return iue; | 172 | return iue; |
| 173 | iue->target = target; | 173 | iue->target = target; |
| @@ -179,7 +179,8 @@ EXPORT_SYMBOL_GPL(srp_iu_get); | |||
| 179 | 179 | ||
| 180 | void srp_iu_put(struct iu_entry *iue) | 180 | void srp_iu_put(struct iu_entry *iue) |
| 181 | { | 181 | { |
| 182 | kfifo_put(iue->target->iu_queue.queue, (void *) &iue, sizeof(void *)); | 182 | kfifo_in_locked(&iue->target->iu_queue.queue, (void *) &iue, |
| 183 | sizeof(void *), &iue->target->iu_queue.lock); | ||
| 183 | } | 184 | } |
| 184 | EXPORT_SYMBOL_GPL(srp_iu_put); | 185 | EXPORT_SYMBOL_GPL(srp_iu_put); |
| 185 | 186 | ||
diff --git a/drivers/usb/host/fhci-sched.c b/drivers/usb/host/fhci-sched.c index 00a29855d0c4..ff43747a614f 100644 --- a/drivers/usb/host/fhci-sched.c +++ b/drivers/usb/host/fhci-sched.c | |||
| @@ -37,7 +37,7 @@ static void recycle_frame(struct fhci_usb *usb, struct packet *pkt) | |||
| 37 | pkt->info = 0; | 37 | pkt->info = 0; |
| 38 | pkt->priv_data = NULL; | 38 | pkt->priv_data = NULL; |
| 39 | 39 | ||
| 40 | cq_put(usb->ep0->empty_frame_Q, pkt); | 40 | cq_put(&usb->ep0->empty_frame_Q, pkt); |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | /* confirm submitted packet */ | 43 | /* confirm submitted packet */ |
| @@ -57,7 +57,7 @@ void fhci_transaction_confirm(struct fhci_usb *usb, struct packet *pkt) | |||
| 57 | if ((td->data + td->actual_len) && trans_len) | 57 | if ((td->data + td->actual_len) && trans_len) |
| 58 | memcpy(td->data + td->actual_len, pkt->data, | 58 | memcpy(td->data + td->actual_len, pkt->data, |
| 59 | trans_len); | 59 | trans_len); |
| 60 | cq_put(usb->ep0->dummy_packets_Q, pkt->data); | 60 | cq_put(&usb->ep0->dummy_packets_Q, pkt->data); |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | recycle_frame(usb, pkt); | 63 | recycle_frame(usb, pkt); |
| @@ -213,7 +213,7 @@ static int add_packet(struct fhci_usb *usb, struct ed *ed, struct td *td) | |||
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | /* update frame object fields before transmitting */ | 215 | /* update frame object fields before transmitting */ |
| 216 | pkt = cq_get(usb->ep0->empty_frame_Q); | 216 | pkt = cq_get(&usb->ep0->empty_frame_Q); |
| 217 | if (!pkt) { | 217 | if (!pkt) { |
| 218 | fhci_dbg(usb->fhci, "there is no empty frame\n"); | 218 | fhci_dbg(usb->fhci, "there is no empty frame\n"); |
| 219 | return -1; | 219 | return -1; |
| @@ -222,7 +222,7 @@ static int add_packet(struct fhci_usb *usb, struct ed *ed, struct td *td) | |||
| 222 | 222 | ||
| 223 | pkt->info = 0; | 223 | pkt->info = 0; |
| 224 | if (data == NULL) { | 224 | if (data == NULL) { |
| 225 | data = cq_get(usb->ep0->dummy_packets_Q); | 225 | data = cq_get(&usb->ep0->dummy_packets_Q); |
| 226 | BUG_ON(!data); | 226 | BUG_ON(!data); |
| 227 | pkt->info = PKT_DUMMY_PACKET; | 227 | pkt->info = PKT_DUMMY_PACKET; |
| 228 | } | 228 | } |
| @@ -246,7 +246,7 @@ static int add_packet(struct fhci_usb *usb, struct ed *ed, struct td *td) | |||
| 246 | list_del_init(&td->frame_lh); | 246 | list_del_init(&td->frame_lh); |
| 247 | td->status = USB_TD_OK; | 247 | td->status = USB_TD_OK; |
| 248 | if (pkt->info & PKT_DUMMY_PACKET) | 248 | if (pkt->info & PKT_DUMMY_PACKET) |
| 249 | cq_put(usb->ep0->dummy_packets_Q, pkt->data); | 249 | cq_put(&usb->ep0->dummy_packets_Q, pkt->data); |
| 250 | recycle_frame(usb, pkt); | 250 | recycle_frame(usb, pkt); |
| 251 | usb->actual_frame->total_bytes -= (len + PROTOCOL_OVERHEAD); | 251 | usb->actual_frame->total_bytes -= (len + PROTOCOL_OVERHEAD); |
| 252 | fhci_err(usb->fhci, "host transaction failed\n"); | 252 | fhci_err(usb->fhci, "host transaction failed\n"); |
diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c index b40332290319..d224ab467a40 100644 --- a/drivers/usb/host/fhci-tds.c +++ b/drivers/usb/host/fhci-tds.c | |||
| @@ -106,33 +106,33 @@ void fhci_ep0_free(struct fhci_usb *usb) | |||
| 106 | cpm_muram_free(cpm_muram_offset(ep->td_base)); | 106 | cpm_muram_free(cpm_muram_offset(ep->td_base)); |
| 107 | 107 | ||
| 108 | if (ep->conf_frame_Q) { | 108 | if (ep->conf_frame_Q) { |
| 109 | size = cq_howmany(ep->conf_frame_Q); | 109 | size = cq_howmany(&ep->conf_frame_Q); |
| 110 | for (; size; size--) { | 110 | for (; size; size--) { |
| 111 | struct packet *pkt = cq_get(ep->conf_frame_Q); | 111 | struct packet *pkt = cq_get(&ep->conf_frame_Q); |
| 112 | 112 | ||
| 113 | kfree(pkt); | 113 | kfree(pkt); |
| 114 | } | 114 | } |
| 115 | cq_delete(ep->conf_frame_Q); | 115 | cq_delete(&ep->conf_frame_Q); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | if (ep->empty_frame_Q) { | 118 | if (ep->empty_frame_Q) { |
| 119 | size = cq_howmany(ep->empty_frame_Q); | 119 | size = cq_howmany(&ep->empty_frame_Q); |
| 120 | for (; size; size--) { | 120 | for (; size; size--) { |
| 121 | struct packet *pkt = cq_get(ep->empty_frame_Q); | 121 | struct packet *pkt = cq_get(&ep->empty_frame_Q); |
| 122 | 122 | ||
| 123 | kfree(pkt); | 123 | kfree(pkt); |
| 124 | } | 124 | } |
| 125 | cq_delete(ep->empty_frame_Q); | 125 | cq_delete(&ep->empty_frame_Q); |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | if (ep->dummy_packets_Q) { | 128 | if (ep->dummy_packets_Q) { |
| 129 | size = cq_howmany(ep->dummy_packets_Q); | 129 | size = cq_howmany(&ep->dummy_packets_Q); |
| 130 | for (; size; size--) { | 130 | for (; size; size--) { |
| 131 | u8 *buff = cq_get(ep->dummy_packets_Q); | 131 | u8 *buff = cq_get(&ep->dummy_packets_Q); |
| 132 | 132 | ||
| 133 | kfree(buff); | 133 | kfree(buff); |
| 134 | } | 134 | } |
| 135 | cq_delete(ep->dummy_packets_Q); | 135 | cq_delete(&ep->dummy_packets_Q); |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | kfree(ep); | 138 | kfree(ep); |
| @@ -175,10 +175,9 @@ u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem, | |||
| 175 | ep->td_base = cpm_muram_addr(ep_offset); | 175 | ep->td_base = cpm_muram_addr(ep_offset); |
| 176 | 176 | ||
| 177 | /* zero all queue pointers */ | 177 | /* zero all queue pointers */ |
| 178 | ep->conf_frame_Q = cq_new(ring_len + 2); | 178 | if (cq_new(&ep->conf_frame_Q, ring_len + 2) || |
| 179 | ep->empty_frame_Q = cq_new(ring_len + 2); | 179 | cq_new(&ep->empty_frame_Q, ring_len + 2) || |
| 180 | ep->dummy_packets_Q = cq_new(ring_len + 2); | 180 | cq_new(&ep->dummy_packets_Q, ring_len + 2)) { |
| 181 | if (!ep->conf_frame_Q || !ep->empty_frame_Q || !ep->dummy_packets_Q) { | ||
| 182 | err_for = "frame_queues"; | 181 | err_for = "frame_queues"; |
| 183 | goto err; | 182 | goto err; |
| 184 | } | 183 | } |
| @@ -199,8 +198,8 @@ u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem, | |||
| 199 | err_for = "buffer"; | 198 | err_for = "buffer"; |
| 200 | goto err; | 199 | goto err; |
| 201 | } | 200 | } |
| 202 | cq_put(ep->empty_frame_Q, pkt); | 201 | cq_put(&ep->empty_frame_Q, pkt); |
| 203 | cq_put(ep->dummy_packets_Q, buff); | 202 | cq_put(&ep->dummy_packets_Q, buff); |
| 204 | } | 203 | } |
| 205 | 204 | ||
| 206 | /* we put the endpoint parameter RAM right behind the TD ring */ | 205 | /* we put the endpoint parameter RAM right behind the TD ring */ |
| @@ -319,7 +318,7 @@ static void fhci_td_transaction_confirm(struct fhci_usb *usb) | |||
| 319 | if ((buf == DUMMY2_BD_BUFFER) && !(td_status & ~TD_W)) | 318 | if ((buf == DUMMY2_BD_BUFFER) && !(td_status & ~TD_W)) |
| 320 | continue; | 319 | continue; |
| 321 | 320 | ||
| 322 | pkt = cq_get(ep->conf_frame_Q); | 321 | pkt = cq_get(&ep->conf_frame_Q); |
| 323 | if (!pkt) | 322 | if (!pkt) |
| 324 | fhci_err(usb->fhci, "no frame to confirm\n"); | 323 | fhci_err(usb->fhci, "no frame to confirm\n"); |
| 325 | 324 | ||
| @@ -460,9 +459,9 @@ u32 fhci_host_transaction(struct fhci_usb *usb, | |||
| 460 | out_be16(&td->length, pkt->len); | 459 | out_be16(&td->length, pkt->len); |
| 461 | 460 | ||
| 462 | /* put the frame to the confirmation queue */ | 461 | /* put the frame to the confirmation queue */ |
| 463 | cq_put(ep->conf_frame_Q, pkt); | 462 | cq_put(&ep->conf_frame_Q, pkt); |
| 464 | 463 | ||
| 465 | if (cq_howmany(ep->conf_frame_Q) == 1) | 464 | if (cq_howmany(&ep->conf_frame_Q) == 1) |
| 466 | out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO); | 465 | out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO); |
| 467 | 466 | ||
| 468 | return 0; | 467 | return 0; |
diff --git a/drivers/usb/host/fhci.h b/drivers/usb/host/fhci.h index 7116284ed21a..72dae1c5ab38 100644 --- a/drivers/usb/host/fhci.h +++ b/drivers/usb/host/fhci.h | |||
| @@ -423,9 +423,9 @@ struct endpoint { | |||
| 423 | struct usb_td __iomem *td_base; /* first TD in the ring */ | 423 | struct usb_td __iomem *td_base; /* first TD in the ring */ |
| 424 | struct usb_td __iomem *conf_td; /* next TD for confirm after transac */ | 424 | struct usb_td __iomem *conf_td; /* next TD for confirm after transac */ |
| 425 | struct usb_td __iomem *empty_td;/* next TD for new transaction req. */ | 425 | struct usb_td __iomem *empty_td;/* next TD for new transaction req. */ |
| 426 | struct kfifo *empty_frame_Q; /* Empty frames list to use */ | 426 | struct kfifo empty_frame_Q; /* Empty frames list to use */ |
| 427 | struct kfifo *conf_frame_Q; /* frames passed to TDs,waiting for tx */ | 427 | struct kfifo conf_frame_Q; /* frames passed to TDs,waiting for tx */ |
| 428 | struct kfifo *dummy_packets_Q;/* dummy packets for the CRC overun */ | 428 | struct kfifo dummy_packets_Q;/* dummy packets for the CRC overun */ |
| 429 | 429 | ||
| 430 | bool already_pushed_dummy_bd; | 430 | bool already_pushed_dummy_bd; |
| 431 | }; | 431 | }; |
| @@ -493,9 +493,9 @@ static inline struct usb_hcd *fhci_to_hcd(struct fhci_hcd *fhci) | |||
| 493 | } | 493 | } |
| 494 | 494 | ||
| 495 | /* fifo of pointers */ | 495 | /* fifo of pointers */ |
| 496 | static inline struct kfifo *cq_new(int size) | 496 | static inline int cq_new(struct kfifo *fifo, int size) |
| 497 | { | 497 | { |
| 498 | return kfifo_alloc(size * sizeof(void *), GFP_KERNEL, NULL); | 498 | return kfifo_alloc(fifo, size * sizeof(void *), GFP_KERNEL); |
| 499 | } | 499 | } |
| 500 | 500 | ||
| 501 | static inline void cq_delete(struct kfifo *kfifo) | 501 | static inline void cq_delete(struct kfifo *kfifo) |
| @@ -505,19 +505,19 @@ static inline void cq_delete(struct kfifo *kfifo) | |||
| 505 | 505 | ||
| 506 | static inline unsigned int cq_howmany(struct kfifo *kfifo) | 506 | static inline unsigned int cq_howmany(struct kfifo *kfifo) |
| 507 | { | 507 | { |
| 508 | return __kfifo_len(kfifo) / sizeof(void *); | 508 | return kfifo_len(kfifo) / sizeof(void *); |
| 509 | } | 509 | } |
| 510 | 510 | ||
| 511 | static inline int cq_put(struct kfifo *kfifo, void *p) | 511 | static inline int cq_put(struct kfifo *kfifo, void *p) |
| 512 | { | 512 | { |
| 513 | return __kfifo_put(kfifo, (void *)&p, sizeof(p)); | 513 | return kfifo_in(kfifo, (void *)&p, sizeof(p)); |
| 514 | } | 514 | } |
| 515 | 515 | ||
| 516 | static inline void *cq_get(struct kfifo *kfifo) | 516 | static inline void *cq_get(struct kfifo *kfifo) |
| 517 | { | 517 | { |
| 518 | void *p = NULL; | 518 | void *p = NULL; |
| 519 | 519 | ||
| 520 | __kfifo_get(kfifo, (void *)&p, sizeof(p)); | 520 | kfifo_out(kfifo, (void *)&p, sizeof(p)); |
| 521 | return p; | 521 | return p; |
| 522 | } | 522 | } |
| 523 | 523 | ||
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index bbe005cefcfb..b0f1183755c9 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
| @@ -276,7 +276,7 @@ static int usb_serial_generic_write_start(struct usb_serial_port *port) | |||
| 276 | if (port->write_urb_busy) | 276 | if (port->write_urb_busy) |
| 277 | start_io = false; | 277 | start_io = false; |
| 278 | else { | 278 | else { |
| 279 | start_io = (__kfifo_len(port->write_fifo) != 0); | 279 | start_io = (kfifo_len(port->write_fifo) != 0); |
| 280 | port->write_urb_busy = start_io; | 280 | port->write_urb_busy = start_io; |
| 281 | } | 281 | } |
| 282 | spin_unlock_irqrestore(&port->lock, flags); | 282 | spin_unlock_irqrestore(&port->lock, flags); |
| @@ -285,7 +285,7 @@ static int usb_serial_generic_write_start(struct usb_serial_port *port) | |||
| 285 | return 0; | 285 | return 0; |
| 286 | 286 | ||
| 287 | data = port->write_urb->transfer_buffer; | 287 | data = port->write_urb->transfer_buffer; |
| 288 | count = kfifo_get(port->write_fifo, data, port->bulk_out_size); | 288 | count = kfifo_out_locked(port->write_fifo, data, port->bulk_out_size, &port->lock); |
| 289 | usb_serial_debug_data(debug, &port->dev, __func__, count, data); | 289 | usb_serial_debug_data(debug, &port->dev, __func__, count, data); |
| 290 | 290 | ||
| 291 | /* set up our urb */ | 291 | /* set up our urb */ |
| @@ -345,7 +345,7 @@ int usb_serial_generic_write(struct tty_struct *tty, | |||
| 345 | return usb_serial_multi_urb_write(tty, port, | 345 | return usb_serial_multi_urb_write(tty, port, |
| 346 | buf, count); | 346 | buf, count); |
| 347 | 347 | ||
| 348 | count = kfifo_put(port->write_fifo, buf, count); | 348 | count = kfifo_in_locked(port->write_fifo, buf, count, &port->lock); |
| 349 | result = usb_serial_generic_write_start(port); | 349 | result = usb_serial_generic_write_start(port); |
| 350 | 350 | ||
| 351 | if (result >= 0) | 351 | if (result >= 0) |
| @@ -370,7 +370,7 @@ int usb_serial_generic_write_room(struct tty_struct *tty) | |||
| 370 | (serial->type->max_in_flight_urbs - | 370 | (serial->type->max_in_flight_urbs - |
| 371 | port->urbs_in_flight); | 371 | port->urbs_in_flight); |
| 372 | } else if (serial->num_bulk_out) | 372 | } else if (serial->num_bulk_out) |
| 373 | room = port->write_fifo->size - __kfifo_len(port->write_fifo); | 373 | room = port->write_fifo->size - kfifo_len(port->write_fifo); |
| 374 | spin_unlock_irqrestore(&port->lock, flags); | 374 | spin_unlock_irqrestore(&port->lock, flags); |
| 375 | 375 | ||
| 376 | dbg("%s - returns %d", __func__, room); | 376 | dbg("%s - returns %d", __func__, room); |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 4543f359be75..636a4f23445e 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
| @@ -939,9 +939,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
| 939 | dev_err(&interface->dev, "No free urbs available\n"); | 939 | dev_err(&interface->dev, "No free urbs available\n"); |
| 940 | goto probe_error; | 940 | goto probe_error; |
| 941 | } | 941 | } |
| 942 | port->write_fifo = kfifo_alloc(PAGE_SIZE, GFP_KERNEL, | 942 | if (kfifo_alloc(port->write_fifo, PAGE_SIZE, GFP_KERNEL)) |
| 943 | &port->lock); | ||
| 944 | if (IS_ERR(port->write_fifo)) | ||
| 945 | goto probe_error; | 943 | goto probe_error; |
| 946 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); | 944 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); |
| 947 | port->bulk_out_size = buffer_size; | 945 | port->bulk_out_size = buffer_size; |
diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index ad6bdf5a5970..486e8ad3bb50 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * A simple kernel FIFO implementation. | 2 | * A generic kernel FIFO implementation. |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2009 Stefani Seibold <stefani@seibold.net> | ||
| 4 | * Copyright (C) 2004 Stelian Pop <stelian@popies.net> | 5 | * Copyright (C) 2004 Stelian Pop <stelian@popies.net> |
| 5 | * | 6 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| @@ -18,6 +19,25 @@ | |||
| 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 19 | * | 20 | * |
| 20 | */ | 21 | */ |
| 22 | |||
| 23 | /* | ||
| 24 | * Howto porting drivers to the new generic fifo API: | ||
| 25 | * | ||
| 26 | * - Modify the declaration of the "struct kfifo *" object into a | ||
| 27 | * in-place "struct kfifo" object | ||
| 28 | * - Init the in-place object with kfifo_alloc() or kfifo_init() | ||
| 29 | * Note: The address of the in-place "struct kfifo" object must be | ||
| 30 | * passed as the first argument to this functions | ||
| 31 | * - Replace the use of __kfifo_put into kfifo_in and __kfifo_get | ||
| 32 | * into kfifo_out | ||
| 33 | * - Replace the use of kfifo_put into kfifo_in_locked and kfifo_get | ||
| 34 | * into kfifo_out_locked | ||
| 35 | * Note: the spinlock pointer formerly passed to kfifo_init/kfifo_alloc | ||
| 36 | * must be passed now to the kfifo_in_locked and kfifo_out_locked | ||
| 37 | * as the last parameter. | ||
| 38 | * - All formerly name __kfifo_* functions has been renamed into kfifo_* | ||
| 39 | */ | ||
| 40 | |||
| 21 | #ifndef _LINUX_KFIFO_H | 41 | #ifndef _LINUX_KFIFO_H |
| 22 | #define _LINUX_KFIFO_H | 42 | #define _LINUX_KFIFO_H |
| 23 | 43 | ||
| @@ -29,124 +49,563 @@ struct kfifo { | |||
| 29 | unsigned int size; /* the size of the allocated buffer */ | 49 | unsigned int size; /* the size of the allocated buffer */ |
| 30 | unsigned int in; /* data is added at offset (in % size) */ | 50 | unsigned int in; /* data is added at offset (in % size) */ |
| 31 | unsigned int out; /* data is extracted from off. (out % size) */ | 51 | unsigned int out; /* data is extracted from off. (out % size) */ |
| 32 | spinlock_t *lock; /* protects concurrent modifications */ | ||
| 33 | }; | 52 | }; |
| 34 | 53 | ||
| 35 | extern struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size, | 54 | /* |
| 36 | gfp_t gfp_mask, spinlock_t *lock); | 55 | * Macros for declaration and initialization of the kfifo datatype |
| 37 | extern struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, | 56 | */ |
| 38 | spinlock_t *lock); | 57 | |
| 58 | /* helper macro */ | ||
| 59 | #define __kfifo_initializer(s, b) \ | ||
| 60 | (struct kfifo) { \ | ||
| 61 | .size = s, \ | ||
| 62 | .in = 0, \ | ||
| 63 | .out = 0, \ | ||
| 64 | .buffer = b \ | ||
| 65 | } | ||
| 66 | |||
| 67 | /** | ||
| 68 | * DECLARE_KFIFO - macro to declare a kfifo and the associated buffer | ||
| 69 | * @name: name of the declared kfifo datatype | ||
| 70 | * @size: size of the fifo buffer | ||
| 71 | * | ||
| 72 | * Note: the macro can be used inside struct or union declaration | ||
| 73 | * Note: the macro creates two objects: | ||
| 74 | * A kfifo object with the given name and a buffer for the kfifo | ||
| 75 | * object named name##kfifo_buffer | ||
| 76 | */ | ||
| 77 | #define DECLARE_KFIFO(name, size) \ | ||
| 78 | union { \ | ||
| 79 | struct kfifo name; \ | ||
| 80 | unsigned char name##kfifo_buffer[size + sizeof(struct kfifo)]; \ | ||
| 81 | } | ||
| 82 | |||
| 83 | /** | ||
| 84 | * INIT_KFIFO - Initialize a kfifo declared by DECLARED_KFIFO | ||
| 85 | * @name: name of the declared kfifo datatype | ||
| 86 | * @size: size of the fifo buffer | ||
| 87 | */ | ||
| 88 | #define INIT_KFIFO(name) \ | ||
| 89 | name = __kfifo_initializer(sizeof(name##kfifo_buffer) - \ | ||
| 90 | sizeof(struct kfifo), name##kfifo_buffer) | ||
| 91 | |||
| 92 | /** | ||
| 93 | * DEFINE_KFIFO - macro to define and initialize a kfifo | ||
| 94 | * @name: name of the declared kfifo datatype | ||
| 95 | * @size: size of the fifo buffer | ||
| 96 | * | ||
| 97 | * Note: the macro can be used for global and local kfifo data type variables | ||
| 98 | * Note: the macro creates two objects: | ||
| 99 | * A kfifo object with the given name and a buffer for the kfifo | ||
| 100 | * object named name##kfifo_buffer | ||
| 101 | */ | ||
| 102 | #define DEFINE_KFIFO(name, size) \ | ||
| 103 | unsigned char name##kfifo_buffer[size]; \ | ||
| 104 | struct kfifo name = __kfifo_initializer(size, name##kfifo_buffer) | ||
| 105 | |||
| 106 | #undef __kfifo_initializer | ||
| 107 | |||
| 108 | extern void kfifo_init(struct kfifo *fifo, unsigned char *buffer, | ||
| 109 | unsigned int size); | ||
| 110 | extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size, | ||
| 111 | gfp_t gfp_mask); | ||
| 39 | extern void kfifo_free(struct kfifo *fifo); | 112 | extern void kfifo_free(struct kfifo *fifo); |
| 40 | extern unsigned int __kfifo_put(struct kfifo *fifo, | 113 | extern unsigned int kfifo_in(struct kfifo *fifo, |
| 41 | const unsigned char *buffer, unsigned int len); | 114 | const unsigned char *from, unsigned int len); |
| 42 | extern unsigned int __kfifo_get(struct kfifo *fifo, | 115 | extern __must_check unsigned int kfifo_out(struct kfifo *fifo, |
| 43 | unsigned char *buffer, unsigned int len); | 116 | unsigned char *to, unsigned int len); |
| 44 | 117 | ||
| 45 | /** | 118 | /** |
| 46 | * __kfifo_reset - removes the entire FIFO contents, no locking version | 119 | * kfifo_reset - removes the entire FIFO contents |
| 47 | * @fifo: the fifo to be emptied. | 120 | * @fifo: the fifo to be emptied. |
| 48 | */ | 121 | */ |
| 49 | static inline void __kfifo_reset(struct kfifo *fifo) | 122 | static inline void kfifo_reset(struct kfifo *fifo) |
| 50 | { | 123 | { |
| 51 | fifo->in = fifo->out = 0; | 124 | fifo->in = fifo->out = 0; |
| 52 | } | 125 | } |
| 53 | 126 | ||
| 54 | /** | 127 | /** |
| 55 | * kfifo_reset - removes the entire FIFO contents | 128 | * kfifo_reset_out - skip FIFO contents |
| 56 | * @fifo: the fifo to be emptied. | 129 | * @fifo: the fifo to be emptied. |
| 57 | */ | 130 | */ |
| 58 | static inline void kfifo_reset(struct kfifo *fifo) | 131 | static inline void kfifo_reset_out(struct kfifo *fifo) |
| 59 | { | 132 | { |
| 60 | unsigned long flags; | 133 | smp_mb(); |
| 134 | fifo->out = fifo->in; | ||
| 135 | } | ||
| 61 | 136 | ||
| 62 | spin_lock_irqsave(fifo->lock, flags); | 137 | /** |
| 138 | * kfifo_size - returns the size of the fifo in bytes | ||
| 139 | * @fifo: the fifo to be used. | ||
| 140 | */ | ||
| 141 | static inline __must_check unsigned int kfifo_size(struct kfifo *fifo) | ||
| 142 | { | ||
| 143 | return fifo->size; | ||
| 144 | } | ||
| 63 | 145 | ||
| 64 | __kfifo_reset(fifo); | 146 | /** |
| 147 | * kfifo_len - returns the number of used bytes in the FIFO | ||
| 148 | * @fifo: the fifo to be used. | ||
| 149 | */ | ||
| 150 | static inline unsigned int kfifo_len(struct kfifo *fifo) | ||
| 151 | { | ||
| 152 | register unsigned int out; | ||
| 65 | 153 | ||
| 66 | spin_unlock_irqrestore(fifo->lock, flags); | 154 | out = fifo->out; |
| 155 | smp_rmb(); | ||
| 156 | return fifo->in - out; | ||
| 67 | } | 157 | } |
| 68 | 158 | ||
| 69 | /** | 159 | /** |
| 70 | * kfifo_put - puts some data into the FIFO | 160 | * kfifo_is_empty - returns true if the fifo is empty |
| 71 | * @fifo: the fifo to be used. | 161 | * @fifo: the fifo to be used. |
| 72 | * @buffer: the data to be added. | 162 | */ |
| 73 | * @len: the length of the data to be added. | 163 | static inline __must_check int kfifo_is_empty(struct kfifo *fifo) |
| 164 | { | ||
| 165 | return fifo->in == fifo->out; | ||
| 166 | } | ||
| 167 | |||
| 168 | /** | ||
| 169 | * kfifo_is_full - returns true if the fifo is full | ||
| 170 | * @fifo: the fifo to be used. | ||
| 171 | */ | ||
| 172 | static inline __must_check int kfifo_is_full(struct kfifo *fifo) | ||
| 173 | { | ||
| 174 | return kfifo_len(fifo) == kfifo_size(fifo); | ||
| 175 | } | ||
| 176 | |||
| 177 | /** | ||
| 178 | * kfifo_avail - returns the number of bytes available in the FIFO | ||
| 179 | * @fifo: the fifo to be used. | ||
| 180 | */ | ||
| 181 | static inline __must_check unsigned int kfifo_avail(struct kfifo *fifo) | ||
| 182 | { | ||
| 183 | return kfifo_size(fifo) - kfifo_len(fifo); | ||
| 184 | } | ||
| 185 | |||
| 186 | /** | ||
| 187 | * kfifo_in_locked - puts some data into the FIFO using a spinlock for locking | ||
| 188 | * @fifo: the fifo to be used. | ||
| 189 | * @from: the data to be added. | ||
| 190 | * @n: the length of the data to be added. | ||
| 191 | * @lock: pointer to the spinlock to use for locking. | ||
| 74 | * | 192 | * |
| 75 | * This function copies at most @len bytes from the @buffer into | 193 | * This function copies at most @len bytes from the @from buffer into |
| 76 | * the FIFO depending on the free space, and returns the number of | 194 | * the FIFO depending on the free space, and returns the number of |
| 77 | * bytes copied. | 195 | * bytes copied. |
| 78 | */ | 196 | */ |
| 79 | static inline unsigned int kfifo_put(struct kfifo *fifo, | 197 | static inline unsigned int kfifo_in_locked(struct kfifo *fifo, |
| 80 | const unsigned char *buffer, unsigned int len) | 198 | const unsigned char *from, unsigned int n, spinlock_t *lock) |
| 81 | { | 199 | { |
| 82 | unsigned long flags; | 200 | unsigned long flags; |
| 83 | unsigned int ret; | 201 | unsigned int ret; |
| 84 | 202 | ||
| 85 | spin_lock_irqsave(fifo->lock, flags); | 203 | spin_lock_irqsave(lock, flags); |
| 86 | 204 | ||
| 87 | ret = __kfifo_put(fifo, buffer, len); | 205 | ret = kfifo_in(fifo, from, n); |
| 88 | 206 | ||
| 89 | spin_unlock_irqrestore(fifo->lock, flags); | 207 | spin_unlock_irqrestore(lock, flags); |
| 90 | 208 | ||
| 91 | return ret; | 209 | return ret; |
| 92 | } | 210 | } |
| 93 | 211 | ||
| 94 | /** | 212 | /** |
| 95 | * kfifo_get - gets some data from the FIFO | 213 | * kfifo_out_locked - gets some data from the FIFO using a spinlock for locking |
| 96 | * @fifo: the fifo to be used. | 214 | * @fifo: the fifo to be used. |
| 97 | * @buffer: where the data must be copied. | 215 | * @to: where the data must be copied. |
| 98 | * @len: the size of the destination buffer. | 216 | * @n: the size of the destination buffer. |
| 217 | * @lock: pointer to the spinlock to use for locking. | ||
| 99 | * | 218 | * |
| 100 | * This function copies at most @len bytes from the FIFO into the | 219 | * This function copies at most @len bytes from the FIFO into the |
| 101 | * @buffer and returns the number of copied bytes. | 220 | * @to buffer and returns the number of copied bytes. |
| 102 | */ | 221 | */ |
| 103 | static inline unsigned int kfifo_get(struct kfifo *fifo, | 222 | static inline __must_check unsigned int kfifo_out_locked(struct kfifo *fifo, |
| 104 | unsigned char *buffer, unsigned int len) | 223 | unsigned char *to, unsigned int n, spinlock_t *lock) |
| 105 | { | 224 | { |
| 106 | unsigned long flags; | 225 | unsigned long flags; |
| 107 | unsigned int ret; | 226 | unsigned int ret; |
| 108 | 227 | ||
| 109 | spin_lock_irqsave(fifo->lock, flags); | 228 | spin_lock_irqsave(lock, flags); |
| 110 | 229 | ||
| 111 | ret = __kfifo_get(fifo, buffer, len); | 230 | ret = kfifo_out(fifo, to, n); |
| 112 | 231 | ||
| 113 | /* | 232 | /* |
| 114 | * optimization: if the FIFO is empty, set the indices to 0 | 233 | * optimization: if the FIFO is empty, set the indices to 0 |
| 115 | * so we don't wrap the next time | 234 | * so we don't wrap the next time |
| 116 | */ | 235 | */ |
| 117 | if (fifo->in == fifo->out) | 236 | if (kfifo_is_empty(fifo)) |
| 118 | fifo->in = fifo->out = 0; | 237 | kfifo_reset(fifo); |
| 238 | |||
| 239 | spin_unlock_irqrestore(lock, flags); | ||
| 240 | |||
| 241 | return ret; | ||
| 242 | } | ||
| 243 | |||
| 244 | extern void kfifo_skip(struct kfifo *fifo, unsigned int len); | ||
| 245 | |||
| 246 | extern __must_check unsigned int kfifo_from_user(struct kfifo *fifo, | ||
| 247 | const void __user *from, unsigned int n); | ||
| 248 | |||
| 249 | extern __must_check unsigned int kfifo_to_user(struct kfifo *fifo, | ||
| 250 | void __user *to, unsigned int n); | ||
| 251 | |||
| 252 | /** | ||
| 253 | * __kfifo_add_out internal helper function for updating the out offset | ||
| 254 | */ | ||
| 255 | static inline void __kfifo_add_out(struct kfifo *fifo, | ||
| 256 | unsigned int off) | ||
| 257 | { | ||
| 258 | smp_mb(); | ||
| 259 | fifo->out += off; | ||
| 260 | } | ||
| 261 | |||
| 262 | /** | ||
| 263 | * __kfifo_add_in internal helper function for updating the in offset | ||
| 264 | */ | ||
| 265 | static inline void __kfifo_add_in(struct kfifo *fifo, | ||
| 266 | unsigned int off) | ||
| 267 | { | ||
| 268 | smp_wmb(); | ||
| 269 | fifo->in += off; | ||
| 270 | } | ||
| 271 | |||
| 272 | /** | ||
| 273 | * __kfifo_off internal helper function for calculating the index of a | ||
| 274 | * given offeset | ||
| 275 | */ | ||
| 276 | static inline unsigned int __kfifo_off(struct kfifo *fifo, unsigned int off) | ||
| 277 | { | ||
| 278 | return off & (fifo->size - 1); | ||
| 279 | } | ||
| 280 | |||
| 281 | /** | ||
| 282 | * __kfifo_peek_n internal helper function for determinate the length of | ||
| 283 | * the next record in the fifo | ||
| 284 | */ | ||
| 285 | static inline unsigned int __kfifo_peek_n(struct kfifo *fifo, | ||
| 286 | unsigned int recsize) | ||
| 287 | { | ||
| 288 | #define __KFIFO_GET(fifo, off, shift) \ | ||
| 289 | ((fifo)->buffer[__kfifo_off((fifo), (fifo)->out+(off))] << (shift)) | ||
| 290 | |||
| 291 | unsigned int l; | ||
| 292 | |||
| 293 | l = __KFIFO_GET(fifo, 0, 0); | ||
| 294 | |||
| 295 | if (--recsize) | ||
| 296 | l |= __KFIFO_GET(fifo, 1, 8); | ||
| 297 | |||
| 298 | return l; | ||
| 299 | #undef __KFIFO_GET | ||
| 300 | } | ||
| 301 | |||
| 302 | /** | ||
| 303 | * __kfifo_poke_n internal helper function for storing the length of | ||
| 304 | * the next record into the fifo | ||
| 305 | */ | ||
| 306 | static inline void __kfifo_poke_n(struct kfifo *fifo, | ||
| 307 | unsigned int recsize, unsigned int n) | ||
| 308 | { | ||
| 309 | #define __KFIFO_PUT(fifo, off, val, shift) \ | ||
| 310 | ( \ | ||
| 311 | (fifo)->buffer[__kfifo_off((fifo), (fifo)->in+(off))] = \ | ||
| 312 | (unsigned char)((val) >> (shift)) \ | ||
| 313 | ) | ||
| 119 | 314 | ||
| 120 | spin_unlock_irqrestore(fifo->lock, flags); | 315 | __KFIFO_PUT(fifo, 0, n, 0); |
| 121 | 316 | ||
| 317 | if (--recsize) | ||
| 318 | __KFIFO_PUT(fifo, 1, n, 8); | ||
| 319 | #undef __KFIFO_PUT | ||
| 320 | } | ||
| 321 | |||
| 322 | /** | ||
| 323 | * __kfifo_in_... internal functions for put date into the fifo | ||
| 324 | * do not call it directly, use kfifo_in_rec() instead | ||
| 325 | */ | ||
| 326 | extern unsigned int __kfifo_in_n(struct kfifo *fifo, | ||
| 327 | const void *from, unsigned int n, unsigned int recsize); | ||
| 328 | |||
| 329 | extern unsigned int __kfifo_in_generic(struct kfifo *fifo, | ||
| 330 | const void *from, unsigned int n, unsigned int recsize); | ||
| 331 | |||
| 332 | static inline unsigned int __kfifo_in_rec(struct kfifo *fifo, | ||
| 333 | const void *from, unsigned int n, unsigned int recsize) | ||
| 334 | { | ||
| 335 | unsigned int ret; | ||
| 336 | |||
| 337 | ret = __kfifo_in_n(fifo, from, n, recsize); | ||
| 338 | |||
| 339 | if (likely(ret == 0)) { | ||
| 340 | if (recsize) | ||
| 341 | __kfifo_poke_n(fifo, recsize, n); | ||
| 342 | __kfifo_add_in(fifo, n + recsize); | ||
| 343 | } | ||
| 122 | return ret; | 344 | return ret; |
| 123 | } | 345 | } |
| 124 | 346 | ||
| 125 | /** | 347 | /** |
| 126 | * __kfifo_len - returns the number of bytes available in the FIFO, no locking version | 348 | * kfifo_in_rec - puts some record data into the FIFO |
| 127 | * @fifo: the fifo to be used. | 349 | * @fifo: the fifo to be used. |
| 350 | * @from: the data to be added. | ||
| 351 | * @n: the length of the data to be added. | ||
| 352 | * @recsize: size of record field | ||
| 353 | * | ||
| 354 | * This function copies @n bytes from the @from into the FIFO and returns | ||
| 355 | * the number of bytes which cannot be copied. | ||
| 356 | * A returned value greater than the @n value means that the record doesn't | ||
| 357 | * fit into the buffer. | ||
| 358 | * | ||
| 359 | * Note that with only one concurrent reader and one concurrent | ||
| 360 | * writer, you don't need extra locking to use these functions. | ||
| 128 | */ | 361 | */ |
| 129 | static inline unsigned int __kfifo_len(struct kfifo *fifo) | 362 | static inline __must_check unsigned int kfifo_in_rec(struct kfifo *fifo, |
| 363 | void *from, unsigned int n, unsigned int recsize) | ||
| 130 | { | 364 | { |
| 131 | return fifo->in - fifo->out; | 365 | if (!__builtin_constant_p(recsize)) |
| 366 | return __kfifo_in_generic(fifo, from, n, recsize); | ||
| 367 | return __kfifo_in_rec(fifo, from, n, recsize); | ||
| 132 | } | 368 | } |
| 133 | 369 | ||
| 134 | /** | 370 | /** |
| 135 | * kfifo_len - returns the number of bytes available in the FIFO | 371 | * __kfifo_out_... internal functions for get date from the fifo |
| 372 | * do not call it directly, use kfifo_out_rec() instead | ||
| 373 | */ | ||
| 374 | extern unsigned int __kfifo_out_n(struct kfifo *fifo, | ||
| 375 | void *to, unsigned int reclen, unsigned int recsize); | ||
| 376 | |||
| 377 | extern unsigned int __kfifo_out_generic(struct kfifo *fifo, | ||
| 378 | void *to, unsigned int n, | ||
| 379 | unsigned int recsize, unsigned int *total); | ||
| 380 | |||
| 381 | static inline unsigned int __kfifo_out_rec(struct kfifo *fifo, | ||
| 382 | void *to, unsigned int n, unsigned int recsize, | ||
| 383 | unsigned int *total) | ||
| 384 | { | ||
| 385 | unsigned int l; | ||
| 386 | |||
| 387 | if (!recsize) { | ||
| 388 | l = n; | ||
| 389 | if (total) | ||
| 390 | *total = l; | ||
| 391 | } else { | ||
| 392 | l = __kfifo_peek_n(fifo, recsize); | ||
| 393 | if (total) | ||
| 394 | *total = l; | ||
| 395 | if (n < l) | ||
| 396 | return l; | ||
| 397 | } | ||
| 398 | |||
| 399 | return __kfifo_out_n(fifo, to, l, recsize); | ||
| 400 | } | ||
| 401 | |||
| 402 | /** | ||
| 403 | * kfifo_out_rec - gets some record data from the FIFO | ||
| 136 | * @fifo: the fifo to be used. | 404 | * @fifo: the fifo to be used. |
| 405 | * @to: where the data must be copied. | ||
| 406 | * @n: the size of the destination buffer. | ||
| 407 | * @recsize: size of record field | ||
| 408 | * @total: pointer where the total number of to copied bytes should stored | ||
| 409 | * | ||
| 410 | * This function copies at most @n bytes from the FIFO to @to and returns the | ||
| 411 | * number of bytes which cannot be copied. | ||
| 412 | * A returned value greater than the @n value means that the record doesn't | ||
| 413 | * fit into the @to buffer. | ||
| 414 | * | ||
| 415 | * Note that with only one concurrent reader and one concurrent | ||
| 416 | * writer, you don't need extra locking to use these functions. | ||
| 137 | */ | 417 | */ |
| 138 | static inline unsigned int kfifo_len(struct kfifo *fifo) | 418 | static inline __must_check unsigned int kfifo_out_rec(struct kfifo *fifo, |
| 419 | void *to, unsigned int n, unsigned int recsize, | ||
| 420 | unsigned int *total) | ||
| 421 | |||
| 139 | { | 422 | { |
| 140 | unsigned long flags; | 423 | if (!__builtin_constant_p(recsize)) |
| 141 | unsigned int ret; | 424 | return __kfifo_out_generic(fifo, to, n, recsize, total); |
| 425 | return __kfifo_out_rec(fifo, to, n, recsize, total); | ||
| 426 | } | ||
| 427 | |||
| 428 | /** | ||
| 429 | * __kfifo_from_user_... internal functions for transfer from user space into | ||
| 430 | * the fifo. do not call it directly, use kfifo_from_user_rec() instead | ||
| 431 | */ | ||
| 432 | extern unsigned int __kfifo_from_user_n(struct kfifo *fifo, | ||
| 433 | const void __user *from, unsigned int n, unsigned int recsize); | ||
| 142 | 434 | ||
| 143 | spin_lock_irqsave(fifo->lock, flags); | 435 | extern unsigned int __kfifo_from_user_generic(struct kfifo *fifo, |
| 436 | const void __user *from, unsigned int n, unsigned int recsize); | ||
| 144 | 437 | ||
| 145 | ret = __kfifo_len(fifo); | 438 | static inline unsigned int __kfifo_from_user_rec(struct kfifo *fifo, |
| 439 | const void __user *from, unsigned int n, unsigned int recsize) | ||
| 440 | { | ||
| 441 | unsigned int ret; | ||
| 146 | 442 | ||
| 147 | spin_unlock_irqrestore(fifo->lock, flags); | 443 | ret = __kfifo_from_user_n(fifo, from, n, recsize); |
| 148 | 444 | ||
| 445 | if (likely(ret == 0)) { | ||
| 446 | if (recsize) | ||
| 447 | __kfifo_poke_n(fifo, recsize, n); | ||
| 448 | __kfifo_add_in(fifo, n + recsize); | ||
| 449 | } | ||
| 149 | return ret; | 450 | return ret; |
| 150 | } | 451 | } |
| 151 | 452 | ||
| 453 | /** | ||
| 454 | * kfifo_from_user_rec - puts some data from user space into the FIFO | ||
| 455 | * @fifo: the fifo to be used. | ||
| 456 | * @from: pointer to the data to be added. | ||
| 457 | * @n: the length of the data to be added. | ||
| 458 | * @recsize: size of record field | ||
| 459 | * | ||
| 460 | * This function copies @n bytes from the @from into the | ||
| 461 | * FIFO and returns the number of bytes which cannot be copied. | ||
| 462 | * | ||
| 463 | * If the returned value is equal or less the @n value, the copy_from_user() | ||
| 464 | * functions has failed. Otherwise the record doesn't fit into the buffer. | ||
| 465 | * | ||
| 466 | * Note that with only one concurrent reader and one concurrent | ||
| 467 | * writer, you don't need extra locking to use these functions. | ||
| 468 | */ | ||
| 469 | static inline __must_check unsigned int kfifo_from_user_rec(struct kfifo *fifo, | ||
| 470 | const void __user *from, unsigned int n, unsigned int recsize) | ||
| 471 | { | ||
| 472 | if (!__builtin_constant_p(recsize)) | ||
| 473 | return __kfifo_from_user_generic(fifo, from, n, recsize); | ||
| 474 | return __kfifo_from_user_rec(fifo, from, n, recsize); | ||
| 475 | } | ||
| 476 | |||
| 477 | /** | ||
| 478 | * __kfifo_to_user_... internal functions for transfer fifo data into user space | ||
| 479 | * do not call it directly, use kfifo_to_user_rec() instead | ||
| 480 | */ | ||
| 481 | extern unsigned int __kfifo_to_user_n(struct kfifo *fifo, | ||
| 482 | void __user *to, unsigned int n, unsigned int reclen, | ||
| 483 | unsigned int recsize); | ||
| 484 | |||
| 485 | extern unsigned int __kfifo_to_user_generic(struct kfifo *fifo, | ||
| 486 | void __user *to, unsigned int n, unsigned int recsize, | ||
| 487 | unsigned int *total); | ||
| 488 | |||
| 489 | static inline unsigned int __kfifo_to_user_rec(struct kfifo *fifo, | ||
| 490 | void __user *to, unsigned int n, | ||
| 491 | unsigned int recsize, unsigned int *total) | ||
| 492 | { | ||
| 493 | unsigned int l; | ||
| 494 | |||
| 495 | if (!recsize) { | ||
| 496 | l = n; | ||
| 497 | if (total) | ||
| 498 | *total = l; | ||
| 499 | } else { | ||
| 500 | l = __kfifo_peek_n(fifo, recsize); | ||
| 501 | if (total) | ||
| 502 | *total = l; | ||
| 503 | if (n < l) | ||
| 504 | return l; | ||
| 505 | } | ||
| 506 | |||
| 507 | return __kfifo_to_user_n(fifo, to, n, l, recsize); | ||
| 508 | } | ||
| 509 | |||
| 510 | /** | ||
| 511 | * kfifo_to_user_rec - gets data from the FIFO and write it to user space | ||
| 512 | * @fifo: the fifo to be used. | ||
| 513 | * @to: where the data must be copied. | ||
| 514 | * @n: the size of the destination buffer. | ||
| 515 | * @recsize: size of record field | ||
| 516 | * @total: pointer where the total number of to copied bytes should stored | ||
| 517 | * | ||
| 518 | * This function copies at most @n bytes from the FIFO to the @to. | ||
| 519 | * In case of an error, the function returns the number of bytes which cannot | ||
| 520 | * be copied. | ||
| 521 | * If the returned value is equal or less the @n value, the copy_to_user() | ||
| 522 | * functions has failed. Otherwise the record doesn't fit into the @to buffer. | ||
| 523 | * | ||
| 524 | * Note that with only one concurrent reader and one concurrent | ||
| 525 | * writer, you don't need extra locking to use these functions. | ||
| 526 | */ | ||
| 527 | static inline __must_check unsigned int kfifo_to_user_rec(struct kfifo *fifo, | ||
| 528 | void __user *to, unsigned int n, unsigned int recsize, | ||
| 529 | unsigned int *total) | ||
| 530 | { | ||
| 531 | if (!__builtin_constant_p(recsize)) | ||
| 532 | return __kfifo_to_user_generic(fifo, to, n, recsize, total); | ||
| 533 | return __kfifo_to_user_rec(fifo, to, n, recsize, total); | ||
| 534 | } | ||
| 535 | |||
| 536 | /** | ||
| 537 | * __kfifo_peek_... internal functions for peek into the next fifo record | ||
| 538 | * do not call it directly, use kfifo_peek_rec() instead | ||
| 539 | */ | ||
| 540 | extern unsigned int __kfifo_peek_generic(struct kfifo *fifo, | ||
| 541 | unsigned int recsize); | ||
| 542 | |||
| 543 | /** | ||
| 544 | * kfifo_peek_rec - gets the size of the next FIFO record data | ||
| 545 | * @fifo: the fifo to be used. | ||
| 546 | * @recsize: size of record field | ||
| 547 | * | ||
| 548 | * This function returns the size of the next FIFO record in number of bytes | ||
| 549 | */ | ||
| 550 | static inline __must_check unsigned int kfifo_peek_rec(struct kfifo *fifo, | ||
| 551 | unsigned int recsize) | ||
| 552 | { | ||
| 553 | if (!__builtin_constant_p(recsize)) | ||
| 554 | return __kfifo_peek_generic(fifo, recsize); | ||
| 555 | if (!recsize) | ||
| 556 | return kfifo_len(fifo); | ||
| 557 | return __kfifo_peek_n(fifo, recsize); | ||
| 558 | } | ||
| 559 | |||
| 560 | /** | ||
| 561 | * __kfifo_skip_... internal functions for skip the next fifo record | ||
| 562 | * do not call it directly, use kfifo_skip_rec() instead | ||
| 563 | */ | ||
| 564 | extern void __kfifo_skip_generic(struct kfifo *fifo, unsigned int recsize); | ||
| 565 | |||
| 566 | static inline void __kfifo_skip_rec(struct kfifo *fifo, | ||
| 567 | unsigned int recsize) | ||
| 568 | { | ||
| 569 | unsigned int l; | ||
| 570 | |||
| 571 | if (recsize) { | ||
| 572 | l = __kfifo_peek_n(fifo, recsize); | ||
| 573 | |||
| 574 | if (l + recsize <= kfifo_len(fifo)) { | ||
| 575 | __kfifo_add_out(fifo, l + recsize); | ||
| 576 | return; | ||
| 577 | } | ||
| 578 | } | ||
| 579 | kfifo_reset_out(fifo); | ||
| 580 | } | ||
| 581 | |||
| 582 | /** | ||
| 583 | * kfifo_skip_rec - skip the next fifo out record | ||
| 584 | * @fifo: the fifo to be used. | ||
| 585 | * @recsize: size of record field | ||
| 586 | * | ||
| 587 | * This function skips the next FIFO record | ||
| 588 | */ | ||
| 589 | static inline void kfifo_skip_rec(struct kfifo *fifo, | ||
| 590 | unsigned int recsize) | ||
| 591 | { | ||
| 592 | if (!__builtin_constant_p(recsize)) | ||
| 593 | __kfifo_skip_generic(fifo, recsize); | ||
| 594 | else | ||
| 595 | __kfifo_skip_rec(fifo, recsize); | ||
| 596 | } | ||
| 597 | |||
| 598 | /** | ||
| 599 | * kfifo_avail_rec - returns the number of bytes available in a record FIFO | ||
| 600 | * @fifo: the fifo to be used. | ||
| 601 | * @recsize: size of record field | ||
| 602 | */ | ||
| 603 | static inline __must_check unsigned int kfifo_avail_rec(struct kfifo *fifo, | ||
| 604 | unsigned int recsize) | ||
| 605 | { | ||
| 606 | unsigned int l = kfifo_size(fifo) - kfifo_len(fifo); | ||
| 607 | |||
| 608 | return (l > recsize) ? l - recsize : 0; | ||
| 609 | } | ||
| 610 | |||
| 152 | #endif | 611 | #endif |
diff --git a/include/linux/memory.h b/include/linux/memory.h index 37fa19b34ef5..1adfe779eb99 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h | |||
| @@ -50,6 +50,19 @@ struct memory_notify { | |||
| 50 | int status_change_nid; | 50 | int status_change_nid; |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | /* | ||
| 54 | * During pageblock isolation, count the number of pages within the | ||
| 55 | * range [start_pfn, start_pfn + nr_pages) which are owned by code | ||
| 56 | * in the notifier chain. | ||
| 57 | */ | ||
| 58 | #define MEM_ISOLATE_COUNT (1<<0) | ||
| 59 | |||
| 60 | struct memory_isolate_notify { | ||
| 61 | unsigned long start_pfn; /* Start of range to check */ | ||
| 62 | unsigned int nr_pages; /* # pages in range to check */ | ||
| 63 | unsigned int pages_found; /* # pages owned found by callbacks */ | ||
| 64 | }; | ||
| 65 | |||
| 53 | struct notifier_block; | 66 | struct notifier_block; |
| 54 | struct mem_section; | 67 | struct mem_section; |
| 55 | 68 | ||
| @@ -76,14 +89,28 @@ static inline int memory_notify(unsigned long val, void *v) | |||
| 76 | { | 89 | { |
| 77 | return 0; | 90 | return 0; |
| 78 | } | 91 | } |
| 92 | static inline int register_memory_isolate_notifier(struct notifier_block *nb) | ||
| 93 | { | ||
| 94 | return 0; | ||
| 95 | } | ||
| 96 | static inline void unregister_memory_isolate_notifier(struct notifier_block *nb) | ||
| 97 | { | ||
| 98 | } | ||
| 99 | static inline int memory_isolate_notify(unsigned long val, void *v) | ||
| 100 | { | ||
| 101 | return 0; | ||
| 102 | } | ||
| 79 | #else | 103 | #else |
| 80 | extern int register_memory_notifier(struct notifier_block *nb); | 104 | extern int register_memory_notifier(struct notifier_block *nb); |
| 81 | extern void unregister_memory_notifier(struct notifier_block *nb); | 105 | extern void unregister_memory_notifier(struct notifier_block *nb); |
| 106 | extern int register_memory_isolate_notifier(struct notifier_block *nb); | ||
| 107 | extern void unregister_memory_isolate_notifier(struct notifier_block *nb); | ||
| 82 | extern int register_new_memory(int, struct mem_section *); | 108 | extern int register_new_memory(int, struct mem_section *); |
| 83 | extern int unregister_memory_section(struct mem_section *); | 109 | extern int unregister_memory_section(struct mem_section *); |
| 84 | extern int memory_dev_init(void); | 110 | extern int memory_dev_init(void); |
| 85 | extern int remove_memory_block(unsigned long, struct mem_section *, int); | 111 | extern int remove_memory_block(unsigned long, struct mem_section *, int); |
| 86 | extern int memory_notify(unsigned long val, void *v); | 112 | extern int memory_notify(unsigned long val, void *v); |
| 113 | extern int memory_isolate_notify(unsigned long val, void *v); | ||
| 87 | extern struct memory_block *find_memory_block(struct mem_section *); | 114 | extern struct memory_block *find_memory_block(struct mem_section *); |
| 88 | #define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT) | 115 | #define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT) |
| 89 | enum mem_add_context { BOOT, HOTPLUG }; | 116 | enum mem_add_context { BOOT, HOTPLUG }; |
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 7394e3bc8f4b..ff92b46f5153 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
| 29 | #include <linux/timer.h> | 29 | #include <linux/timer.h> |
| 30 | #include <linux/workqueue.h> | 30 | #include <linux/workqueue.h> |
| 31 | #include <linux/kfifo.h> | ||
| 31 | #include <scsi/iscsi_proto.h> | 32 | #include <scsi/iscsi_proto.h> |
| 32 | #include <scsi/iscsi_if.h> | 33 | #include <scsi/iscsi_if.h> |
| 33 | #include <scsi/scsi_transport_iscsi.h> | 34 | #include <scsi/scsi_transport_iscsi.h> |
| @@ -231,7 +232,7 @@ struct iscsi_conn { | |||
| 231 | }; | 232 | }; |
| 232 | 233 | ||
| 233 | struct iscsi_pool { | 234 | struct iscsi_pool { |
| 234 | struct kfifo *queue; /* FIFO Queue */ | 235 | struct kfifo queue; /* FIFO Queue */ |
| 235 | void **pool; /* Pool of elements */ | 236 | void **pool; /* Pool of elements */ |
| 236 | int max; /* Max number of elements */ | 237 | int max; /* Max number of elements */ |
| 237 | }; | 238 | }; |
diff --git a/include/scsi/libiscsi_tcp.h b/include/scsi/libiscsi_tcp.h index 9e3182e659db..741ae7ed4394 100644 --- a/include/scsi/libiscsi_tcp.h +++ b/include/scsi/libiscsi_tcp.h | |||
| @@ -80,7 +80,7 @@ struct iscsi_tcp_task { | |||
| 80 | int data_offset; | 80 | int data_offset; |
| 81 | struct iscsi_r2t_info *r2t; /* in progress solict R2T */ | 81 | struct iscsi_r2t_info *r2t; /* in progress solict R2T */ |
| 82 | struct iscsi_pool r2tpool; | 82 | struct iscsi_pool r2tpool; |
| 83 | struct kfifo *r2tqueue; | 83 | struct kfifo r2tqueue; |
| 84 | void *dd_data; | 84 | void *dd_data; |
| 85 | }; | 85 | }; |
| 86 | 86 | ||
diff --git a/include/scsi/libsrp.h b/include/scsi/libsrp.h index ba615e4c1d7c..07e3adde21d9 100644 --- a/include/scsi/libsrp.h +++ b/include/scsi/libsrp.h | |||
| @@ -21,7 +21,7 @@ struct srp_buf { | |||
| 21 | struct srp_queue { | 21 | struct srp_queue { |
| 22 | void *pool; | 22 | void *pool; |
| 23 | void *items; | 23 | void *items; |
| 24 | struct kfifo *queue; | 24 | struct kfifo queue; |
| 25 | spinlock_t lock; | 25 | spinlock_t lock; |
| 26 | }; | 26 | }; |
| 27 | 27 | ||
diff --git a/kernel/kfifo.c b/kernel/kfifo.c index 3765ff3c1bbe..e92d519f93b1 100644 --- a/kernel/kfifo.c +++ b/kernel/kfifo.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * A simple kernel FIFO implementation. | 2 | * A generic kernel FIFO implementation. |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2009 Stefani Seibold <stefani@seibold.net> | ||
| 4 | * Copyright (C) 2004 Stelian Pop <stelian@popies.net> | 5 | * Copyright (C) 2004 Stelian Pop <stelian@popies.net> |
| 5 | * | 6 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| @@ -25,50 +26,48 @@ | |||
| 25 | #include <linux/err.h> | 26 | #include <linux/err.h> |
| 26 | #include <linux/kfifo.h> | 27 | #include <linux/kfifo.h> |
| 27 | #include <linux/log2.h> | 28 | #include <linux/log2.h> |
| 29 | #include <linux/uaccess.h> | ||
| 30 | |||
| 31 | static void _kfifo_init(struct kfifo *fifo, unsigned char *buffer, | ||
| 32 | unsigned int size) | ||
| 33 | { | ||
| 34 | fifo->buffer = buffer; | ||
| 35 | fifo->size = size; | ||
| 36 | |||
| 37 | kfifo_reset(fifo); | ||
| 38 | } | ||
| 28 | 39 | ||
| 29 | /** | 40 | /** |
| 30 | * kfifo_init - allocates a new FIFO using a preallocated buffer | 41 | * kfifo_init - initialize a FIFO using a preallocated buffer |
| 42 | * @fifo: the fifo to assign the buffer | ||
| 31 | * @buffer: the preallocated buffer to be used. | 43 | * @buffer: the preallocated buffer to be used. |
| 32 | * @size: the size of the internal buffer, this have to be a power of 2. | 44 | * @size: the size of the internal buffer, this have to be a power of 2. |
| 33 | * @gfp_mask: get_free_pages mask, passed to kmalloc() | ||
| 34 | * @lock: the lock to be used to protect the fifo buffer | ||
| 35 | * | 45 | * |
| 36 | * Do NOT pass the kfifo to kfifo_free() after use! Simply free the | ||
| 37 | * &struct kfifo with kfree(). | ||
| 38 | */ | 46 | */ |
| 39 | struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size, | 47 | void kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int size) |
| 40 | gfp_t gfp_mask, spinlock_t *lock) | ||
| 41 | { | 48 | { |
| 42 | struct kfifo *fifo; | ||
| 43 | |||
| 44 | /* size must be a power of 2 */ | 49 | /* size must be a power of 2 */ |
| 45 | BUG_ON(!is_power_of_2(size)); | 50 | BUG_ON(!is_power_of_2(size)); |
| 46 | 51 | ||
| 47 | fifo = kmalloc(sizeof(struct kfifo), gfp_mask); | 52 | _kfifo_init(fifo, buffer, size); |
| 48 | if (!fifo) | ||
| 49 | return ERR_PTR(-ENOMEM); | ||
| 50 | |||
| 51 | fifo->buffer = buffer; | ||
| 52 | fifo->size = size; | ||
| 53 | fifo->in = fifo->out = 0; | ||
| 54 | fifo->lock = lock; | ||
| 55 | |||
| 56 | return fifo; | ||
| 57 | } | 53 | } |
| 58 | EXPORT_SYMBOL(kfifo_init); | 54 | EXPORT_SYMBOL(kfifo_init); |
| 59 | 55 | ||
| 60 | /** | 56 | /** |
| 61 | * kfifo_alloc - allocates a new FIFO and its internal buffer | 57 | * kfifo_alloc - allocates a new FIFO internal buffer |
| 62 | * @size: the size of the internal buffer to be allocated. | 58 | * @fifo: the fifo to assign then new buffer |
| 59 | * @size: the size of the buffer to be allocated, this have to be a power of 2. | ||
| 63 | * @gfp_mask: get_free_pages mask, passed to kmalloc() | 60 | * @gfp_mask: get_free_pages mask, passed to kmalloc() |
| 64 | * @lock: the lock to be used to protect the fifo buffer | 61 | * |
| 62 | * This function dynamically allocates a new fifo internal buffer | ||
| 65 | * | 63 | * |
| 66 | * The size will be rounded-up to a power of 2. | 64 | * The size will be rounded-up to a power of 2. |
| 65 | * The buffer will be release with kfifo_free(). | ||
| 66 | * Return 0 if no error, otherwise the an error code | ||
| 67 | */ | 67 | */ |
| 68 | struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock) | 68 | int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask) |
| 69 | { | 69 | { |
| 70 | unsigned char *buffer; | 70 | unsigned char *buffer; |
| 71 | struct kfifo *ret; | ||
| 72 | 71 | ||
| 73 | /* | 72 | /* |
| 74 | * round up to the next power of 2, since our 'let the indices | 73 | * round up to the next power of 2, since our 'let the indices |
| @@ -80,48 +79,91 @@ struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock) | |||
| 80 | } | 79 | } |
| 81 | 80 | ||
| 82 | buffer = kmalloc(size, gfp_mask); | 81 | buffer = kmalloc(size, gfp_mask); |
| 83 | if (!buffer) | 82 | if (!buffer) { |
| 84 | return ERR_PTR(-ENOMEM); | 83 | _kfifo_init(fifo, 0, 0); |
| 85 | 84 | return -ENOMEM; | |
| 86 | ret = kfifo_init(buffer, size, gfp_mask, lock); | 85 | } |
| 87 | 86 | ||
| 88 | if (IS_ERR(ret)) | 87 | _kfifo_init(fifo, buffer, size); |
| 89 | kfree(buffer); | ||
| 90 | 88 | ||
| 91 | return ret; | 89 | return 0; |
| 92 | } | 90 | } |
| 93 | EXPORT_SYMBOL(kfifo_alloc); | 91 | EXPORT_SYMBOL(kfifo_alloc); |
| 94 | 92 | ||
| 95 | /** | 93 | /** |
| 96 | * kfifo_free - frees the FIFO | 94 | * kfifo_free - frees the FIFO internal buffer |
| 97 | * @fifo: the fifo to be freed. | 95 | * @fifo: the fifo to be freed. |
| 98 | */ | 96 | */ |
| 99 | void kfifo_free(struct kfifo *fifo) | 97 | void kfifo_free(struct kfifo *fifo) |
| 100 | { | 98 | { |
| 101 | kfree(fifo->buffer); | 99 | kfree(fifo->buffer); |
| 102 | kfree(fifo); | ||
| 103 | } | 100 | } |
| 104 | EXPORT_SYMBOL(kfifo_free); | 101 | EXPORT_SYMBOL(kfifo_free); |
| 105 | 102 | ||
| 106 | /** | 103 | /** |
| 107 | * __kfifo_put - puts some data into the FIFO, no locking version | 104 | * kfifo_skip - skip output data |
| 108 | * @fifo: the fifo to be used. | 105 | * @fifo: the fifo to be used. |
| 109 | * @buffer: the data to be added. | 106 | * @len: number of bytes to skip |
| 110 | * @len: the length of the data to be added. | ||
| 111 | * | ||
| 112 | * This function copies at most @len bytes from the @buffer into | ||
| 113 | * the FIFO depending on the free space, and returns the number of | ||
| 114 | * bytes copied. | ||
| 115 | * | ||
| 116 | * Note that with only one concurrent reader and one concurrent | ||
| 117 | * writer, you don't need extra locking to use these functions. | ||
| 118 | */ | 107 | */ |
| 119 | unsigned int __kfifo_put(struct kfifo *fifo, | 108 | void kfifo_skip(struct kfifo *fifo, unsigned int len) |
| 120 | const unsigned char *buffer, unsigned int len) | 109 | { |
| 110 | if (len < kfifo_len(fifo)) { | ||
| 111 | __kfifo_add_out(fifo, len); | ||
| 112 | return; | ||
| 113 | } | ||
| 114 | kfifo_reset_out(fifo); | ||
| 115 | } | ||
| 116 | EXPORT_SYMBOL(kfifo_skip); | ||
| 117 | |||
| 118 | static inline void __kfifo_in_data(struct kfifo *fifo, | ||
| 119 | const void *from, unsigned int len, unsigned int off) | ||
| 121 | { | 120 | { |
| 122 | unsigned int l; | 121 | unsigned int l; |
| 123 | 122 | ||
| 124 | len = min(len, fifo->size - fifo->in + fifo->out); | 123 | /* |
| 124 | * Ensure that we sample the fifo->out index -before- we | ||
| 125 | * start putting bytes into the kfifo. | ||
| 126 | */ | ||
| 127 | |||
| 128 | smp_mb(); | ||
| 129 | |||
| 130 | off = __kfifo_off(fifo, fifo->in + off); | ||
| 131 | |||
| 132 | /* first put the data starting from fifo->in to buffer end */ | ||
| 133 | l = min(len, fifo->size - off); | ||
| 134 | memcpy(fifo->buffer + off, from, l); | ||
| 135 | |||
| 136 | /* then put the rest (if any) at the beginning of the buffer */ | ||
| 137 | memcpy(fifo->buffer, from + l, len - l); | ||
| 138 | } | ||
| 139 | |||
| 140 | static inline void __kfifo_out_data(struct kfifo *fifo, | ||
| 141 | void *to, unsigned int len, unsigned int off) | ||
| 142 | { | ||
| 143 | unsigned int l; | ||
| 144 | |||
| 145 | /* | ||
| 146 | * Ensure that we sample the fifo->in index -before- we | ||
| 147 | * start removing bytes from the kfifo. | ||
| 148 | */ | ||
| 149 | |||
| 150 | smp_rmb(); | ||
| 151 | |||
| 152 | off = __kfifo_off(fifo, fifo->out + off); | ||
| 153 | |||
| 154 | /* first get the data from fifo->out until the end of the buffer */ | ||
| 155 | l = min(len, fifo->size - off); | ||
| 156 | memcpy(to, fifo->buffer + off, l); | ||
| 157 | |||
| 158 | /* then get the rest (if any) from the beginning of the buffer */ | ||
| 159 | memcpy(to + l, fifo->buffer, len - l); | ||
| 160 | } | ||
| 161 | |||
| 162 | static inline unsigned int __kfifo_from_user_data(struct kfifo *fifo, | ||
| 163 | const void __user *from, unsigned int len, unsigned int off) | ||
| 164 | { | ||
| 165 | unsigned int l; | ||
| 166 | int ret; | ||
| 125 | 167 | ||
| 126 | /* | 168 | /* |
| 127 | * Ensure that we sample the fifo->out index -before- we | 169 | * Ensure that we sample the fifo->out index -before- we |
| @@ -130,68 +172,229 @@ unsigned int __kfifo_put(struct kfifo *fifo, | |||
| 130 | 172 | ||
| 131 | smp_mb(); | 173 | smp_mb(); |
| 132 | 174 | ||
| 175 | off = __kfifo_off(fifo, fifo->in + off); | ||
| 176 | |||
| 133 | /* first put the data starting from fifo->in to buffer end */ | 177 | /* first put the data starting from fifo->in to buffer end */ |
| 134 | l = min(len, fifo->size - (fifo->in & (fifo->size - 1))); | 178 | l = min(len, fifo->size - off); |
| 135 | memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l); | 179 | ret = copy_from_user(fifo->buffer + off, from, l); |
| 180 | |||
| 181 | if (unlikely(ret)) | ||
| 182 | return ret + len - l; | ||
| 136 | 183 | ||
| 137 | /* then put the rest (if any) at the beginning of the buffer */ | 184 | /* then put the rest (if any) at the beginning of the buffer */ |
| 138 | memcpy(fifo->buffer, buffer + l, len - l); | 185 | return copy_from_user(fifo->buffer, from + l, len - l); |
| 186 | } | ||
| 187 | |||
| 188 | static inline unsigned int __kfifo_to_user_data(struct kfifo *fifo, | ||
| 189 | void __user *to, unsigned int len, unsigned int off) | ||
| 190 | { | ||
| 191 | unsigned int l; | ||
| 192 | int ret; | ||
| 139 | 193 | ||
| 140 | /* | 194 | /* |
| 141 | * Ensure that we add the bytes to the kfifo -before- | 195 | * Ensure that we sample the fifo->in index -before- we |
| 142 | * we update the fifo->in index. | 196 | * start removing bytes from the kfifo. |
| 143 | */ | 197 | */ |
| 144 | 198 | ||
| 145 | smp_wmb(); | 199 | smp_rmb(); |
| 200 | |||
| 201 | off = __kfifo_off(fifo, fifo->out + off); | ||
| 202 | |||
| 203 | /* first get the data from fifo->out until the end of the buffer */ | ||
| 204 | l = min(len, fifo->size - off); | ||
| 205 | ret = copy_to_user(to, fifo->buffer + off, l); | ||
| 206 | |||
| 207 | if (unlikely(ret)) | ||
| 208 | return ret + len - l; | ||
| 209 | |||
| 210 | /* then get the rest (if any) from the beginning of the buffer */ | ||
| 211 | return copy_to_user(to + l, fifo->buffer, len - l); | ||
| 212 | } | ||
| 213 | |||
| 214 | unsigned int __kfifo_in_n(struct kfifo *fifo, | ||
| 215 | const void *from, unsigned int len, unsigned int recsize) | ||
| 216 | { | ||
| 217 | if (kfifo_avail(fifo) < len + recsize) | ||
| 218 | return len + 1; | ||
| 219 | |||
| 220 | __kfifo_in_data(fifo, from, len, recsize); | ||
| 221 | return 0; | ||
| 222 | } | ||
| 223 | EXPORT_SYMBOL(__kfifo_in_n); | ||
| 146 | 224 | ||
| 147 | fifo->in += len; | 225 | /** |
| 226 | * kfifo_in - puts some data into the FIFO | ||
| 227 | * @fifo: the fifo to be used. | ||
| 228 | * @from: the data to be added. | ||
| 229 | * @len: the length of the data to be added. | ||
| 230 | * | ||
| 231 | * This function copies at most @len bytes from the @from buffer into | ||
| 232 | * the FIFO depending on the free space, and returns the number of | ||
| 233 | * bytes copied. | ||
| 234 | * | ||
| 235 | * Note that with only one concurrent reader and one concurrent | ||
| 236 | * writer, you don't need extra locking to use these functions. | ||
| 237 | */ | ||
| 238 | unsigned int kfifo_in(struct kfifo *fifo, const unsigned char *from, | ||
| 239 | unsigned int len) | ||
| 240 | { | ||
| 241 | len = min(kfifo_avail(fifo), len); | ||
| 148 | 242 | ||
| 243 | __kfifo_in_data(fifo, from, len, 0); | ||
| 244 | __kfifo_add_in(fifo, len); | ||
| 149 | return len; | 245 | return len; |
| 150 | } | 246 | } |
| 151 | EXPORT_SYMBOL(__kfifo_put); | 247 | EXPORT_SYMBOL(kfifo_in); |
| 248 | |||
| 249 | unsigned int __kfifo_in_generic(struct kfifo *fifo, | ||
| 250 | const void *from, unsigned int len, unsigned int recsize) | ||
| 251 | { | ||
| 252 | return __kfifo_in_rec(fifo, from, len, recsize); | ||
| 253 | } | ||
| 254 | EXPORT_SYMBOL(__kfifo_in_generic); | ||
| 255 | |||
| 256 | unsigned int __kfifo_out_n(struct kfifo *fifo, | ||
| 257 | void *to, unsigned int len, unsigned int recsize) | ||
| 258 | { | ||
| 259 | if (kfifo_len(fifo) < len + recsize) | ||
| 260 | return len; | ||
| 261 | |||
| 262 | __kfifo_out_data(fifo, to, len, recsize); | ||
| 263 | __kfifo_add_out(fifo, len + recsize); | ||
| 264 | return 0; | ||
| 265 | } | ||
| 266 | EXPORT_SYMBOL(__kfifo_out_n); | ||
| 152 | 267 | ||
| 153 | /** | 268 | /** |
| 154 | * __kfifo_get - gets some data from the FIFO, no locking version | 269 | * kfifo_out - gets some data from the FIFO |
| 155 | * @fifo: the fifo to be used. | 270 | * @fifo: the fifo to be used. |
| 156 | * @buffer: where the data must be copied. | 271 | * @to: where the data must be copied. |
| 157 | * @len: the size of the destination buffer. | 272 | * @len: the size of the destination buffer. |
| 158 | * | 273 | * |
| 159 | * This function copies at most @len bytes from the FIFO into the | 274 | * This function copies at most @len bytes from the FIFO into the |
| 160 | * @buffer and returns the number of copied bytes. | 275 | * @to buffer and returns the number of copied bytes. |
| 161 | * | 276 | * |
| 162 | * Note that with only one concurrent reader and one concurrent | 277 | * Note that with only one concurrent reader and one concurrent |
| 163 | * writer, you don't need extra locking to use these functions. | 278 | * writer, you don't need extra locking to use these functions. |
| 164 | */ | 279 | */ |
| 165 | unsigned int __kfifo_get(struct kfifo *fifo, | 280 | unsigned int kfifo_out(struct kfifo *fifo, unsigned char *to, unsigned int len) |
| 166 | unsigned char *buffer, unsigned int len) | ||
| 167 | { | 281 | { |
| 168 | unsigned int l; | 282 | len = min(kfifo_len(fifo), len); |
| 169 | 283 | ||
| 170 | len = min(len, fifo->in - fifo->out); | 284 | __kfifo_out_data(fifo, to, len, 0); |
| 285 | __kfifo_add_out(fifo, len); | ||
| 171 | 286 | ||
| 172 | /* | 287 | return len; |
| 173 | * Ensure that we sample the fifo->in index -before- we | 288 | } |
| 174 | * start removing bytes from the kfifo. | 289 | EXPORT_SYMBOL(kfifo_out); |
| 175 | */ | ||
| 176 | 290 | ||
| 177 | smp_rmb(); | 291 | unsigned int __kfifo_out_generic(struct kfifo *fifo, |
| 292 | void *to, unsigned int len, unsigned int recsize, | ||
| 293 | unsigned int *total) | ||
| 294 | { | ||
| 295 | return __kfifo_out_rec(fifo, to, len, recsize, total); | ||
| 296 | } | ||
| 297 | EXPORT_SYMBOL(__kfifo_out_generic); | ||
| 178 | 298 | ||
| 179 | /* first get the data from fifo->out until the end of the buffer */ | 299 | unsigned int __kfifo_from_user_n(struct kfifo *fifo, |
| 180 | l = min(len, fifo->size - (fifo->out & (fifo->size - 1))); | 300 | const void __user *from, unsigned int len, unsigned int recsize) |
| 181 | memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l); | 301 | { |
| 302 | if (kfifo_avail(fifo) < len + recsize) | ||
| 303 | return len + 1; | ||
| 182 | 304 | ||
| 183 | /* then get the rest (if any) from the beginning of the buffer */ | 305 | return __kfifo_from_user_data(fifo, from, len, recsize); |
| 184 | memcpy(buffer + l, fifo->buffer, len - l); | 306 | } |
| 307 | EXPORT_SYMBOL(__kfifo_from_user_n); | ||
| 185 | 308 | ||
| 186 | /* | 309 | /** |
| 187 | * Ensure that we remove the bytes from the kfifo -before- | 310 | * kfifo_from_user - puts some data from user space into the FIFO |
| 188 | * we update the fifo->out index. | 311 | * @fifo: the fifo to be used. |
| 189 | */ | 312 | * @from: pointer to the data to be added. |
| 313 | * @len: the length of the data to be added. | ||
| 314 | * | ||
| 315 | * This function copies at most @len bytes from the @from into the | ||
| 316 | * FIFO depending and returns the number of copied bytes. | ||
| 317 | * | ||
| 318 | * Note that with only one concurrent reader and one concurrent | ||
| 319 | * writer, you don't need extra locking to use these functions. | ||
| 320 | */ | ||
| 321 | unsigned int kfifo_from_user(struct kfifo *fifo, | ||
| 322 | const void __user *from, unsigned int len) | ||
| 323 | { | ||
| 324 | len = min(kfifo_avail(fifo), len); | ||
| 325 | len -= __kfifo_from_user_data(fifo, from, len, 0); | ||
| 326 | __kfifo_add_in(fifo, len); | ||
| 327 | return len; | ||
| 328 | } | ||
| 329 | EXPORT_SYMBOL(kfifo_from_user); | ||
| 190 | 330 | ||
| 191 | smp_mb(); | 331 | unsigned int __kfifo_from_user_generic(struct kfifo *fifo, |
| 332 | const void __user *from, unsigned int len, unsigned int recsize) | ||
| 333 | { | ||
| 334 | return __kfifo_from_user_rec(fifo, from, len, recsize); | ||
| 335 | } | ||
| 336 | EXPORT_SYMBOL(__kfifo_from_user_generic); | ||
| 192 | 337 | ||
| 193 | fifo->out += len; | 338 | unsigned int __kfifo_to_user_n(struct kfifo *fifo, |
| 339 | void __user *to, unsigned int len, unsigned int reclen, | ||
| 340 | unsigned int recsize) | ||
| 341 | { | ||
| 342 | unsigned int ret; | ||
| 343 | |||
| 344 | if (kfifo_len(fifo) < reclen + recsize) | ||
| 345 | return len; | ||
| 346 | |||
| 347 | ret = __kfifo_to_user_data(fifo, to, reclen, recsize); | ||
| 194 | 348 | ||
| 349 | if (likely(ret == 0)) | ||
| 350 | __kfifo_add_out(fifo, reclen + recsize); | ||
| 351 | |||
| 352 | return ret; | ||
| 353 | } | ||
| 354 | EXPORT_SYMBOL(__kfifo_to_user_n); | ||
| 355 | |||
| 356 | /** | ||
| 357 | * kfifo_to_user - gets data from the FIFO and write it to user space | ||
| 358 | * @fifo: the fifo to be used. | ||
| 359 | * @to: where the data must be copied. | ||
| 360 | * @len: the size of the destination buffer. | ||
| 361 | * | ||
| 362 | * This function copies at most @len bytes from the FIFO into the | ||
| 363 | * @to buffer and returns the number of copied bytes. | ||
| 364 | * | ||
| 365 | * Note that with only one concurrent reader and one concurrent | ||
| 366 | * writer, you don't need extra locking to use these functions. | ||
| 367 | */ | ||
| 368 | unsigned int kfifo_to_user(struct kfifo *fifo, | ||
| 369 | void __user *to, unsigned int len) | ||
| 370 | { | ||
| 371 | len = min(kfifo_len(fifo), len); | ||
| 372 | len -= __kfifo_to_user_data(fifo, to, len, 0); | ||
| 373 | __kfifo_add_out(fifo, len); | ||
| 195 | return len; | 374 | return len; |
| 196 | } | 375 | } |
| 197 | EXPORT_SYMBOL(__kfifo_get); | 376 | EXPORT_SYMBOL(kfifo_to_user); |
| 377 | |||
| 378 | unsigned int __kfifo_to_user_generic(struct kfifo *fifo, | ||
| 379 | void __user *to, unsigned int len, unsigned int recsize, | ||
| 380 | unsigned int *total) | ||
| 381 | { | ||
| 382 | return __kfifo_to_user_rec(fifo, to, len, recsize, total); | ||
| 383 | } | ||
| 384 | EXPORT_SYMBOL(__kfifo_to_user_generic); | ||
| 385 | |||
| 386 | unsigned int __kfifo_peek_generic(struct kfifo *fifo, unsigned int recsize) | ||
| 387 | { | ||
| 388 | if (recsize == 0) | ||
| 389 | return kfifo_avail(fifo); | ||
| 390 | |||
| 391 | return __kfifo_peek_n(fifo, recsize); | ||
| 392 | } | ||
| 393 | EXPORT_SYMBOL(__kfifo_peek_generic); | ||
| 394 | |||
| 395 | void __kfifo_skip_generic(struct kfifo *fifo, unsigned int recsize) | ||
| 396 | { | ||
| 397 | __kfifo_skip_rec(fifo, recsize); | ||
| 398 | } | ||
| 399 | EXPORT_SYMBOL(__kfifo_skip_generic); | ||
| 400 | |||
diff --git a/kernel/resource.c b/kernel/resource.c index dc15686b7a77..af96c1e4b54b 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
| @@ -308,37 +308,37 @@ static int find_resource(struct resource *root, struct resource *new, | |||
| 308 | void *alignf_data) | 308 | void *alignf_data) |
| 309 | { | 309 | { |
| 310 | struct resource *this = root->child; | 310 | struct resource *this = root->child; |
| 311 | resource_size_t start, end; | 311 | struct resource tmp = *new; |
| 312 | 312 | ||
| 313 | start = root->start; | 313 | tmp.start = root->start; |
| 314 | /* | 314 | /* |
| 315 | * Skip past an allocated resource that starts at 0, since the assignment | 315 | * Skip past an allocated resource that starts at 0, since the assignment |
| 316 | * of this->start - 1 to new->end below would cause an underflow. | 316 | * of this->start - 1 to tmp->end below would cause an underflow. |
| 317 | */ | 317 | */ |
| 318 | if (this && this->start == 0) { | 318 | if (this && this->start == 0) { |
| 319 | start = this->end + 1; | 319 | tmp.start = this->end + 1; |
| 320 | this = this->sibling; | 320 | this = this->sibling; |
| 321 | } | 321 | } |
| 322 | for(;;) { | 322 | for(;;) { |
| 323 | if (this) | 323 | if (this) |
| 324 | end = this->start - 1; | 324 | tmp.end = this->start - 1; |
| 325 | else | 325 | else |
| 326 | end = root->end; | 326 | tmp.end = root->end; |
| 327 | if (start < min) | 327 | if (tmp.start < min) |
| 328 | start = min; | 328 | tmp.start = min; |
| 329 | if (end > max) | 329 | if (tmp.end > max) |
| 330 | end = max; | 330 | tmp.end = max; |
| 331 | start = ALIGN(start, align); | 331 | tmp.start = ALIGN(tmp.start, align); |
| 332 | if (alignf) | 332 | if (alignf) |
| 333 | alignf(alignf_data, new, size, align); | 333 | alignf(alignf_data, &tmp, size, align); |
| 334 | if (start < end && end - start >= size - 1) { | 334 | if (tmp.start < tmp.end && tmp.end - tmp.start >= size - 1) { |
| 335 | new->start = start; | 335 | new->start = tmp.start; |
| 336 | new->end = start + size - 1; | 336 | new->end = tmp.start + size - 1; |
| 337 | return 0; | 337 | return 0; |
| 338 | } | 338 | } |
| 339 | if (!this) | 339 | if (!this) |
| 340 | break; | 340 | break; |
| 341 | start = this->end + 1; | 341 | tmp.start = this->end + 1; |
| 342 | this = this->sibling; | 342 | this = this->sibling; |
| 343 | } | 343 | } |
| 344 | return -EBUSY; | 344 | return -EBUSY; |
diff --git a/kernel/time.c b/kernel/time.c index c6324d96009e..804798005d19 100644 --- a/kernel/time.c +++ b/kernel/time.c | |||
| @@ -136,6 +136,7 @@ static inline void warp_clock(void) | |||
| 136 | write_seqlock_irq(&xtime_lock); | 136 | write_seqlock_irq(&xtime_lock); |
| 137 | wall_to_monotonic.tv_sec -= sys_tz.tz_minuteswest * 60; | 137 | wall_to_monotonic.tv_sec -= sys_tz.tz_minuteswest * 60; |
| 138 | xtime.tv_sec += sys_tz.tz_minuteswest * 60; | 138 | xtime.tv_sec += sys_tz.tz_minuteswest * 60; |
| 139 | update_xtime_cache(0); | ||
| 139 | write_sequnlock_irq(&xtime_lock); | 140 | write_sequnlock_irq(&xtime_lock); |
| 140 | clock_was_set(); | 141 | clock_was_set(); |
| 141 | } | 142 | } |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index af4135f05825..7faaa32fbf4f 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
| @@ -165,6 +165,13 @@ struct timespec raw_time; | |||
| 165 | /* flag for if timekeeping is suspended */ | 165 | /* flag for if timekeeping is suspended */ |
| 166 | int __read_mostly timekeeping_suspended; | 166 | int __read_mostly timekeeping_suspended; |
| 167 | 167 | ||
| 168 | static struct timespec xtime_cache __attribute__ ((aligned (16))); | ||
| 169 | void update_xtime_cache(u64 nsec) | ||
| 170 | { | ||
| 171 | xtime_cache = xtime; | ||
| 172 | timespec_add_ns(&xtime_cache, nsec); | ||
| 173 | } | ||
| 174 | |||
| 168 | /* must hold xtime_lock */ | 175 | /* must hold xtime_lock */ |
| 169 | void timekeeping_leap_insert(int leapsecond) | 176 | void timekeeping_leap_insert(int leapsecond) |
| 170 | { | 177 | { |
| @@ -325,6 +332,8 @@ int do_settimeofday(struct timespec *tv) | |||
| 325 | 332 | ||
| 326 | xtime = *tv; | 333 | xtime = *tv; |
| 327 | 334 | ||
| 335 | update_xtime_cache(0); | ||
| 336 | |||
| 328 | timekeeper.ntp_error = 0; | 337 | timekeeper.ntp_error = 0; |
| 329 | ntp_clear(); | 338 | ntp_clear(); |
| 330 | 339 | ||
| @@ -550,6 +559,7 @@ void __init timekeeping_init(void) | |||
| 550 | } | 559 | } |
| 551 | set_normalized_timespec(&wall_to_monotonic, | 560 | set_normalized_timespec(&wall_to_monotonic, |
| 552 | -boot.tv_sec, -boot.tv_nsec); | 561 | -boot.tv_sec, -boot.tv_nsec); |
| 562 | update_xtime_cache(0); | ||
| 553 | total_sleep_time.tv_sec = 0; | 563 | total_sleep_time.tv_sec = 0; |
| 554 | total_sleep_time.tv_nsec = 0; | 564 | total_sleep_time.tv_nsec = 0; |
| 555 | write_sequnlock_irqrestore(&xtime_lock, flags); | 565 | write_sequnlock_irqrestore(&xtime_lock, flags); |
| @@ -583,6 +593,7 @@ static int timekeeping_resume(struct sys_device *dev) | |||
| 583 | wall_to_monotonic = timespec_sub(wall_to_monotonic, ts); | 593 | wall_to_monotonic = timespec_sub(wall_to_monotonic, ts); |
| 584 | total_sleep_time = timespec_add_safe(total_sleep_time, ts); | 594 | total_sleep_time = timespec_add_safe(total_sleep_time, ts); |
| 585 | } | 595 | } |
| 596 | update_xtime_cache(0); | ||
| 586 | /* re-base the last cycle value */ | 597 | /* re-base the last cycle value */ |
| 587 | timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock); | 598 | timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock); |
| 588 | timekeeper.ntp_error = 0; | 599 | timekeeper.ntp_error = 0; |
| @@ -722,6 +733,7 @@ static void timekeeping_adjust(s64 offset) | |||
| 722 | timekeeper.ntp_error_shift; | 733 | timekeeper.ntp_error_shift; |
| 723 | } | 734 | } |
| 724 | 735 | ||
| 736 | |||
| 725 | /** | 737 | /** |
| 726 | * logarithmic_accumulation - shifted accumulation of cycles | 738 | * logarithmic_accumulation - shifted accumulation of cycles |
| 727 | * | 739 | * |
| @@ -765,6 +777,7 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift) | |||
| 765 | return offset; | 777 | return offset; |
| 766 | } | 778 | } |
| 767 | 779 | ||
| 780 | |||
| 768 | /** | 781 | /** |
| 769 | * update_wall_time - Uses the current clocksource to increment the wall time | 782 | * update_wall_time - Uses the current clocksource to increment the wall time |
| 770 | * | 783 | * |
| @@ -774,6 +787,7 @@ void update_wall_time(void) | |||
| 774 | { | 787 | { |
| 775 | struct clocksource *clock; | 788 | struct clocksource *clock; |
| 776 | cycle_t offset; | 789 | cycle_t offset; |
| 790 | u64 nsecs; | ||
| 777 | int shift = 0, maxshift; | 791 | int shift = 0, maxshift; |
| 778 | 792 | ||
| 779 | /* Make sure we're fully resumed: */ | 793 | /* Make sure we're fully resumed: */ |
| @@ -839,6 +853,9 @@ void update_wall_time(void) | |||
| 839 | timekeeper.ntp_error += timekeeper.xtime_nsec << | 853 | timekeeper.ntp_error += timekeeper.xtime_nsec << |
| 840 | timekeeper.ntp_error_shift; | 854 | timekeeper.ntp_error_shift; |
| 841 | 855 | ||
| 856 | nsecs = clocksource_cyc2ns(offset, timekeeper.mult, timekeeper.shift); | ||
| 857 | update_xtime_cache(nsecs); | ||
| 858 | |||
| 842 | /* check to see if there is a new clocksource to use */ | 859 | /* check to see if there is a new clocksource to use */ |
| 843 | update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult); | 860 | update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult); |
| 844 | } | 861 | } |
| @@ -875,13 +892,13 @@ void monotonic_to_bootbased(struct timespec *ts) | |||
| 875 | 892 | ||
| 876 | unsigned long get_seconds(void) | 893 | unsigned long get_seconds(void) |
| 877 | { | 894 | { |
| 878 | return xtime.tv_sec; | 895 | return xtime_cache.tv_sec; |
| 879 | } | 896 | } |
| 880 | EXPORT_SYMBOL(get_seconds); | 897 | EXPORT_SYMBOL(get_seconds); |
| 881 | 898 | ||
| 882 | struct timespec __current_kernel_time(void) | 899 | struct timespec __current_kernel_time(void) |
| 883 | { | 900 | { |
| 884 | return xtime; | 901 | return xtime_cache; |
| 885 | } | 902 | } |
| 886 | 903 | ||
| 887 | struct timespec current_kernel_time(void) | 904 | struct timespec current_kernel_time(void) |
| @@ -891,7 +908,8 @@ struct timespec current_kernel_time(void) | |||
| 891 | 908 | ||
| 892 | do { | 909 | do { |
| 893 | seq = read_seqbegin(&xtime_lock); | 910 | seq = read_seqbegin(&xtime_lock); |
| 894 | now = xtime; | 911 | |
| 912 | now = xtime_cache; | ||
| 895 | } while (read_seqretry(&xtime_lock, seq)); | 913 | } while (read_seqretry(&xtime_lock, seq)); |
| 896 | 914 | ||
| 897 | return now; | 915 | return now; |
| @@ -905,7 +923,8 @@ struct timespec get_monotonic_coarse(void) | |||
| 905 | 923 | ||
| 906 | do { | 924 | do { |
| 907 | seq = read_seqbegin(&xtime_lock); | 925 | seq = read_seqbegin(&xtime_lock); |
| 908 | now = xtime; | 926 | |
| 927 | now = xtime_cache; | ||
| 909 | mono = wall_to_monotonic; | 928 | mono = wall_to_monotonic; |
| 910 | } while (read_seqretry(&xtime_lock, seq)); | 929 | } while (read_seqretry(&xtime_lock, seq)); |
| 911 | 930 | ||
diff --git a/lib/string.c b/lib/string.c index afce96af3afd..9f75b4ec50b8 100644 --- a/lib/string.c +++ b/lib/string.c | |||
| @@ -338,10 +338,10 @@ EXPORT_SYMBOL(strnchr); | |||
| 338 | #endif | 338 | #endif |
| 339 | 339 | ||
| 340 | /** | 340 | /** |
| 341 | * skip_spaces - Removes leading whitespace from @s. | 341 | * skip_spaces - Removes leading whitespace from @str. |
| 342 | * @s: The string to be stripped. | 342 | * @str: The string to be stripped. |
| 343 | * | 343 | * |
| 344 | * Returns a pointer to the first non-whitespace character in @s. | 344 | * Returns a pointer to the first non-whitespace character in @str. |
| 345 | */ | 345 | */ |
| 346 | char *skip_spaces(const char *str) | 346 | char *skip_spaces(const char *str) |
| 347 | { | 347 | { |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 4e869657cb51..d79b92580561 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -48,6 +48,7 @@ | |||
| 48 | #include <linux/page_cgroup.h> | 48 | #include <linux/page_cgroup.h> |
| 49 | #include <linux/debugobjects.h> | 49 | #include <linux/debugobjects.h> |
| 50 | #include <linux/kmemleak.h> | 50 | #include <linux/kmemleak.h> |
| 51 | #include <linux/memory.h> | ||
| 51 | #include <trace/events/kmem.h> | 52 | #include <trace/events/kmem.h> |
| 52 | 53 | ||
| 53 | #include <asm/tlbflush.h> | 54 | #include <asm/tlbflush.h> |
| @@ -5008,23 +5009,65 @@ void set_pageblock_flags_group(struct page *page, unsigned long flags, | |||
| 5008 | int set_migratetype_isolate(struct page *page) | 5009 | int set_migratetype_isolate(struct page *page) |
| 5009 | { | 5010 | { |
| 5010 | struct zone *zone; | 5011 | struct zone *zone; |
| 5011 | unsigned long flags; | 5012 | struct page *curr_page; |
| 5013 | unsigned long flags, pfn, iter; | ||
| 5014 | unsigned long immobile = 0; | ||
| 5015 | struct memory_isolate_notify arg; | ||
| 5016 | int notifier_ret; | ||
| 5012 | int ret = -EBUSY; | 5017 | int ret = -EBUSY; |
| 5013 | int zone_idx; | 5018 | int zone_idx; |
| 5014 | 5019 | ||
| 5015 | zone = page_zone(page); | 5020 | zone = page_zone(page); |
| 5016 | zone_idx = zone_idx(zone); | 5021 | zone_idx = zone_idx(zone); |
| 5022 | |||
| 5017 | spin_lock_irqsave(&zone->lock, flags); | 5023 | spin_lock_irqsave(&zone->lock, flags); |
| 5024 | if (get_pageblock_migratetype(page) == MIGRATE_MOVABLE || | ||
| 5025 | zone_idx == ZONE_MOVABLE) { | ||
| 5026 | ret = 0; | ||
| 5027 | goto out; | ||
| 5028 | } | ||
| 5029 | |||
| 5030 | pfn = page_to_pfn(page); | ||
| 5031 | arg.start_pfn = pfn; | ||
| 5032 | arg.nr_pages = pageblock_nr_pages; | ||
| 5033 | arg.pages_found = 0; | ||
| 5034 | |||
| 5018 | /* | 5035 | /* |
| 5019 | * In future, more migrate types will be able to be isolation target. | 5036 | * It may be possible to isolate a pageblock even if the |
| 5037 | * migratetype is not MIGRATE_MOVABLE. The memory isolation | ||
| 5038 | * notifier chain is used by balloon drivers to return the | ||
| 5039 | * number of pages in a range that are held by the balloon | ||
| 5040 | * driver to shrink memory. If all the pages are accounted for | ||
| 5041 | * by balloons, are free, or on the LRU, isolation can continue. | ||
| 5042 | * Later, for example, when memory hotplug notifier runs, these | ||
| 5043 | * pages reported as "can be isolated" should be isolated(freed) | ||
| 5044 | * by the balloon driver through the memory notifier chain. | ||
| 5020 | */ | 5045 | */ |
| 5021 | if (get_pageblock_migratetype(page) != MIGRATE_MOVABLE && | 5046 | notifier_ret = memory_isolate_notify(MEM_ISOLATE_COUNT, &arg); |
| 5022 | zone_idx != ZONE_MOVABLE) | 5047 | notifier_ret = notifier_to_errno(notifier_ret); |
| 5048 | if (notifier_ret || !arg.pages_found) | ||
| 5023 | goto out; | 5049 | goto out; |
| 5024 | set_pageblock_migratetype(page, MIGRATE_ISOLATE); | 5050 | |
| 5025 | move_freepages_block(zone, page, MIGRATE_ISOLATE); | 5051 | for (iter = pfn; iter < (pfn + pageblock_nr_pages); iter++) { |
| 5026 | ret = 0; | 5052 | if (!pfn_valid_within(pfn)) |
| 5053 | continue; | ||
| 5054 | |||
| 5055 | curr_page = pfn_to_page(iter); | ||
| 5056 | if (!page_count(curr_page) || PageLRU(curr_page)) | ||
| 5057 | continue; | ||
| 5058 | |||
| 5059 | immobile++; | ||
| 5060 | } | ||
| 5061 | |||
| 5062 | if (arg.pages_found == immobile) | ||
| 5063 | ret = 0; | ||
| 5064 | |||
| 5027 | out: | 5065 | out: |
| 5066 | if (!ret) { | ||
| 5067 | set_pageblock_migratetype(page, MIGRATE_ISOLATE); | ||
| 5068 | move_freepages_block(zone, page, MIGRATE_ISOLATE); | ||
| 5069 | } | ||
| 5070 | |||
| 5028 | spin_unlock_irqrestore(&zone->lock, flags); | 5071 | spin_unlock_irqrestore(&zone->lock, flags); |
| 5029 | if (!ret) | 5072 | if (!ret) |
| 5030 | drain_all_pages(); | 5073 | drain_all_pages(); |
diff --git a/net/dccp/probe.c b/net/dccp/probe.c index dc328425fa20..a1362dc8abb0 100644 --- a/net/dccp/probe.c +++ b/net/dccp/probe.c | |||
| @@ -43,7 +43,7 @@ static int bufsize = 64 * 1024; | |||
| 43 | static const char procname[] = "dccpprobe"; | 43 | static const char procname[] = "dccpprobe"; |
| 44 | 44 | ||
| 45 | static struct { | 45 | static struct { |
| 46 | struct kfifo *fifo; | 46 | struct kfifo fifo; |
| 47 | spinlock_t lock; | 47 | spinlock_t lock; |
| 48 | wait_queue_head_t wait; | 48 | wait_queue_head_t wait; |
| 49 | struct timespec tstart; | 49 | struct timespec tstart; |
| @@ -67,7 +67,7 @@ static void printl(const char *fmt, ...) | |||
| 67 | len += vscnprintf(tbuf+len, sizeof(tbuf)-len, fmt, args); | 67 | len += vscnprintf(tbuf+len, sizeof(tbuf)-len, fmt, args); |
| 68 | va_end(args); | 68 | va_end(args); |
| 69 | 69 | ||
| 70 | kfifo_put(dccpw.fifo, tbuf, len); | 70 | kfifo_in_locked(&dccpw.fifo, tbuf, len, &dccpw.lock); |
| 71 | wake_up(&dccpw.wait); | 71 | wake_up(&dccpw.wait); |
| 72 | } | 72 | } |
| 73 | 73 | ||
| @@ -109,7 +109,7 @@ static struct jprobe dccp_send_probe = { | |||
| 109 | 109 | ||
| 110 | static int dccpprobe_open(struct inode *inode, struct file *file) | 110 | static int dccpprobe_open(struct inode *inode, struct file *file) |
| 111 | { | 111 | { |
| 112 | kfifo_reset(dccpw.fifo); | 112 | kfifo_reset(&dccpw.fifo); |
| 113 | getnstimeofday(&dccpw.tstart); | 113 | getnstimeofday(&dccpw.tstart); |
| 114 | return 0; | 114 | return 0; |
| 115 | } | 115 | } |
| @@ -131,11 +131,11 @@ static ssize_t dccpprobe_read(struct file *file, char __user *buf, | |||
| 131 | return -ENOMEM; | 131 | return -ENOMEM; |
| 132 | 132 | ||
| 133 | error = wait_event_interruptible(dccpw.wait, | 133 | error = wait_event_interruptible(dccpw.wait, |
| 134 | __kfifo_len(dccpw.fifo) != 0); | 134 | kfifo_len(&dccpw.fifo) != 0); |
| 135 | if (error) | 135 | if (error) |
| 136 | goto out_free; | 136 | goto out_free; |
| 137 | 137 | ||
| 138 | cnt = kfifo_get(dccpw.fifo, tbuf, len); | 138 | cnt = kfifo_out_locked(&dccpw.fifo, tbuf, len, &dccpw.lock); |
| 139 | error = copy_to_user(buf, tbuf, cnt) ? -EFAULT : 0; | 139 | error = copy_to_user(buf, tbuf, cnt) ? -EFAULT : 0; |
| 140 | 140 | ||
| 141 | out_free: | 141 | out_free: |
| @@ -156,10 +156,8 @@ static __init int dccpprobe_init(void) | |||
| 156 | 156 | ||
| 157 | init_waitqueue_head(&dccpw.wait); | 157 | init_waitqueue_head(&dccpw.wait); |
| 158 | spin_lock_init(&dccpw.lock); | 158 | spin_lock_init(&dccpw.lock); |
| 159 | dccpw.fifo = kfifo_alloc(bufsize, GFP_KERNEL, &dccpw.lock); | 159 | if (kfifo_alloc(&dccpw.fifo, bufsize, GFP_KERNEL)) |
| 160 | if (IS_ERR(dccpw.fifo)) | 160 | return ret; |
| 161 | return PTR_ERR(dccpw.fifo); | ||
| 162 | |||
| 163 | if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &dccpprobe_fops)) | 161 | if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &dccpprobe_fops)) |
| 164 | goto err0; | 162 | goto err0; |
| 165 | 163 | ||
| @@ -172,14 +170,14 @@ static __init int dccpprobe_init(void) | |||
| 172 | err1: | 170 | err1: |
| 173 | proc_net_remove(&init_net, procname); | 171 | proc_net_remove(&init_net, procname); |
| 174 | err0: | 172 | err0: |
| 175 | kfifo_free(dccpw.fifo); | 173 | kfifo_free(&dccpw.fifo); |
| 176 | return ret; | 174 | return ret; |
| 177 | } | 175 | } |
| 178 | module_init(dccpprobe_init); | 176 | module_init(dccpprobe_init); |
| 179 | 177 | ||
| 180 | static __exit void dccpprobe_exit(void) | 178 | static __exit void dccpprobe_exit(void) |
| 181 | { | 179 | { |
| 182 | kfifo_free(dccpw.fifo); | 180 | kfifo_free(&dccpw.fifo); |
| 183 | proc_net_remove(&init_net, procname); | 181 | proc_net_remove(&init_net, procname); |
| 184 | unregister_jprobe(&dccp_send_probe); | 182 | unregister_jprobe(&dccp_send_probe); |
| 185 | 183 | ||
